From fecb67ded78dcd8599278e55fe1c44709b11345b Mon Sep 17 00:00:00 2001 From: aniampio Date: Wed, 3 Aug 2022 15:46:15 +0100 Subject: [PATCH] Update for compact e-cash - remove requirement for security tag --- .../src/proofs/mod.rs | 24 ++-- .../src/proofs/proof_spend.rs | 109 ++++-------------- .../src/proofs/proof_withdrawal.rs | 38 +++--- .../src/scheme/aggregation.rs | 17 ++- .../src/scheme/identify.rs | 14 +-- .../src/scheme/keygen.rs | 2 +- .../src/scheme/mod.rs | 54 +++------ .../src/scheme/setup.rs | 22 ++-- .../src/scheme/withdrawal.rs | 17 +-- .../src/tests/e2e.rs | 12 +- 10 files changed, 92 insertions(+), 217 deletions(-) diff --git a/common/nym_offline_compact_ecash/src/proofs/mod.rs b/common/nym_offline_compact_ecash/src/proofs/mod.rs index 7208560002..6f42ee0f05 100644 --- a/common/nym_offline_compact_ecash/src/proofs/mod.rs +++ b/common/nym_offline_compact_ecash/src/proofs/mod.rs @@ -1,18 +1,10 @@ use std::borrow::Borrow; -use std::convert::TryFrom; -use std::convert::TryInto; -use bls12_381::{G1Affine, G1Projective, Scalar}; -use digest::generic_array::typenum::Unsigned; +use bls12_381::Scalar; use digest::Digest; -use group::GroupEncoding; +use digest::generic_array::typenum::Unsigned; use sha2::Sha256; -use crate::error::{CompactEcashError, Result}; -use crate::scheme::keygen::PublicKeyUser; -use crate::scheme::setup::GroupParameters; -use crate::utils::try_deserialize_g1_projective; - pub mod proof_spend; pub mod proof_withdrawal; @@ -20,10 +12,10 @@ type ChallengeDigest = Sha256; /// Generates a Scalar [or Fp] challenge by hashing a number of elliptic curve points. fn compute_challenge(iter: I) -> Scalar -where - D: Digest, - I: Iterator, - B: AsRef<[u8]>, + where + D: Digest, + I: Iterator, + B: AsRef<[u8]>, { let mut h = D::new(); for point_representation in iter { @@ -51,8 +43,8 @@ fn produce_response(witness_replacement: &Scalar, challenge: &Scalar, secret: &S // note: it's caller's responsibility to ensure witnesses.len() = secrets.len() fn produce_responses(witnesses: &[Scalar], challenge: &Scalar, secrets: &[S]) -> Vec -where - S: Borrow, + where + S: Borrow, { debug_assert_eq!(witnesses.len(), secrets.len()); diff --git a/common/nym_offline_compact_ecash/src/proofs/proof_spend.rs b/common/nym_offline_compact_ecash/src/proofs/proof_spend.rs index a193aedf11..2674658c39 100644 --- a/common/nym_offline_compact_ecash/src/proofs/proof_spend.rs +++ b/common/nym_offline_compact_ecash/src/proofs/proof_spend.rs @@ -1,13 +1,12 @@ use std::convert::{TryFrom, TryInto}; -use std::ops::Neg; use bls12_381::{G1Projective, G2Projective, Scalar}; -use group::{Curve, Group, GroupEncoding}; +use group::{Curve, GroupEncoding}; use crate::error::{CompactEcashError, Result}; use crate::proofs::{ChallengeDigest, compute_challenge, produce_response, produce_responses}; -use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth}; -use crate::scheme::setup::{GroupParameters, Parameters}; +use crate::scheme::keygen::VerificationKeyAuth; +use crate::scheme::setup::Parameters; use crate::utils::{try_deserialize_g1_projective, try_deserialize_g2_projective}; #[derive(Debug)] @@ -15,7 +14,6 @@ use crate::utils::{try_deserialize_g1_projective, try_deserialize_g2_projective} pub struct SpendInstance { pub kappa: G2Projective, pub cc: G1Projective, - pub dd: G1Projective, pub aa: Vec, pub ss: Vec, pub tt: Vec, @@ -78,13 +76,6 @@ impl TryFrom<&[u8]> for SpendInstance { )?; j += 48; - let dd_bytes = bytes[j..j + 48].try_into().unwrap(); - let dd = try_deserialize_g1_projective( - &dd_bytes, - CompactEcashError::Deserialization("Failed to deserialize D".to_string()), - )?; - j += 48; - let s_len = u64::from_le_bytes(bytes[j..j + 8].try_into().unwrap()); j += 8; if bytes[j..].len() < s_len as usize * 48 { @@ -167,7 +158,6 @@ impl TryFrom<&[u8]> for SpendInstance { kappa, aa, cc, - dd, ss, tt, kappa_k, @@ -186,7 +176,6 @@ impl SpendInstance { } bytes.extend_from_slice(self.cc.to_bytes().as_ref()); - bytes.extend_from_slice(self.dd.to_bytes().as_ref()); bytes.extend_from_slice(&self.ss.len().to_le_bytes()); for s in &self.ss { @@ -211,13 +200,10 @@ pub struct SpendWitness { // signature randomizing element pub r: Scalar, pub o_c: Scalar, - pub o_d: Scalar, pub lk: Vec, pub o_a: Vec, pub mu: Vec, - pub lambda: Vec, pub o_mu: Vec, - pub o_lambda: Vec, pub r_k: Vec, } @@ -229,11 +215,8 @@ pub struct SpendProof { response_l: Vec, response_o_a: Vec, response_o_c: Scalar, - response_o_d: Scalar, response_mu: Vec, - response_lambda: Vec, response_o_mu: Vec, - response_o_lambda: Vec, response_attributes: Vec, } @@ -250,18 +233,14 @@ impl SpendProof { let r_attributes = grparams.n_random_scalars(witness.attributes.len()); let r_sk = r_attributes[0]; let r_v = r_attributes[1]; - let r_t = r_attributes[2]; let r_r = grparams.random_scalar(); let r_o_c = grparams.random_scalar(); - let r_o_d = grparams.random_scalar(); let r_r_lk = grparams.n_random_scalars(witness.r_k.len()); let r_lk = grparams.n_random_scalars(witness.lk.len()); let r_o_a = grparams.n_random_scalars(witness.o_a.len()); let r_mu = grparams.n_random_scalars(witness.mu.len()); - let r_lambda = grparams.n_random_scalars(witness.lambda.len()); let r_o_mu = grparams.n_random_scalars(witness.o_mu.len()); - let r_o_lambda = grparams.n_random_scalars(witness.o_lambda.len()); let g1 = *grparams.gen1(); let gamma1 = *grparams.gamma1(); @@ -281,7 +260,6 @@ impl SpendProof { .sum::(); let zkcm_cc = g1 * r_o_c + gamma1 * r_v; - let zkcm_dd = g1 * r_o_d + gamma1 * r_t; let zkcm_aa: Vec = r_o_a @@ -294,7 +272,7 @@ impl SpendProof { .map(|x| x.to_bytes()) .collect::>(); - let zkcm_ss = r_mu.iter().map(|r_mu_k| g1 * r_mu_k).collect::>(); + let zkcm_ss = r_mu.iter().map(|r_mu_k| grparams.delta() * r_mu_k).collect::>(); let zkcm_ss_bytes = zkcm_ss .iter() @@ -303,7 +281,7 @@ impl SpendProof { let zkcm_tt = rr .iter() - .zip(r_lambda.iter()).map(|(rr_k, r_lambda_k)| g1 * r_sk + (g1 * rr_k) * r_lambda_k).collect::>(); + .zip(r_mu.iter()).map(|(rr_k, r_mu_k)| g1 * r_sk + (g1 * rr_k) * r_mu_k).collect::>(); let zkcm_tt_bytes = zkcm_tt .iter() @@ -322,21 +300,9 @@ impl SpendProof { .map(|x| x.to_bytes()) .collect::>(); - let zkcm_gamma12 = instance.aa - .iter() - .zip(r_lambda.iter()) - .zip(r_o_lambda.iter()) - .map(|((aa_k, r_lambda_k), r_o_lambda_k)| (aa_k + instance.dd + gamma1) * r_lambda_k + g1 * r_o_lambda_k) - .collect::>(); - - let zkcm_gamma12_bytes = zkcm_gamma12 - .iter() - .map(|x| x.to_bytes()) - .collect::>(); - let zkcm_kappa_k = r_lk.iter() .zip(r_r_lk.iter()) - .map(|(r_k, r_r_k)| params.pkRP().alpha + params.pkRP().beta * r_k + grparams.gen2() * r_r_k) + .map(|(r_k, r_r_k)| params.pk_rp().alpha + params.pk_rp().beta * r_k + grparams.gen2() * r_r_k) .collect::>(); let zkcm_kappa_k_bytes = zkcm_kappa_k @@ -353,13 +319,11 @@ impl SpendProof { .chain(std::iter::once(instance.to_bytes().as_ref())) .chain(std::iter::once(zkcm_kappa.to_bytes().as_ref())) .chain(std::iter::once(zkcm_cc.to_bytes().as_ref())) - .chain(std::iter::once(zkcm_dd.to_bytes().as_ref())) .chain(zkcm_aa_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_ss_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_kappa_k_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_tt_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_gamma11_bytes.iter().map(|x| x.as_ref())) - .chain(zkcm_gamma12_bytes.iter().map(|x| x.as_ref())), ); // compute response for each witness @@ -373,12 +337,9 @@ impl SpendProof { let response_l = produce_responses(&r_lk, &challenge, &witness.lk); let response_o_a = produce_responses(&r_o_a, &challenge, &witness.o_a); let response_o_c = produce_response(&r_o_c, &challenge, &witness.o_c); - let response_o_d = produce_response(&r_o_d, &challenge, &witness.o_d); let response_mu = produce_responses(&r_mu, &challenge, &witness.mu); - let response_lambda = produce_responses(&r_lambda, &challenge, &witness.lambda); let response_o_mu = produce_responses(&r_o_mu, &challenge, &witness.o_mu); - let response_o_lambda = produce_responses(&r_o_lambda, &challenge, &witness.o_lambda); SpendProof { challenge, @@ -387,11 +348,8 @@ impl SpendProof { response_l, response_o_a, response_o_c, - response_o_d, response_mu, - response_lambda, response_o_mu, - response_o_lambda, response_attributes, } } @@ -438,14 +396,11 @@ impl SpendProof { let zkcm_cc = g1 * self.response_o_c + gamma1 * self.response_attributes[1] + instance.cc * self.challenge; - let zkcm_dd = g1 * self.response_o_d - + gamma1 * self.response_attributes[2] - + instance.dd * self.challenge; let zkcm_ss = self.response_mu .iter() .zip(instance.ss.iter()) - .map(|(resp_mu_k, ss_k)| g1 * resp_mu_k + ss_k * self.challenge) + .map(|(resp_mu_k, ss_k)| grparams.delta() * resp_mu_k + ss_k * self.challenge) .collect::>(); let zkcm_ss_bytes = zkcm_ss @@ -453,11 +408,11 @@ impl SpendProof { .map(|x| x.to_bytes()) .collect::>(); - let zkcm_tt = self.response_lambda + let zkcm_tt = self.response_mu .iter() .zip(rr.iter()) .zip(instance.tt.iter()) - .map(|((resp_lambda_k, rr_k), tt_k)| g1 * self.response_attributes[0] + (g1 * rr_k) * resp_lambda_k + tt_k * self.challenge) + .map(|((resp_mu_k, rr_k), tt_k)| g1 * self.response_attributes[0] + (g1 * rr_k) * resp_mu_k + tt_k * self.challenge) .collect::>(); let zkcm_tt_bytes = zkcm_tt @@ -479,24 +434,11 @@ impl SpendProof { .collect::>(); - let zkcm_gamma12 = instance.aa - .iter() - .zip(self.response_lambda.iter()) - .zip(self.response_o_lambda.iter()) - .map(|((aa_k, resp_lambda_k), resp_o_lambda_k)| (aa_k + instance.dd + gamma1) * resp_lambda_k - + g1 * resp_o_lambda_k + gamma1 * self.challenge) - .collect::>(); - - let zkcm_gamma12_bytes = zkcm_gamma12 - .iter() - .map(|x| x.to_bytes()) - .collect::>(); - let zkcm_kappa_k = instance.kappa_k .iter() .zip(self.response_r_l.iter()) .zip(self.response_l.iter()) - .map(|((kappa_k, resp_r_k), resp_r_l_k)| kappa_k * self.challenge + grparams.gen2() * resp_r_k + params.pkRP().alpha * (Scalar::one() - self.challenge) + params.pkRP().beta * resp_r_l_k) + .map(|((kappa_k, resp_r_k), resp_r_l_k)| kappa_k * self.challenge + grparams.gen2() * resp_r_k + params.pk_rp().alpha * (Scalar::one() - self.challenge) + params.pk_rp().beta * resp_r_l_k) .collect::>(); let zkcm_kappa_k_bytes = zkcm_kappa_k @@ -513,13 +455,11 @@ impl SpendProof { .chain(std::iter::once(instance.to_bytes().as_ref())) .chain(std::iter::once(zkcm_kappa.to_bytes().as_ref())) .chain(std::iter::once(zkcm_cc.to_bytes().as_ref())) - .chain(std::iter::once(zkcm_dd.to_bytes().as_ref())) .chain(zkcm_aa_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_ss_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_kappa_k_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_tt_bytes.iter().map(|x| x.as_ref())) .chain(zkcm_gamma11_bytes.iter().map(|x| x.as_ref())) - .chain(zkcm_gamma12_bytes.iter().map(|x| x.as_ref())), ); challenge == self.challenge @@ -528,26 +468,25 @@ impl SpendProof { #[cfg(test)] mod tests { - use bls12_381::{G1Projective, G2Projective, Scalar}; - use group::Curve; - use rand::{Rng, thread_rng}; + use bls12_381::{G2Projective, Scalar}; + use rand::thread_rng; use crate::proofs::proof_spend::{SpendInstance, SpendProof, SpendWitness}; - use crate::scheme::{pseudorandom_fgt, pseudorandom_fgv}; + use crate::scheme::{pseudorandom_f_delta_v, pseudorandom_f_g_v}; use crate::scheme::aggregation::aggregate_verification_keys; use crate::scheme::keygen::{PublicKeyUser, ttp_keygen, VerificationKeyAuth}; use crate::scheme::PayInfo; - use crate::scheme::setup::{GroupParameters, setup}; + use crate::scheme::setup::setup; use crate::utils::hash_to_scalar; #[test] fn spend_proof_construct_and_verify() { - let rng = thread_rng(); + let _rng = thread_rng(); let L = 32; let params = setup(L); let grparams = params.grp(); let sk = grparams.random_scalar(); - let pk_user = PublicKeyUser { + let _pk_user = PublicKeyUser { pk: grparams.gen1() * sk, }; let authorities_keypairs = ttp_keygen(&grparams, 2, 3).unwrap(); @@ -578,40 +517,35 @@ mod tests { let o_a = grparams.random_scalar(); let o_c = grparams.random_scalar(); - let o_d = grparams.random_scalar(); // compute commitments A, C, D let aa = g1 * o_a + gamma1 * Scalar::from(l); let cc = g1 * o_c + gamma1 * v; - let dd = g1 * o_d + gamma1 * t; // compute hash of the payment info let pay_info = PayInfo { info: [37u8; 32] }; let rr = hash_to_scalar(pay_info.info); // evaluate the pseudorandom functions - let ss = pseudorandom_fgv(&grparams, v, l); - let tt = g1 * sk + pseudorandom_fgt(&grparams, t, l) * rr; + let ss = pseudorandom_f_delta_v(&grparams, v, l); + let tt = g1 * sk + pseudorandom_f_g_v(&grparams, v, l) * rr; // compute values mu, o_mu, lambda, o_lambda let mu: Scalar = (v + Scalar::from(l) + Scalar::from(1)).invert().unwrap(); let o_mu = ((o_a + o_c) * mu).neg(); - let lambda = (t + Scalar::from(l) + Scalar::from(1)).invert().unwrap(); - let o_lambda = ((o_a + o_d) * lambda).neg(); // parse the signature associated with value l let sign_l = params.get_sign_by_idx(l).unwrap(); // randomise the signature associated with value l - let (sign_l_prime, r_l) = sign_l.randomise(grparams); + let (_sign_l_prime, r_l) = sign_l.randomise(grparams); // compute kappa_l let kappa_k = - grparams.gen2() * r_l + params.pkRP().alpha + params.pkRP().beta * Scalar::from(l); + grparams.gen2() * r_l + params.pk_rp().alpha + params.pk_rp().beta * Scalar::from(l); let instance = SpendInstance { kappa, aa: vec![aa], cc, - dd, ss: vec![ss], tt: vec![tt], kappa_k: vec![kappa_k], @@ -621,13 +555,10 @@ mod tests { attributes, r, o_c, - o_d, lk: vec![Scalar::from(l)], o_a: vec![o_a], mu: vec![mu], - lambda: vec![lambda], o_mu: vec![o_mu], - o_lambda: vec![o_lambda], r_k: vec![r_l], }; diff --git a/common/nym_offline_compact_ecash/src/proofs/proof_withdrawal.rs b/common/nym_offline_compact_ecash/src/proofs/proof_withdrawal.rs index d44db84c42..35c4da55a8 100644 --- a/common/nym_offline_compact_ecash/src/proofs/proof_withdrawal.rs +++ b/common/nym_offline_compact_ecash/src/proofs/proof_withdrawal.rs @@ -5,7 +5,7 @@ use group::GroupEncoding; use itertools::izip; use crate::error::{CompactEcashError, Result}; -use crate::proofs::{compute_challenge, produce_response, produce_responses, ChallengeDigest}; +use crate::proofs::{ChallengeDigest, compute_challenge, produce_response, produce_responses}; use crate::scheme::keygen::PublicKeyUser; use crate::scheme::setup::GroupParameters; use crate::utils::try_deserialize_g1_projective; @@ -136,10 +136,10 @@ impl WithdrawalReqProof { // compute zkp commitments for each instance let zkcm_com = params.gen1() * r_com_opening + r_attributes - .iter() - .zip(params.gammas().iter()) - .map(|(rm_i, gamma_i)| gamma_i * rm_i) - .sum::(); + .iter() + .zip(params.gammas().iter()) + .map(|(rm_i, gamma_i)| gamma_i * rm_i) + .sum::(); let zkcm_pedcom = r_pedcom_openings .iter() @@ -201,21 +201,21 @@ impl WithdrawalReqProof { let zkcm_com = instance.com * self.challenge + params.gen1() * self.response_opening + self - .response_attributes - .iter() - .zip(params.gammas().iter()) - .map(|(m_i, gamma_i)| gamma_i * m_i) - .sum::(); + .response_attributes + .iter() + .zip(params.gammas().iter()) + .map(|(m_i, gamma_i)| gamma_i * m_i) + .sum::(); let zkcm_pedcom = izip!( instance.pc_coms.iter(), self.response_openings.iter(), self.response_attributes.iter() ) - .map(|(cm_j, resp_o_j, resp_m_j)| { - cm_j * self.challenge + params.gen1() * resp_o_j + instance.h * resp_m_j - }) - .collect::>(); + .map(|(cm_j, resp_o_j, resp_m_j)| { + cm_j * self.challenge + params.gen1() * resp_o_j + instance.h * resp_m_j + }) + .collect::>(); let zk_commitment_user_sk = instance.pk_user.pk * self.challenge + params.gen1() * self.response_attributes[0]; @@ -279,7 +279,7 @@ mod tests { #[test] fn withdrawal_proof_construct_and_verify() { - let rng = thread_rng(); + let _rng = thread_rng(); let params = GroupParameters::new().unwrap(); let sk = params.random_scalar(); let pk_user = PublicKeyUser { @@ -292,10 +292,10 @@ mod tests { let com_opening = params.random_scalar(); let com = params.gen1() * com_opening + attr - .iter() - .zip(params.gammas()) - .map(|(&m, gamma)| gamma * m) - .sum::(); + .iter() + .zip(params.gammas()) + .map(|(&m, gamma)| gamma * m) + .sum::(); let h = hash_g1(com.to_bytes()); let pc_openings = params.n_random_scalars(attr.len()); diff --git a/common/nym_offline_compact_ecash/src/scheme/aggregation.rs b/common/nym_offline_compact_ecash/src/scheme/aggregation.rs index 30aa282798..aba7d19f01 100644 --- a/common/nym_offline_compact_ecash/src/scheme/aggregation.rs +++ b/common/nym_offline_compact_ecash/src/scheme/aggregation.rs @@ -6,16 +6,16 @@ use bls12_381::{G2Prepared, G2Projective, Scalar}; use group::Curve; use itertools::Itertools; +use crate::Attribute; use crate::error::{CompactEcashError, Result}; +use crate::scheme::{PartialWallet, Wallet}; use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth}; use crate::scheme::setup::GroupParameters; use crate::scheme::withdrawal::RequestInfo; -use crate::scheme::{PartialWallet, Wallet}; use crate::utils::{ - check_bilinear_pairing, perform_lagrangian_interpolation_at_origin, PartialSignature, + check_bilinear_pairing, PartialSignature, perform_lagrangian_interpolation_at_origin, Signature, SignatureShare, SignerIndex, }; -use crate::Attribute; pub(crate) trait Aggregatable: Sized { fn aggregate(aggregatable: &[Self], indices: Option<&[SignerIndex]>) -> Result; @@ -27,10 +27,10 @@ pub(crate) trait Aggregatable: Sized { } impl Aggregatable for T -where - T: Sum, - for<'a> T: Sum<&'a T>, - for<'a> &'a T: Mul, + where + T: Sum, + for<'a> T: Sum<&'a T>, + for<'a> &'a T: Mul, { fn aggregate(aggregatable: &[T], indices: Option<&[u64]>) -> Result { if aggregatable.is_empty() { @@ -156,14 +156,13 @@ pub fn aggregate_wallets( .map(|(idx, wallet)| SignatureShare::new(*wallet.signature(), (idx + 1) as u64)) .collect(); - let attributes = vec![sk_user.sk, req_info.get_v(), req_info.get_t()]; + let attributes = vec![sk_user.sk, req_info.get_v()]; let aggregated_signature = aggregate_signature_shares(¶ms, &verification_key, &attributes, &signature_shares)?; Ok(Wallet { sig: aggregated_signature, v: req_info.get_v(), - t: req_info.get_t(), l: Cell::new(0), }) } diff --git a/common/nym_offline_compact_ecash/src/scheme/identify.rs b/common/nym_offline_compact_ecash/src/scheme/identify.rs index 8d9cd9280e..7b4deaed14 100644 --- a/common/nym_offline_compact_ecash/src/scheme/identify.rs +++ b/common/nym_offline_compact_ecash/src/scheme/identify.rs @@ -1,8 +1,3 @@ -use std::collections::HashSet; - -use bls12_381::G1Projective; -use group::Curve; - use crate::{PayInfo, VerificationKeyAuth}; use crate::error::{CompactEcashError, Result}; use crate::scheme::keygen::PublicKeyUser; @@ -51,9 +46,6 @@ pub fn identify(params: &Parameters, public_keys_u: &[PublicKeyUser], verificati #[cfg(test)] mod tests { - use std::collections::HashSet; - - use group::Curve; use itertools::izip; use crate::{aggregate_verification_keys, aggregate_wallets, generate_keypair_user, issue_verify, issue_wallet, PartialWallet, PayInfo, ttp_keygen, VerificationKeyAuth, withdrawal_request}; @@ -109,7 +101,7 @@ mod tests { let pay_info1 = PayInfo { info: [6u8; 32] }; let spend_vv = 1; - let (payment1, upd_wallet) = aggr_wallet.spend( + let (payment1, _upd_wallet) = aggr_wallet.spend( ¶ms, &verification_key, &user_keypair.secret_key(), @@ -221,7 +213,7 @@ mod tests { // GENERATE KEYS FOR OTHER USERS let mut public_keys: Vec = Default::default(); - for i in 0..50 { + for _i in 0..50 { let sk = grp.random_scalar(); let sk_user = SecretKeyUser { sk }; let pk_user = sk_user.public_key(&grp); @@ -271,7 +263,7 @@ mod tests { let pay_info1 = PayInfo { info: [6u8; 32] }; let spend_vv = 1; - let (payment1, _) = aggr_wallet.spend( + let (payment1, _upd_wallet) = aggr_wallet.spend( ¶ms, &verification_key, &user_keypair.secret_key(), diff --git a/common/nym_offline_compact_ecash/src/scheme/keygen.rs b/common/nym_offline_compact_ecash/src/scheme/keygen.rs index 92f47557f0..13d670fb20 100644 --- a/common/nym_offline_compact_ecash/src/scheme/keygen.rs +++ b/common/nym_offline_compact_ecash/src/scheme/keygen.rs @@ -5,7 +5,7 @@ use std::convert::TryFrom; use std::convert::TryInto; use bls12_381::{G1Projective, G2Projective, Scalar}; -use group::{Curve, GroupEncoding}; +use group::Curve; use crate::error::{CompactEcashError, Result}; use crate::scheme::aggregation::aggregate_verification_keys; diff --git a/common/nym_offline_compact_ecash/src/scheme/mod.rs b/common/nym_offline_compact_ecash/src/scheme/mod.rs index 789bfd7d97..bdda78e4c5 100644 --- a/common/nym_offline_compact_ecash/src/scheme/mod.rs +++ b/common/nym_offline_compact_ecash/src/scheme/mod.rs @@ -1,9 +1,7 @@ use std::cell::Cell; -use std::convert::TryFrom; -use std::convert::TryInto; use bls12_381::{G1Projective, G2Prepared, G2Projective, Scalar}; -use group::{Curve, Group}; +use group::Curve; use crate::Attribute; use crate::error::{CompactEcashError, Result}; @@ -11,7 +9,7 @@ use crate::proofs::proof_spend::{SpendInstance, SpendProof, SpendWitness}; use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth}; use crate::scheme::setup::{GroupParameters, Parameters}; use crate::utils::{ - check_bilinear_pairing, hash_to_scalar, Signature, SignerIndex, try_deserialize_g1_projective, + check_bilinear_pairing, hash_to_scalar, Signature, SignerIndex, }; pub mod aggregation; @@ -41,7 +39,6 @@ impl PartialWallet { pub struct Wallet { sig: Signature, v: Scalar, - t: Scalar, pub l: Cell, } @@ -52,9 +49,6 @@ impl Wallet { pub fn v(&self) -> Scalar { self.v } - pub fn t(&self) -> Scalar { - self.t - } pub fn l(&self) -> u64 { self.l.get() } @@ -63,9 +57,6 @@ impl Wallet { self.l.set(self.l.get() + 1); } - fn down(&self) { - self.l.set(self.l.get() - 1); - } pub fn spend( &self, @@ -86,7 +77,7 @@ impl Wallet { // randomize signature in the wallet let (signature_prime, sign_blinding_factor) = self.signature().randomise(grparams); // construct kappa i.e., blinded attributes for show - let attributes = vec![sk_user.sk, self.v(), self.t()]; + let attributes = vec![sk_user.sk, self.v()]; // compute kappa let kappa = compute_kappa( &grparams, @@ -95,13 +86,11 @@ impl Wallet { sign_blinding_factor, ); - // pick random openings o_c, o_d + // pick random openings o_c let o_c = grparams.random_scalar(); - let o_d = grparams.random_scalar(); - // compute commitments C, D + // compute commitments C let cc = grparams.gen1() * o_c + grparams.gamma1() * self.v(); - let dd = grparams.gen1() * o_d + grparams.gamma1() * self.t(); let mut aa: Vec = Default::default(); @@ -111,8 +100,6 @@ impl Wallet { let mut o_a: Vec = Default::default(); let mut o_mu: Vec = Default::default(); let mut mu: Vec = Default::default(); - let mut o_lambda: Vec = Default::default(); - let mut lambda: Vec = Default::default(); let mut r_k_vec: Vec = Default::default(); let mut kappa_k_vec: Vec = Default::default(); let mut sign_lk_prime_vec: Vec = Default::default(); @@ -131,10 +118,10 @@ impl Wallet { aa.push(aa_k); // evaluate the pseudorandom functions - let ss_k = pseudorandom_fgv(&grparams, self.v(), self.l() + k); + let ss_k = pseudorandom_f_delta_v(&grparams, self.v(), self.l() + k); ss.push(ss_k); let tt_k = - grparams.gen1() * sk_user.sk + pseudorandom_fgt(&grparams, self.t(), self.l() + k) * rr_k; + grparams.gen1() * sk_user.sk + pseudorandom_f_g_v(&grparams, self.v(), self.l() + k) * rr_k; tt.push(tt_k); // compute values mu, o_mu, lambda, o_lambda @@ -146,14 +133,6 @@ impl Wallet { let o_mu_k = ((o_a_k + o_c) * mu_k).neg(); o_mu.push(o_mu_k); - let lambda_k = (self.t() + Scalar::from(self.l() + k) + Scalar::from(1)) - .invert() - .unwrap(); - lambda.push(lambda_k); - - let o_lambda_k = ((o_a_k + o_d) * lambda_k).neg(); - o_lambda.push(o_lambda_k); - // parse the signature associated with value l+k let sign_lk = params.get_sign_by_idx(self.l() + k)?; // randomise the signature associated with value l+k @@ -162,8 +141,8 @@ impl Wallet { r_k_vec.push(r_k); // compute kappa_k let kappa_k = grparams.gen2() * r_k - + params.pkRP().alpha - + params.pkRP().beta * Scalar::from(self.l() + k); + + params.pk_rp().alpha + + params.pk_rp().beta * Scalar::from(self.l() + k); kappa_k_vec.push(kappa_k); } @@ -172,7 +151,6 @@ impl Wallet { let spend_instance = SpendInstance { kappa, cc, - dd, aa: aa.clone(), ss: ss.clone(), tt: tt.clone(), @@ -182,13 +160,10 @@ impl Wallet { attributes, r: sign_blinding_factor, o_c, - o_d, lk, o_a, mu, - lambda, o_mu, - o_lambda, r_k: r_k_vec, }; let zk_proof = SpendProof::construct( @@ -210,7 +185,6 @@ impl Wallet { kappa_k: kappa_k_vec.clone(), sig_lk: sign_lk_prime_vec, cc, - dd, zk_proof, vv: spend_vv, }; @@ -229,13 +203,13 @@ impl Wallet { } } -pub fn pseudorandom_fgv(params: &GroupParameters, v: Scalar, l: u64) -> G1Projective { +pub fn pseudorandom_f_delta_v(params: &GroupParameters, v: Scalar, l: u64) -> G1Projective { let pow = (v + Scalar::from(l) + Scalar::from(1)).invert().unwrap(); - params.gen1() * pow + params.delta() * pow } -pub fn pseudorandom_fgt(params: &GroupParameters, t: Scalar, l: u64) -> G1Projective { - let pow = (t + Scalar::from(l) + Scalar::from(1)).invert().unwrap(); +pub fn pseudorandom_f_g_v(params: &GroupParameters, v: Scalar, l: u64) -> G1Projective { + let pow = (v + Scalar::from(l) + Scalar::from(1)).invert().unwrap(); params.gen1() * pow } @@ -270,7 +244,6 @@ pub struct Payment { pub kappa_k: Vec, pub sig_lk: Vec, pub cc: G1Projective, - pub dd: G1Projective, pub zk_proof: SpendProof, pub vv: u64, } @@ -331,7 +304,6 @@ impl Payment { kappa: self.kappa, aa: self.aa.clone(), cc: self.cc, - dd: self.dd, ss: self.ss.clone(), tt: self.tt.clone(), kappa_k: self.kappa_k.clone(), diff --git a/common/nym_offline_compact_ecash/src/scheme/setup.rs b/common/nym_offline_compact_ecash/src/scheme/setup.rs index 502b4be5f3..d0507129fa 100644 --- a/common/nym_offline_compact_ecash/src/scheme/setup.rs +++ b/common/nym_offline_compact_ecash/src/scheme/setup.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use bls12_381::{G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, Scalar}; use ff::Field; -use group::{Curve, GroupEncoding}; use rand::thread_rng; use crate::error::{CompactEcashError, Result}; @@ -17,6 +16,8 @@ pub struct GroupParameters { g2: G2Affine, /// Additional generators of the G1 group gammas: Vec, + // Additional generator of the G1 group + delta: G1Projective, /// Precomputed G2 generator used for the miller loop _g2_prepared_miller: G2Prepared, } @@ -27,10 +28,13 @@ impl GroupParameters { .map(|i| hash_g1(format!("gamma{}", i))) .collect(); + let delta = hash_g1("delta"); + Ok(GroupParameters { g1: G1Affine::generator(), g2: G2Affine::generator(), gammas, + delta, _g2_prepared_miller: G2Prepared::from(G2Affine::generator()), }) } @@ -55,9 +59,7 @@ impl GroupParameters { self.gammas.get(2) } - pub(crate) fn gamma3(&self) -> Option<&G1Projective> { - self.gammas.get(3) - } + pub(crate) fn delta(&self) -> &G1Projective { &self.delta } pub fn random_scalar(&self) -> Scalar { // lazily-initialized thread-local random number generator, seeded by the system @@ -99,7 +101,7 @@ pub struct Parameters { /// group parameters grp: GroupParameters, /// Public Key for range proof verification - pkRP: PublicKeyRP, + pk_rp: PublicKeyRP, /// Max value of wallet L: u64, /// list of signatures for values l in [0, L] @@ -110,8 +112,8 @@ impl Parameters { pub fn grp(&self) -> &GroupParameters { &self.grp } - pub fn pkRP(&self) -> &PublicKeyRP { - &self.pkRP + pub fn pk_rp(&self) -> &PublicKeyRP { + &self.pk_rp } pub fn L(&self) -> u64 { self.L @@ -137,8 +139,8 @@ pub fn setup(L: u64) -> Parameters { let grp = GroupParameters::new().unwrap(); let x = grp.random_scalar(); let y = grp.random_scalar(); - let skRP = SecretKeyRP { x, y }; - let pkRP = skRP.public_key(&grp); + let sk_rp = SecretKeyRP { x, y }; + let pk_rp = sk_rp.public_key(&grp); let mut signs = HashMap::new(); for l in 0..L { let r = grp.random_scalar(); @@ -153,7 +155,7 @@ pub fn setup(L: u64) -> Parameters { } Parameters { grp, - pkRP, + pk_rp, L, signs, } diff --git a/common/nym_offline_compact_ecash/src/scheme/withdrawal.rs b/common/nym_offline_compact_ecash/src/scheme/withdrawal.rs index ad455984fb..4f8411fb63 100644 --- a/common/nym_offline_compact_ecash/src/scheme/withdrawal.rs +++ b/common/nym_offline_compact_ecash/src/scheme/withdrawal.rs @@ -6,9 +6,8 @@ use crate::proofs::proof_withdrawal::{ WithdrawalReqInstance, WithdrawalReqProof, WithdrawalReqWitness, }; use crate::scheme::keygen::{PublicKeyUser, SecretKeyAuth, SecretKeyUser, VerificationKeyAuth}; -use crate::scheme::keygen::ttp_keygen; use crate::scheme::PartialWallet; -use crate::scheme::setup::{GroupParameters, Parameters}; +use crate::scheme::setup::GroupParameters; use crate::utils::{check_bilinear_pairing, hash_g1}; use crate::utils::{BlindedSignature, Signature}; @@ -24,7 +23,6 @@ pub struct RequestInfo { com_opening: Scalar, pc_coms_openings: Vec, v: Scalar, - t: Scalar, } impl RequestInfo { @@ -40,9 +38,6 @@ impl RequestInfo { pub fn get_v(&self) -> Scalar { self.v } - pub fn get_t(&self) -> Scalar { - self.t - } } pub fn withdrawal_request( @@ -50,9 +45,8 @@ pub fn withdrawal_request( sk_user: &SecretKeyUser, ) -> Result<(WithdrawalRequest, RequestInfo)> { let v = params.random_scalar(); - let t = params.random_scalar(); - let attributes = vec![sk_user.sk, v, t]; + let attributes = vec![sk_user.sk, v]; let gammas = params.gammas(); let com_opening = params.random_scalar(); let com = params.gen1() * com_opening @@ -105,7 +99,6 @@ pub fn withdrawal_request( com_opening, pc_coms_openings: pc_coms_openings.clone(), v, - t, }; Ok((req, req_info)) @@ -176,7 +169,7 @@ pub fn issue_verify( let unblinded_c = c - blinding_removers; - let attr = vec![sk_user.sk, req_info.v, req_info.t]; + let attr = vec![sk_user.sk, req_info.v]; let signed_attributes = attr .iter() @@ -203,7 +196,3 @@ pub fn issue_verify( }) } -#[cfg(test)] -mod tests { - use super::*; -} diff --git a/common/nym_offline_compact_ecash/src/tests/e2e.rs b/common/nym_offline_compact_ecash/src/tests/e2e.rs index 33ae9bc07a..9469e3b5d5 100644 --- a/common/nym_offline_compact_ecash/src/tests/e2e.rs +++ b/common/nym_offline_compact_ecash/src/tests/e2e.rs @@ -1,18 +1,16 @@ use itertools::izip; use crate::error::CompactEcashError; -use crate::scheme::{PartialWallet, Payment, pseudorandom_fgt}; use crate::scheme::aggregation::{ - aggregate_signature_shares, aggregate_verification_keys, aggregate_wallets, + aggregate_verification_keys, aggregate_wallets, }; -use crate::scheme::identify::identify; use crate::scheme::keygen::{ - generate_keypair_user, PublicKeyUser, SecretKeyUser, ttp_keygen, VerificationKeyAuth, + generate_keypair_user, ttp_keygen, VerificationKeyAuth, }; +use crate::scheme::PartialWallet; use crate::scheme::PayInfo; -use crate::scheme::setup::{GroupParameters, Parameters, setup}; +use crate::scheme::setup::setup; use crate::scheme::withdrawal::{issue_verify, issue_wallet, withdrawal_request}; -use crate::utils::{hash_to_scalar, SignatureShare}; #[test] fn main() -> Result<(), CompactEcashError> { @@ -62,7 +60,7 @@ fn main() -> Result<(), CompactEcashError> { let pay_info = PayInfo { info: [6u8; 32] }; let spend_vv = 1; - let (payment, upd_wallet) = aggr_wallet.spend( + let (payment, _) = aggr_wallet.spend( ¶ms, &verification_key, &user_keypair.secret_key(),