diff --git a/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/Nargo.toml b/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/Nargo.toml new file mode 100644 index 00000000000..7199d3305bf --- /dev/null +++ b/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ECDSA secp256k1 verification" +authors = [""] +compiler_version = "0.1" + +[dependencies] diff --git a/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/Prover.toml b/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/Prover.toml new file mode 100644 index 00000000000..412c7b36e4c --- /dev/null +++ b/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/Prover.toml @@ -0,0 +1,209 @@ + +hashed_message = [ + 0x3a, + 0x73, + 0xf4, + 0x12, + 0x3a, + 0x5c, + 0xd2, + 0x12, + 0x1f, + 0x21, + 0xcd, + 0x7e, + 0x8d, + 0x35, + 0x88, + 0x35, + 0x47, + 0x69, + 0x49, + 0xd0, + 0x35, + 0xd9, + 0xc2, + 0xda, + 0x68, + 0x06, + 0xb4, + 0x63, + 0x3a, + 0xc8, + 0xc1, + 0xe2, +] +message = [ + 0x49, + 0x6e, + 0x73, + 0x74, + 0x72, + 0x75, + 0x63, + 0x74, + 0x69, + 0x6f, + 0x6e, + 0x73, + 0x20, + 0x75, + 0x6e, + 0x63, + 0x6c, + 0x65, + 0x61, + 0x72, + 0x2c, + 0x20, + 0x61, + 0x73, + 0x6b, + 0x20, + 0x61, + 0x67, + 0x61, + 0x69, + 0x6e, + 0x20, + 0x6c, + 0x61, + 0x74, + 0x65, + 0x72, + 0x2e, +] +pub_key_x = [ + 0xa0, + 0x43, + 0x4d, + 0x9e, + 0x47, + 0xf3, + 0xc8, + 0x62, + 0x35, + 0x47, + 0x7c, + 0x7b, + 0x1a, + 0xe6, + 0xae, + 0x5d, + 0x34, + 0x42, + 0xd4, + 0x9b, + 0x19, + 0x43, + 0xc2, + 0xb7, + 0x52, + 0xa6, + 0x8e, + 0x2a, + 0x47, + 0xe2, + 0x47, + 0xc7, +] +pub_key_y = [ + 0x89, + 0x3a, + 0xba, + 0x42, + 0x54, + 0x19, + 0xbc, + 0x27, + 0xa3, + 0xb6, + 0xc7, + 0xe6, + 0x93, + 0xa2, + 0x4c, + 0x69, + 0x6f, + 0x79, + 0x4c, + 0x2e, + 0xd8, + 0x77, + 0xa1, + 0x59, + 0x3c, + 0xbe, + 0xe5, + 0x3b, + 0x03, + 0x73, + 0x68, + 0xd7, +] +signature = [ + 0xe5, + 0x08, + 0x1c, + 0x80, + 0xab, + 0x42, + 0x7d, + 0xc3, + 0x70, + 0x34, + 0x6f, + 0x4a, + 0x0e, + 0x31, + 0xaa, + 0x2b, + 0xad, + 0x8d, + 0x97, + 0x98, + 0xc3, + 0x80, + 0x61, + 0xdb, + 0x9a, + 0xe5, + 0x5a, + 0x4e, + 0x8d, + 0xf4, + 0x54, + 0xfd, + 0x28, + 0x11, + 0x98, + 0x94, + 0x34, + 0x4e, + 0x71, + 0xb7, + 0x87, + 0x70, + 0xcc, + 0x93, + 0x1d, + 0x61, + 0xf4, + 0x80, + 0xec, + 0xbb, + 0x0b, + 0x89, + 0xd6, + 0xeb, + 0x69, + 0x69, + 0x01, + 0x61, + 0xe4, + 0x9a, + 0x71, + 0x5f, + 0xcd, + 0x55, +] diff --git a/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/src/main.nr b/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/src/main.nr new file mode 100644 index 00000000000..1cb40f09cd0 --- /dev/null +++ b/crates/nargo_cli/tests/test_data/ecdsa_secp256k1/src/main.nr @@ -0,0 +1,11 @@ +use dep::std; + + +fn main(message : [u8;38],hashed_message : [u8;32], pub_key_x : [u8;32], pub_key_y : [u8;32], signature : [u8;64]) { + // Hash the message, since secp256k1 expects a hashed_message + let expected= std::hash::sha256(message); + assert(hashed_message == expected); + + let x = std::ecdsa_secp256k1::verify_signature(pub_key_x, pub_key_y, signature, hashed_message); + assert(x == 1); +} \ No newline at end of file diff --git a/crates/nargo_cli/tests/test_data/to_bytes_integration/Prover.toml b/crates/nargo_cli/tests/test_data/to_bytes_integration/Prover.toml index 07fe857ac7c..23f7acea449 100644 --- a/crates/nargo_cli/tests/test_data/to_bytes_integration/Prover.toml +++ b/crates/nargo_cli/tests/test_data/to_bytes_integration/Prover.toml @@ -1 +1,2 @@ x = "2040124" +_y = "0x2000000000000000000000000000000000000000000000000000000000000000" diff --git a/crates/nargo_cli/tests/test_data/to_bytes_integration/src/main.nr b/crates/nargo_cli/tests/test_data/to_bytes_integration/src/main.nr index 6f57b407da7..36e6d430e2e 100644 --- a/crates/nargo_cli/tests/test_data/to_bytes_integration/src/main.nr +++ b/crates/nargo_cli/tests/test_data/to_bytes_integration/src/main.nr @@ -1,14 +1,27 @@ use dep::std; -fn main(x : Field) { +fn main(x : Field, _y: Field) { // The result of this byte array will be big-endian let y: Field = 2040124; let be_byte_array = y.to_be_bytes(31); // The result of this byte array will be little-endian let le_byte_array = x.to_le_bytes(31); - constrain le_byte_array[0] == 60; - constrain le_byte_array[0] == be_byte_array[30]; - constrain le_byte_array[1] == be_byte_array[29]; - constrain le_byte_array[2] == be_byte_array[28]; + assert(le_byte_array[0] == 60); + assert(le_byte_array[0] == be_byte_array[30]); + assert(le_byte_array[1] == be_byte_array[29]); + assert(le_byte_array[2] == be_byte_array[28]); + + let z = 0 - 1; + let p_bytes = std::field::modulus_le_bytes(); + let z_bytes = z.to_le_bytes(32); + assert(p_bytes[10] == z_bytes[10]); + assert(p_bytes[0] == z_bytes[0] as u8 + 1 as u8); + + let p_bits = std::field::modulus_le_bits(); + let z_bits = z.to_le_bits(std::field::modulus_num_bits() as u32); + assert(z_bits[0] == 0); + assert(p_bits[100] == z_bits[100]); + + _y.to_le_bits(std::field::modulus_num_bits() as u32); } \ No newline at end of file diff --git a/crates/noirc_evaluator/src/ssa/acir_gen/constraints.rs b/crates/noirc_evaluator/src/ssa/acir_gen/constraints.rs index 375ccf1f4dd..5a4176c0893 100644 --- a/crates/noirc_evaluator/src/ssa/acir_gen/constraints.rs +++ b/crates/noirc_evaluator/src/ssa/acir_gen/constraints.rs @@ -558,7 +558,8 @@ pub(crate) fn evaluate_constant_modulo( ) -> Expression { let modulus = FieldElement::from(rhs as i128); let modulus_exp = Expression::from_field(modulus); - let modulus_bits = bit_size_u128(rhs as u128); + assert_ne!(rhs, 0); + let modulus_bits = bit_size_u128((rhs - 1) as u128); assert!(max_bits >= rhs, "max_bits = {max_bits}, rhs = {rhs}"); //0. Check for constant expression. This can happen through arithmetic simplifications if let Some(a_c) = lhs.to_const() { @@ -584,8 +585,12 @@ pub(crate) fn evaluate_constant_modulo( modulus_bits, evaluator, ); - try_range_constraint(b_witness, modulus_bits, evaluator); - try_range_constraint(c_witness, max_bits - modulus_bits, evaluator); + //if rhs is a power of 2, then we avoid this range check as it is redundant with the previous one. + if rhs & (rhs - 1) != 0 { + try_range_constraint(b_witness, modulus_bits, evaluator); + } + let c_bound = FieldElement::modulus() / BigUint::from(rhs) - BigUint::one(); + try_range_constraint(c_witness, c_bound.bits() as u32, evaluator); //2. Add the constraint lhs = b+q*rhs let b_arith = b_witness.into();