Small updates and code cleaning
This commit is contained in:
Generated
+3
-3
@@ -3136,12 +3136,12 @@ dependencies = [
|
||||
name = "nym_compact_ecash"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bls12_381 0.5.0",
|
||||
"bls12_381 0.6.0",
|
||||
"bs58",
|
||||
"criterion",
|
||||
"digest 0.9.0",
|
||||
"ff 0.10.1",
|
||||
"group 0.10.0",
|
||||
"ff 0.11.0",
|
||||
"group 0.11.0",
|
||||
"itertools",
|
||||
"rand 0.8.5",
|
||||
"sha2",
|
||||
|
||||
@@ -7,7 +7,8 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] }
|
||||
#bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] }
|
||||
bls12_381 = { path = "/Users/ania/Documents/Git/andrew_bls12_381", default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] }
|
||||
itertools = "0.10"
|
||||
digest = "0.9"
|
||||
rand = "0.8"
|
||||
@@ -19,11 +20,11 @@ bs58 = "0.4.0"
|
||||
criterion = { version = "0.3", features = ["html_reports"] }
|
||||
|
||||
[dependencies.ff]
|
||||
version = "0.10"
|
||||
version = "0.11"
|
||||
default-features = false
|
||||
|
||||
[dependencies.group]
|
||||
version = "0.10"
|
||||
version = "0.11"
|
||||
default-features = false
|
||||
|
||||
[[bench]]
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
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;
|
||||
@@ -11,6 +16,7 @@ pub enum IdentifyResult {
|
||||
DoubleSpendingPublicKeys(PublicKeyUser),
|
||||
}
|
||||
|
||||
|
||||
pub fn identify(params: &Parameters, public_keys_u: &[PublicKeyUser], verification_key: &VerificationKeyAuth, payment1: Payment, payment2: Payment, pay_info1: PayInfo, pay_info2: PayInfo) -> Result<IdentifyResult> {
|
||||
// verify first the validity of both payments
|
||||
assert!(payment1.spend_verify(¶ms, &verification_key, &pay_info1).unwrap());
|
||||
@@ -45,6 +51,9 @@ 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};
|
||||
@@ -210,6 +219,17 @@ mod tests {
|
||||
let grp = params.grp();
|
||||
let user_keypair = generate_keypair_user(&grp);
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut public_keys: Vec<PublicKeyUser> = Default::default();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
public_keys.push(pk_user.clone());
|
||||
}
|
||||
public_keys.push(user_keypair.public_key().clone());
|
||||
|
||||
|
||||
let (req, req_info) = withdrawal_request(grp, &user_keypair.secret_key()).unwrap();
|
||||
let authorities_keypairs = ttp_keygen(&grp, 2, 3).unwrap();
|
||||
|
||||
@@ -251,7 +271,7 @@ mod tests {
|
||||
let pay_info1 = PayInfo { info: [6u8; 32] };
|
||||
let spend_vv = 1;
|
||||
|
||||
let (payment1, upd_wallet) = aggr_wallet.spend(
|
||||
let (payment1, _) = aggr_wallet.spend(
|
||||
¶ms,
|
||||
&verification_key,
|
||||
&user_keypair.secret_key(),
|
||||
@@ -269,7 +289,6 @@ mod tests {
|
||||
aggr_wallet.l.set(current_l - 1);
|
||||
|
||||
let pay_info2 = PayInfo { info: [7u8; 32] };
|
||||
let spend_vv = 1;
|
||||
|
||||
let (payment2, _) = aggr_wallet.spend(
|
||||
¶ms,
|
||||
@@ -284,17 +303,6 @@ mod tests {
|
||||
.spend_verify(¶ms, &verification_key, &pay_info2)
|
||||
.unwrap());
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut public_keys: Vec<PublicKeyUser> = Default::default();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
public_keys.push(pk_user);
|
||||
}
|
||||
public_keys.push(user_keypair.public_key());
|
||||
|
||||
|
||||
let identify_result = identify(¶ms, &public_keys, &verification_key, payment1, payment2, pay_info1.clone(), pay_info2.clone()).unwrap();
|
||||
assert_eq!(identify_result, IdentifyResult::DoubleSpendingPublicKeys(user_keypair.public_key()));
|
||||
}
|
||||
@@ -306,6 +314,16 @@ mod tests {
|
||||
let grp = params.grp();
|
||||
let user_keypair = generate_keypair_user(&grp);
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut public_keys: Vec<PublicKeyUser> = Default::default();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
public_keys.push(pk_user.clone());
|
||||
}
|
||||
public_keys.push(user_keypair.public_key().clone());
|
||||
|
||||
let (req, req_info) = withdrawal_request(grp, &user_keypair.secret_key()).unwrap();
|
||||
let authorities_keypairs = ttp_keygen(&grp, 2, 3).unwrap();
|
||||
|
||||
@@ -347,7 +365,7 @@ mod tests {
|
||||
let pay_info1 = PayInfo { info: [6u8; 32] };
|
||||
let spend_vv = 10;
|
||||
|
||||
let (payment1, upd_wallet) = aggr_wallet.spend(
|
||||
let (payment1, _) = aggr_wallet.spend(
|
||||
¶ms,
|
||||
&verification_key,
|
||||
&user_keypair.secret_key(),
|
||||
@@ -374,15 +392,6 @@ mod tests {
|
||||
spend_vv,
|
||||
).unwrap();
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut public_keys: Vec<PublicKeyUser> = Default::default();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
public_keys.push(pk_user);
|
||||
}
|
||||
public_keys.push(user_keypair.public_key());
|
||||
|
||||
let identify_result = identify(¶ms, &public_keys, &verification_key, payment1, payment2, pay_info1.clone(), pay_info2.clone()).unwrap();
|
||||
assert_eq!(identify_result, IdentifyResult::DoubleSpendingPublicKeys(user_keypair.public_key()));
|
||||
|
||||
@@ -332,7 +332,7 @@ impl SecretKeyUser {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
pub struct PublicKeyUser {
|
||||
pub(crate) pk: G1Projective,
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ use core::ops::Mul;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Neg;
|
||||
|
||||
use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField};
|
||||
use bls12_381::{
|
||||
multi_miller_loop, G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, Scalar,
|
||||
G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, multi_miller_loop, Scalar,
|
||||
};
|
||||
use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField};
|
||||
use ff::Field;
|
||||
use group::{Curve, Group};
|
||||
|
||||
@@ -36,7 +36,7 @@ impl Polynomial {
|
||||
Scalar::zero()
|
||||
// if x is zero then we can ignore most of the expensive computation and
|
||||
// just return the last term of the polynomial
|
||||
} else if x.is_zero() {
|
||||
} else if x.is_zero().unwrap_u8() == 1 {
|
||||
// we checked that coefficients are not empty so unwrap here is fine
|
||||
*self.coefficients.first().unwrap()
|
||||
} else {
|
||||
@@ -85,9 +85,9 @@ pub(crate) fn perform_lagrangian_interpolation_at_origin<T>(
|
||||
points: &[SignerIndex],
|
||||
values: &[T],
|
||||
) -> Result<T>
|
||||
where
|
||||
T: Sum,
|
||||
for<'a> &'a T: Mul<Scalar, Output = T>,
|
||||
where
|
||||
T: Sum,
|
||||
for<'a> &'a T: Mul<Scalar, Output=T>,
|
||||
{
|
||||
if points.is_empty() || values.is_empty() {
|
||||
return Err(CompactEcashError::Interpolation(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use std::ops::Neg;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -134,14 +135,14 @@ fn bench_divisible_ecash(c: &mut Criterion) {
|
||||
let pk_user = SecretKeyUser::public_key(&sk_user, &grp);
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut pk_all_users: Vec<PublicKeyUser> = Default::default();
|
||||
let mut pk_all_users = HashSet::new();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
pk_all_users.push(pk_user);
|
||||
pk_all_users.insert(pk_user);
|
||||
}
|
||||
pk_all_users.push(pk_user.clone());
|
||||
pk_all_users.insert(pk_user.clone());
|
||||
|
||||
// WITHDRAWAL REQUEST
|
||||
let (withdrawal_req, req_info) = withdrawal_request(¶ms, &sk_user).unwrap();
|
||||
|
||||
@@ -22,7 +22,7 @@ pub enum IdentifyResult {
|
||||
pub fn identify(
|
||||
params: &Parameters,
|
||||
verification_key: &VerificationKeyAuth,
|
||||
public_keys_u: &[PublicKeyUser],
|
||||
public_keys_u: &HashSet<PublicKeyUser>,
|
||||
payment1: Payment,
|
||||
payment2: Payment,
|
||||
pay_info1: PayInfo,
|
||||
@@ -32,56 +32,53 @@ pub fn identify(
|
||||
assert!(payment2.spend_verify(¶ms, &verification_key, &pay_info2).unwrap());
|
||||
|
||||
let params_a = params.get_params_a();
|
||||
|
||||
// compute the serial numbers for k1 in [0, V1-1]
|
||||
let mut serial_numbers = HashMap::new();
|
||||
|
||||
for k1 in 0..payment1.vv {
|
||||
let sn = pairing(&payment1.phi.1.to_affine(), ¶ms_a.get_ith_delta(k1 as usize).to_affine())
|
||||
+ pairing(&payment1.phi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment1.vv as usize, k1 as usize).to_affine());
|
||||
serial_numbers.insert(sn, k1);
|
||||
for k in 0..payment1.vv {
|
||||
let sn = pairing(&payment1.phi.1.to_affine(), ¶ms_a.get_ith_delta(k as usize).to_affine())
|
||||
+ pairing(&payment1.phi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment1.vv as usize, k as usize).to_affine());
|
||||
serial_numbers.insert(sn, k);
|
||||
}
|
||||
|
||||
// compute the serial numbers fo k2 in [0, V2-1]
|
||||
let mut k1 = 0;
|
||||
let mut k2 = 0;
|
||||
let mut duplicate_serial_numbers: Vec<(Gt, u64, u64)> = Default::default();
|
||||
for k2 in 0..payment2.vv {
|
||||
let sn = pairing(&payment2.phi.1.to_affine(), ¶ms_a.get_ith_delta(k2 as usize).to_affine())
|
||||
+ pairing(&payment2.phi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment2.vv as usize, k2 as usize).to_affine());
|
||||
for j in 0..payment2.vv {
|
||||
let sn = pairing(&payment2.phi.1.to_affine(), ¶ms_a.get_ith_delta(j as usize).to_affine())
|
||||
+ pairing(&payment2.phi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment2.vv as usize, j as usize).to_affine());
|
||||
if !serial_numbers.contains_key(&sn) {
|
||||
serial_numbers.insert(sn, k2);
|
||||
serial_numbers.insert(sn, j);
|
||||
} else {
|
||||
let k1 = *serial_numbers.get(&sn).unwrap() as u64;
|
||||
duplicate_serial_numbers.push((sn, k1, k2));
|
||||
k1 = *serial_numbers.get(&sn).unwrap() as u64;
|
||||
k2 = j.clone();
|
||||
break;
|
||||
}
|
||||
return Ok(IdentifyResult::NotADuplicatePayment);
|
||||
}
|
||||
|
||||
if duplicate_serial_numbers.is_empty() {
|
||||
Ok(IdentifyResult::NotADuplicatePayment)
|
||||
if pay_info1 == pay_info2 {
|
||||
Ok(IdentifyResult::DuplicatePayInfo(pay_info1))
|
||||
} else {
|
||||
if pay_info1.info == pay_info2.info {
|
||||
Ok(IdentifyResult::DuplicatePayInfo(pay_info1))
|
||||
} else {
|
||||
for elem in duplicate_serial_numbers.iter() {
|
||||
let k1 = elem.1;
|
||||
let k2 = elem.2;
|
||||
let delta_k1 = params_a.get_ith_delta(k1 as usize);
|
||||
let delta_k2 = params_a.get_ith_delta(k2 as usize);
|
||||
let tt1 = pairing(&payment1.varphi.1.to_affine(), &delta_k1.to_affine())
|
||||
+ pairing(&payment1.varphi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment1.vv as usize, k1 as usize).to_affine());
|
||||
let tt2 = pairing(&payment2.varphi.1.to_affine(), &delta_k2.to_affine())
|
||||
+ pairing(&payment2.varphi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment2.vv as usize, k2 as usize).to_affine());
|
||||
let delta_k1 = params_a.get_ith_delta(k1 as usize);
|
||||
let delta_k2 = params_a.get_ith_delta(k2 as usize);
|
||||
let tt1 = pairing(&payment1.varphi.1.to_affine(), &delta_k1.to_affine())
|
||||
+ pairing(&payment1.varphi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment1.vv as usize, k1 as usize).to_affine());
|
||||
let tt2 = pairing(&payment2.varphi.1.to_affine(), &delta_k2.to_affine())
|
||||
+ pairing(&payment2.varphi.0.to_affine(), ¶ms_a.get_etas_ith_jth_elem(payment2.vv as usize, k2 as usize).to_affine());
|
||||
|
||||
|
||||
for pk_u in public_keys_u.iter() {
|
||||
let pg_pku_deltas = pairing(&pk_u.pk.to_affine(), &(delta_k1 * payment1.rr + delta_k2 * payment2.rr.neg()).to_affine());
|
||||
if tt1 - tt2 == pg_pku_deltas {
|
||||
return Ok(IdentifyResult::DoubleSpendingPublicKeys(pk_u.clone()));
|
||||
}
|
||||
}
|
||||
for pk_u in public_keys_u.iter() {
|
||||
let pg_pku_deltas = pairing(&pk_u.pk.to_affine(), &(delta_k1 * payment1.rr + delta_k2 * payment2.rr.neg()).to_affine());
|
||||
if tt1 - tt2 == pg_pku_deltas {
|
||||
return Ok(IdentifyResult::DoubleSpendingPublicKeys(pk_u.clone()));
|
||||
}
|
||||
return Err(DivisibleEcashError::Identify(
|
||||
"A duplicate serial number was detected, the payinfo1 and payinfo2 are different, but we failed to identify the double-spending public key".to_string(),
|
||||
));
|
||||
}
|
||||
return Err(DivisibleEcashError::Identify(
|
||||
"A duplicate serial number was detected, the payinfo1 and payinfo2 are different, but we failed to identify the double-spending public key".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +157,8 @@ mod tests {
|
||||
|
||||
let pay_info2 = pay_info1.clone();
|
||||
|
||||
let identify_result = identify(¶ms, &verification_key, &[pk_user1, pk_user2], payment1, payment2, pay_info1, pay_info2).unwrap();
|
||||
let public_keys = HashSet::from([pk_user1, pk_user2]);
|
||||
let identify_result = identify(¶ms, &verification_key, &public_keys, payment1, payment2, pay_info1, pay_info2).unwrap();
|
||||
assert_eq!(identify_result, IdentifyResult::DuplicatePayInfo(pay_info1));
|
||||
}
|
||||
|
||||
@@ -189,14 +187,14 @@ mod tests {
|
||||
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut pk_all_users: Vec<PublicKeyUser> = Default::default();
|
||||
let mut pk_all_users = HashSet::new();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
pk_all_users.push(pk_user);
|
||||
pk_all_users.insert(pk_user);
|
||||
}
|
||||
pk_all_users.push(pk_user1.clone());
|
||||
pk_all_users.insert(pk_user1.clone());
|
||||
|
||||
// WITHDRAWAL REQUEST FOR USER1
|
||||
let (withdrawal_req1, req_info1) = withdrawal_request(¶ms, &sk_user1).unwrap();
|
||||
@@ -257,14 +255,14 @@ mod tests {
|
||||
let pk_user1 = SecretKeyUser::public_key(&sk_user1, &grp);
|
||||
|
||||
// GENERATE KEYS FOR OTHER USERS
|
||||
let mut pk_all_users: Vec<PublicKeyUser> = Default::default();
|
||||
let mut public_keys = HashSet::new();
|
||||
for i in 0..50 {
|
||||
let sk = grp.random_scalar();
|
||||
let sk_user = SecretKeyUser { sk };
|
||||
let pk_user = sk_user.public_key(&grp);
|
||||
pk_all_users.push(pk_user);
|
||||
public_keys.insert(pk_user);
|
||||
}
|
||||
pk_all_users.push(pk_user1.clone());
|
||||
public_keys.insert(pk_user1.clone());
|
||||
|
||||
// WITHDRAWAL REQUEST FOR USER1
|
||||
let (withdrawal_req1, req_info1) = withdrawal_request(¶ms, &sk_user1).unwrap();
|
||||
@@ -296,7 +294,7 @@ mod tests {
|
||||
let (payment2, wallet1) = wallet1.spend(¶ms, &verification_key, &sk_user1, &pay_info2, 10, false).unwrap();
|
||||
|
||||
|
||||
let identify_result = identify(¶ms, &verification_key, &pk_all_users, payment1, payment2, pay_info1, pay_info2).unwrap();
|
||||
let identify_result = identify(¶ms, &verification_key, &public_keys, payment1, payment2, pay_info1, pay_info2).unwrap();
|
||||
|
||||
assert_eq!(identify_result, IdentifyResult::DoubleSpendingPublicKeys(pk_user1));
|
||||
}
|
||||
@@ -380,7 +378,8 @@ mod tests {
|
||||
// SPEND VERIFICATION for USER2
|
||||
assert!(payment2.spend_verify(¶ms, &verification_key, &pay_info2).unwrap());
|
||||
|
||||
let identify_result = identify(¶ms, &verification_key, &[pk_user1, pk_user2], payment1, payment2, pay_info1, pay_info2).unwrap();
|
||||
let public_keys = HashSet::from([pk_user1, pk_user2]);
|
||||
let identify_result = identify(¶ms, &verification_key, &public_keys, payment1, payment2, pay_info1, pay_info2).unwrap();
|
||||
assert_eq!(identify_result, IdentifyResult::NotADuplicatePayment);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user