1#include "../bigfield/bigfield.hpp"
2#include "../biggroup/biggroup.hpp"
3#include "../bool/bool.hpp"
4#include "../field/field.hpp"
14#include "gtest/gtest.h"
29 using fq =
typename Curve::fq;
30 using fr =
typename Curve::fr;
31 using g1 =
typename Curve::g1;
40 info(
"num gates = ",
builder.get_estimated_num_finalized_gates());
48 auto get_val = [](uint64_t fragment_u64, uint64_t stagger,
bool is_negative,
bool wnaf_skew) {
49 return stdlib::element_default::element_test_accessor::
50 get_staggered_wnaf_fragment_value<Builder, typename Curve::fq_ct, scalar_ct, g1, wnaf_size>(
51 fragment_u64, stagger, is_negative, wnaf_skew);
56 auto [frag, skew] = get_val(123, 0,
false,
false);
58 EXPECT_EQ(skew,
false);
60 auto [frag2, skew2] = get_val(456, 0,
true,
true);
62 EXPECT_EQ(skew2,
true);
66 for (
size_t i = 0; i < 20; ++i) {
68 for (
size_t num_stagger_bits = 1; num_stagger_bits <= 10; ++num_stagger_bits) {
69 uint64_t input_frag =
engine.get_random_uint32() % (1ULL << num_stagger_bits);
70 bool inp_skew =
engine.get_random_uint32() & 1;
71 bool is_negative =
false;
73 auto [output_frag, output_skew] = get_val(input_frag, num_stagger_bits, is_negative, inp_skew);
76 int lhs =
static_cast<int>(input_frag) -
static_cast<int>(inp_skew * (1ULL << num_stagger_bits));
78 int output_wnaf_value =
79 (2 *
static_cast<int>(output_frag) + 1) -
static_cast<int>(1ULL << wnaf_size);
80 int rhs = output_wnaf_value -
static_cast<int>(output_skew);
88 for (
size_t i = 0; i < 20; ++i) {
90 for (
size_t num_stagger_bits = 1; num_stagger_bits <= 10; ++num_stagger_bits) {
91 uint64_t input_frag =
engine.get_random_uint32() % (1ULL << num_stagger_bits);
92 bool inp_skew =
engine.get_random_uint32() & 1;
93 bool is_negative =
true;
95 auto [output_frag, output_skew] = get_val(input_frag, num_stagger_bits, is_negative, inp_skew);
100 int lhs = -
static_cast<int>(input_frag) +
static_cast<int>(inp_skew * (1ULL << num_stagger_bits));
102 int output_wnaf_value =
103 (2 *
static_cast<int>(output_frag) + 1) -
static_cast<int>(1ULL << wnaf_size);
104 int rhs = output_wnaf_value +
static_cast<int>(output_skew);
118 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
122 element_ct::template compute_secp256k1_endo_wnaf<4, 0, 3>(x_a,
false);
123 element_ct::template compute_secp256k1_endo_wnaf<4, 1, 2>(x_a,
false);
124 element_ct::template compute_secp256k1_endo_wnaf<4, 2, 1>(x_a,
false);
125 element_ct::template compute_secp256k1_endo_wnaf<4, 3, 0>(x_a,
false);
130 if ((
uint256_t(scalar_b).get_bit(0) & 1) == 0) {
134 element_ct::template compute_secp256k1_endo_wnaf<4, 0, 3>(x_b,
false);
135 element_ct::template compute_secp256k1_endo_wnaf<4, 1, 2>(x_b,
false);
136 element_ct::template compute_secp256k1_endo_wnaf<4, 2, 1>(x_b,
false);
137 element_ct::template compute_secp256k1_endo_wnaf<4, 3, 0>(x_b,
false);
149 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
156 element_ct::template compute_secp256k1_endo_wnaf<4, 10, 0>(
160 EXPECT_EQ(
builder.err(),
"biggroup_nafs: stagger fragment is not in range");
166 const uint512_t scalar_field_modulus = scalar_ct::modulus_u512;
177 scalar_ct large_scalar_ct = scalar_ct::create_from_u512_as_witness(&
builder, large_value,
true);
178 EXPECT_EQ(large_scalar_ct.get_value() >= (
uint512_t(1) << 256),
true);
179 EXPECT_EQ(large_scalar_ct.get_value() >=
uint512_t(scalar_field_modulus),
true);
180 EXPECT_EQ(large_scalar_ct.get_value() %
uint512_t(scalar_field_modulus),
uint512_t(scalar_a));
183 element_ct::template compute_secp256k1_endo_wnaf<4, 0, 1>(scalar_a_ct,
false);
186 element_ct::template compute_secp256k1_endo_wnaf<4, 0, 1>(large_scalar_ct,
false);
194 const uint512_t scalar_field_modulus = scalar_ct::modulus_u512;
197 const size_t num_allowed_bits = ((
uint512_t(1) << 256) - scalar_field_modulus).
get_msb();
203 scalar_ct large_scalar_ct = scalar_ct::create_from_u512_as_witness(&
builder, large_value,
true);
204 EXPECT_EQ(large_scalar_ct.get_value() < (
uint512_t(1) << 256),
true);
205 EXPECT_EQ(large_scalar_ct.get_value() >=
uint512_t(scalar_field_modulus),
true);
206 EXPECT_EQ(large_scalar_ct.get_value() %
uint512_t(scalar_field_modulus),
uint512_t(scalar_a));
209 element_ct::template compute_secp256k1_endo_wnaf<4, 0, 1>(scalar_a_ct,
false);
212 element_ct::template compute_secp256k1_endo_wnaf<4, 0, 1>(large_scalar_ct,
false);
222 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
226 element_ct::template compute_secp256k1_endo_wnaf<8, 0, 3>(x_a,
false);
227 element_ct::template compute_secp256k1_endo_wnaf<8, 1, 2>(x_a,
false);
228 element_ct::template compute_secp256k1_endo_wnaf<8, 2, 1>(x_a,
false);
229 element_ct::template compute_secp256k1_endo_wnaf<8, 3, 0>(x_a,
false);
234 if ((
uint256_t(scalar_b).get_bit(0) & 1) == 0) {
238 element_ct::template compute_secp256k1_endo_wnaf<8, 0, 3>(x_b,
false);
239 element_ct::template compute_secp256k1_endo_wnaf<8, 1, 2>(x_b,
false);
240 element_ct::template compute_secp256k1_endo_wnaf<8, 2, 1>(x_b,
false);
241 element_ct::template compute_secp256k1_endo_wnaf<8, 3, 0>(x_b,
false);
250 size_t num_repetitions = 1;
251 for (
size_t i = 0; i < num_repetitions; ++i) {
255 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
270 auto output = element_ct::secp256k1_ecdsa_mul(P_a, u1, u2);
273 EXPECT_EQ(output.x.get_value().lo,
uint256_t(expected.x));
274 EXPECT_EQ(output.y.get_value().lo,
uint256_t(expected.y));
313 const uint256_t scalar_s1(
"0x66ad81e84534c20431c795de922fb592c3d8c68edcacfc6c5b52ab7ad10e47d3");
314 const uint256_t scalar_u1(
"0x37e0ba2e9c4dd42077fd751a7426a8484a8ff2928a6c85a651e4470b461c6215");
315 const uint256_t scalar_u2(
"0xdefbb9bbabde5b9f8d7175946e75babc2f11203a8bfb71beaeec1d7a2bff17dd");
321 ASSERT((
fr(scalar_s1) *
fr(scalar_u2) +
fr(scalar_u1)).is_zero());
335 auto output = element_ct::secp256k1_ecdsa_mul(P_a, u1, u2);
338 EXPECT_EQ(output.is_point_at_infinity().get_value(),
true);
373 const uint256_t scalar_g1(
"0x9d496650d261d31af6aa4cf41e435ed739d0fe2c34728a21a0df5c66a3504ccd");
374 const uint256_t scalar_u1(
"0xf3d9f52f0f55d3da6f902aa842aa604005633f3d165bc800f3a3aa661b18df5f");
375 const uint256_t scalar_u2(
"0x1323b0342b1a56a076cbf5e3899156fbf3f439f2c3b0d5a95b9ef74622447f2e");
381 ASSERT((
fr(scalar_g1) *
fr(scalar_u2) +
fr(scalar_u1)).is_zero());
389 auto output = element_ct::secp256k1_ecdsa_mul(P_a, u1, u2);
392 EXPECT_EQ(output.is_point_at_infinity().get_value(),
true);
408 TestFixture::template test_get_staggered_wnaf_fragment_value<4>();
412 TestFixture::template test_get_staggered_wnaf_fragment_value<8>();
416 TestFixture::test_wnaf_secp256k1();
420 TestFixture::test_wnaf_secp256k1_stagger_out_of_range_fails();
424 TestFixture::test_wnaf_secp256k1_scalar_exceeding_modulus_regression_1();
428 TestFixture::test_wnaf_secp256k1_scalar_exceeding_modulus_regression_2();
432 TestFixture::test_wnaf_8bit_secp256k1();
436 TestFixture::test_ecdsa_mul_secp256k1();
440 TestFixture::test_secp256k1_ecdsa_mul_skew_handling_regression();
444 TestFixture::test_secp256k1_ecdsa_mul_stagger_regression();
#define ASSERT(expression,...)
testing::Types< stdlib::secp256k1< bb::UltraCircuitBuilder >, stdlib::secp256k1< bb::MegaCircuitBuilder > > Secp256k1TestTypes
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
group_elements::affine_element< Fq, Fr, Params > affine_element
static constexpr element one
group_elements::element< Fq, Fr, Params > element
constexpr uint64_t get_msb() const
Implements boolean logic in-circuit.
static void test_wnaf_secp256k1_stagger_out_of_range_fails()
typename Curve::g1_bigfr_ct element_ct
static void test_wnaf_secp256k1()
static void test_secp256k1_ecdsa_mul_skew_handling_regression()
static void test_wnaf_secp256k1_scalar_exceeding_modulus_regression_1()
static constexpr auto EXPECT_CIRCUIT_CORRECTNESS
typename g1::element element
static void test_ecdsa_mul_secp256k1()
static void test_wnaf_secp256k1_scalar_exceeding_modulus_regression_2()
static void test_wnaf_8bit_secp256k1()
typename Curve::bigfr_ct scalar_ct
typename Curve::Builder Builder
typename g1::affine_element affine_element
static void test_secp256k1_ecdsa_mul_stagger_regression()
void test_get_staggered_wnaf_fragment_value()
uintx< uint256_t > uint512_t
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
static constexpr uint256_t modulus
static void split_into_endomorphism_scalars(const field &k, field &k1, field &k2)
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr field from_montgomery_form() const noexcept