Fix in the identify function

This commit is contained in:
aniampio
2022-06-30 18:14:59 +01:00
parent 014374e33e
commit 5bdbee6dae
2 changed files with 106 additions and 37 deletions
@@ -35,20 +35,9 @@ pub fn identify(
// compute the serial numbers for k1 in [0, V1-1]
let mut serial_numbers = HashMap::new();
println!("Let's see, where is the difference");
println!("Payment1 Phi1 {:?}", payment1.phi.1);
println!("Payment2 Phi1 {:?}", payment2.phi.1);
println!("Payment1 Phi0 {:?}", payment1.phi.0);
println!("Payment2 Phi0 {:?}", payment2.phi.0);
println!("Payment1 vv {:?}", payment1.vv);
println!("Payment2 vv {:?}", payment2.vv);
for k1 in 0..payment1.vv {
let sn = pairing(&payment1.phi.1.to_affine(), &params_a.get_ith_delta(k1 as usize).to_affine())
+ pairing(&payment1.phi.0.to_affine(), &params_a.get_ith_eta(k1 as usize).to_affine());
+ pairing(&payment1.phi.0.to_affine(), &params_a.get_etas_ith_jth_elem(payment1.vv as usize, k1 as usize).to_affine());
serial_numbers.insert(sn, k1);
}
@@ -56,7 +45,7 @@ pub fn identify(
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(), &params_a.get_ith_delta(k2 as usize).to_affine())
+ pairing(&payment2.phi.0.to_affine(), &params_a.get_ith_eta(k2 as usize).to_affine());
+ pairing(&payment2.phi.0.to_affine(), &params_a.get_etas_ith_jth_elem(payment2.vv as usize, k2 as usize).to_affine());
if !serial_numbers.contains_key(&sn) {
serial_numbers.insert(sn, k2);
} else {
@@ -65,7 +54,6 @@ pub fn identify(
}
}
println!("HOw many duplicates: {:?}", duplicate_serial_numbers.len());
if duplicate_serial_numbers.is_empty() {
Ok(IdentifyResult::NotADuplicatePayment)
} else {
@@ -78,14 +66,14 @@ pub fn identify(
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(), &params_a.get_ith_eta(k1 as usize).to_affine());
+ pairing(&payment1.varphi.0.to_affine(), &params_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(), &params_a.get_ith_eta(k2 as usize).to_affine());
+ pairing(&payment2.varphi.0.to_affine(), &params_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.neg() + delta_k2 * payment2.rr.neg()).to_affine());
if tt1 + tt2 * Scalar::from(1).neg() == pg_pku_deltas {
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()));
}
}
@@ -101,6 +89,8 @@ pub fn identify(
mod tests {
use std::collections::HashSet;
use bls12_381::pairing;
use group::Curve;
use rand::thread_rng;
use crate::scheme::{PayInfo, Payment};
@@ -204,12 +194,12 @@ mod tests {
// GENERATE KEYS FOR OTHER USERS
let mut pk_all_users: 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);
// pk_all_users.push(pk_user);
// }
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.push(pk_user1.clone());
pk_all_users.push(pk_user2.clone());
@@ -235,10 +225,82 @@ mod tests {
let pay_info1 = PayInfo { info: [67u8; 32] };
let (payment1, new_wallet1) = wallet1.spend(&params, &verification_key, &sk_user1, &pay_info1, 10).unwrap();
// let's reverse the spending counter in the wallet to create a double spending payment
let current_l = wallet1.l.get();
wallet1.l.set(current_l - 1);
let pay_info2 = PayInfo { info: [52u8; 32] };
let (payment2, wallet1) = wallet1.spend(&params, &verification_key, &sk_user1, &pay_info2, 10).unwrap();
let identify_result = identify(&params, &verification_key, &pk_all_users, payment1, payment2, pay_info1, pay_info2).unwrap();
assert_eq!(identify_result, IdentifyResult::DoubleSpendingPublicKeys(pk_user1));
}
#[test]
fn two_payments_with_multiple_repeating_serial_number_but_different_pay_info() {
let rng = thread_rng();
let grp = GroupParameters::new().unwrap();
let params = Parameters::new(grp.clone());
let params_u = params.get_params_u();
let params_a = params.get_params_a();
// KEY GENERATION FOR THE AUTHORITIES
let authorities_keypairs = ttp_keygen_authorities(&params, 2, 3).unwrap();
let verification_keys_auth: Vec<VerificationKeyAuth> = authorities_keypairs
.iter()
.map(|keypair| keypair.verification_key())
.collect();
let verification_key =
aggregate_verification_keys(&verification_keys_auth, Some(&[1, 2, 3])).unwrap();
// KEY GENERATION FOR THE USER1
let sk1 = grp.random_scalar();
let sk_user1 = SecretKeyUser { sk: sk1 };
let pk_user1 = SecretKeyUser::public_key(&sk_user1, &grp);
// KEY GENERATION FOR THE USER2
let sk_user2 = sk_user1.clone();
let pk_user2 = pk_user1.clone();
// GENERATE KEYS FOR OTHER USERS
let mut pk_all_users: 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);
pk_all_users.push(pk_user);
}
pk_all_users.push(pk_user1.clone());
pk_all_users.push(pk_user2.clone());
// WITHDRAWAL REQUEST FOR USER1
let (withdrawal_req1, req_info1) = withdrawal_request(&params, &sk_user1).unwrap();
// ISSUE PARTIAL WALLETS for USER1
let mut partial_wallets1 = Vec::new();
for auth_keypair in authorities_keypairs.clone() {
let blind_signature = issue(
&params,
&withdrawal_req1,
pk_user1.clone(),
&auth_keypair.secret_key(),
).unwrap();
let partial_wallet1 = issue_verify(&grp, &auth_keypair.verification_key(), &sk_user1, &blind_signature, &req_info1).unwrap();
partial_wallets1.push(partial_wallet1);
}
// AGGREGATE WALLET FOR USER1
let mut wallet1 = aggregate_wallets(&grp, &verification_key, &sk_user1, &partial_wallets1).unwrap();
let pay_info1 = PayInfo { info: [67u8; 32] };
let (payment1, new_wallet1) = wallet1.spend(&params, &verification_key, &sk_user1, &pay_info1, 10).unwrap();
// let's reverse the spending counter in the wallet to create a double spending payment
// let current_l = wallet1.l.get();
// wallet1.l.set(current_l - 1);
let current_l = wallet1.l.get();
wallet1.l.set(current_l - 7);
let pay_info2 = PayInfo { info: [52u8; 32] };
let (payment2, wallet1) = wallet1.spend(&params, &verification_key, &sk_user1, &pay_info2, 10).unwrap();
@@ -1,7 +1,7 @@
use std::convert::TryFrom;
use std::net::ToSocketAddrs;
use bls12_381::{G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, Scalar};
use bls12_381::{G1Affine, G1Projective, G2Affine, G2Prepared, G2Projective, pairing, Scalar};
use ff::Field;
use group::Curve;
use rand::thread_rng;
@@ -59,6 +59,8 @@ pub struct Parameters {
grp: GroupParameters,
params_u: ParametersUser,
params_a: ParametersAuthority,
tmp_sigma: G1Projective,
pub y: Scalar,
}
impl Parameters {
@@ -77,7 +79,6 @@ impl Parameters {
let gamma1 = hash_g1("gamma1");
let gamma2 = hash_g1("gamma2");
let eta = hash_g1("eta");
let omega = hash_g1("omega");
let z = grp.random_scalar();
let y = grp.random_scalar();
@@ -101,11 +102,13 @@ impl Parameters {
let etas_u: Vec<G1Projective> = vec_a.iter().map(|x| g1 * x).collect();
let mut etas_a: Vec<G2Projective> = Default::default();
let mut etas_a: Vec<Vec<G2Projective>> = Default::default();
for l in 1..=L {
let mut etas_a_l: Vec<G2Projective> = Default::default();
for k in 0..=l - 1 {
etas_a.push(g2 * (vec_a[l as usize - 1].neg() * (y.pow(&[k as u64, 0, 0, 0]))));
etas_a_l.push(g2 * (vec_a[l as usize - 1].neg() * (y.pow(&[k as u64, 0, 0, 0]))));
}
etas_a.push(etas_a_l);
}
let sps_keypair = SPSKeyPair::new(grp.clone(), 2, 0);
@@ -123,7 +126,6 @@ impl Parameters {
psi_g1,
psi_g2,
eta,
omega,
etas: etas_u,
sigmas: sigmas_u,
thetas: thetas_u,
@@ -140,17 +142,22 @@ impl Parameters {
grp,
params_u,
params_a,
tmp_sigma: sigma,
y,
};
}
}
impl Parameters {
pub(crate) fn get_sigma(&self) -> &G1Projective { &self.tmp_sigma }
}
#[derive(Debug, Clone)]
pub struct ParametersUser {
gammas: Vec<G1Projective>,
psi_g1: G1Projective,
psi_g2: G2Projective,
eta: G1Projective,
omega: G1Projective,
etas: Vec<G1Projective>,
sigmas: Vec<G1Projective>,
thetas: Vec<G1Projective>,
@@ -167,8 +174,6 @@ impl ParametersUser {
pub(crate) fn get_eta(&self) -> &G1Projective { &self.eta }
pub(crate) fn get_omega(&self) -> &G1Projective { &self.omega }
pub(crate) fn get_etas(&self) -> &[G1Projective] { &self.etas }
pub(crate) fn get_ith_eta(&self, idx: usize) -> &G1Projective { self.etas.get(idx - 1).unwrap() }
@@ -191,7 +196,7 @@ impl ParametersUser {
#[derive(Debug, Clone)]
pub struct ParametersAuthority {
deltas: Vec<G2Projective>,
etas: Vec<G2Projective>,
etas: Vec<Vec<G2Projective>>,
}
impl ParametersAuthority {
@@ -199,7 +204,9 @@ impl ParametersAuthority {
pub(crate) fn get_ith_delta(&self, idx: usize) -> &G2Projective { self.deltas.get(idx).unwrap() }
pub(crate) fn get_etas(&self) -> &[G2Projective] { &self.etas }
pub(crate) fn get_etas(&self) -> &Vec<Vec<G2Projective>> { &self.etas }
pub(crate) fn get_ith_eta(&self, idx: usize) -> &G2Projective { self.etas.get(idx).unwrap() }
pub(crate) fn get_eta_ith_row(&self, idx: usize) -> &[G2Projective] { self.etas.get(idx).unwrap() }
pub(crate) fn get_etas_ith_jth_elem(&self, row: usize, column: usize) -> &G2Projective { self.etas.get(row - 1).unwrap().get(column).unwrap() }
}