Internals
Keccak
KangarooTwelve.keccak_p1600 — Functionkeccak_p1600(state::NTuple{25, UInt64}, ::Val{nrounds}=Val{12}())Apply the Keccak-p[nrounds, 1600] permutation to state. This is formally defined in the Keccak reference and formalised in FIPS 202.
Extended help
This is a variable-round permutation, with up to 24 rounds, where the last round performed matches the final Keccak-f permutation round.
Each round of permutation consists of five steps, termed θ, ρ, π, χ, and ι. These all operate on a 200-byte state, viewed in a number of different configurations.
┌─┬─┬─┬─┬─┐
┌─┬─┬─┬─┬─┐┤
┌─┬─┬─┬─┬─┐┤┤
┌─┬─┬─┬─┬─┐┤┤┤
┌─┬─┬─┬─┬─┐┤┤┤┤
┌─┬─┬─┬─┬─┐┤┤┤┤┘
┌─┬─┬─┬─┬─┐┤┤┤┤┘
┌─┬─┬─┬─┬─┐┤┤┤┤┘
├─┼─┼─┼─┼─┤┤┤┤┘
├─┼─┼─┼─┼─┤┤┤┘
├─┼─┼─┼─┼─┤┤┘ ┌─┐ bit
├─┼─┼─┼─┼─┤┘ └─┘ ┌─┐
└─┴─┴─┴─┴─┘ ┌─┐┘
state ┌─┐┘
┌─┐┘
┌─┐ ┌─┐┘
├─┤ column ┌─┐┘
row ├─┤ ┌─┐┘
┌─┬─┬─┬─┬─┐ ├─┤ ┌─┐┘ lane
└─┴─┴─┴─┴─┘ ├─┤ └─┘
└─┘- θ step Compute the parity of five columns, and xor-diffuse their parity into nearby columns.
- ρ step Bitwise-rotate each of the 25 lanes by a different triangular number.
- π step Permute each lane in a fixed pattern.
- χ step Intra-row bitwise combination. This provides the non-linearity.
- ι step The first lane is (xor-)mixed with a LFSR sequence across rounds. This serves to disrupt the symmetry of the scheme.
Turboshake
KangarooTwelve.turboshake — Functionturboshake(output::Type, message::AbstractVector{<:UInt8to64},
delimsuffix::UInt8=0x80, ::Val{capacity} = Val{256}())Produce an output (Unsigned or NTuple{n, <:Unsigned}) value, by performing TurboSHAKE on message with a certain capacity and delimsuffix.
Sponge & Vine
KangarooTwelve.AbstractSponge — TypeAbstractSpongeA sponge is a generalisation of hash functions and stream ciphers. It is in essance an iterated construction of a variable-input variable-output function based on a fixed length permutation and an internal state.
The way the sponge operates can be illustrated well with a diagram following the state.
Message (padded)
└───┬──────┬──────┬──────┐ ┊ ┌──────┬──────┬───▶ Output
│ │ │ │ ┊ │ │ │
┌─┐ │ ╭─╮ │ ╭─╮ │ ╭─╮ │ ╭─╮ ┆ │ ╭─╮ │ ╭─╮ │
│ │ ▼ │ │ ▼ │ │ ▼ │ │ ▼ │ │ ┆ │ │ │ │ │ │ │
r│0├──⨁─▶│ ├─⨁─▶│ ├─⨁─▶│ ├─⨁─▶│ ├─┼─┴─▶│ ├─┴─▶│ ├─┴─▶ ╍
│ │ │f│ │f│ │f│ │f│ ┆ │f│ │f│
├─┤ │ │ │ │ │ │ │ │ ┆ │ │ │ │
c│0├────▶│ ├───▶│ ├───▶│ ├───▶│ ├─┼───▶│ ├───▶│ ├───▶ ╍
└─┘ ╰─╯ ╰─╯ ╰─╯ ╰─╯ ┆ ╰─╯ ╰─╯
Absorbing ┆ SqueezingFirst, the input is padded with a reversible padding rule and the state is initialised to zero.
- In the absorbing phase, the input is processed in blocks of
rbits, and xor'd with the firstrbits of the state (leaving the remainingcbits unchanged), with absorptions interlieved with applications of the functionf. - In the squeezing phase, the first
rbits of the state are returned as the output. Shoult more output be wanted,fcan simply be applied to the state again.
While this construction is defined for any fixed-length permutation f, however we specialise on keccak_p1600.
It is possible to either incrementally either one lane at a time, or one byte at a time. To handle these two cases we have the Sponge and ByteSponge subtypes.
KangarooTwelve.Sponge — TypeSponge{rate}A Keccak state that keeps track of the current lane.
For more information on the sponge construction see AbstractSponge.
KangarooTwelve.ByteSponge — TypeByteSponge{rate}A Keccak state that keeps track of the last byte updated.
For more information on the sponge construction see AbstractSponge.
KangarooTwelve.AbstractCoralVine — TypeAbstractCoralVine{rate}A binary tree where at each node, only one child itself has children.
trunk ◆
/ \
◆ ◇ leaf
/ \
◆ ◇ leaf
┆This esentially creates a "vine" like structure, with a single "trunk" that has terminal "leaves" sprouting off it.
The trunk and its leaves are sponges, and it is this "vine of sponges" conception that lends itself to the "Coral Vine" name (since coral sponges are the only sponge that grows I'm aware of).
Since the final result of the vine is obtained from folding all leaves into it sequentially, we can represent the intermediate state of the vine with just the "trunk" and the most recent leaf (having folded all completed leaves into the trunk).
╭──────╮
│ Leaf │
╭─────────╮ □ ╰─┬────╯
│ Trunk ├──┬───┴───┬──╯
╰─────────╯ □ □However, at the very start data is absorbed into the trunk itself. After it is full, all subsequent data goes to the leaves, and the trunk only absorbs values squeezed from leaves.
The distinction between these two stages is made with the subtypes CoralVineSeedling and CoralVine.
KangarooTwelve.CoralVineSeedling — TypeCoralVineSeedling{rate}A vine that hasn't started to grow leaves yet (see the AbstractCoralVine docstring).
╭─────────╮
│ Trunk ├───
╰─────────╯See also: CoralVine, absorb, absorb_length, and finalise.
KangarooTwelve.CoralVine — TypeCoralVine{rate}A vine with leaves (see the k12 docstring).
╭──────╮
│ Leaf │
╭─────────╮ □ ╰─┬────╯
│ Trunk ├──┬───┴───┬──╯
╰─────────╯ □ □See also: CoralVineSeedling, absorb, absorb_length, and finalise.
KangarooTwelve.absorb_length — Functionabsorb_length(accumulator::Union{<:ByteSponge, <:AbstractCoralVine}, val::UInt, ::Val{bufsize}=Val{8}())Ingest a right-encoded form of val into accumulator, allowing the encoding to be up to bufsize bytes.
KangarooTwelve.finalise — Functionfinalise(vine::AbstractCoralVine) -> ByteSpongeFinalise vine by folding in the current leaf returning the padded trunk.
State operations
The absorb, pad, squeeze, and squeeze! are implemented for state tuples, sponges, and vines.
KangarooTwelve.absorb — Functionabsorb(state::NTuple{25, UInt64}, block::NTuple{rate, UInt64})Ingest a single block of input (with implied rate) into state.
The first rate elements of the state are xor'd block, and then the state is permuted with keccak_p1600.
absorb(state::NTuple{25, UInt64}, ::Val{capacity}, message::AbstractVector{<:Unsigned})Ingest message into state, with the rate calculated based on capacity.
This breaks message into rate-sized blocks and then absorbs them (as per absorb(state, ::NTuple{rate, UInt64})) in turn.
absorb(sponge::ByteSponge, x::Union{<:Unsigned, NTuple{N, <:Unsigned}})Ingest x into sponge.
absorb(sponge::AbstractSponge, block::AbstractVector{<:Unsigned})Ingest each element of block into sponge.
absorb(vine::AbstractCoralVine, leaflet::AbstractVector{<:Unsigned})
absorb(vine::AbstractCoralVine, x::Unsigned)Ingest leaflet/x into vine, this may go into the leaves or the trunk depending on the vine type, and may cause the current leaf to be folded into the trunk, and a new leaf grown.
KangarooTwelve.pad — Functionpad(state::NTuple{25, UInt64}, ::Val{capacity}, lastbyte::UInt, delimsuffix::UInt8)Perform "padding" of the lastbyte byte of state with delimsuffix.
This is the final modification to state in turboshake.
KangarooTwelve.squeeze — Functionsqueeze(outtype::Type, state::NTuple{25, UInt64}, ::Val{capacity})Squeeze an outtype out of state. outtype can be an Unsigned type or an unsigned NTuple.
squeeze(T::Type, sponge::AbstractSponge)Squeeze a T out of sponge.
KangarooTwelve.squeeze! — Functionsqueeze!(output::Vector{UInt64}, state::NTuple{25, UInt64}, ::Val{capacity})Squeeze state into output.
squeeze!(output::Vector{UInt64}, sponge::AbstractSponge)Squeeze sponge into output.