44template <
typename Builder>
53 lookup[ColumnIdx::C2][0],
54 lookup[ColumnIdx::C2][1],
55 lookup[ColumnIdx::C2][2],
56 lookup[ColumnIdx::C2][3],
59 lookup[ColumnIdx::C3][0],
60 lookup[ColumnIdx::C3][1],
61 lookup[ColumnIdx::C3][2],
62 lookup[ColumnIdx::C3][3],
81template <
typename Builder>
86 Builder* ctx = w_in[0].get_context();
91 for (
size_t i = 0; i < 16; ++i) {
94 if ((ctx ==
nullptr) && w_in[i].get_context()) {
95 ctx = w_in[i].get_context();
100 for (
size_t i = 16; i < 64; ++i) {
101 auto& w_left = w_sparse[i - 15];
102 auto& w_right = w_sparse[i - 2];
104 if (!w_left.has_sparse_limbs) {
105 w_left = convert_witness(w_left.normal);
107 if (!w_right.has_sparse_limbs) {
108 w_right = convert_witness(w_right.normal);
114 w_left.sparse_limbs[0] * left_multipliers[0],
115 w_left.sparse_limbs[1] * left_multipliers[1],
116 w_left.sparse_limbs[2] * left_multipliers[2],
117 w_left.sparse_limbs[3] * left_multipliers[3],
123 w_right.sparse_limbs[0] * right_multipliers[0],
124 w_right.sparse_limbs[1] * right_multipliers[1],
125 w_right.sparse_limbs[2] * right_multipliers[2],
126 w_right.sparse_limbs[3] * right_multipliers[3],
134 left[0].
add_two(left[1], left[2]).
add_two(left[3], w_left.rotated_limb_corrections[1]) *
fr(4);
137 const field_pt xor_result_sparse = right[0]
139 .
add_two(right[3], w_right.rotated_limb_corrections[2])
140 .
add_two(w_right.rotated_limb_corrections[3], left_xor_sparse);
146 field_pt w_out_raw = xor_result.
add_two(w_sparse[i - 16].normal, w_sparse[i - 7].normal);
159 field_pt w_out_raw_inv_pow_two = w_out_raw * inv_pow_two;
160 field_pt w_out_inv_pow_two = w_out * inv_pow_two;
161 field_pt divisor = w_out_raw_inv_pow_two - w_out_inv_pow_two;
182 for (
size_t i = 0; i < 64; ++i) {
183 w_extended[i] = w_sparse[i].normal;
198template <
typename Builder>
218template <
typename Builder>
245template <
typename Builder>
250 constexpr fr SPARSE_MULT =
fr(7);
255 field_pt rotation_result = lookup[ColumnIdx::C3][0];
256 e.
sparse = lookup[ColumnIdx::C2][0];
257 field_pt sparse_L2 = lookup[ColumnIdx::C2][2];
260 field_pt xor_result = (rotation_result * SPARSE_MULT)
261 .add_two(e.
sparse * (rotation_coefficients[0] * SPARSE_MULT +
fr(1)),
262 sparse_L2 * (rotation_coefficients[2] * SPARSE_MULT));
270 return choose_result;
290template <
typename Builder>
295 constexpr fr SPARSE_MULT =
fr(4);
301 field_pt rotation_result = lookup[ColumnIdx::C3][0];
302 a.sparse = lookup[ColumnIdx::C2][0];
303 field_pt sparse_L1_acc = lookup[ColumnIdx::C2][1];
306 field_pt xor_result = (rotation_result * SPARSE_MULT)
307 .add_two(
a.sparse * (rotation_coefficients[0] * SPARSE_MULT +
fr(1)),
308 sparse_L1_acc * (rotation_coefficients[1] * SPARSE_MULT));
316 return majority_result;
328template <
typename Builder>
334 Builder* ctx =
a.get_context() ?
a.get_context() :
b.get_context();
337 uint256_t normalized_sum =
static_cast<uint32_t
>(
sum.data[0]);
339 if (
a.is_constant() &&
b.is_constant()) {
340 return field_pt(ctx, normalized_sum);
343 fr overflow_value =
fr((
sum - normalized_sum) >> 32);
378template <
typename Builder>
417 auto b = map_into_maj_sparse_form(h_init[1]);
418 auto c = map_into_maj_sparse_form(h_init[2]);
421 auto f = map_into_choose_sparse_form(h_init[5]);
422 auto g = map_into_choose_sparse_form(h_init[6]);
439 for (
size_t i = 0; i < 64; ++i) {
440 auto ch = choose_with_sigma1(e, f,
g);
441 auto maj = majority_with_sigma0(
a,
b, c);
442 auto temp1 = ch.add_two(h.
normal, w[i] +
fr(round_constants[i]));
468 for (
size_t i = 0; i < 8; i++) {
469 output[i].create_range_constraint(32);
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 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.
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 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 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 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.
void create_range_constraint(size_t num_bits, std::string const &msg="field_t::range_constraint") const
Let x = *this.normalize(), constrain x.v < 2^{num_bits}.
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
field_t add_two(const field_t &add_b, const field_t &add_c) const
Efficiently compute (this + a + b) using big_mul gate.
static plookup::ReadData< field_pt > get_lookup_accumulators(const plookup::MultiTableId id, const field_pt &key_a, const field_pt &key_b=0, const bool is_2_to_1_lookup=false)
static field_pt read_from_1_to_2_table(const plookup::MultiTableId id, const field_pt &key_a)
stdlib::witness_t< bb::UltraCircuitBuilder > witness_pt
stdlib::field_t< UltraCircuitBuilder > field_pt
std::array< bb::fr, 3 > get_choose_rotation_multipliers()
Returns multipliers for computing Σ₁(e) rotations in choose_with_sigma1.
std::array< bb::fr, 3 > get_majority_rotation_multipliers()
Returns multipliers for computing Σ₀(a) rotations in majority_with_sigma0.
field_t< Builder > add_normalize(const field_t< Builder > &a, const field_t< Builder > &b)
void g(field_t< Builder > state[BLAKE_STATE_SIZE], size_t a, size_t b, size_t c, size_t d, field_t< Builder > x, field_t< Builder > y)
Entry point for Barretenberg command-line interface.
field< Bn254FrParams > fr
Inner sum(Cont< Inner, Args... > const &in)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Plookup tables for SHA-256 using sparse form representation.
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
constexpr field invert() const noexcept
BB_INLINE constexpr field from_montgomery_form() const noexcept
std::array< field_ct, 4 > rotated_limb_corrections
std::array< field_ct, 4 > sparse_limbs