Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bb::stdlib::SHA256< Builder > Class Template Reference

#include <sha256.hpp>

Classes

struct  sparse_value
 
struct  sparse_witness_limbs
 

Static Public Member Functions

static std::array< field_ct, 8 > sha256_block (const std::array< field_ct, 8 > &h_init, const std::array< field_ct, 16 > &input)
 Apply the SHA-256 compression function to a single 512-bit message block.
 
static std::array< field_ct, 64 > extend_witness (const std::array< field_ct, 16 > &w_in)
 Extend the 16-word message block to 64 words per SHA-256 specification.
 

Private Types

using field_ct = field_t< Builder >
 

Static Private Member Functions

static sparse_witness_limbs convert_witness (const field_ct &input)
 Convert a 32-bit value to sparse limbs form for message schedule extension.
 
static void apply_32_bit_range_constraint_via_lookup (const field_ct &input)
 Apply an implicit 32-bit range constraint by performing a lookup on the input.
 
static field_ct choose_with_sigma1 (sparse_value &e, const sparse_value &f, const sparse_value &g)
 Compute Σ₁(e) + Ch(e,f,g) for SHA-256 compression rounds.
 
static field_ct majority_with_sigma0 (sparse_value &a, const sparse_value &b, const sparse_value &c)
 Compute Σ₀(a) + Maj(a,b,c) for SHA-256 compression rounds.
 
static sparse_value map_into_choose_sparse_form (const field_ct &input)
 Convert a field element to sparse form for use in the Choose function.
 
static sparse_value map_into_maj_sparse_form (const field_ct &input)
 Convert a field element to sparse form for use in the Majority function.
 
static field_ct add_normalize_unsafe (const field_ct &a, const field_ct &b, size_t overflow_bits)
 Compute (a + b) mod 2^32 with circuit constraints.
 

Static Private Attributes

static constexpr fr base { 16 }
 
static constexpr std::array< fr, 4 > left_multipliers
 Multipliers for computing σ₀ during message schedule extension.
 
static constexpr std::array< fr, 4 > right_multipliers
 Multipliers for computing σ₁ during message schedule extension.
 
static constexpr std::array< uint64_t, 64 > round_constants
 

Detailed Description

template<typename Builder>
class bb::stdlib::SHA256< Builder >

Definition at line 18 of file sha256.hpp.

Member Typedef Documentation

◆ field_ct

template<typename Builder >
using bb::stdlib::SHA256< Builder >::field_ct = field_t<Builder>
private

Definition at line 20 of file sha256.hpp.

Member Function Documentation

◆ add_normalize_unsafe()

template<typename Builder >
field_t< Builder > bb::stdlib::SHA256< Builder >::add_normalize_unsafe ( const field_ct a,
const field_ct b,
size_t  overflow_bits 
)
staticprivate

Compute (a + b) mod 2^32 with circuit constraints.

Constrains: result = a + b - overflow * 2^32, where overflow is range-checked to overflow_bits.

Parameters
overflow_bitsNumber of bits for overflow range constraint. Must accommodate max(a + b) / 2^32.
Warning
Marked unsafe since result is not explicitly range-constrained herein because it is typically used downstream in lookup tables which implicitly impose the 32-bit range.

Definition at line 343 of file sha256.cpp.

◆ apply_32_bit_range_constraint_via_lookup()

template<typename Builder >
void bb::stdlib::SHA256< Builder >::apply_32_bit_range_constraint_via_lookup ( const field_ct input)
staticprivate

Apply an implicit 32-bit range constraint by performing a lookup on the input.

This is more efficient in the context of SHA-256 operations than explicit 32-bit range constraints since the lookup table is already in use. We use the SHA256_MAJ_INPUT MultiTable since it results in only 3 lookup gates per lookup.

Note
The result of the lookup is not used, but the accumulator outputs are marked as intentionally unused to avoid false positives in the boomerang value detection analysis.
Parameters
inputThe field element to constrain to 32 bits.

