|
@@ -13,8 +13,8 @@
|
|
use sha2::Sha512;
|
|
use sha2::Sha512;
|
|
|
|
|
|
use curve25519_dalek::constants as dalek_constants;
|
|
use curve25519_dalek::constants as dalek_constants;
|
|
-use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
|
|
+use curve25519_dalek::ristretto::RistrettoPoint;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
|
|
|
|
use lazy_static::lazy_static;
|
|
use lazy_static::lazy_static;
|
|
@@ -22,15 +22,13 @@ use lazy_static::lazy_static;
|
|
lazy_static! {
|
|
lazy_static! {
|
|
pub static ref CMZ_A: RistrettoPoint =
|
|
pub static ref CMZ_A: RistrettoPoint =
|
|
RistrettoPoint::hash_from_bytes::<Sha512>(b"CMZ Generator A");
|
|
RistrettoPoint::hash_from_bytes::<Sha512>(b"CMZ Generator A");
|
|
- pub static ref CMZ_B: RistrettoPoint =
|
|
+ pub static ref CMZ_B: RistrettoPoint = dalek_constants::RISTRETTO_BASEPOINT_POINT;
|
|
- dalek_constants::RISTRETTO_BASEPOINT_POINT;
|
|
+ pub static ref CMZ_A_TABLE: RistrettoBasepointTable = RistrettoBasepointTable::create(&CMZ_A);
|
|
- pub static ref CMZ_A_TABLE: RistrettoBasepointTable =
|
|
|
|
- RistrettoBasepointTable::create(&CMZ_A);
|
|
|
|
pub static ref CMZ_B_TABLE: RistrettoBasepointTable =
|
|
pub static ref CMZ_B_TABLE: RistrettoBasepointTable =
|
|
dalek_constants::RISTRETTO_BASEPOINT_TABLE;
|
|
dalek_constants::RISTRETTO_BASEPOINT_TABLE;
|
|
}
|
|
}
|
|
|
|
|
|
-#[derive(Clone,Debug)]
|
|
+#[derive(Clone, Debug)]
|
|
pub struct IssuerPrivKey {
|
|
pub struct IssuerPrivKey {
|
|
x0tilde: Scalar,
|
|
x0tilde: Scalar,
|
|
x: Vec<Scalar>,
|
|
x: Vec<Scalar>,
|
|
@@ -42,16 +40,16 @@ impl IssuerPrivKey {
|
|
pub fn new(n: u16) -> IssuerPrivKey {
|
|
pub fn new(n: u16) -> IssuerPrivKey {
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let x0tilde: Scalar = Scalar::random(&mut rng);
|
|
let x0tilde: Scalar = Scalar::random(&mut rng);
|
|
- let mut x: Vec<Scalar> = Vec::with_capacity((n+1) as usize);
|
|
+ let mut x: Vec<Scalar> = Vec::with_capacity((n + 1) as usize);
|
|
|
|
|
|
// Set x to a vector of n+1 random Scalars
|
|
// Set x to a vector of n+1 random Scalars
|
|
- x.resize_with((n+1) as usize, || { Scalar::random(&mut rng) });
|
|
+ x.resize_with((n + 1) as usize, || Scalar::random(&mut rng));
|
|
|
|
|
|
IssuerPrivKey { x0tilde, x }
|
|
IssuerPrivKey { x0tilde, x }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-#[derive(Clone,Debug)]
|
|
+#[derive(Clone, Debug)]
|
|
pub struct IssuerPubKey {
|
|
pub struct IssuerPubKey {
|
|
X: Vec<RistrettoPoint>,
|
|
X: Vec<RistrettoPoint>,
|
|
}
|
|
}
|
|
@@ -59,8 +57,8 @@ pub struct IssuerPubKey {
|
|
impl IssuerPubKey {
|
|
impl IssuerPubKey {
|
|
// Create an IssuerPubKey from the corresponding IssuerPrivKey
|
|
// Create an IssuerPubKey from the corresponding IssuerPrivKey
|
|
pub fn new(privkey: &IssuerPrivKey) -> IssuerPubKey {
|
|
pub fn new(privkey: &IssuerPrivKey) -> IssuerPubKey {
|
|
- let Atable : &RistrettoBasepointTable = &CMZ_A_TABLE;
|
|
+ let Atable: &RistrettoBasepointTable = &CMZ_A_TABLE;
|
|
- let Btable : &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
+ let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
let n_plus_one: usize = privkey.x.len();
|
|
let n_plus_one: usize = privkey.x.len();
|
|
let mut X: Vec<RistrettoPoint> = Vec::with_capacity(n_plus_one);
|
|
let mut X: Vec<RistrettoPoint> = Vec::with_capacity(n_plus_one);
|
|
|
|
|
|
@@ -113,8 +111,8 @@ pub struct Credential {
|
|
// do a ZKP at all. The more general blinded issuing case is the next
|
|
// do a ZKP at all. The more general blinded issuing case is the next
|
|
// submodule after this one.
|
|
// submodule after this one.
|
|
pub mod issue_nonblind_5 {
|
|
pub mod issue_nonblind_5 {
|
|
- use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
|
|
+ use curve25519_dalek::ristretto::RistrettoPoint;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::traits::IsIdentity;
|
|
use curve25519_dalek::traits::IsIdentity;
|
|
|
|
|
|
@@ -122,7 +120,7 @@ pub mod issue_nonblind_5 {
|
|
use zkp::ProofError;
|
|
use zkp::ProofError;
|
|
use zkp::Transcript;
|
|
use zkp::Transcript;
|
|
|
|
|
|
- use super::{CMZ_A,CMZ_B,CMZ_B_TABLE,Issuer,IssuerPubKey,Credential};
|
|
+ use super::{Credential, Issuer, IssuerPubKey, CMZ_A, CMZ_B, CMZ_B_TABLE};
|
|
|
|
|
|
#[derive(Debug)]
|
|
#[derive(Debug)]
|
|
pub struct CredentialRequest {
|
|
pub struct CredentialRequest {
|
|
@@ -163,9 +161,13 @@ pub mod issue_nonblind_5 {
|
|
Q = (x0*P + x1*P1 + x2*P2 + x3*P3 + x4*P4 + x5*P5)
|
|
Q = (x0*P + x1*P1 + x2*P2 + x3*P3 + x4*P4 + x5*P5)
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn request(m1: &Scalar, m2: &Scalar, m3: &Scalar,
|
|
+ pub fn request(
|
|
- m4: &Scalar, m5: &Scalar) -> (CredentialRequest,
|
|
+ m1: &Scalar,
|
|
- CredentialRequestState) {
|
|
+ m2: &Scalar,
|
|
|
|
+ m3: &Scalar,
|
|
|
|
+ m4: &Scalar,
|
|
|
|
+ m5: &Scalar,
|
|
|
|
+ ) -> (CredentialRequest, CredentialRequestState) {
|
|
// For nonblind requests, just send the attributes in the clear
|
|
// For nonblind requests, just send the attributes in the clear
|
|
(
|
|
(
|
|
CredentialRequest {
|
|
CredentialRequest {
|
|
@@ -173,26 +175,25 @@ pub mod issue_nonblind_5 {
|
|
m2: *m2,
|
|
m2: *m2,
|
|
m3: *m3,
|
|
m3: *m3,
|
|
m4: *m4,
|
|
m4: *m4,
|
|
- m5: *m5
|
|
+ m5: *m5,
|
|
},
|
|
},
|
|
CredentialRequestState {
|
|
CredentialRequestState {
|
|
m1: *m1,
|
|
m1: *m1,
|
|
m2: *m2,
|
|
m2: *m2,
|
|
m3: *m3,
|
|
m3: *m3,
|
|
m4: *m4,
|
|
m4: *m4,
|
|
- m5: *m5
|
|
+ m5: *m5,
|
|
- }
|
|
+ },
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
impl Issuer {
|
|
impl Issuer {
|
|
// Issue a credential with (for example) 5 given attributes. In
|
|
// Issue a credential with (for example) 5 given attributes. In
|
|
// this (nonblinded) version, the issuer sees all of the attributes.
|
|
// this (nonblinded) version, the issuer sees all of the attributes.
|
|
- pub fn issue_nonblind_5(&self, req: CredentialRequest)
|
|
+ pub fn issue_nonblind_5(&self, req: CredentialRequest) -> CredentialResponse {
|
|
- -> CredentialResponse {
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
- let A : &RistrettoPoint = &CMZ_A;
|
|
+ let B: &RistrettoPoint = &CMZ_B;
|
|
- let B : &RistrettoPoint = &CMZ_B;
|
|
+ let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
- let Btable : &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
|
|
|
|
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let b: Scalar = Scalar::random(&mut rng);
|
|
let b: Scalar = Scalar::random(&mut rng);
|
|
@@ -200,12 +201,13 @@ pub mod issue_nonblind_5 {
|
|
// There is a typo in the Hyphae paper: in Section 4.1, Q should
|
|
// There is a typo in the Hyphae paper: in Section 4.1, Q should
|
|
// also have an x0*P term (also in Q'). (You can see that term
|
|
// also have an x0*P term (also in Q'). (You can see that term
|
|
// in Section 4.2.)
|
|
// in Section 4.2.)
|
|
- let Q: RistrettoPoint = (self.privkey.x[0] + (
|
|
+ let Q: RistrettoPoint = (self.privkey.x[0]
|
|
- self.privkey.x[1] * req.m1 +
|
|
+ + (self.privkey.x[1] * req.m1
|
|
- self.privkey.x[2] * req.m2 +
|
|
+ + self.privkey.x[2] * req.m2
|
|
- self.privkey.x[3] * req.m3 +
|
|
+ + self.privkey.x[3] * req.m3
|
|
- self.privkey.x[4] * req.m4 +
|
|
+ + self.privkey.x[4] * req.m4
|
|
- self.privkey.x[5] * req.m5)) * P;
|
|
+ + self.privkey.x[5] * req.m5))
|
|
|
|
+ * P;
|
|
|
|
|
|
let mut transcript = Transcript::new(b"Nonblind 5 issuing proof");
|
|
let mut transcript = Transcript::new(b"Nonblind 5 issuing proof");
|
|
let piNonblindIssue: CompactProof = issue::prove_compact(
|
|
let piNonblindIssue: CompactProof = issue::prove_compact(
|
|
@@ -232,18 +234,26 @@ pub mod issue_nonblind_5 {
|
|
x3: &self.privkey.x[3],
|
|
x3: &self.privkey.x[3],
|
|
x4: &self.privkey.x[4],
|
|
x4: &self.privkey.x[4],
|
|
x5: &self.privkey.x[5],
|
|
x5: &self.privkey.x[5],
|
|
- x0tilde: &self.privkey.x0tilde
|
|
+ x0tilde: &self.privkey.x0tilde,
|
|
- }).0;
|
|
+ },
|
|
-
|
|
+ )
|
|
- CredentialResponse { P, Q, piNonblindIssue }
|
|
+ .0;
|
|
|
|
+
|
|
|
|
+ CredentialResponse {
|
|
|
|
+ P,
|
|
|
|
+ Q,
|
|
|
|
+ piNonblindIssue,
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn verify(state: CredentialRequestState,
|
|
+ pub fn verify(
|
|
- resp: CredentialResponse, pubkey: &IssuerPubKey)
|
|
+ state: CredentialRequestState,
|
|
- -> Result<Credential, ProofError> {
|
|
+ resp: CredentialResponse,
|
|
- let A : &RistrettoPoint = &CMZ_A;
|
|
+ pubkey: &IssuerPubKey,
|
|
- let B : &RistrettoPoint = &CMZ_B;
|
|
+ ) -> Result<Credential, ProofError> {
|
|
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
|
|
+ let B: &RistrettoPoint = &CMZ_B;
|
|
|
|
|
|
if resp.P.is_identity() {
|
|
if resp.P.is_identity() {
|
|
return Err(ProofError::VerificationFailure);
|
|
return Err(ProofError::VerificationFailure);
|
|
@@ -268,13 +278,19 @@ pub mod issue_nonblind_5 {
|
|
P3: &(state.m3 * resp.P).compress(),
|
|
P3: &(state.m3 * resp.P).compress(),
|
|
P4: &(state.m4 * resp.P).compress(),
|
|
P4: &(state.m4 * resp.P).compress(),
|
|
P5: &(state.m5 * resp.P).compress(),
|
|
P5: &(state.m5 * resp.P).compress(),
|
|
- }
|
|
+ },
|
|
)?;
|
|
)?;
|
|
Ok(Credential {
|
|
Ok(Credential {
|
|
P: resp.P,
|
|
P: resp.P,
|
|
Q: resp.Q,
|
|
Q: resp.Q,
|
|
- m: vec![Scalar::zero(), state.m1, state.m2,
|
|
+ m: vec![
|
|
- state.m3, state.m4, state.m5],
|
|
+ Scalar::zero(),
|
|
|
|
+ state.m1,
|
|
|
|
+ state.m2,
|
|
|
|
+ state.m3,
|
|
|
|
+ state.m4,
|
|
|
|
+ state.m5,
|
|
|
|
+ ],
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -290,8 +306,8 @@ pub mod issue_nonblind_5 {
|
|
// generally knows the set of statements one will require at compile,
|
|
// generally knows the set of statements one will require at compile,
|
|
// and not at run, time.
|
|
// and not at run, time.
|
|
pub mod issue_blind124_5 {
|
|
pub mod issue_blind124_5 {
|
|
- use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
|
|
+ use curve25519_dalek::ristretto::RistrettoPoint;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::traits::IsIdentity;
|
|
use curve25519_dalek::traits::IsIdentity;
|
|
|
|
|
|
@@ -299,8 +315,8 @@ pub mod issue_blind124_5 {
|
|
use zkp::ProofError;
|
|
use zkp::ProofError;
|
|
use zkp::Transcript;
|
|
use zkp::Transcript;
|
|
|
|
|
|
- use super::{CMZ_A,CMZ_B,CMZ_A_TABLE,CMZ_B_TABLE};
|
|
+ use super::{Credential, Issuer, IssuerPubKey};
|
|
- use super::{Issuer,IssuerPubKey,Credential};
|
|
+ use super::{CMZ_A, CMZ_A_TABLE, CMZ_B, CMZ_B_TABLE};
|
|
|
|
|
|
// Example of a 5-attribute credential where the issuer sees attributes
|
|
// Example of a 5-attribute credential where the issuer sees attributes
|
|
// 3 and 5, but attributes 1, 2, and 4 are blinded.
|
|
// 3 and 5, but attributes 1, 2, and 4 are blinded.
|
|
@@ -383,11 +399,15 @@ pub mod issue_blind124_5 {
|
|
x0*P + x3*P3 + x5*P5)
|
|
x0*P + x3*P3 + x5*P5)
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn request(m1: &Scalar, m2: &Scalar, m3: &Scalar,
|
|
+ pub fn request(
|
|
- m4: &Scalar, m5: &Scalar) -> (CredentialRequest,
|
|
+ m1: &Scalar,
|
|
- CredentialRequestState) {
|
|
+ m2: &Scalar,
|
|
- let B : &RistrettoPoint = &CMZ_B;
|
|
+ m3: &Scalar,
|
|
- let Btable : &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
+ m4: &Scalar,
|
|
|
|
+ m5: &Scalar,
|
|
|
|
+ ) -> (CredentialRequest, CredentialRequestState) {
|
|
|
|
+ let B: &RistrettoPoint = &CMZ_B;
|
|
|
|
+ let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
|
|
|
|
// Pick an ElGamal keypair
|
|
// Pick an ElGamal keypair
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
@@ -422,33 +442,45 @@ pub mod issue_blind124_5 {
|
|
m1: &m1,
|
|
m1: &m1,
|
|
m2: &m2,
|
|
m2: &m2,
|
|
m4: &m4,
|
|
m4: &m4,
|
|
- }).0;
|
|
+ },
|
|
|
|
+ )
|
|
|
|
+ .0;
|
|
(
|
|
(
|
|
CredentialRequest {
|
|
CredentialRequest {
|
|
- D, Encm1B, Encm2B, Encm4B, piUserBlinding,
|
|
+ D,
|
|
|
|
+ Encm1B,
|
|
|
|
+ Encm2B,
|
|
|
|
+ Encm4B,
|
|
|
|
+ piUserBlinding,
|
|
m3: *m3,
|
|
m3: *m3,
|
|
m5: *m5,
|
|
m5: *m5,
|
|
},
|
|
},
|
|
CredentialRequestState {
|
|
CredentialRequestState {
|
|
- d, D, Encm1B, Encm2B, Encm4B,
|
|
+ d,
|
|
|
|
+ D,
|
|
|
|
+ Encm1B,
|
|
|
|
+ Encm2B,
|
|
|
|
+ Encm4B,
|
|
m1: *m1,
|
|
m1: *m1,
|
|
m2: *m2,
|
|
m2: *m2,
|
|
m3: *m3,
|
|
m3: *m3,
|
|
m4: *m4,
|
|
m4: *m4,
|
|
m5: *m5,
|
|
m5: *m5,
|
|
- }
|
|
+ },
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
impl Issuer {
|
|
impl Issuer {
|
|
// Issue a credential with 5 attributes, of which attributes 1, 2,
|
|
// Issue a credential with 5 attributes, of which attributes 1, 2,
|
|
// and 4 are blinded from the issuer, and 3 and 5 are visible.
|
|
// and 4 are blinded from the issuer, and 3 and 5 are visible.
|
|
- pub fn issue_blind124_5(&self, req: CredentialRequest)
|
|
+ pub fn issue_blind124_5(
|
|
- -> Result<CredentialResponse, ProofError> {
|
|
+ &self,
|
|
- let A : &RistrettoPoint = &CMZ_A;
|
|
+ req: CredentialRequest,
|
|
- let B : &RistrettoPoint = &CMZ_B;
|
|
+ ) -> Result<CredentialResponse, ProofError> {
|
|
- let Atable : &RistrettoBasepointTable = &CMZ_A_TABLE;
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
- let Btable : &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
+ let B: &RistrettoPoint = &CMZ_B;
|
|
|
|
+ let Atable: &RistrettoBasepointTable = &CMZ_A_TABLE;
|
|
|
|
+ let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
|
|
|
|
// First check the proof in the request
|
|
// First check the proof in the request
|
|
let mut transcript = Transcript::new(b"Blind124 5 userblind proof");
|
|
let mut transcript = Transcript::new(b"Blind124 5 userblind proof");
|
|
@@ -464,35 +496,36 @@ pub mod issue_blind124_5 {
|
|
Encm4B0: &req.Encm4B.0.compress(),
|
|
Encm4B0: &req.Encm4B.0.compress(),
|
|
Encm4B1: &req.Encm4B.1.compress(),
|
|
Encm4B1: &req.Encm4B.1.compress(),
|
|
D: &req.D.compress(),
|
|
D: &req.D.compress(),
|
|
- }
|
|
+ },
|
|
)?;
|
|
)?;
|
|
|
|
|
|
// Compute the MAC on the visible attributes
|
|
// Compute the MAC on the visible attributes
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let b: Scalar = Scalar::random(&mut rng);
|
|
let b: Scalar = Scalar::random(&mut rng);
|
|
let P: RistrettoPoint = &b * Btable;
|
|
let P: RistrettoPoint = &b * Btable;
|
|
- let QHc: RistrettoPoint = (self.privkey.x[0] + (
|
|
+ let QHc: RistrettoPoint =
|
|
- self.privkey.x[3] * req.m3 +
|
|
+ (self.privkey.x[0] + (self.privkey.x[3] * req.m3 + self.privkey.x[5] * req.m5)) * P;
|
|
- self.privkey.x[5] * req.m5)) * P;
|
|
|
|
|
|
|
|
// El Gamal encrypt it to the public key req.D
|
|
// El Gamal encrypt it to the public key req.D
|
|
let s: Scalar = Scalar::random(&mut rng);
|
|
let s: Scalar = Scalar::random(&mut rng);
|
|
- let EncQHc = (&s*Btable, QHc + s*req.D);
|
|
+ let EncQHc = (&s * Btable, QHc + s * req.D);
|
|
|
|
|
|
// Homomorphically compute the part of the MAC corresponding to
|
|
// Homomorphically compute the part of the MAC corresponding to
|
|
// the blinded attributes
|
|
// the blinded attributes
|
|
let t1 = self.privkey.x[1] * b;
|
|
let t1 = self.privkey.x[1] * b;
|
|
let T1 = &t1 * Atable;
|
|
let T1 = &t1 * Atable;
|
|
- let EncQ1 = ( t1 * req.Encm1B.0, t1 * req.Encm1B.1 );
|
|
+ let EncQ1 = (t1 * req.Encm1B.0, t1 * req.Encm1B.1);
|
|
let t2 = self.privkey.x[2] * b;
|
|
let t2 = self.privkey.x[2] * b;
|
|
let T2 = &t2 * Atable;
|
|
let T2 = &t2 * Atable;
|
|
- let EncQ2 = ( t2 * req.Encm2B.0, t2 * req.Encm2B.1 );
|
|
+ let EncQ2 = (t2 * req.Encm2B.0, t2 * req.Encm2B.1);
|
|
let t4 = self.privkey.x[4] * b;
|
|
let t4 = self.privkey.x[4] * b;
|
|
let T4 = &t4 * Atable;
|
|
let T4 = &t4 * Atable;
|
|
- let EncQ4 = ( t4 * req.Encm4B.0, t4 * req.Encm4B.1 );
|
|
+ let EncQ4 = (t4 * req.Encm4B.0, t4 * req.Encm4B.1);
|
|
|
|
|
|
- let EncQ = ( EncQHc.0 + EncQ1.0 + EncQ2.0 + EncQ4.0,
|
|
+ let EncQ = (
|
|
- EncQHc.1 + EncQ1.1 + EncQ2.1 + EncQ4.1 );
|
|
+ EncQHc.0 + EncQ1.0 + EncQ2.0 + EncQ4.0,
|
|
|
|
+ EncQHc.1 + EncQ1.1 + EncQ2.1 + EncQ4.1,
|
|
|
|
+ );
|
|
|
|
|
|
let mut transcript = Transcript::new(b"Blind124 5 issuing proof");
|
|
let mut transcript = Transcript::new(b"Blind124 5 issuing proof");
|
|
let piBlindIssue: CompactProof = blindissue::prove_compact(
|
|
let piBlindIssue: CompactProof = blindissue::prove_compact(
|
|
@@ -532,20 +565,29 @@ pub mod issue_blind124_5 {
|
|
b: &b,
|
|
b: &b,
|
|
t1: &t1,
|
|
t1: &t1,
|
|
t2: &t2,
|
|
t2: &t2,
|
|
- t4: &t4
|
|
+ t4: &t4,
|
|
- }).0;
|
|
+ },
|
|
|
|
+ )
|
|
|
|
+ .0;
|
|
|
|
|
|
Ok(CredentialResponse {
|
|
Ok(CredentialResponse {
|
|
- P, EncQ, T1, T2, T4, piBlindIssue
|
|
+ P,
|
|
|
|
+ EncQ,
|
|
|
|
+ T1,
|
|
|
|
+ T2,
|
|
|
|
+ T4,
|
|
|
|
+ piBlindIssue,
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn verify(state: CredentialRequestState,
|
|
+ pub fn verify(
|
|
- resp: CredentialResponse, pubkey: &IssuerPubKey)
|
|
+ state: CredentialRequestState,
|
|
- -> Result<Credential, ProofError> {
|
|
+ resp: CredentialResponse,
|
|
- let A : &RistrettoPoint = &CMZ_A;
|
|
+ pubkey: &IssuerPubKey,
|
|
- let B : &RistrettoPoint = &CMZ_B;
|
|
+ ) -> Result<Credential, ProofError> {
|
|
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
|
|
+ let B: &RistrettoPoint = &CMZ_B;
|
|
|
|
|
|
if resp.P.is_identity() {
|
|
if resp.P.is_identity() {
|
|
return Err(ProofError::VerificationFailure);
|
|
return Err(ProofError::VerificationFailure);
|
|
@@ -579,7 +621,7 @@ pub mod issue_blind124_5 {
|
|
Encm2B1: &state.Encm2B.1.compress(),
|
|
Encm2B1: &state.Encm2B.1.compress(),
|
|
Encm4B0: &state.Encm4B.0.compress(),
|
|
Encm4B0: &state.Encm4B.0.compress(),
|
|
Encm4B1: &state.Encm4B.1.compress(),
|
|
Encm4B1: &state.Encm4B.1.compress(),
|
|
- }
|
|
+ },
|
|
)?;
|
|
)?;
|
|
|
|
|
|
// Decrypt EncQ
|
|
// Decrypt EncQ
|
|
@@ -588,8 +630,14 @@ pub mod issue_blind124_5 {
|
|
Ok(Credential {
|
|
Ok(Credential {
|
|
P: resp.P,
|
|
P: resp.P,
|
|
Q,
|
|
Q,
|
|
- m: vec![Scalar::zero(), state.m1, state.m2,
|
|
+ m: vec![
|
|
- state.m3, state.m4, state.m5],
|
|
+ Scalar::zero(),
|
|
|
|
+ state.m1,
|
|
|
|
+ state.m2,
|
|
|
|
+ state.m3,
|
|
|
|
+ state.m4,
|
|
|
|
+ state.m5,
|
|
|
|
+ ],
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -598,8 +646,8 @@ pub mod issue_blind124_5 {
|
|
// attributes 3, 4, and 5, and displaying attributes 1 and 2. As above,
|
|
// attributes 3, 4, and 5, and displaying attributes 1 and 2. As above,
|
|
// this could possibly be generated by a Rust macro in the future.
|
|
// this could possibly be generated by a Rust macro in the future.
|
|
pub mod show_blind345_5 {
|
|
pub mod show_blind345_5 {
|
|
- use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
|
|
+ use curve25519_dalek::ristretto::RistrettoPoint;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::scalar::Scalar;
|
|
use curve25519_dalek::traits::IsIdentity;
|
|
use curve25519_dalek::traits::IsIdentity;
|
|
|
|
|
|
@@ -607,7 +655,7 @@ pub mod show_blind345_5 {
|
|
use zkp::ProofError;
|
|
use zkp::ProofError;
|
|
use zkp::Transcript;
|
|
use zkp::Transcript;
|
|
|
|
|
|
- use super::{CMZ_A,CMZ_A_TABLE,Issuer,IssuerPubKey,Credential};
|
|
+ use super::{Credential, Issuer, IssuerPubKey, CMZ_A, CMZ_A_TABLE};
|
|
|
|
|
|
// A typo in the Hyphae paper (Section 4.4): P must also be sent to
|
|
// A typo in the Hyphae paper (Section 4.4): P must also be sent to
|
|
// the issuer in the credential presentation message.
|
|
// the issuer in the credential presentation message.
|
|
@@ -632,7 +680,7 @@ pub mod show_blind345_5 {
|
|
}
|
|
}
|
|
|
|
|
|
// If you want to prove additional statements about the blinded
|
|
// If you want to prove additional statements about the blinded
|
|
- // attributes when showing them, this is the place to add those
|
|
+ // attributes when showing them, this is the place to add those
|
|
// statements (and also the code that creates and verifies this
|
|
// statements (and also the code that creates and verifies this
|
|
// proof).
|
|
// proof).
|
|
define_proof! {
|
|
define_proof! {
|
|
@@ -647,10 +695,9 @@ pub mod show_blind345_5 {
|
|
V = (z3*X3 + z4*X4 + z5*X5 + negzQ*A)
|
|
V = (z3*X3 + z4*X4 + z5*X5 + negzQ*A)
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn show(cred: &Credential, pubkey: &IssuerPubKey)
|
|
+ pub fn show(cred: &Credential, pubkey: &IssuerPubKey) -> ShowMessage {
|
|
- -> ShowMessage {
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
- let A : &RistrettoPoint = &CMZ_A;
|
|
+ let Atable: &RistrettoBasepointTable = &CMZ_A_TABLE;
|
|
- let Atable : &RistrettoBasepointTable = &CMZ_A_TABLE;
|
|
|
|
|
|
|
|
// Reblind P and Q
|
|
// Reblind P and Q
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
|
|
@@ -674,9 +721,8 @@ pub mod show_blind345_5 {
|
|
let CQ: RistrettoPoint = Q - &negzQ * Atable;
|
|
let CQ: RistrettoPoint = Q - &negzQ * Atable;
|
|
|
|
|
|
// Compute the "error factor"
|
|
// Compute the "error factor"
|
|
- let V: RistrettoPoint = z3 * pubkey.X[3]
|
|
+ let V: RistrettoPoint =
|
|
- + z4 * pubkey.X[4] + z5 * pubkey.X[5]
|
|
+ z3 * pubkey.X[3] + z4 * pubkey.X[4] + z5 * pubkey.X[5] + &negzQ * Atable;
|
|
- + &negzQ * Atable;
|
|
|
|
|
|
|
|
// Create the ZKP
|
|
// Create the ZKP
|
|
let mut transcript = Transcript::new(b"Blind345 5 showing proof");
|
|
let mut transcript = Transcript::new(b"Blind345 5 showing proof");
|
|
@@ -698,14 +744,20 @@ pub mod show_blind345_5 {
|
|
z3: &z3,
|
|
z3: &z3,
|
|
z4: &z4,
|
|
z4: &z4,
|
|
z5: &z5,
|
|
z5: &z5,
|
|
- negzQ: &negzQ
|
|
+ negzQ: &negzQ,
|
|
- }).0;
|
|
+ },
|
|
|
|
+ )
|
|
|
|
+ .0;
|
|
|
|
|
|
ShowMessage {
|
|
ShowMessage {
|
|
P,
|
|
P,
|
|
m1: cred.m[1],
|
|
m1: cred.m[1],
|
|
m2: cred.m[2],
|
|
m2: cred.m[2],
|
|
- Cm3, Cm4, Cm5, CQ, piCredShow
|
|
+ Cm3,
|
|
|
|
+ Cm4,
|
|
|
|
+ Cm5,
|
|
|
|
+ CQ,
|
|
|
|
+ piCredShow,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -716,9 +768,11 @@ pub mod show_blind345_5 {
|
|
// will end up with verified Pedersen commitments Cm3, Cm4, Cm5
|
|
// will end up with verified Pedersen commitments Cm3, Cm4, Cm5
|
|
// to the blinded attributes, so that additional things can be
|
|
// to the blinded attributes, so that additional things can be
|
|
// proved about those attributes in zero knowledge if desired.
|
|
// proved about those attributes in zero knowledge if desired.
|
|
- pub fn verify_blind345_5(&self, showmsg: ShowMessage)
|
|
+ pub fn verify_blind345_5(
|
|
- -> Result<VerifiedCredential, ProofError> {
|
|
+ &self,
|
|
- let A : &RistrettoPoint = &CMZ_A;
|
|
+ showmsg: ShowMessage,
|
|
|
|
+ ) -> Result<VerifiedCredential, ProofError> {
|
|
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
|
|
|
|
if showmsg.P.is_identity() {
|
|
if showmsg.P.is_identity() {
|
|
return Err(ProofError::VerificationFailure);
|
|
return Err(ProofError::VerificationFailure);
|
|
@@ -727,10 +781,9 @@ pub mod show_blind345_5 {
|
|
// Recompute the "error factor" using knowledge of our own
|
|
// Recompute the "error factor" using knowledge of our own
|
|
// (the issuer's) private key instead of knowledge of the
|
|
// (the issuer's) private key instead of knowledge of the
|
|
// hidden attributes
|
|
// hidden attributes
|
|
- let Vprime: RistrettoPoint =
|
|
+ let Vprime: RistrettoPoint = (self.privkey.x[0]
|
|
- (self.privkey.x[0]
|
|
+ + (self.privkey.x[1] * showmsg.m1 + self.privkey.x[2] * showmsg.m2))
|
|
- + (self.privkey.x[1] * showmsg.m1
|
|
+ * showmsg.P
|
|
- + self.privkey.x[2] * showmsg.m2)) * showmsg.P
|
|
|
|
+ self.privkey.x[3] * showmsg.Cm3
|
|
+ self.privkey.x[3] * showmsg.Cm3
|
|
+ self.privkey.x[4] * showmsg.Cm4
|
|
+ self.privkey.x[4] * showmsg.Cm4
|
|
+ self.privkey.x[5] * showmsg.Cm5
|
|
+ self.privkey.x[5] * showmsg.Cm5
|
|
@@ -751,7 +804,7 @@ pub mod show_blind345_5 {
|
|
X3: &self.pubkey.X[3].compress(),
|
|
X3: &self.pubkey.X[3].compress(),
|
|
X4: &self.pubkey.X[4].compress(),
|
|
X4: &self.pubkey.X[4].compress(),
|
|
X5: &self.pubkey.X[5].compress(),
|
|
X5: &self.pubkey.X[5].compress(),
|
|
- }
|
|
+ },
|
|
)?;
|
|
)?;
|
|
Ok(VerifiedCredential {
|
|
Ok(VerifiedCredential {
|
|
m1: showmsg.m1,
|
|
m1: showmsg.m1,
|