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 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 (const field_ct &a, const field_ct &b)
 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()

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

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

Used throughout SHA-256 to add 32-bit values and reduce modulo 2^32. Constrains: result = a + b - overflow * 2^32, where overflow is range-checked.

Warning
result is not explicitly range-constrained here because it is typically used downstream in lookup tables (e.g. in choose_with_sigma1, majority_with_sigma0) which implicitly validates the 32-bit range.

Definition at line 329 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) as a constrained 32-bit field element

Definition at line 246 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 45 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 82 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) as a constrained 32-bit field element

Definition at line 291 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 199 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 219 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.

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 379 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: