Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
biggroup_secp256k1.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
16
17template <typename C, class Fq, class Fr, class G>
18template <typename, typename>
20{
50 const auto [u1_lo_wnaf, u1_hi_wnaf] = compute_secp256k1_endo_wnaf<8, 2, 3>(u1, false);
51 const auto [u2_lo_wnaf, u2_hi_wnaf] = compute_secp256k1_endo_wnaf<4, 0, 1>(u2, false);
52
56 auto P1 = element::one(pubkey.get_context());
57 auto P2 = pubkey;
58 const auto P1_table =
59 element::eight_bit_fixed_base_table(element::eight_bit_fixed_base_table::CurveType::SECP256K1, false);
60 const auto endoP1_table =
61 element::eight_bit_fixed_base_table(element::eight_bit_fixed_base_table::CurveType::SECP256K1, true);
62 const auto [P2_table, endoP2_table] = create_endo_pair_four_bit_table_plookup(P2);
63
64 // Initialize our accumulator
65 auto accumulator = P2_table[u2_lo_wnaf.wnaf[0]];
66
86 for (size_t i = 0; i < 16; ++i) {
87 accumulator = accumulator.dbl();
88 accumulator = accumulator.dbl();
89
90 // u2_hi_wnaf.wnaf[2 * i] is a field_t element (as are the other wnafs).
91 // See `stdlib/memory/rom_table.hpp` for how indirect array accesses are implemented in Ultra
92 const auto& add_1 = endoP2_table[u2_hi_wnaf.wnaf[2 * i]];
93 const auto& add_2 = P2_table[u2_lo_wnaf.wnaf[2 * i + 1]];
94 const auto& add_3 = endoP1_table[u1_hi_wnaf.wnaf[i]];
95 const auto& add_4 = P1_table[u1_lo_wnaf.wnaf[i]];
96 const auto& add_5 = endoP2_table[u2_hi_wnaf.wnaf[2 * i + 1]];
97 const auto& add_6 = P2_table[u2_lo_wnaf.wnaf[2 * i + 2]];
98
99 accumulator = accumulator.multiple_montgomery_ladder({ element::chain_add_accumulator(add_1),
100 element::chain_add_accumulator(add_2),
101 element::chain_add_accumulator(add_3) });
102
103 accumulator = accumulator.multiple_montgomery_ladder({ element::chain_add_accumulator(add_4),
104 element::chain_add_accumulator(add_5),
105 element::chain_add_accumulator(add_6) });
106 }
107
111 const auto& add_1 = endoP1_table[u1_hi_wnaf.least_significant_wnaf_fragment];
112 const auto& add_2 = endoP2_table[u2_hi_wnaf.least_significant_wnaf_fragment];
113 const auto& add_3 = P1_table[u1_lo_wnaf.least_significant_wnaf_fragment];
114 accumulator += add_1;
115 accumulator += add_2;
116 accumulator += add_3;
117
124 const auto conditional_add = [](const element& accumulator,
125 const element& base_point,
126 const bool_ct& positive_skew,
127 const bool_ct& negative_skew) {
128 auto to_add = base_point;
129 to_add.y = to_add.y.conditional_negate(negative_skew);
130 element result = accumulator + to_add;
131
132 // when computing the wNAF we have already validated that positive_skew and negative_skew cannot both be true
133 bool_ct skew_combined = positive_skew ^ negative_skew;
134 result = accumulator.conditional_select(result, skew_combined);
135 return result;
136 };
137
138 accumulator = conditional_add(accumulator, P1, u1_lo_wnaf.positive_skew, u1_lo_wnaf.negative_skew);
139 accumulator = conditional_add(accumulator, endoP1_table[128], u1_hi_wnaf.positive_skew, u1_hi_wnaf.negative_skew);
140 accumulator = conditional_add(accumulator, P2, u2_lo_wnaf.positive_skew, u2_lo_wnaf.negative_skew);
141 accumulator = conditional_add(accumulator, endoP2_table[8], u2_hi_wnaf.positive_skew, u2_hi_wnaf.negative_skew);
142
143 return accumulator;
144}
145} // namespace bb::stdlib::element_default
Implements boolean logic in-circuit.
Definition bool.hpp:59
element conditional_select(const element &other, const bool_ct &predicate) const
Selects this if predicate is false, other if predicate is true.
Definition biggroup.hpp:264