Definition at line 83 of file sha256.cpp.

◆ choose_with_sigma1()

template<typename Builder >
field_t< Builder > bb::stdlib::SHA256< Builder >::choose_with_sigma1 ( sparse_value e,
const sparse_value f,
const sparse_value g 
)
staticprivate

Compute Σ₁(e) + Ch(e,f,g) for SHA-256 compression rounds.

Combines two operations efficiently using base-28 sparse form:

  • Σ₁(e) = (e >>> 6) ^ (e >>> 11) ^ (e >>> 25)
  • Ch(e,f,g) = (e & f) ^ (~e & g)

Sparse encoding: 7*[rotations] + [e + 2f + 3g], where factor 7 separates rotation contributions (0-3) from Choose encoding (0-6) within each base-28 digit.

See get_choose_input_table() in plookup_tables/sha256.hpp for the mathematical derivation.

Parameters
eInput/output: e.normal read, e.sparse populated as side effect
fInput: must have .sparse already populated
gInput: must have .sparse already populated
Returns
Σ₁(e) + Ch(e,f,g) (lookup-constrained to ≤ 2*(2^32-1))

Definition at line 259 of file sha256.cpp.

◆ convert_witness()

template<typename Builder >
SHA256< Builder >::sparse_witness_limbs bb::stdlib::SHA256< Builder >::convert_witness ( const field_ct input)
staticprivate

Convert a 32-bit value to sparse limbs form for message schedule extension.

Uses SHA256_WITNESS_INPUT lookup table to decompose input into sparse limbs and pre-rotated correction terms needed for σ₀/σ₁ computation.

See get_witness_extension_input_table() in plookup_tables/sha256.hpp for table structure.

Definition at line 46 of file sha256.cpp.

◆ extend_witness()

template<typename Builder >
std::array< field_t< Builder >, 64 > bb::stdlib::SHA256< Builder >::extend_witness ( const std::array< field_ct, 16 > &  w_in)
static

Extend the 16-word message block to 64 words per SHA-256 specification.

SHA-256 Spec (FIPS 180-4, Section 6.2.2): W[i] = σ₁(W[i-2]) + W[i-7] + σ₀(W[i-15]) + W[i-16] (mod 2³²) for i = 16..63

Uses base-16 sparse form to compute σ₀ + σ₁ efficiently via lookup tables, then adds W[i-7] and W[i-16] and reduces mod 2³².

Parameters
w_inThe 16 input message words (512 bits total)
Returns
64 extended message schedule words

Definition at line 107 of file sha256.cpp.

◆ majority_with_sigma0()

template<typename Builder >
field_t< Builder > bb::stdlib::SHA256< Builder >::majority_with_sigma0 ( sparse_value a,
const sparse_value b,
const sparse_value c 
)
staticprivate

Compute Σ₀(a) + Maj(a,b,c) for SHA-256 compression rounds.

Combines two operations efficiently using base-16 sparse form:

  • Σ₀(a) = (a >>> 2) ^ (a >>> 13) ^ (a >>> 22)
  • Maj(a,b,c) = (a & b) ^ (a & c) ^ (b & c)

Sparse encoding: 4*[rotations] + [a + b + c], where factor 4 separates rotation contributions (0-3) from Majority encoding (0-3) within each base-16 digit.

See get_majority_input_table() in plookup_tables/sha256.hpp for the mathematical derivation.

Parameters
aInput/output: a.normal read, a.sparse populated as side effect
bInput: must have .sparse already populated
cInput: must have .sparse already populated
Returns
Σ₀(a) + Maj(a,b,c) (lookup-constrained to ≤ 2*(2^32-1))

Definition at line 304 of file sha256.cpp.

◆ map_into_choose_sparse_form()

template<typename Builder >
SHA256< Builder >::sparse_value bb::stdlib::SHA256< Builder >::map_into_choose_sparse_form ( const field_ct input)
staticprivate

Convert a field element to sparse form for use in the Choose function.

