Internals

API described here is intended for internal use. Changing it in incompatible ways will not be considered a breaking change w.r.t versioning. If you feel the need to use any of this outside of Keccak.jl, feel free to open a Github issue about it.

Sponge

Keccak.SpongeType
Sponge{R,T<:NTuple,Fxfm,Fpad}

Cryptographic sponge holding a fixed-length permutation function, state of that length, a function to apply padding, and an offset for byte-wise input and output.

A Sponge allows absorbing and squeezing arbitrary-sized data chunks. Once per every rate bytes absorbed or squeezed, the permutation function is invoked. After the last absorb and before the first squeeze, pad should be called to perform any necessary padding. I.e. the valid sequence of operations on a sponge is: Any number (including zero) calls to absorb, exactly one call to pad, any number (including zero) calls to squeeze.

Note that a Sponge is immutable; any operations updating it return an updated Sponge instead of mutating the given one.

Type parameters

  • T: type of the NTuple holding the sponge contents
  • R: the rate in units of the state elements (eltype(T))
  • Fxfm: type of the permutation function
  • Fpad: type of the padding function

Fields

  • transform: the permutation function invoked for every rate bytes absorbed or squeezed
  • pad: the padding function invoked by pad(::Sponge)
  • state: the sponge contents
  • k: the write (while absorbing) or read (while squeezing) byte offset inside the state, between 0 (inclusive) and R*sizeof(eltype(T)) (exclusive)

SIMD support

If T<:SIMD.Vec (i.e. the state tuple holds SIMD.Vecs), absorbing and squeezing treats the individual data paths separately (and the rate in bytes is given by R*sizeof(eltype(eltype(T)))) in this case.)

source
Keccak.AbsorbableDataType
AbsorbableData

Type alias for the type of data acceptable as input to absorb.

If a String is to be absorbed, its codeunits are used.

source
Keccak.updateFunction
update(sponge::Sponge, state, k)

Return a new Sponge of the same type as sponge with the same transform function, but with state and k replaced with the given values.

source
Keccak.lanetypeFunction
lanetype(sponge::Sponge)

Returns type of the sponge state data. For SIMD sponge, the eltype of the SIMD.Vec is returned. I.e. assuming the data is a Tuple{Vararg{T}}, then T is returned if T<:Unsigned and eltype(T) is returned if T<:SIMD.Vec.

source
Keccak.rateFunction
rate(sponge::Sponge)

Returns the rate (in bytes) of the given sponge.

source

Kᴇᴄᴄᴀᴋ Helpers

Keccak.ℓFunction
ℓ(::Type{T<:Unsigned})

Returns the base-2 logarithm of the bitwidth of values of type T.

Examples

julia> ℓ(UInt32)
5

julia> 2^5
32
source
Keccak.rcFunction
rc(t)

Evaluate t rounds of a linear feedback shift register and return the leading bit after the final round as specified in Algorithm 5 of FIPS-202.

This function is used for computing the round constants by round_consts.

source
Keccak.round_constsFunction
round_consts(::Type{T}, ::Val{nrounds}=Val(12+2ℓ(T)))

Compute the Keccak round constants for lane length w corresponding to the bitwidth of T and the given number fo rounds nrounds.

The return value is a tuple of Ts containing the round constants for round indices 12+2ℓ(T)-nrounds to 12+2ℓ(T)-1 in that order. The default for nrounds results in the first round index being 0.

Note

It is valid to have nrounds>12+2ℓ(T), so that round index starts negative.

Examples

julia> round_consts(UInt16)
(0x0001, 0x8082, 0x808a, 0x8000, 0x808b, 0x0001, 0x8081, 0x8009, 0x008a, 0x0088, 0x8009, 0x000a, 0x808b, 0x008b, 0x8089, 0x8003, 0x8002, 0x0080, 0x800a, 0x000a)

julia> round_consts(UInt8)
(0x01, 0x82, 0x8a, 0x00, 0x8b, 0x01, 0x81, 0x09, 0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80)

julia> round_consts(UInt8, Val(10))
(0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80)

julia> round_consts(UInt8, Val(20))
(0x02, 0x8a, 0x01, 0x82, 0x8a, 0x00, 0x8b, 0x01, 0x81, 0x09, 0x8a, 0x88, 0x09, 0x0a, 0x8b, 0x8b, 0x89, 0x03, 0x02, 0x80)
source

Kᴇᴄᴄᴀᴋ step mappings

These functions follow the specification in section 3.2 of FIPS-202.

Keccak.ιFunction
ι(state, RC)

Perform the step mapping ι (round-dependent modification of lane[0,0]) of the Keccak algorithm and return the updated state.

