From 50516445e0ac87083accee2e8b778518eb0cce8a Mon Sep 17 00:00:00 2001 From: skaunov Date: Sat, 2 Dec 2023 17:29:22 +0300 Subject: [PATCH 1/4] Solve #63, reduce `unwrap`, streamline error handling, and ditch panicing. --- rust-k256/src/lib.rs | 69 ++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/rust-k256/src/lib.rs b/rust-k256/src/lib.rs index a92153d..16cc0ef 100644 --- a/rust-k256/src/lib.rs +++ b/rust-k256/src/lib.rs @@ -1,6 +1,8 @@ // #![feature(generic_const_expr)] // #![allow(incomplete_features)] +use std::panic; + use elliptic_curve::bigint::ArrayEncoding; use elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest}; use elliptic_curve::ops::Reduce; @@ -21,11 +23,6 @@ const COUNT: usize = 2; const OUT: usize = L * COUNT; const DST: &[u8] = b"QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_"; // Hash to curve algorithm -#[derive(Debug, PartialEq)] -pub enum Error { - IsPointAtInfinityError, -} - fn print_type_of(_: &T) { println!("{}", std::any::type_name::()); } @@ -33,7 +30,7 @@ fn print_type_of(_: &T) { fn c_sha256_vec_signal(values: Vec<&ProjectivePoint>) -> Output { let preimage_vec = values .into_iter() - .map(|value| encode_pt(value).unwrap()) + .map(|value| encode_pt(value)) .collect::>() .concat(); let mut sha256_hasher = Sha256::new(); @@ -49,12 +46,12 @@ fn sha256hash6signals( g_r: &ProjectivePoint, hash_m_pk_pow_r: &ProjectivePoint, ) -> Scalar { - let g_bytes = encode_pt(g).unwrap(); - let pk_bytes = encode_pt(pk).unwrap(); - let h_bytes = encode_pt(hash_m_pk).unwrap(); - let nul_bytes = encode_pt(nullifier).unwrap(); - let g_r_bytes = encode_pt(g_r).unwrap(); - let z_bytes = encode_pt(hash_m_pk_pow_r).unwrap(); + let g_bytes = encode_pt(g); + let pk_bytes = encode_pt(pk); + let h_bytes = encode_pt(hash_m_pk); + let nul_bytes = encode_pt(nullifier); + let g_r_bytes = encode_pt(g_r); + let z_bytes = encode_pt(hash_m_pk_pow_r); let c_preimage_vec = [g_bytes, pk_bytes, h_bytes, nul_bytes, g_r_bytes, z_bytes].concat(); @@ -69,14 +66,12 @@ fn sha256hash6signals( } // Hashes two values to the curve -fn hash_to_curve(m: &[u8], pk: &ProjectivePoint) -> ProjectivePoint { - let pt: ProjectivePoint = Secp256k1::hash_from_bytes::>( - &[[m, &encode_pt(pk).unwrap()].concat().as_slice()], +fn hash_to_curve(m: &[u8], pk: &ProjectivePoint) -> Result { + Secp256k1::hash_from_bytes::>( + &[[m, &encode_pt(pk)].concat().as_slice()], //b"CURVE_XMD:SHA-256_SSWU_RO_", DST, ) - .unwrap(); - pt } /* currently seems to right place for this `struct` declaration; @@ -96,8 +91,6 @@ pub struct PlumeSignatureV1Fields<'a> { pub hashed_to_curve_r: &'a ProjectivePoint, } impl PlumeSignature<'_> { - /// WARNING: panics when `self.c` isn't an `Output::`. - /// So catch it if it's a possible case for you. // Verifier check in SNARK: // g^[r + sk * c] / (g^sk)^c = g^r // hash[m, gsk]^[r + sk * c] / (hash[m, pk]^sk)^c = hash[m, pk]^r @@ -105,27 +98,28 @@ impl PlumeSignature<'_> { pub fn verify_signals(&self) -> bool { // don't forget to check `c` is `Output` in the #API let c = Output::::from_slice(self.c); + // TODO should we allow `c` input greater than BaseField::MODULUS? - let c_scalar = &Scalar::from_uint_reduced(U256::from_be_byte_array(c.to_owned())); - /* @skaunov would be glad to discuss with @Divide-By-0 excessive of the following check. + let c_scalar = panic::catch_unwind(|| { + Scalar::from_uint_reduced(U256::from_be_byte_array(c.to_owned())) + }); + if c_scalar.is_err() {return false;} + let c_scalar = c_scalar.unwrap(); + + /* @skaunov would be glad to discuss with @Divide-By-0 excessiveness of the following check. Though I should notice that it at least doesn't breaking anything. */ if c_scalar.is_zero().into() { return false; } let r_point = ProjectivePoint::GENERATOR * self.s - self.pk * &c_scalar; + let hashed_to_curve = hash_to_curve(self.message, self.pk); + if hashed_to_curve.is_err() {return false;} + let hashed_to_curve = hashed_to_curve.unwrap(); + let hashed_to_curve_r = &hashed_to_curve * self.s - self.nullifier * &c_scalar; - // Check if the given hash matches - let result = |components: Vec<&ProjectivePoint>| -> bool { - if &c_sha256_vec_signal(components) == c { - true - } else { - false - } - }; - if let Some(PlumeSignatureV1Fields { r_point: sig_r_point, hashed_to_curve_r: sig_hashed_to_curve_r, @@ -141,7 +135,8 @@ impl PlumeSignature<'_> { return false; } - result(vec![ + // Check if the given hash matches + c == &c_sha256_vec_signal(vec![ &ProjectivePoint::GENERATOR, self.pk, &hashed_to_curve, @@ -150,15 +145,15 @@ impl PlumeSignature<'_> { &hashed_to_curve_r, ]) } else { - result(vec![self.nullifier, &r_point, &hashed_to_curve_r]) + // Check if the given hash matches + c == &c_sha256_vec_signal(vec![self.nullifier, &r_point, &hashed_to_curve_r]) } } } /// Encodes the point by compressing it to 33 bytes -fn encode_pt(point: &ProjectivePoint) -> Result, Error> { - let encoded = point.to_encoded_point(true); - Ok(encoded.to_bytes().to_vec()) +fn encode_pt(point: &ProjectivePoint) -> Vec { + point.to_encoded_point(true).to_bytes().to_vec() } /// Convert a 32-byte array to a scalar @@ -251,7 +246,7 @@ mod tests { let g_r = &g * &r; // hash[m, pk] - let hash_m_pk = hash_to_curve(m, &pk); + let hash_m_pk = hash_to_curve(m, &pk).unwrap(); println!( "h.x: {:?}", @@ -408,7 +403,7 @@ mod tests { ); // Test encode_pt() - let g_as_bytes = encode_pt(&g).unwrap(); + let g_as_bytes = encode_pt(&g); assert_eq!( hex::encode(g_as_bytes), "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" From 4396fb4b44a173eb26ce21e08455e95d38857176 Mon Sep 17 00:00:00 2001 From: skaunov Date: Sat, 2 Dec 2023 17:32:17 +0300 Subject: [PATCH 2/4] `fmt` and lint --- rust-k256/src/lib.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/rust-k256/src/lib.rs b/rust-k256/src/lib.rs index 16cc0ef..3f776ce 100644 --- a/rust-k256/src/lib.rs +++ b/rust-k256/src/lib.rs @@ -98,14 +98,16 @@ impl PlumeSignature<'_> { pub fn verify_signals(&self) -> bool { // don't forget to check `c` is `Output` in the #API let c = Output::::from_slice(self.c); - + // TODO should we allow `c` input greater than BaseField::MODULUS? let c_scalar = panic::catch_unwind(|| { Scalar::from_uint_reduced(U256::from_be_byte_array(c.to_owned())) }); - if c_scalar.is_err() {return false;} + if c_scalar.is_err() { + return false; + } let c_scalar = c_scalar.unwrap(); - + /* @skaunov would be glad to discuss with @Divide-By-0 excessiveness of the following check. Though I should notice that it at least doesn't breaking anything. */ if c_scalar.is_zero().into() { @@ -113,12 +115,14 @@ impl PlumeSignature<'_> { } let r_point = ProjectivePoint::GENERATOR * self.s - self.pk * &c_scalar; - + let hashed_to_curve = hash_to_curve(self.message, self.pk); - if hashed_to_curve.is_err() {return false;} + if hashed_to_curve.is_err() { + return false; + } let hashed_to_curve = hashed_to_curve.unwrap(); - - let hashed_to_curve_r = &hashed_to_curve * self.s - self.nullifier * &c_scalar; + + let hashed_to_curve_r = hashed_to_curve * self.s - self.nullifier * &c_scalar; if let Some(PlumeSignatureV1Fields { r_point: sig_r_point, From 9167fabbe4a77f0bf61d4d438ef1b6f0e87dabb9 Mon Sep 17 00:00:00 2001 From: skaunov Date: Sat, 2 Dec 2023 17:46:41 +0300 Subject: [PATCH 3/4] Some chore --- rust-k256/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rust-k256/src/lib.rs b/rust-k256/src/lib.rs index 3f776ce..bc96998 100644 --- a/rust-k256/src/lib.rs +++ b/rust-k256/src/lib.rs @@ -2,13 +2,11 @@ // #![allow(incomplete_features)] use std::panic; - use elliptic_curve::bigint::ArrayEncoding; use elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest}; use elliptic_curve::ops::Reduce; use elliptic_curve::sec1::ToEncodedPoint; use k256::{ - // ecdsa::{signature::Signer, Signature, SigningKey}, elliptic_curve::group::ff::PrimeField, sha2::{digest::Output, Digest, Sha256}, FieldBytes, @@ -30,7 +28,7 @@ fn print_type_of(_: &T) { fn c_sha256_vec_signal(values: Vec<&ProjectivePoint>) -> Output { let preimage_vec = values .into_iter() - .map(|value| encode_pt(value)) + .map(encode_pt) .collect::>() .concat(); let mut sha256_hasher = Sha256::new(); From 44e48202a3c27b8770863360da35acf229d3c996 Mon Sep 17 00:00:00 2001 From: skaunov Date: Sat, 2 Dec 2023 17:48:21 +0300 Subject: [PATCH 4/4] `fmt` --- rust-k256/src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust-k256/src/lib.rs b/rust-k256/src/lib.rs index bc96998..208d6cb 100644 --- a/rust-k256/src/lib.rs +++ b/rust-k256/src/lib.rs @@ -1,7 +1,6 @@ // #![feature(generic_const_expr)] // #![allow(incomplete_features)] -use std::panic; use elliptic_curve::bigint::ArrayEncoding; use elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest}; use elliptic_curve::ops::Reduce; @@ -9,12 +8,9 @@ use elliptic_curve::sec1::ToEncodedPoint; use k256::{ elliptic_curve::group::ff::PrimeField, sha2::{digest::Output, Digest, Sha256}, - FieldBytes, - ProjectivePoint, - Scalar, - Secp256k1, - U256, + FieldBytes, ProjectivePoint, Scalar, Secp256k1, U256, }; // requires 'getrandom' feature +use std::panic; const L: usize = 48; const COUNT: usize = 2;