Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
secp256r1_ecdsa_mul_ultra.fuzzer.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
28
29#include <cassert>
30#include <cstdint>
31#include <cstring>
32
36using element_ct = typename Curve::Group;
40using affine_native = typename g1_native::affine_element;
41using element_native = typename g1_native::element;
42
43namespace {
44fr_native scalar_from_bytes(const uint8_t* p)
45{
46 uint64_t limbs[4]{};
47 for (size_t i = 0; i < 4; ++i) {
48 std::memcpy(&limbs[i], p + i * 8, sizeof(uint64_t));
49 }
50 return fr_native(uint256_t(limbs[0], limbs[1], limbs[2], limbs[3]));
51}
52} // namespace
53
54extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
55{
56 if (Size < 96) {
57 return 0;
58 }
59
60 const fr_native u1_native = scalar_from_bytes(Data + 0);
61 const fr_native u2_native = scalar_from_bytes(Data + 32);
62 const fr_native q_native = scalar_from_bytes(Data + 64);
63
64 // Q = q · G. If q = 0 the pubkey is at infinity, which `secp256r1_ecdsa_mul` doesn't support.
65 if (q_native == fr_native::zero()) {
66 return 0;
67 }
68
69 const affine_native Q_native(g1_native::one * q_native);
70
72 element_ct Q = element_ct::from_witness(&builder, Q_native);
75
76 const auto out = element_ct::secp256r1_ecdsa_mul(Q, u1, u2);
77
78 const bool u2_degenerate =
79 (u2_native == fr_native::zero()) || (u2_native == fr_native::one()) || (u2_native == -fr_native::one());
80
81 // The soundness flag must mirror the degeneracy in both directions.
82 assert(out.u2_is_acceptable.get_value() == !u2_degenerate && "ecdsa_mul: u2_is_acceptable mismatch");
83
84 if (!u2_degenerate) {
85 // Result must match the native u₁·G + u₂·Q.
86 const affine_native expected(g1_native::one * u1_native + element_native(Q_native) * u2_native);
87
88 if (expected.is_point_at_infinity()) {
89 assert(out.result.is_point_at_infinity().get_value() && "ecdsa_mul: expected infinity");
90 } else {
91 assert(!out.result.is_point_at_infinity().get_value() && "ecdsa_mul: unexpected infinity");
92 assert(out.result.x().get_value().lo == uint256_t(expected.x) && "ecdsa_mul: x mismatch");
93 assert(out.result.y().get_value().lo == uint256_t(expected.y) && "ecdsa_mul: y mismatch");
94 }
95 }
96
97 assert(bb::CircuitChecker::check(builder) && "ecdsa_mul: circuit check failed");
98 return 0;
99}
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
static bigfield from_witness(Builder *ctx, const bb::field< T > &input)
Definition bigfield.hpp:322
AluTraceBuilder builder
Definition alu.test.cpp:124
secp256r1_ct::Group element_ct
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
bb::VectorAffineElementPushSpan< BaseParams > out
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
typename Curve::ScalarFieldNative fr_native
typename g1_native::affine_element affine_native
typename g1_native::element element_native
typename Curve::GroupNative g1_native
::bb::secp256r1::g1 GroupNative
Definition secp256r1.hpp:24
element< CircuitType, BaseField, ScalarField, GroupNative > Group
Definition secp256r1.hpp:31
bigfield< CircuitType, typename ::bb::secp256r1::FrParams > ScalarField
Definition secp256r1.hpp:29
::bb::secp256r1::fr ScalarFieldNative
Definition secp256r1.hpp:22