Performs a lookup to convert a normal 32-bit value to its base-28 sparse representation. Base 28 is required because the Choose lookup table index formula is 7 × rotation_sum + (e + 2f + 3g), where rotation_sum ranges 0-3 and the weighted sum (e + 2f + 3g) ranges 0-6, giving max index 27.

Parameters
inputThe field element to convert (expected to be a 32-bit value)
Returns
sparse_value containing both normal and sparse representations

Definition at line 212 of file sha256.cpp.

◆ map_into_maj_sparse_form()

template<typename Builder >
SHA256< Builder >::sparse_value bb::stdlib::SHA256< Builder >::map_into_maj_sparse_form ( const field_ct input)
staticprivate

Convert a field element to sparse form for use in the Majority function.

Performs a lookup to convert a normal 32-bit value to its base-16 sparse representation. Base 16 is required because the Majority lookup table index formula is 4 × rotation_sum + (a + b + c), where rotation_sum ranges 0-3 and (a + b + c) ranges 0-3, giving max index 15.

Parameters
inputThe field element to convert (expected to be a 32-bit value)
Returns
sparse_value containing both normal and sparse representations

Definition at line 232 of file sha256.cpp.

◆ sha256_block()

template<typename Builder >
std::array< field_t< Builder >, 8 > bb::stdlib::SHA256< Builder >::sha256_block ( const std::array< field_ct, 8 > &  h_init,
const std::array< field_ct, 16 > &  input 
)
static

Apply the SHA-256 compression function to a single 512-bit message block.

This is the only public entry point for the stdlib SHA-256 implementation. We implement only the compression function (rather than a full hash) because this is all that is required in DSL.

Note
It is assumed that all 24 inputs (8 hash state + 16 message words) are 32-bit constrained externally so that the input has a unique representation.
Parameters
h_initThe 8-word (256-bit) initial hash state. For the first block of a message, this should be the standard SHA-256 IV. For subsequent blocks, this is the output of the previous compression.
inputThe 16-word (512-bit) message block to compress.
Returns
The updated 8-word hash state after compression.

Initialize round variables with previous block output. Note: We delay converting a and e into their respective sparse forms because it's done as part of the majority and choose functions in the first round.

Apply SHA-256 compression function to the message schedule.

Standard SHA-256 round: T1 = h + Σ1(e) + Ch(e,f,g) + K[i] + W[i] T2 = Σ0(a) + Maj(a,b,c) h,g,f,e,d,c,b,a = g,f,e,d+T1,c,b,a,T1+T2

NOTE: Order-dependent side effects below. choose_with_sigma1() populates e.sparse (subsequently copied to f). majority_with_sigma0() populates a.sparse (subsequently copied to b). Do not reorder relative to f=e or b=a.

Definition at line 383 of file sha256.cpp.

Member Data Documentation

◆ base

template<typename Builder >
constexpr fr bb::stdlib::SHA256< Builder >::base { 16 }
staticconstexprprivate

Definition at line 22 of file sha256.hpp.

◆ left_multipliers

template<typename Builder >
constexpr std::array<fr, 4> bb::stdlib::SHA256< Builder >::left_multipliers
staticconstexprprivate
Initial value:
{
base.pow(32 - 7) + base.pow(32 - 18),
base.pow(32 - 18 + 3) + fr(1),
base.pow(10 - 7) + base.pow(32 - 18 + 10) + base.pow(10 - 3),
base.pow(18 - 7) + fr(1) + base.pow(18 - 3),
}
static constexpr fr base
Definition sha256.hpp:22
field< Bn254FrParams > fr
Definition fr.hpp:174
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept

Multipliers for computing σ₀ during message schedule extension.

σ₀(x) = (x >>> 7) ⊕ (x >>> 18) ⊕ (x >> 3)

These multipliers handle rotations that keep the limb within the 32-bit word boundary. Rotations that split a limb across the wrap boundary (i.e., rot7 for limb 1) cannot be represented as a simple scalar and are instead handled via rotated_limb_corrections from the lookup table.