Instead of the round index as in FIPS-202, the corresponding round constant RC is expected as the second argument.

The state is a 25-tuple of unsigned integers, related to state array A in FIPS-202 by

A[x,y,z] == state[5y+x+1] >> z & 1

for x = 0,...,4, y = 0,...,4 and z = 0,...,w-1, where w is the bitwidth of the integers in state.

Alternatively, the state can contain SIMD.Vecs of unsigned integers to perform a parallel transformation of multiple state instances.

source
Keccak.θFunction
θ(state)

Perform the step mapping θ of the Keccak algorithm and return the updated state.

The state is a 25-tuple of unsigned integers, related to state array A in FIPS-202 by

A[x,y,z] == state[5y+x+1] >> z & 1

for x = 0,...,4, y = 0,...,4 and z = 0,...,w-1, where w is the bitwidth of the integers in state.

Alternatively, the state can contain SIMD.Vecs of unsigned integers to perform a parallel transformation of multiple state instances.

source
Keccak.πFunction
π(state)

Perform the step mapping π (permutation of the lanes) of the Keccak algorithm and return the updated state.

The state is a 25-tuple of unsigned integers, related to state array A in FIPS-202 by

A[x,y,z] == state[5y+x+1] >> z & 1

for x = 0,...,4, y = 0,...,4 and z = 0,...,w-1, where w is the bitwidth of the integers in state.

Alternatively, the state can contain SIMD.Vecs of unsigned integers to perform a parallel transformation of multiple state instances.

source
Keccak.χFunction
χ(state)

Perform the nonlinear step mapping χ of the Keccak algorithm and return the updated state.

The state is a 25-tuple of unsigned integers, related to state array A in FIPS-202 by

A[x,y,z] == state[5y+x+1] >> z & 1

for x = 0,...,4, y = 0,...,4 and z = 0,...,w-1, where w is the bitwidth of the integers in state.

Alternatively, the state can contain SIMD.Vecs of unsigned integers to perform a parallel transformation of multiple state instances.

source
Keccak.ρFunction
ρ(state)

Perform the step mapping ρ (bit rotation in each lane) of the Keccak algorithm and return the updated state.

The state is a 25-tuple of unsigned integers, related to state array A in FIPS-202 by

A[x,y,z] == state[5y+x+1] >> z & 1

for x = 0,...,4, y = 0,...,4 and z = 0,...,w-1, where w is the bitwidth of the integers in state.

Alternatively, the state can contain SIMD.Vecs of unsigned integers to perform a parallel transformation of multiple state instances.

source

SP.800-185 helpers

Keccak.absorb_right_encodedFunction
absorb_right_encoded(sponge::Sponge, x::Integer)

Absorbs the non-negative integer x into the given sponge after applying the "right_encode" operation from NIST SP.800-185 to it.

Note

The current implementation requires x ≤ typemax(UInt64).

source
Keccak.absorb_left_encodedFunction
absorb_left_encoded(sponge::Sponge, x::Integer)

Absorbs the non-negative integer x into the given sponge after applying the "left_encode" operation from NIST SP.800-185 to it. Returns the updated sponge.

Note

The current implementation requires x ≤ typemax(UInt64).

source
Keccak.absorb_encoded_stringFunction
absorb_encoded_string(sponge::Sponge, str::AbsorbableData)

Absorbs the string str (which can also be a Tuple or AbstractVector of UInt8s) into the given sponge after applying the "encode_string" operation from NIST SP.800-185 to it. Returns the updated sponge.

source
Keccak.absorb_ratepaddedFunction
absorb_ratepadded(f, sponge::Sponge)

Absorb data into the given sponge and zero-pad to a multiple of the sponges rate. The padding uses the "bytepad" operation from NIST SP.800-185, but is limited to "w" being the sponge's rate.

The data is provided implicitly by passing a function f that is called with a sponge and has to return an updated sponge with the data absorbed.

Example

absorb_ratepadded(sponge) do sponge
    return absorb_encoded_string(sponge, "Test")
end == absorb(sponge, [
    0x01, UInt8(rate(sponge)), # left_encode'd pad width w=rate(sponge)
    # start of data produced by `f` (i.e. absorb_encoded_string)
    0x01, UInt8(4*8),
    codeunits("Test")...,
    # end of data produced by `f`
    zeros(UInt8, rate(sponge)-8)... # absorbed 8 bytes so far, zero-pad up to rate
])

# output

true
source
Keccak.KMACPadType
KMACPad(basepad::KeccakPad, len::UInt64)

A padding function that first appends (i.e. absorbs) 8*len after "right_encode"ing it and then invokes basepad.

source