|
@@ -14,12 +14,14 @@ credential. The credential will have attributes:
|
|
|
use curve25519_dalek::ristretto::RistrettoBasepointTable;
|
|
|
use curve25519_dalek::ristretto::RistrettoPoint;
|
|
|
use curve25519_dalek::scalar::Scalar;
|
|
|
+use curve25519_dalek::traits::IsIdentity;
|
|
|
|
|
|
use zkp::CompactProof;
|
|
|
use zkp::ProofError;
|
|
|
use zkp::Transcript;
|
|
|
|
|
|
use super::bridge_table;
|
|
|
+use super::cred;
|
|
|
use super::dup_filter::SeenType;
|
|
|
use super::{BridgeAuth, IssuerPubKey};
|
|
|
use super::{CMZ_A, CMZ_A_TABLE, CMZ_B, CMZ_B_TABLE};
|
|
@@ -74,7 +76,8 @@ define_proof! {
|
|
|
(x0, x0tilde, xid, xbucket, xsince, s, b, tid,
|
|
|
x0_nm, x0tilde_nm, xid_nm, xfrom_nm, xto_nm, s_nm, b_nm, tid_nm),
|
|
|
(P, EncQ0, EncQ1, X0, Xid, Xbucket, Xsince, Pbucket, Psince, TId,
|
|
|
- P_nm, EncQ0_nm, EncQ1_nm, X0_nm, Xid_nm, Xfrom_nm, Xto_nm, TId_nm,
|
|
|
+ P_nm, EncQ0_nm, EncQ1_nm, X0_nm, Xid_nm, Xfrom_nm, Xto_nm,
|
|
|
+ Pbucket_nm, TId_nm,
|
|
|
D, EncId0, EncId1),
|
|
|
(A, B) :
|
|
|
Xid = (xid*A),
|
|
@@ -94,7 +97,7 @@ define_proof! {
|
|
|
TId_nm = (b_nm*Xid_nm),
|
|
|
TId_nm = (tid_nm*A),
|
|
|
EncQ0_nm = (s_nm*B + tid_nm*EncId0),
|
|
|
- EncQ1_nm = (s_nm*D + tid_nm*EncId1 + x0_nm*P_nm + xfrom_nm*Pbucket + xto_nm*Pbucket)
|
|
|
+ EncQ1_nm = (s_nm*D + tid_nm*EncId1 + x0_nm*P_nm + xfrom_nm*Pbucket_nm + xto_nm*Pbucket_nm)
|
|
|
}
|
|
|
|
|
|
/// Submit an open invitation issued by the BridgeDb to receive your
|
|
@@ -231,7 +234,7 @@ impl BridgeAuth {
|
|
|
let QHc_noopmigration = (self.migration_priv.x[0]
|
|
|
+ self.migration_priv.x[2] * bucket
|
|
|
+ self.migration_priv.x[3] * bucket)
|
|
|
- * P;
|
|
|
+ * P_noopmigration;
|
|
|
|
|
|
// El Gamal encrypt it to the public key req.D
|
|
|
let s_noopmigration = Scalar::random(&mut rng);
|
|
@@ -274,6 +277,7 @@ impl BridgeAuth {
|
|
|
Xid_nm: &self.migration_pub.X[1],
|
|
|
Xfrom_nm: &self.migration_pub.X[2],
|
|
|
Xto_nm: &self.migration_pub.X[3],
|
|
|
+ Pbucket_nm: &(bucket * P_noopmigration),
|
|
|
TId_nm: &TId_noopmigration,
|
|
|
D: &req.D,
|
|
|
EncId0: &EncId.0,
|
|
@@ -312,3 +316,80 @@ impl BridgeAuth {
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+/// Handle the reponse to the request, producing the desired Lox
|
|
|
+/// credential if successful.
|
|
|
+pub fn handle_response(
|
|
|
+ state: State,
|
|
|
+ resp: Response,
|
|
|
+ lox_pub: &IssuerPubKey,
|
|
|
+ migration_pub: &IssuerPubKey,
|
|
|
+) -> Result<cred::Lox, ProofError> {
|
|
|
+ let A: &RistrettoPoint = &CMZ_A;
|
|
|
+ let B: &RistrettoPoint = &CMZ_B;
|
|
|
+ let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
|
|
|
+
|
|
|
+ if resp.P.is_identity() || resp.P_noopmigration.is_identity() {
|
|
|
+ return Err(ProofError::VerificationFailure);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add the server's contribution to the id to our own, both in plain
|
|
|
+ // and encrypted form
|
|
|
+ let id = state.id_client + resp.id_server;
|
|
|
+ let EncId = (
|
|
|
+ state.EncIdClient.0,
|
|
|
+ state.EncIdClient.1 + &resp.id_server * Btable,
|
|
|
+ );
|
|
|
+
|
|
|
+ // Verify the proof
|
|
|
+ let mut transcript = Transcript::new(b"open invite issuing");
|
|
|
+ blindissue::verify_compact(
|
|
|
+ &resp.piBlindIssue,
|
|
|
+ &mut transcript,
|
|
|
+ blindissue::VerifyAssignments {
|
|
|
+ A: &A.compress(),
|
|
|
+ B: &B.compress(),
|
|
|
+ P: &resp.P.compress(),
|
|
|
+ EncQ0: &resp.EncQ.0.compress(),
|
|
|
+ EncQ1: &resp.EncQ.1.compress(),
|
|
|
+ X0: &lox_pub.X[0].compress(),
|
|
|
+ Xid: &lox_pub.X[1].compress(),
|
|
|
+ Xbucket: &lox_pub.X[2].compress(),
|
|
|
+ Xsince: &lox_pub.X[4].compress(),
|
|
|
+ Pbucket: &(resp.bucket * resp.P).compress(),
|
|
|
+ Psince: &(resp.level_since * resp.P).compress(),
|
|
|
+ TId: &resp.TId.compress(),
|
|
|
+ P_nm: &resp.P_noopmigration.compress(),
|
|
|
+ EncQ0_nm: &resp.EncQ_noopmigration.0.compress(),
|
|
|
+ EncQ1_nm: &resp.EncQ_noopmigration.1.compress(),
|
|
|
+ X0_nm: &migration_pub.X[0].compress(),
|
|
|
+ Xid_nm: &migration_pub.X[1].compress(),
|
|
|
+ Xfrom_nm: &migration_pub.X[2].compress(),
|
|
|
+ Xto_nm: &migration_pub.X[3].compress(),
|
|
|
+ Pbucket_nm: &(resp.bucket * resp.P_noopmigration).compress(),
|
|
|
+ TId_nm: &resp.TId_noopmigration.compress(),
|
|
|
+ D: &state.D.compress(),
|
|
|
+ EncId0: &EncId.0.compress(),
|
|
|
+ EncId1: &EncId.1.compress(),
|
|
|
+ },
|
|
|
+ )?;
|
|
|
+
|
|
|
+ // Decrypt EncQ
|
|
|
+ let Q = resp.EncQ.1 - (state.d * resp.EncQ.0);
|
|
|
+
|
|
|
+ // Decrypt EncQ_noopmigration
|
|
|
+ let Q_noopmigration = resp.EncQ_noopmigration.1 - (state.d * resp.EncQ_noopmigration.0);
|
|
|
+
|
|
|
+ Ok(cred::Lox {
|
|
|
+ P: resp.P,
|
|
|
+ Q,
|
|
|
+ id,
|
|
|
+ bucket: resp.bucket,
|
|
|
+ trust_level: Scalar::zero(),
|
|
|
+ level_since: resp.level_since,
|
|
|
+ invites_remaining: Scalar::zero(),
|
|
|
+ invites_issued: Scalar::zero(),
|
|
|
+ P_noopmigration: resp.P_noopmigration,
|
|
|
+ Q_noopmigration,
|
|
|
+ })
|
|
|
+}
|