Browse Source

Complete the issue invitation protocol

Ian Goldberg 3 years ago
parent
commit
5d739005e8
3 changed files with 121 additions and 4 deletions
  1. 2 2
      Cargo.toml
  2. 113 2
      src/proto/issue_invite.rs
  3. 6 0
      src/tests.rs

+ 2 - 2
Cargo.toml

@@ -7,8 +7,8 @@ edition = "2018"
 [dependencies]
 curve25519-dalek = { package = "curve25519-dalek-ng", version = "3", default-features = false, features = ["serde", "std"] }
 ed25519-dalek = "1"
-# zkp = { version = "0.8", features = ["debug-transcript"] }
-zkp = "0.8"
+zkp = { version = "0.8", features = ["debug-transcript"] }
+# zkp = "0.8"
 bincode = "1"
 rand = "0.7"
 serde = "1"

+ 113 - 2
src/proto/issue_invite.rs

@@ -282,7 +282,7 @@ pub fn request(
         return Err(ProofError::VerificationFailure);
     }
     // The new invites_remaining
-    let new_invites_remaining = &lox_cred.invites_remaining - Scalar::one();
+    let new_invites_remaining = lox_cred.invites_remaining - Scalar::one();
 
     // Blind showing the Lox credential
 
@@ -662,7 +662,7 @@ impl BridgeAuth {
         // Compute the MAC on the visible attributes
         let b_inv = Scalar::random(&mut rng);
         let P_inv = &b_inv * Btable;
-        let QHc_inv = (self.invitation_priv.x[0] + self.invitation_priv.x[2] * today) * P;
+        let QHc_inv = (self.invitation_priv.x[0] + self.invitation_priv.x[2] * today) * P_inv;
 
         // El Gamal encrypt it to the public key req.D
         let s_inv = Scalar::random(&mut rng);
@@ -791,3 +791,114 @@ impl BridgeAuth {
         })
     }
 }
+
+/// Handle the response to the request, producing the new Lox credential
+/// and Invitation credential if successful.
+pub fn handle_response(
+    state: State,
+    resp: Response,
+    lox_pub: &IssuerPubKey,
+    invitation_pub: &IssuerPubKey,
+) -> Result<(cred::Lox, cred::Invitation), ProofError> {
+    let A: &RistrettoPoint = &CMZ_A;
+    let B: &RistrettoPoint = &CMZ_B;
+    let Btable: &RistrettoBasepointTable = &CMZ_B_TABLE;
+
+    if resp.P.is_identity() || resp.P_inv.is_identity() {
+        return Err(ProofError::VerificationFailure);
+    }
+
+    // Add the server's contribution to the id to our own, both in plain
+    // and encrypted form and for both the Lox credential id and the
+    // Invitation credential id
+    let id = state.id_client + resp.id_server;
+    let EncId = (
+        state.EncIdClient.0,
+        state.EncIdClient.1 + &resp.id_server * Btable,
+    );
+
+    let inv_id = state.inv_id_client + resp.inv_id_server;
+    let EncInvId = (
+        state.EncInvIdClient.0,
+        state.EncInvIdClient.1 + &resp.inv_id_server * Btable,
+    );
+
+    // Verify the proof
+    let mut transcript = Transcript::new(b"issue 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(),
+            Xlevel: &lox_pub.X[3].compress(),
+            Xsince: &lox_pub.X[4].compress(),
+            Xinvremain: &lox_pub.X[5].compress(),
+            Xblockages: &lox_pub.X[6].compress(),
+            TId: &resp.TId.compress(),
+            TBucket: &resp.TBucket.compress(),
+            TLevel: &resp.TLevel.compress(),
+            TSince: &resp.TSince.compress(),
+            TInvRemain: &resp.TInvRemain.compress(),
+            TBlockages: &resp.TBlockages.compress(),
+            P_inv: &resp.P_inv.compress(),
+            EncQ_inv0: &resp.EncQ_inv.0.compress(),
+            EncQ_inv1: &resp.EncQ_inv.1.compress(),
+            X0_inv: &invitation_pub.X[0].compress(),
+            Xid_inv: &invitation_pub.X[1].compress(),
+            Xdate_inv: &invitation_pub.X[2].compress(),
+            Xbucket_inv: &invitation_pub.X[3].compress(),
+            Xblockages_inv: &invitation_pub.X[4].compress(),
+            Pdate_inv: &(resp.date_inv * resp.P_inv).compress(),
+            TId_inv: &resp.TId_inv.compress(),
+            TBucket_inv: &resp.TBucket_inv.compress(),
+            TBlockages_inv: &resp.TBlockages_inv.compress(),
+            D: &state.D.compress(),
+            EncId0: &EncId.0.compress(),
+            EncId1: &EncId.1.compress(),
+            EncBucket0: &state.EncBucket.0.compress(),
+            EncBucket1: &state.EncBucket.1.compress(),
+            EncLevel0: &state.EncLevel.0.compress(),
+            EncLevel1: &state.EncLevel.1.compress(),
+            EncSince0: &state.EncSince.0.compress(),
+            EncSince1: &state.EncSince.1.compress(),
+            EncInvRemain0: &state.EncInvRemain.0.compress(),
+            EncInvRemain1: &state.EncInvRemain.1.compress(),
+            EncBlockages0: &state.EncBlockages.0.compress(),
+            EncBlockages1: &state.EncBlockages.1.compress(),
+            EncInvId0: &EncInvId.0.compress(),
+            EncInvId1: &EncInvId.1.compress(),
+        },
+    )?;
+
+    // Decrypt EncQ and EncQ_inv
+    let Q = resp.EncQ.1 - (state.d * resp.EncQ.0);
+    let Q_inv = resp.EncQ_inv.1 - (state.d * resp.EncQ_inv.0);
+
+    Ok((
+        cred::Lox {
+            P: resp.P,
+            Q,
+            id,
+            bucket: state.bucket,
+            trust_level: state.level,
+            level_since: state.since,
+            invites_remaining: state.invremain,
+            blockages: state.blockages,
+        },
+        cred::Invitation {
+            P: resp.P_inv,
+            Q: Q_inv,
+            inv_id,
+            date: resp.date_inv,
+            bucket: state.bucket,
+            blockages: state.blockages,
+        },
+    ))
+}

+ 6 - 0
src/tests.rs

@@ -232,4 +232,10 @@ fn test_issue_inv() {
     )
     .unwrap();
     let resp = ba.handle_issue_invite(req).unwrap();
+    let (cred3, invite) =
+        issue_invite::handle_response(state, resp, &ba.lox_pub, &ba.invitation_pub).unwrap();
+    assert!(ba.verify_lox(&cred3));
+    assert!(ba.verify_invitation(&invite));
+    println!("cred3 = {:?}", cred3);
+    println!("invite = {:?}", invite);
 }