limb 0) bits [0..2]; pos_0 = 0

  • rotation by 7: 16^(-7 + pos_0 mod 32) = 16^(32 - 7 + 0)
  • rotation by 18: 16^(-18 + pos_0 mod 32) = 16^(32 - 18 + 0)
  • shift by 3: no contribution (all 3 bits shifted out) limb 1) bits [3..9]; pos_1 = 3
  • rotation by 7: not representable as scalar; accounted for in rotated_limb_corrections[1]
  • rotation by 18: 16^(-18 + pos_1 mod 32) = 16^(32 - 18 + 3)
  • shift by 3: 16^(pos_1 - 3) = 16^0 = 1 limb 2) bits [10..17]; pos_2 = 10
  • rotation by 7: 16^(-7 + pos_2) = 16^(10 - 7)
  • rotation by 18: 16^(-18 + pos_2 mod 32) = 16^(32 - 18 + 10)
  • shift by 3: 16^(pos_2 - 3) = 16^(10 - 3) limb 3) bits [18..31]; pos_3 = 18

rotation by 7: 16^(-7 + pos_3) = 16^(18 - 7)

  • rotation by 18: 16^(-18 + pos_3) = 16^(18 - 18) = 1
  • shift by 3: 16^(pos_3 - 3) = 16^(18 - 3)

Definition at line 50 of file sha256.hpp.

◆ right_multipliers

template<typename Builder >
constexpr std::array<fr, 4> bb::stdlib::SHA256< Builder >::right_multipliers
staticconstexprprivate
Initial value:
{
base.pow(32 - 17) + base.pow(32 - 19),
base.pow(32 - 17 + 3) + base.pow(32 - 19 + 3),
base.pow(32 - 19 + 10) + fr(1),
base.pow(18 - 17) + base.pow(18 - 10),
}

Multipliers for computing σ₁ during message schedule extension.

σ₁(x) = (x >>> 17) ⊕ (x >>> 19) ⊕ (x >> 10)

These multipliers handle rotations that keep the limb within the 32-bit word boundary. Rotations that split a limb across the wrap boundary (i.e., rot17 for limb 2, rot19 for limb 3) cannot be represented as a simple scalar and are instead handled via rotated_limb_corrections from the lookup table.

limb 0) bits [0..2]; pos_0 = 0

  • rotation by 17: 16^(-17 + pos_0 mod 32) = 16^(32 - 17 + 0)
  • rotation by 19: 16^(-19 + pos_0 mod 32) = 16^(32 - 19 + 0)
  • shift by 10: no contribution (all 3 bits shifted out) limb 1) bits [3..9]; pos_1 = 3
  • rotation by 17: 16^(-17 + pos_1 mod 32) = 16^(32 - 17 + 3)
  • rotation by 19: 16^(-19 + pos_1 mod 32) = 16^(32 - 19 + 3)
  • shift by 10: no contribution (all 7 bits shifted out) limb 2) bits [10..17]; pos_2 = 10
  • rotation by 17: not representable as scalar; accounted for in rotated_limb_corrections[2]
  • rotation by 19: 16^(-19 + pos_2 mod 32) = 16^(32 - 19 + 10)
  • shift by 10: 16^(pos_2 - 10) = 16^0 = 1 limb 3) bits [18..31]; pos_3 = 18
  • rotation by 17: 16^(-17 + pos_3) = 16^(18 - 17)
  • rotation by 19: not representable as scalar; accounted for in rotated_limb_corrections[3]
  • shift by 10: 16^(pos_3 - 10) = 16^(18 - 10)

Definition at line 84 of file sha256.hpp.

◆ round_constants

template<typename Builder >
constexpr std::array<uint64_t, 64> bb::stdlib::SHA256< Builder >::round_constants
staticconstexprprivate
Initial value:
{
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
}

Definition at line 91 of file sha256.hpp.


The documentation for this class was generated from the following files: