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
— TypeAbstractSponge
A 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 ┆ Squeezing
First, 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
r
bits, and xor'd with the firstr
bits of the state (leaving the remainingc
bits unchanged), with absorptions interlieved with applications of the functionf
. - In the squeezing phase, the first
r
bits of the state are returned as the output. Shoult more output be wanted,f
can 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) -> ByteSponge
Finalise vine
by folding in the current leaf returning the pad
ded 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
.