|
| template<typename Builder , typename Curve , typename Fq , typename Fr , typename G1 > |
| bool_t< Builder > | ecdsa_verify_signature (const stdlib::byte_array< Builder > &hashed_message, const G1 &public_key, const ecdsa_signature< Builder > &sig) |
| | Verify ECDSA signature. Returns bool_t(true/false) depending on whether the signature is valid or not.
|
| |
| template<typename Builder > |
| void | generate_ecdsa_verification_test_circuit (Builder &builder, size_t num_iterations) |
| | Generate a simple ecdsa verification circuit for testing purposes.
|
| |
| constexpr size_t | get_num_blocks (const size_t num_bits) |
| |
| template<typename C , typename T > |
| std::ostream & | operator<< (std::ostream &os, bigfield< T, C > const &v) |
| |
| template<typename C > |
| std::ostream & | operator<< (std::ostream &os, goblin_field< C > const &v) |
| |
| template<typename T > |
| std::ostream & | operator<< (std::ostream &os, bool_t< T > const &v) |
| |
| template<typename Builder > |
| std::ostream & | operator<< (std::ostream &os, byte_array< Builder > const &arr) |
| |
| template<typename T > |
| T * | validate_context (T *ptr) |
| |
| template<typename T , typename... Ts> |
| T * | validate_context (T *first, Ts *... rest) |
| |
| template<typename T , typename Container > |
| T * | validate_context (const Container &elements) |
| |
| template<typename Builder > |
| std::ostream & | operator<< (std::ostream &os, field_t< Builder > const &v) |
| |
| template<typename Builder > |
| void | validate_split_in_field_unsafe (const field_t< Builder > &lo, const field_t< Builder > &hi, const size_t lo_bits, const uint256_t &field_modulus) |
| | Validates that lo + hi * 2^lo_bits < field_modulus (assuming range constraints on lo and hi)
|
| |
| template<typename Builder > |
| std::pair< field_t< Builder >, field_t< Builder > > | split_unique (const field_t< Builder > &field, const size_t lo_bits, const bool skip_range_constraints=false) |
| | Split a bn254 scalar field element into unique lo and hi limbs.
|
| |
| template<typename Builder > |
| void | mark_witness_as_used (const field_t< Builder > &field) |
| | Mark a field_t witness as used (for UltraBuilder only).
|
| |
| template std::pair< field_t< bb::UltraCircuitBuilder >, field_t< bb::UltraCircuitBuilder > > | split_unique (const field_t< bb::UltraCircuitBuilder > &field, const size_t lo_bits, const bool skip_range_constraints) |
| |
| template std::pair< field_t< bb::MegaCircuitBuilder >, field_t< bb::MegaCircuitBuilder > > | split_unique (const field_t< bb::MegaCircuitBuilder > &field, const size_t lo_bits, const bool skip_range_constraints) |
| |
| template void | validate_split_in_field_unsafe (const field_t< bb::UltraCircuitBuilder > &lo, const field_t< bb::UltraCircuitBuilder > &hi, const size_t lo_bits, const uint256_t &field_modulus) |
| |
| template void | validate_split_in_field_unsafe (const field_t< bb::MegaCircuitBuilder > &lo, const field_t< bb::MegaCircuitBuilder > &hi, const size_t lo_bits, const uint256_t &field_modulus) |
| |
| template void | mark_witness_as_used (const field_t< bb::UltraCircuitBuilder > &field) |
| |
| template void | mark_witness_as_used (const field_t< bb::MegaCircuitBuilder > &field) |
| |
| template<typename Builder > |
| std::ostream & | operator<< (std::ostream &os, cycle_group< Builder > const &v) |
| |
| template<typename Builder > |
| std::ostream & | operator<< (std::ostream &os, safe_uint_t< Builder > const &v) |
| |
Verify ECDSA signature. Returns bool_t(true/false) depending on whether the signature is valid or not.
Fix the following notation:
- \(E\) is an elliptic curve over the base field \(\mathbb{F}_q\).
- \(G\) is a generator of the group of points of \(E\), the order of \(G\) is \(n\) and prime.
- \(a \in \mathbb{F}_n^{\ast}\) is a private key, and \(P := aG\) is the associated public key
- \(\mathbf{H}\) is a hash function
Given a message \(m\), a couple \((r,s)\) is a valid signature for the message \(m\) with respect to the public key \(P\) if (following https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf):
- \(P\) is a point on \(E\)
- \(P = (x,y)\), then x < q, y < q
- \(P\) is not the point at infinity
- \(0 < r < n\)
- \(0 < s < (n+1) / 2\)
- Define \(e := \mathbf{H}(m) \mod n\) and \(Q := e s^{-1} G + r s^{-1} P \)
- \(Q\) is not the point at infinity
- \(Q_x = r \mod n\) (note that \(Q_x \in \mathbb{F}_q\))
- Note
- The requirement of step 4. is to avoid signature malleability: if \((r,s)\) is a valid signature for message \(m\) and public key \(P\), so is \((r,n-s)\). We protect against malleability by enforcing that \(s\) is always the lowest of the two possible values.
-
In Ethereum signatures contain also a recovery byte \(v\) which is used to recover the public key for which the signature is to be validated. As we receive the public key as part of the inputs to the verification function, we do not handle the recovery byte. The signature which is the input to the verification function is given by \((r,s)\). The users of the verification function should handle the recovery byte if that is in their interest.
-
This function verifies that
sig is a valid signature for the public key public_key. The function returns an in-circuit boolean value which bears witness to whether the signature verification was successfull or not. The boolean is NOT constrained to be equal to bool_t(true).
-
The circuit introduces constraints for the following assertions:
- \(P = (x,y)\), then x < q, y < q
- \(P\) is on the curve
- \(P\) is not the point at infinity
- \(0 < r < n\)
- \(0 < s < (n+1)/2\)
- \(Q := H(m) s^{-1} G + r s^{-1} P\) is not the point at infinity Therefore, if the witnesses passed to this function do not satisfy these constraints, the resulting circuit will be unsatisfied. If a user wants to use the verification inside a in-circuit branch, then they need to supply valid data for \(P, r, s\), even though \((r,s)\) doesn't need to be a valid signature.
- Template Parameters
-
- Parameters
-
| hashed_message | |
| public_key | |
| sig | |
- Returns
- bool_t<Builder>
Definition at line 75 of file ecdsa_impl.hpp.
| void bb::stdlib::mark_witness_as_used |
( |
const field_t< Builder > & |
field | ) |
|
Mark a field_t witness as used (for UltraBuilder only).
For certain operations like assert_is_not_zero, we create intermediate witnesses that are not part of the circuit's primary logic but are needed for constraints. This function marks such witnesses as "used" to prevent them from being incorrectly identified as unused. Uses raw witness_index to avoid normalization overhead.
This is a no-op for non-Ultra builders.
- Parameters
-
| field | The field element whose witness should be marked as used |
Definition at line 97 of file field_utils.cpp.