[Cryptography] Bent, crooked, and twisted functions

Pierre Abbat phma at bezitopo.org
Mon Sep 22 03:20:18 EDT 2025


A bent function is a Boolean function whose Hadamard transform is flat. 
Wikipedia has an article about bent functions, including a construction for 
all even orders. Bent functions satisfy the SAC for any positive number of 
changed bits.

Bent functions have a couple of problems when used for S-boxes:
* Bent functions exist only in even orders. You can't make a bent function 
which takes three or seven bits as input.
* Bent functions aren't balanced. For some kinds of ciphers, you want S-boxes 
which are permutations (invertible functions), which are balanced (the output 
has as many one-bits as zero-bits).

A crooked function is a vectorial Boolean function whose derivative, for any 
nonzero difference, takes as many different values as possible. Crooked 
functions exist for both odd and even orders, and they can be permutations. I 
did some web searching, but did not find an example of a crooked function.

I define a twisted function as follows: A twisted function is a vectorial 
Boolean function whose input and output have the same size, consisting of 
these steps:
1. Exclusive-or the input with a constant.
2. Apply a constant permutation to the bits.
3. Rotate the bit vector by its population count.
4. Apply a constant permutation to the bits.
5. Exclusive-or the output with a constant.

Twisted functions of order at least 3 satisfy the SAC for single bit flips, but 
not double bit flips. (All 24 permutations of order 2 are linear.) They are 
permutations and either preserve or invert the parity. The simplest nonlinear 
twisted function is [0,2,4,5,1,6,3,7]. It is not a crooked function, as when 
the difference has two bits (3, 5, or 6), there are only two different values of 
the derivative.

I wrote this code to calculate what degrees have nonzero coefficients in the 
expansion of a vectorial Boolean function:

"""
    powerTransform(buf::OffsetVector{<:Integer})

Takes a vector Boolean function and transforms it so that the constant term
is in [0], the linear terms are in [1],[2],[4],[8],..., the quadratic terms
are in [3],[5],[6],[9],[10],[12],..., and so on. I don't know what this is
called. It seems to be a variant of the pseudo-Hadamard transform.
"""
function powerTransform(buf::OffsetVector{<:Integer})
  tmp0=copy(buf)
  tmp1=copy(buf)
  sz=length(buf)
  h=sz÷2
  if ispow2(sz) && Origin(buf)==Origin((0,))
    while h>0
      for i in 0:sz-1
	j=i⊻h
	if i>j
	  @inbounds tmp1[i]=tmp0[j]⊻tmp0[i]
	else
	  @inbounds tmp1[i]=tmp0[i]
	end
      end
      tmp0,tmp1=tmp1,tmp0
      h÷=2
    end
  end
  tmp0
end

function powerSpectrum(buf::OffsetVector{<:Integer})
  # "power" means exponentiation, not energy per time.
  spectrum=OffsetVector(fill(0,count_ones(length(buf)-1)+1),-1)
  pt=powerTransform(buf)
  for i in eachindex(pt)
    if pt[i]!=0
      spectrum[count_ones(i)]+=1
    end
  end
  spectrum
end

nonlinearity(buf)=sum(powerSpectrum(buf)[2:end])

Here's what it says for bent functions of orders 4 and 6:

julia> powerSpectrum(OffsetVector([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0],-1))
5-element OffsetArray(::Vector{Int64}, 0:4) with eltype Int64 with indices 0:4:
 0
 0
 2
 0
 0

julia> 
powerSpectrum(OffsetVector([0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,1],-1))
7-element OffsetArray(::Vector{Int64}, 0:6) with eltype Int64 with indices 0:6:
 0
 0
 3
 0
 0
 0
 0

They are entirely quadratic. And for the simplest twisted function:

julia> powerSpectrum(OffsetVector([0,2,4,5,1,6,3,7],-1))
4-element OffsetArray(::Vector{Int64}, 0:3) with eltype Int64 with indices 0:3:
 0
 3
 3
 0

The Daphne S-box is an order-8 twisted function:

julia> powerSpectrum(DaphneCipher.sbox)
9-element OffsetArray(::Vector{Int64}, 0:8) with eltype Int64 with indices 0:8:
  1
  8
 27
 56
 67
 56
 23
  8
  0

The last term is always 0 for a permutation, because it's the count of all the 
only 1 exclusive-or of all the outputs of the function (except for order 1).

Pierre
-- 
lo ponse be lo mruli ku po'o cu ga'ezga roda lo ka dinko





More information about the cryptography mailing list