Skip to main content

sha256_compress

Function sha256_compress 

Source
pub fn sha256_compress(
    builder: &CircuitBuilder,
    state_in: State,
    m: [Wire; 16],
) -> State
Expand description

SHA-256 compression function.

Runs the message schedule and 64 rounds over state_in for one 512-bit block. The round output is then added back into state_in, giving the updated state.

A gate costs one constraint whatever its operand width. So one compression is evaluated as the two 32-bit lanes of a single 64-bit core.

Each phase is cut in half, and the halves run side by side instead of one after the other:

    schedule, high lane [32:64]:  w[24] .. w[39]  ->  w[40] .. w[63]
    schedule, low  lane [0:32] :  w[0]  .. w[15]  ->  w[16] .. w[39]

    rounds,   high lane [32:64]:  round 0  -> ... -> round 31
    rounds,   low  lane [0:32] :  round 32 -> ... -> round 63

Each half now needs what the other half produces, which no ordering of gates can supply.

  • The schedule’s high lane opens at w[24], which the low lane only reaches at the end.
  • The rounds’ low lane opens at the state after round 31, which the high lane ends on.

A hint breaks both dependencies at once by computing those two seeds off-circuit.

Every hinted word is then constrained against what the circuit itself computed. So the hint can be wrong, but a wrong one has no satisfying witness.

24 packed passes and 32 packed rounds replace 48 and 64 single-lane ones. That halves the AND constraints a compression spends.

§Arguments

  • state_in: the 8-word input state, value in the low 32 bits of each wire.
  • m: 16 big-endian message words for this block, value in the low 32 bits of each wire.

§Preconditions

  • Every input wire holds a valid 32-bit value in its low 32 bits.
  • High halves need not be empty.
    • A message word’s high half is masked off.
    • A state word’s is discarded by the shift that lifts it into the high lane.

§Returns

The updated 8-word state, value in the low 32 bits of each wire and the high 32 bits zero.