Complete the issue invitation protocol
This commit is contained in:
parent
a6d98dde73
commit
8b517aa4c8
|
@ -7,8 +7,8 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
curve25519-dalek = { package = "curve25519-dalek-ng", version = "3", default-features = false, features = ["serde", "std"] }
|
curve25519-dalek = { package = "curve25519-dalek-ng", version = "3", default-features = false, features = ["serde", "std"] }
|
||||||
ed25519-dalek = "1"
|
ed25519-dalek = "1"
|
||||||
# zkp = { version = "0.8", features = ["debug-transcript"] }
|
zkp = { version = "0.8", features = ["debug-transcript"] }
|
||||||
zkp = "0.8"
|
# zkp = "0.8"
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
|
|
|
@ -282,7 +282,7 @@ pub fn request(
|
||||||
return Err(ProofError::VerificationFailure);
|
return Err(ProofError::VerificationFailure);
|
||||||
}
|
}
|
||||||
// The new invites_remaining
|
// 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
|
// Blind showing the Lox credential
|
||||||
|
|
||||||
|
@ -662,7 +662,7 @@ impl BridgeAuth {
|
||||||
// Compute the MAC on the visible attributes
|
// Compute the MAC on the visible attributes
|
||||||
let b_inv = Scalar::random(&mut rng);
|
let b_inv = Scalar::random(&mut rng);
|
||||||
let P_inv = &b_inv * Btable;
|
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
|
// El Gamal encrypt it to the public key req.D
|
||||||
let s_inv = Scalar::random(&mut rng);
|
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,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
|
@ -232,4 +232,10 @@ fn test_issue_inv() {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let resp = ba.handle_issue_invite(req).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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue