diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs index d2611f72535..99cc11ecd2a 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/foreign.rs @@ -87,7 +87,6 @@ fn call_foreign( "sha256_compression" => sha256_compression(interner, args, location), _ => { let explanation = match name { - "schnorr_verify" => "Schnorr verification will be removed.".into(), "and" | "xor" => "It should be turned into a binary operation.".into(), "recursive_aggregation" => "A proof cannot be verified at comptime.".into(), _ => { diff --git a/docs/docs/noir/standard_library/black_box_fns.md b/docs/docs/noir/standard_library/black_box_fns.md index d6079ab182c..e9392b20a92 100644 --- a/docs/docs/noir/standard_library/black_box_fns.md +++ b/docs/docs/noir/standard_library/black_box_fns.md @@ -14,7 +14,6 @@ Here is a list of the current black box functions: - [AES128](./cryptographic_primitives/ciphers.mdx#aes128) - [SHA256](./cryptographic_primitives/hashes.mdx#sha256) -- [Schnorr signature verification](./cryptographic_primitives/schnorr.mdx) - [Blake2s](./cryptographic_primitives/hashes.mdx#blake2s) - [Blake3](./cryptographic_primitives/hashes.mdx#blake3) - [Pedersen Hash](./cryptographic_primitives/hashes.mdx#pedersen_hash) diff --git a/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx b/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx deleted file mode 100644 index 4c859043787..00000000000 --- a/docs/docs/noir/standard_library/cryptographic_primitives/schnorr.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: Schnorr Signatures -description: Learn how you can verify Schnorr signatures using Noir -keywords: [cryptographic primitives, Noir project, schnorr, signatures] -sidebar_position: 2 ---- - -import BlackBoxInfo from '@site/src/components/Notes/_blackbox'; - -## schnorr::verify_signature - -Verifier for Schnorr signatures over the embedded curve (for BN254 it is Grumpkin). - -#include_code schnorr_verify noir_stdlib/src/schnorr.nr rust - -where `_signature` can be generated like so using the npm package -[@noir-lang/barretenberg](https://www.npmjs.com/package/@noir-lang/barretenberg) - -```js -const { BarretenbergWasm } = require('@noir-lang/barretenberg/dest/wasm'); -const { Schnorr } = require('@noir-lang/barretenberg/dest/crypto/schnorr'); - -... - -const barretenberg = await BarretenbergWasm.new(); -const schnorr = new Schnorr(barretenberg); -const pubKey = schnorr.computePublicKey(privateKey); -const message = ... -const signature = Array.from( - schnorr.constructSignature(hash, privateKey).toBuffer() -); - -... -``` - - diff --git a/noir_stdlib/src/schnorr.nr b/noir_stdlib/src/schnorr.nr deleted file mode 100644 index d9d494e3093..00000000000 --- a/noir_stdlib/src/schnorr.nr +++ /dev/null @@ -1,95 +0,0 @@ -use crate::embedded_curve_ops::{EmbeddedCurvePoint, EmbeddedCurveScalar}; - -// docs:start:schnorr_verify -pub fn verify_signature( - public_key: EmbeddedCurvePoint, - signature: [u8; 64], - message: [u8; N], -) -> bool -// docs:end:schnorr_verify -{ - //scalar lo/hi from bytes - let sig_s = EmbeddedCurveScalar::from_bytes(signature, 0); - let sig_e = EmbeddedCurveScalar::from_bytes(signature, 32); - // pub_key is on Grumpkin curve - let mut is_ok = (public_key.y * public_key.y == public_key.x * public_key.x * public_key.x - 17) - & (!public_key.is_infinite); - - if ((sig_s.lo != 0) | (sig_s.hi != 0)) & ((sig_e.lo != 0) | (sig_e.hi != 0)) { - let (r_is_infinite, result) = - calculate_signature_challenge(public_key, sig_s, sig_e, message); - - is_ok &= !r_is_infinite; - for i in 0..32 { - is_ok &= result[i] == signature[32 + i]; - } - } else { - is_ok = false; - } - is_ok -} - -pub fn assert_valid_signature( - public_key: EmbeddedCurvePoint, - signature: [u8; 64], - message: [u8; N], -) { - //scalar lo/hi from bytes - let sig_s = EmbeddedCurveScalar::from_bytes(signature, 0); - let sig_e = EmbeddedCurveScalar::from_bytes(signature, 32); - - // assert pub_key is on Grumpkin curve - assert(public_key.y * public_key.y == public_key.x * public_key.x * public_key.x - 17); - assert(public_key.is_infinite == false); - // assert signature is not null - assert((sig_s.lo != 0) | (sig_s.hi != 0)); - assert((sig_e.lo != 0) | (sig_e.hi != 0)); - - let (r_is_infinite, result) = calculate_signature_challenge(public_key, sig_s, sig_e, message); - - assert(!r_is_infinite); - for i in 0..32 { - assert(result[i] == signature[32 + i]); - } -} - -fn calculate_signature_challenge( - public_key: EmbeddedCurvePoint, - sig_s: EmbeddedCurveScalar, - sig_e: EmbeddedCurveScalar, - message: [u8; N], -) -> (bool, [u8; 32]) { - let g1 = EmbeddedCurvePoint { - x: 1, - y: 17631683881184975370165255887551781615748388533673675138860, - is_infinite: false, - }; - let r = crate::embedded_curve_ops::multi_scalar_mul([g1, public_key], [sig_s, sig_e]); - // compare the _hashes_ rather than field elements modulo r - let pedersen_hash = crate::hash::pedersen_hash([r.x, public_key.x, public_key.y]); - let pde: [u8; 32] = pedersen_hash.to_be_bytes(); - - let mut hash_input = [0; N + 32]; - for i in 0..32 { - hash_input[i] = pde[i]; - } - for i in 0..N { - hash_input[32 + i] = message[i]; - } - - let result = crate::hash::blake2s(hash_input); - (r.is_infinite, result) -} - -#[test] -fn test_zero_signature() { - let public_key: EmbeddedCurvePoint = EmbeddedCurvePoint { - x: 1, - y: 17631683881184975370165255887551781615748388533673675138860, - is_infinite: false, - }; - let signature: [u8; 64] = [0; 64]; - let message: [u8; _] = [2; 64]; // every message - let verified = verify_signature(public_key, signature, message); - assert(!verified); -} diff --git a/test_programs/compile_success_empty/schnorr_simplification/Nargo.toml b/test_programs/compile_success_empty/schnorr_simplification/Nargo.toml deleted file mode 100644 index 599f06ac3d2..00000000000 --- a/test_programs/compile_success_empty/schnorr_simplification/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "schnorr_simplification" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/compile_success_empty/schnorr_simplification/src/main.nr b/test_programs/compile_success_empty/schnorr_simplification/src/main.nr deleted file mode 100644 index 53b71fc3842..00000000000 --- a/test_programs/compile_success_empty/schnorr_simplification/src/main.nr +++ /dev/null @@ -1,21 +0,0 @@ -use std::embedded_curve_ops::EmbeddedCurvePoint; - -// Note: If main has any unsized types, then the verifier will never be able -// to figure out the circuit instance -fn main() { - let message = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; - let pub_key = EmbeddedCurvePoint { - x: 0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a, - y: 0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197, - is_infinite: false, - }; - let signature = [ - 1, 13, 119, 112, 212, 39, 233, 41, 84, 235, 255, 93, 245, 172, 186, 83, 157, 253, 76, 77, - 33, 128, 178, 15, 214, 67, 105, 107, 177, 234, 77, 48, 27, 237, 155, 84, 39, 84, 247, 27, - 22, 8, 176, 230, 24, 115, 145, 220, 254, 122, 135, 179, 171, 4, 214, 202, 64, 199, 19, 84, - 239, 138, 124, 12, - ]; - - let valid_signature = std::schnorr::verify_signature(pub_key, signature, message); - assert(valid_signature); -} diff --git a/test_programs/execution_success/schnorr/Nargo.toml b/test_programs/execution_success/schnorr/Nargo.toml deleted file mode 100644 index aa24a2f3caf..00000000000 --- a/test_programs/execution_success/schnorr/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "schnorr" -type = "bin" -authors = [""] - -[dependencies] diff --git a/test_programs/execution_success/schnorr/Prover.toml b/test_programs/execution_success/schnorr/Prover.toml deleted file mode 100644 index 2faf2018e07..00000000000 --- a/test_programs/execution_success/schnorr/Prover.toml +++ /dev/null @@ -1,70 +0,0 @@ -message = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] -message_field = "0x010203040506070809" -pub_key_x = "0x04b260954662e97f00cab9adb773a259097f7a274b83b113532bce27fa3fb96a" -pub_key_y = "0x2fd51571db6c08666b0edfbfbc57d432068bccd0110a39b166ab243da0037197" -signature = [ - 1, - 13, - 119, - 112, - 212, - 39, - 233, - 41, - 84, - 235, - 255, - 93, - 245, - 172, - 186, - 83, - 157, - 253, - 76, - 77, - 33, - 128, - 178, - 15, - 214, - 67, - 105, - 107, - 177, - 234, - 77, - 48, - 27, - 237, - 155, - 84, - 39, - 84, - 247, - 27, - 22, - 8, - 176, - 230, - 24, - 115, - 145, - 220, - 254, - 122, - 135, - 179, - 171, - 4, - 214, - 202, - 64, - 199, - 19, - 84, - 239, - 138, - 124, - 12, -] diff --git a/test_programs/execution_success/schnorr/src/main.nr b/test_programs/execution_success/schnorr/src/main.nr deleted file mode 100644 index ab3c65372c5..00000000000 --- a/test_programs/execution_success/schnorr/src/main.nr +++ /dev/null @@ -1,24 +0,0 @@ -use std::embedded_curve_ops; - -// Note: If main has any unsized types, then the verifier will never be able -// to figure out the circuit instance -fn main( - message: [u8; 10], - message_field: Field, - pub_key_x: Field, - pub_key_y: Field, - signature: [u8; 64], -) { - // Regression for issue #2421 - // We want to make sure that we can accurately verify a signature whose message is a slice vs. an array - let message_field_bytes: [u8; 10] = message_field.to_be_bytes(); - - // Check that passing an array as the message is valid - let pub_key = - embedded_curve_ops::EmbeddedCurvePoint { x: pub_key_x, y: pub_key_y, is_infinite: false }; - let valid_signature = std::schnorr::verify_signature(pub_key, signature, message_field_bytes); - assert(valid_signature); - let valid_signature = std::schnorr::verify_signature(pub_key, signature, message); - assert(valid_signature); - std::schnorr::assert_valid_signature(pub_key, signature, message); -} diff --git a/tooling/nargo_cli/src/cli/test_cmd.rs b/tooling/nargo_cli/src/cli/test_cmd.rs index aa0ee1bb94b..e8c0e16ff4a 100644 --- a/tooling/nargo_cli/src/cli/test_cmd.rs +++ b/tooling/nargo_cli/src/cli/test_cmd.rs @@ -304,3 +304,31 @@ fn display_test_report( Ok(()) } + +#[cfg(test)] +mod tests { + use std::io::Write; + use std::{thread, time::Duration}; + use termcolor::{ColorChoice, StandardStream}; + + #[test] + fn test_stderr_lock() { + for i in 0..4 { + thread::spawn(move || { + let mut writer = StandardStream::stderr(ColorChoice::Always); + //let mut writer = writer.lock(); + + let mut show = |msg| { + thread::sleep(Duration::from_millis(10)); + //println!("{i} {msg}"); + writeln!(writer, "{i} {msg}").unwrap(); + }; + + show("a"); + show("b"); + show("c"); + }); + } + thread::sleep(Duration::from_millis(100)); + } +}