Define spend instance and witness structs
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use bls12_381::{G1Projective, G2Projective, Scalar};
|
||||
use bls12_381::{G1Projective, G2Projective, Gt, Scalar};
|
||||
|
||||
use crate::scheme::{Phi, VarPhi};
|
||||
use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth};
|
||||
@@ -7,25 +7,59 @@ use crate::scheme::setup::Parameters;
|
||||
pub struct SpendInstance {
|
||||
pub kappa: G2Projective,
|
||||
pub phi: Phi,
|
||||
pub var_phi: VarPhi,
|
||||
pub varphi: VarPhi,
|
||||
pub rr: G1Projective,
|
||||
pub ss: G1Projective,
|
||||
pub tt: G1Projective,
|
||||
pub tt: G2Projective,
|
||||
pub pg_varsigpr1_delta: Gt,
|
||||
pub pg_psi0_delta: Gt,
|
||||
pub pg_varsigpr2_gen2: Gt,
|
||||
pub pg_psi0_gen2: Gt,
|
||||
pub pg_thetapr1_delta: Gt,
|
||||
pub pg_thetapr2_gen2: Gt,
|
||||
pub pg_rr_yy: Gt,
|
||||
pub pg_psi0_yy: Gt,
|
||||
pub pg_ssprime_gen2: Gt,
|
||||
pub pg_varsigpr2_ww1: Gt,
|
||||
pub pg_psi0_ww1: Gt,
|
||||
pub pg_thetapr2_ww2: Gt,
|
||||
pub pg_psi0_ww2: Gt,
|
||||
pub pg_gen1_zz: Gt,
|
||||
pub pg_rr_tt: Gt,
|
||||
pub pg_rr_psi1: Gt,
|
||||
pub pg_psi0_tt: Gt,
|
||||
pub pg_psi0_psi1: Gt,
|
||||
pub pg_gen1_gen2: Gt,
|
||||
}
|
||||
|
||||
pub struct SpendWitness {
|
||||
sk_u: SecretKeyUser,
|
||||
v: Scalar,
|
||||
r: Scalar,
|
||||
r1: Scalar,
|
||||
r2: Scalar,
|
||||
pub sk_u: SecretKeyUser,
|
||||
pub v: Scalar,
|
||||
pub r: Scalar,
|
||||
pub r1: Scalar,
|
||||
pub r2: Scalar,
|
||||
pub r_varsig1: Scalar,
|
||||
pub r_theta1: Scalar,
|
||||
pub r_varsig2: Scalar,
|
||||
pub r_theta2: Scalar,
|
||||
pub r_rr: Scalar,
|
||||
pub r_ss: Scalar,
|
||||
pub r_tt: Scalar,
|
||||
pub rho1: Scalar,
|
||||
pub rho2: Scalar,
|
||||
pub rho3: Scalar,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SpendProof {}
|
||||
|
||||
impl SpendProof {
|
||||
pub fn construct() {}
|
||||
pub fn construct(
|
||||
params: &Parameters,
|
||||
instance: &SpendInstance,
|
||||
witness: &SpendWitness) -> Self {
|
||||
SpendProof {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use std::cell::Cell;
|
||||
|
||||
use bls12_381::{G1Projective, G2Prepared, G2Projective, Scalar};
|
||||
use bls12_381::{G1Projective, G2Prepared, G2Projective, pairing, Scalar};
|
||||
use group::Curve;
|
||||
|
||||
use crate::Attribute;
|
||||
use crate::constants::L;
|
||||
use crate::error::{DivisibleEcashError, Result};
|
||||
use crate::proofs::proof_spend::SpendProof;
|
||||
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};
|
||||
@@ -33,10 +33,10 @@ pub fn compute_kappa(
|
||||
.sum::<G2Projective>()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Phi(pub(crate) G1Projective, pub(crate) G1Projective);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct VarPhi(pub(crate) G1Projective, pub(crate) G1Projective);
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ impl Wallet {
|
||||
|
||||
let grp = params.get_grp();
|
||||
let params_u = params.get_params_u();
|
||||
let params_a = params.get_params_a();
|
||||
// randomize signature in the wallet
|
||||
let (signature_prime, sign_blinding_factor) = self.signature().randomise(grp);
|
||||
// construct kappa i.e., blinded attributes for show
|
||||
@@ -123,8 +124,102 @@ impl Wallet {
|
||||
// compute hash of the payment info
|
||||
let rr = hash_to_scalar(pay_info.info);
|
||||
let varphi = VarPhi(grp.gen1() * r2, (grp.gen1() * rr) * sk_user.sk + params_u.get_ith_theta(self.l.get() as usize) * self.v + params_u.get_ith_eta(vv as usize) * r2);
|
||||
|
||||
// random value used to compute blinded bases
|
||||
let r_varsig1 = grp.random_scalar();
|
||||
let r_theta1 = grp.random_scalar();
|
||||
let r_varsig2 = grp.random_scalar();
|
||||
let r_theta2 = grp.random_scalar();
|
||||
let r_rr = grp.random_scalar();
|
||||
let r_ss = grp.random_scalar();
|
||||
let r_tt = grp.random_scalar();
|
||||
|
||||
// compute blinded bases
|
||||
let psi0 = params_u.get_psi0();
|
||||
let psi1 = params_u.get_psi1();
|
||||
let varsig_prime1 = params_u.get_ith_sigma(self.l() as usize) + (psi0 * r_varsig1);
|
||||
let theta_prime1 = params_u.get_ith_theta(self.l() as usize) + (psi0 * r_theta1);
|
||||
let varsig_prime2 = params_u.get_ith_sigma(self.l() as usize + vv as usize - 1) + (psi0 * r_varsig2);
|
||||
let theta_prime2 = params_u.get_ith_sigma(self.l() as usize + vv as usize - 1) + (psi0 * r_theta2);
|
||||
let rr_prime = params_u.get_ith_sps_sign(self.l() as usize + vv as usize - 1).rr + (psi0 * r_rr);
|
||||
let ss_prime = params_u.get_ith_sps_sign(self.l() as usize + vv as usize - 1).ss + (psi0 * r_ss);
|
||||
let tt_prime = params_u.get_ith_sps_sign(self.l() as usize + vv as usize - 1).tt + (psi1 * r_tt);
|
||||
|
||||
let rho1 = self.v.neg() * r_varsig1;
|
||||
let rho2 = self.v.neg() * r_theta1;
|
||||
let rho3 = r_rr * r_tt;
|
||||
|
||||
let pg_varsigpr1_delta = pairing(&varsig_prime1.to_affine(), ¶ms_a.get_ith_delta((vv - 1) as usize).to_affine());
|
||||
let pg_psi0_delta = pairing(&psi0.to_affine(), ¶ms_a.get_ith_delta((vv - 1) as usize).to_affine());
|
||||
let pg_varsigpr2_gen2 = pairing(&varsig_prime2.to_affine(), grp.gen2());
|
||||
let pg_psi0_gen2 = pairing(&psi0.to_affine(), grp.gen2());
|
||||
let pg_thetapr1_delta = pairing(&theta_prime1.to_affine(), ¶ms_a.get_ith_delta((vv - 1) as usize).to_affine());
|
||||
let pg_thetapr2_gen2 = pairing(&theta_prime1.to_affine(), grp.gen2());
|
||||
let yy = params_u.get_sps_pk().get_yy();
|
||||
let pg_rr_yy = pairing(&rr_prime.to_affine(), &yy.to_affine());
|
||||
let pg_psi0_yy = pairing(&psi0.to_affine(), &yy.to_affine());
|
||||
let pg_ssprime_gen2 = pairing(&ss_prime.to_affine(), grp.gen2());
|
||||
let ww1 = params_u.get_sps_pk().get_ith_ww(0);
|
||||
let ww2 = params_u.get_sps_pk().get_ith_ww(1);
|
||||
let pg_varsigpr2_ww1 = pairing(&varsig_prime2.to_affine(), &ww1.to_affine());
|
||||
let pg_psi0_ww1 = pairing(&psi0.to_affine(), &ww1.to_affine());
|
||||
let pg_thetapr2_ww2 = pairing(&theta_prime1.to_affine(), &ww2.to_affine());
|
||||
let pg_psi0_ww2 = pairing(&psi0.to_affine(), &ww2.to_affine());
|
||||
let pg_gen1_zz = pairing(grp.gen1(), ¶ms_u.get_sps_pk().get_zz().to_affine());
|
||||
let pg_rr_tt = pairing(&rr_prime.to_affine(), &tt_prime.to_affine());
|
||||
let pg_rr_psi1 = pairing(&rr_prime.to_affine(), &psi1.to_affine());
|
||||
let pg_psi0_tt = pairing(&psi0.to_affine(), &tt_prime.to_affine());
|
||||
let pg_psi0_psi1 = pairing(&psi0.to_affine(), &psi1.to_affine());
|
||||
let pg_gen1_gen2 = pairing(grp.gen1(), grp.gen2());
|
||||
|
||||
let instance = SpendInstance {
|
||||
kappa,
|
||||
phi,
|
||||
varphi,
|
||||
rr: rr_prime,
|
||||
ss: ss_prime,
|
||||
tt: tt_prime,
|
||||
pg_varsigpr1_delta,
|
||||
pg_psi0_delta,
|
||||
pg_varsigpr2_gen2,
|
||||
pg_psi0_gen2,
|
||||
pg_thetapr1_delta,
|
||||
pg_thetapr2_gen2,
|
||||
pg_rr_yy,
|
||||
pg_psi0_yy,
|
||||
pg_ssprime_gen2,
|
||||
pg_varsigpr2_ww1,
|
||||
pg_psi0_ww1,
|
||||
pg_thetapr2_ww2,
|
||||
pg_psi0_ww2,
|
||||
pg_gen1_zz,
|
||||
pg_rr_tt,
|
||||
pg_rr_psi1,
|
||||
pg_psi0_tt,
|
||||
pg_psi0_psi1,
|
||||
pg_gen1_gen2,
|
||||
};
|
||||
|
||||
let witness = SpendWitness {
|
||||
sk_u: sk_user.clone(),
|
||||
v: self.v,
|
||||
r: sign_blinding_factor,
|
||||
r1,
|
||||
r2,
|
||||
r_varsig1,
|
||||
r_theta1,
|
||||
r_varsig2,
|
||||
r_theta2,
|
||||
r_rr,
|
||||
r_ss,
|
||||
r_tt,
|
||||
rho1,
|
||||
rho2,
|
||||
rho3,
|
||||
};
|
||||
|
||||
// compute the zk proof
|
||||
let zkproof = SpendProof {};
|
||||
let zkproof = SpendProof::construct(params, &instance, &witness);
|
||||
|
||||
// output pay and updated wallet
|
||||
let pay = Payment {
|
||||
|
||||
@@ -5,7 +5,7 @@ use rand::thread_rng;
|
||||
use crate::constants::L;
|
||||
use crate::error::Result;
|
||||
use crate::scheme::structure_preserving_signature::{SPSKeyPair, SPSSignature, SPSVerificationKey};
|
||||
use crate::utils::hash_g1;
|
||||
use crate::utils::{hash_g1, hash_g2};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GroupParameters {
|
||||
@@ -67,7 +67,7 @@ impl Parameters {
|
||||
let g1 = grp.gen1();
|
||||
let g2 = grp.gen2();
|
||||
let psi1 = hash_g1("psi1");
|
||||
let psi2 = hash_g1("psi2");
|
||||
let psi2 = hash_g2("psi2");
|
||||
let gamma1 = hash_g1("gamma1");
|
||||
let gamma2 = hash_g1("gamma2");
|
||||
let eta = hash_g1("eta");
|
||||
@@ -115,7 +115,8 @@ impl Parameters {
|
||||
// Compute signature for each pair sigma, theta
|
||||
let params_u = ParametersUser {
|
||||
gammas: vec![gamma1, gamma2],
|
||||
psi: vec![psi1, psi2],
|
||||
psi1,
|
||||
psi2,
|
||||
eta,
|
||||
omega,
|
||||
etas: etas_u,
|
||||
@@ -141,7 +142,8 @@ impl Parameters {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParametersUser {
|
||||
gammas: Vec<G1Projective>,
|
||||
psi: Vec<G1Projective>,
|
||||
psi1: G1Projective,
|
||||
psi2: G2Projective,
|
||||
eta: G1Projective,
|
||||
omega: G1Projective,
|
||||
etas: Vec<G1Projective>,
|
||||
@@ -154,7 +156,9 @@ pub struct ParametersUser {
|
||||
impl ParametersUser {
|
||||
pub(crate) fn get_gammas(&self) -> &Vec<G1Projective> { &self.gammas }
|
||||
|
||||
pub(crate) fn get_psi(&self) -> &Vec<G1Projective> { &self.psi }
|
||||
pub(crate) fn get_psi0(&self) -> &G1Projective { &self.psi1 }
|
||||
|
||||
pub(crate) fn get_psi1(&self) -> &G2Projective { &self.psi2 }
|
||||
|
||||
pub(crate) fn get_eta(&self) -> &G1Projective { &self.eta }
|
||||
|
||||
@@ -188,5 +192,9 @@ pub struct ParametersAuthority {
|
||||
impl ParametersAuthority {
|
||||
pub(crate) fn get_deltas(&self) -> &[G2Projective] { &self.deltas }
|
||||
|
||||
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_ith_eta(&self, idx: usize) -> &G2Projective { self.etas.get(idx).unwrap() }
|
||||
}
|
||||
|
||||
@@ -72,6 +72,12 @@ impl SPSVerificationKey {
|
||||
pub fn verify() -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn get_ith_ww(&self, idx: usize) -> &G2Projective { return self.wws.get(idx).unwrap(); }
|
||||
|
||||
pub fn get_zz(&self) -> &G2Projective { return &self.zz; }
|
||||
|
||||
pub fn get_yy(&self) -> &G2Projective { return &self.yy; }
|
||||
}
|
||||
|
||||
pub struct SPSKeyPair {
|
||||
@@ -110,7 +116,7 @@ impl SPSKeyPair {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SPSSignature {
|
||||
rr: G1Projective,
|
||||
ss: G1Projective,
|
||||
tt: G2Projective,
|
||||
pub rr: G1Projective,
|
||||
pub ss: G1Projective,
|
||||
pub tt: G2Projective,
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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(DivisibleEcashError::Interpolation(
|
||||
@@ -123,6 +123,9 @@ where
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-J.9.1
|
||||
const G1_HASH_DOMAIN: &[u8] = b"QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_";
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-J.10.1
|
||||
const G2_HASH_DOMAIN: &[u8] = b"QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_";
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-K.1
|
||||
const SCALAR_HASH_DOMAIN: &[u8] = b"QUUX-V01-CS02-with-expander";
|
||||
|
||||
@@ -130,6 +133,10 @@ pub fn hash_g1<M: AsRef<[u8]>>(msg: M) -> G1Projective {
|
||||
<G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(msg, G1_HASH_DOMAIN)
|
||||
}
|
||||
|
||||
pub fn hash_g2<M: AsRef<[u8]>>(msg: M) -> G2Projective {
|
||||
<G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(msg, G2_HASH_DOMAIN)
|
||||
}
|
||||
|
||||
pub fn hash_to_scalar<M: AsRef<[u8]>>(msg: M) -> Scalar {
|
||||
let mut output = vec![Scalar::zero()];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user