From 2e5a8b16c68451a5a71ddc3d9c0775930fddab65 Mon Sep 17 00:00:00 2001 From: skaunov Date: Sun, 28 Apr 2024 19:40:18 +0300 Subject: [PATCH] proposes tackling of #72 and #101 --- rust-k256/src/lib.rs | 40 ++++++++++++++++++++----------- rust-k256/src/randomizedsigner.rs | 14 ++++++----- rust-k256/src/utils.rs | 6 ++--- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/rust-k256/src/lib.rs b/rust-k256/src/lib.rs index f0e66dc..4860c2e 100644 --- a/rust-k256/src/lib.rs +++ b/rust-k256/src/lib.rs @@ -57,8 +57,31 @@ use utils::*; pub mod randomizedsigner; use randomizedsigner::PlumeSigner; -/// The domain separation tag used for hashing to the `secp256k1` curve -pub const DST: &[u8] = b"QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_"; // Hash to curve algorithm +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +pub struct PlumeMessage/* Dst */ { + // /* dst_ */protocol: &'signing [u8], + // /* dst_ */msg_id: &'signing [u8], + /// WARNING: MUST contain the protocol id, and *unique* message id for this protocol. Consider safe separation of these ids (it + /// could be length of the protocol id, or anything you choose). + /// + /// WARNING: keep length of this field *less than 255* to enjoy better compatibility and smaller constraints number in + /// proving circuits. + pub dst: Vec, + pub msg: Vec +} +impl PlumeMessage { + /// Yields the signature with `None` for `v1specific`. Same as using [`RandomizedSigner`] with [`PlumeSigner`]; + /// use it when you don't want to `use` PlumeSigner and the trait in your code. + pub fn sign_v1(&self, secret_key: &SecretKey, rng: &mut impl CryptoRngCore) -> PlumeSignature { + PlumeSigner::new(secret_key, &self.dst, true).sign_with_rng(rng, &self.msg) + } + /// Yields the signature with `Some` for `v1specific`. Same as using [`RandomizedSigner`] with [`PlumeSigner`]; + /// use it when you don't want to `use` PlumeSigner and the trait in your code. + pub fn sign_v2(&self, secret_key: &SecretKey, rng: &mut impl CryptoRngCore) -> PlumeSignature { + // PlumeSigner::new(secret_key, false).sign_with_rng(rng, msg) + PlumeSigner::new(secret_key, &self.dst, false).sign_with_rng(rng, &self.msg) + } +} /// Struct holding signature data for a PLUME signature. /// @@ -66,7 +89,7 @@ pub const DST: &[u8] = b"QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_"; // #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct PlumeSignature { /// The message that was signed. - pub message: Vec, + pub message: PlumeMessage, /// The public key used to verify the signature. pub pk: AffinePoint, /// The nullifier. @@ -143,17 +166,6 @@ impl PlumeSignature { ]))) } } - - /// Yields the signature with `None` for `v1specific`. Same as using [`RandomizedSigner`] with [`PlumeSigner`]; - /// use it when you don't want to `use` PlumeSigner and the trait in your code. - pub fn sign_v1(secret_key: &SecretKey, msg: &[u8], rng: &mut impl CryptoRngCore) -> Self { - PlumeSigner::new(secret_key, true).sign_with_rng(rng, msg) - } - /// Yields the signature with `Some` for `v1specific`. Same as using [`RandomizedSigner`] with [`PlumeSigner`]; - /// use it when you don't want to `use` PlumeSigner and the trait in your code. - pub fn sign_v2(secret_key: &SecretKey, msg: &[u8], rng: &mut impl CryptoRngCore) -> Self { - PlumeSigner::new(secret_key, false).sign_with_rng(rng, msg) - } } fn c_sha256_vec_signal(values: Vec<&ProjectivePoint>) -> Output { diff --git a/rust-k256/src/randomizedsigner.rs b/rust-k256/src/randomizedsigner.rs index e066467..6e548b8 100644 --- a/rust-k256/src/randomizedsigner.rs +++ b/rust-k256/src/randomizedsigner.rs @@ -1,6 +1,6 @@ use super::{ CryptoRngCore, NonZeroScalar, PlumeSignature, PlumeSignatureV1Fields, ProjectivePoint, - SecretKey, DST, + SecretKey, PlumeMessage }; use k256::{ elliptic_curve::{ @@ -25,6 +25,7 @@ use signature::{Error, RandomizedSigner}; pub struct PlumeSigner<'signing> { /// The secret key to use for signing. This is borrowed immutably. secret_key: &'signing SecretKey, + pub dst: &'signing [u8], /// Whether to generate a PlumeSignature V1 (true) or PlumeSignature V2 (false). /// /// `bool` is fine to use here since the choice affects only the hashing which doesn't @@ -35,8 +36,8 @@ pub struct PlumeSigner<'signing> { impl<'signing> PlumeSigner<'signing> { /// Creates a new `PlumeSigner` instance with the given secret key and signature /// variant. - pub fn new(secret_key: &SecretKey, v1: bool) -> PlumeSigner { - PlumeSigner { secret_key, v1 } + pub fn new(secret_key: &'signing SecretKey, dst: &'signing [u8], v1: bool) -> PlumeSigner<'signing> { + PlumeSigner { secret_key, dst, v1 } } } impl<'signing> RandomizedSigner for PlumeSigner<'signing> { @@ -55,8 +56,9 @@ impl<'signing> RandomizedSigner for PlumeSigner<'signing> { // Compute h = htc([m, pk]) let hashed_to_curve = NonIdentity::new( - Secp256k1::hash_from_bytes::>(&[msg, &pk_bytes], &[DST]) - .map_err(|_| Error::new())?, + Secp256k1::hash_from_bytes::>( + &[msg, &pk_bytes], &[self.dst] + ).map_err(|_| Error::new())?, ) .expect("something is drammatically wrong if the input hashed to the identity"); @@ -95,7 +97,7 @@ impl<'signing> RandomizedSigner for PlumeSigner<'signing> { .expect("something is terribly wrong if the nonce is equal to negated product of the secret and the hash"); Ok(PlumeSignature { - message: msg.to_owned(), + message: PlumeMessage{ dst: self.dst.to_owned(), msg: msg.to_owned() }, pk: pk.into(), nullifier: nullifier.to_point().to_affine(), c: c_scalar, diff --git a/rust-k256/src/utils.rs b/rust-k256/src/utils.rs index 86501e6..a6cf199 100644 --- a/rust-k256/src/utils.rs +++ b/rust-k256/src/utils.rs @@ -9,13 +9,13 @@ use k256::{ // Hashes two values to the curve pub(crate) fn hash_to_curve( - m: &[u8], + m: &PlumeMessage, pk: &ProjectivePoint, ) -> Result { Secp256k1::hash_from_bytes::>( - &[[m, &encode_pt(pk)].concat().as_slice()], + &[[m.msg.as_slice(), &encode_pt(pk)].concat().as_slice()], //b"CURVE_XMD:SHA-256_SSWU_RO_", - &[DST], + &[&m.dst], ) }