Check the proof in the request message of the trust promotion protocol
This commit is contained in:
parent
53652914eb
commit
2ffa2c6ab0
|
@ -7,7 +7,7 @@ edition = "2018"
|
|||
[dependencies]
|
||||
curve25519-dalek = { package = "curve25519-dalek-ng", version = "3", default-features = false, features = ["serde", "std"] }
|
||||
ed25519-dalek = "1"
|
||||
zkp = "0.8"
|
||||
zkp = { version = "0.8", features = ["debug-transcript"] }
|
||||
bincode = "1"
|
||||
rand = "0.7"
|
||||
serde = "1"
|
||||
|
|
|
@ -234,11 +234,13 @@ impl BridgeAuth {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// For testing only: manually advance the day by 1 day
|
||||
pub fn advance_day(&mut self) {
|
||||
self.time_offset += time::Duration::days(1);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// For testing only: manually advance the day by the given number
|
||||
/// of days
|
||||
pub fn advance_days(&mut self, days: u16) {
|
||||
|
@ -253,6 +255,20 @@ impl BridgeAuth {
|
|||
.try_into()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Verify the MAC on a Lox credential
|
||||
pub fn verify_lox(&self, cred: &cred::Lox) -> bool {
|
||||
let Q = (self.lox_priv.x[0]
|
||||
+ cred.id * self.lox_priv.x[1]
|
||||
+ cred.bucket * self.lox_priv.x[2]
|
||||
+ cred.trust_level * self.lox_priv.x[3]
|
||||
+ cred.level_since * self.lox_priv.x[4]
|
||||
+ cred.invites_remaining * self.lox_priv.x[5]
|
||||
+ cred.invites_issued * self.lox_priv.x[6])
|
||||
* cred.P;
|
||||
return Q == cred.Q;
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to extract a u64 from a Scalar
|
||||
|
@ -270,6 +286,11 @@ pub fn scalar_dbl(s: &Scalar) -> Scalar {
|
|||
s + s
|
||||
}
|
||||
|
||||
/// Double a RistrettoPoint
|
||||
pub fn pt_dbl(P: &RistrettoPoint) -> RistrettoPoint {
|
||||
P + P
|
||||
}
|
||||
|
||||
// The protocol modules
|
||||
pub mod open_invite;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ fn test_open_invite() {
|
|||
let bucket = ba.bridge_table.decrypt_bucket_id(id, &key).unwrap();
|
||||
println!("cred = {:?}", cred);
|
||||
println!("bucket = {:?}", bucket);
|
||||
assert!(ba.verify_lox(&cred));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -82,9 +83,11 @@ fn test_trust_promotion() {
|
|||
let (req, state) = open_invite::request(&inv);
|
||||
let resp = ba.handle_open_invite(req).unwrap();
|
||||
let cred = open_invite::handle_response(state, resp, &ba.lox_pub, &ba.migration_pub).unwrap();
|
||||
assert!(ba.verify_lox(&cred));
|
||||
|
||||
// Time passes
|
||||
ba.advance_days(40);
|
||||
ba.advance_days(47);
|
||||
|
||||
let (promreq, promstate) = trust_promotion::request(&cred, &ba.lox_pub, ba.today()).unwrap();
|
||||
let resp = ba.handle_trust_promotion(promreq).unwrap();
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ use zkp::ProofError;
|
|||
use zkp::Transcript;
|
||||
|
||||
use super::cred;
|
||||
use super::IssuerPubKey;
|
||||
use super::{scalar_dbl, scalar_u64};
|
||||
use super::{pt_dbl, scalar_dbl, scalar_u64};
|
||||
use super::{BridgeAuth, IssuerPubKey};
|
||||
use super::{CMZ_A, CMZ_A_TABLE, CMZ_B, CMZ_B_TABLE};
|
||||
|
||||
/// The minimum number of days a user has to be at trust level 0
|
||||
|
@ -74,6 +74,15 @@ pub struct Request {
|
|||
CG6: RistrettoPoint,
|
||||
CG7: RistrettoPoint,
|
||||
CG8: RistrettoPoint,
|
||||
CG0sq: RistrettoPoint,
|
||||
CG1sq: RistrettoPoint,
|
||||
CG2sq: RistrettoPoint,
|
||||
CG3sq: RistrettoPoint,
|
||||
CG4sq: RistrettoPoint,
|
||||
CG5sq: RistrettoPoint,
|
||||
CG6sq: RistrettoPoint,
|
||||
CG7sq: RistrettoPoint,
|
||||
CG8sq: RistrettoPoint,
|
||||
|
||||
// The combined ZKP
|
||||
piUser: CompactProof,
|
||||
|
@ -223,7 +232,7 @@ pub fn request(
|
|||
// Compute zg0 to cancel things out as
|
||||
// zg0 = -(zsince + 2*zg1 + 4*zg2 + 8*zg3 + 16*zg4 + 32*zg5 + 64*zg6 + 128*zg7 + 256*zg8)
|
||||
// but use Horner's method
|
||||
let zg0 = -scalar_dbl(
|
||||
let zg0 = -(scalar_dbl(
|
||||
&(scalar_dbl(
|
||||
&(scalar_dbl(
|
||||
&(scalar_dbl(
|
||||
|
@ -233,7 +242,7 @@ pub fn request(
|
|||
) + zg3),
|
||||
) + zg2),
|
||||
) + zg1),
|
||||
) + zsince;
|
||||
) + zsince);
|
||||
|
||||
let yg0 = wg0 + g0 * zg0;
|
||||
let yg1 = wg1 + g1 * zg1;
|
||||
|
@ -255,6 +264,16 @@ pub fn request(
|
|||
let CG7 = g7 * P + &zg7 * Atable;
|
||||
let CG8 = g8 * P + &zg8 * Atable;
|
||||
|
||||
let CG0sq = g0 * P + &yg0 * Atable;
|
||||
let CG1sq = g1 * P + &yg1 * Atable;
|
||||
let CG2sq = g2 * P + &yg2 * Atable;
|
||||
let CG3sq = g3 * P + &yg3 * Atable;
|
||||
let CG4sq = g4 * P + &yg4 * Atable;
|
||||
let CG5sq = g5 * P + &yg5 * Atable;
|
||||
let CG6sq = g6 * P + &yg6 * Atable;
|
||||
let CG7sq = g7 * P + &yg7 * Atable;
|
||||
let CG8sq = g8 * P + &yg8 * Atable;
|
||||
|
||||
// Construct the proof
|
||||
let mut transcript = Transcript::new(b"trust promotion request");
|
||||
let piUser = requestproof::prove_compact(
|
||||
|
@ -280,15 +299,15 @@ pub fn request(
|
|||
CG6: &CG6,
|
||||
CG7: &CG7,
|
||||
CG8: &CG8,
|
||||
CG0sq: &(g0 * P + &yg0 * Atable),
|
||||
CG1sq: &(g1 * P + &yg1 * Atable),
|
||||
CG2sq: &(g2 * P + &yg2 * Atable),
|
||||
CG3sq: &(g3 * P + &yg3 * Atable),
|
||||
CG4sq: &(g4 * P + &yg4 * Atable),
|
||||
CG5sq: &(g5 * P + &yg5 * Atable),
|
||||
CG6sq: &(g6 * P + &yg6 * Atable),
|
||||
CG7sq: &(g7 * P + &yg7 * Atable),
|
||||
CG8sq: &(g8 * P + &yg8 * Atable),
|
||||
CG0sq: &CG0sq,
|
||||
CG1sq: &CG1sq,
|
||||
CG2sq: &CG2sq,
|
||||
CG3sq: &CG3sq,
|
||||
CG4sq: &CG4sq,
|
||||
CG5sq: &CG5sq,
|
||||
CG6sq: &CG6sq,
|
||||
CG7sq: &CG7sq,
|
||||
CG8sq: &CG8sq,
|
||||
bucket: &lox_cred.bucket,
|
||||
since: &lox_cred.level_since,
|
||||
zbucket: &zbucket,
|
||||
|
@ -353,6 +372,15 @@ pub fn request(
|
|||
CG6,
|
||||
CG7,
|
||||
CG8,
|
||||
CG0sq,
|
||||
CG1sq,
|
||||
CG2sq,
|
||||
CG3sq,
|
||||
CG4sq,
|
||||
CG5sq,
|
||||
CG6sq,
|
||||
CG7sq,
|
||||
CG8sq,
|
||||
piUser,
|
||||
},
|
||||
State {
|
||||
|
@ -364,3 +392,81 @@ pub fn request(
|
|||
},
|
||||
))
|
||||
}
|
||||
|
||||
impl BridgeAuth {
|
||||
/// Receive a trust promotion request
|
||||
pub fn handle_trust_promotion(&mut self, req: Request) -> Result<(), ProofError> {
|
||||
let A: &RistrettoPoint = &CMZ_A;
|
||||
let B: &RistrettoPoint = &CMZ_B;
|
||||
|
||||
if req.P.is_identity() {
|
||||
return Err(ProofError::VerificationFailure);
|
||||
}
|
||||
|
||||
// Recompute the "error factor" using knowledge of our own
|
||||
// (the issuer's) private key instead of knowledge of the
|
||||
// hidden attributes
|
||||
let Vprime = (self.lox_priv.x[0] + self.lox_priv.x[1] * req.id) * req.P
|
||||
+ self.lox_priv.x[2] * req.CBucket
|
||||
+ self.lox_priv.x[4] * req.CSince
|
||||
- req.CQ;
|
||||
|
||||
// Recompute CG0 using Horner's method
|
||||
let today: Scalar = self.today().into();
|
||||
let unt: Scalar = UNTRUSTED_INTERVAL.into();
|
||||
let CG0prime = (today - unt) * req.P
|
||||
- req.CSince
|
||||
- pt_dbl(
|
||||
&(pt_dbl(
|
||||
&(pt_dbl(
|
||||
&(pt_dbl(
|
||||
&(pt_dbl(
|
||||
&(pt_dbl(&(pt_dbl(&(pt_dbl(&req.CG8) + req.CG7)) + req.CG6))
|
||||
+ req.CG5),
|
||||
) + req.CG4),
|
||||
) + req.CG3),
|
||||
) + req.CG2),
|
||||
) + req.CG1),
|
||||
);
|
||||
|
||||
// Verify the ZKP
|
||||
let mut transcript = Transcript::new(b"trust promotion request");
|
||||
requestproof::verify_compact(
|
||||
&req.piUser,
|
||||
&mut transcript,
|
||||
requestproof::VerifyAssignments {
|
||||
A: &A.compress(),
|
||||
B: &B.compress(),
|
||||
P: &req.P.compress(),
|
||||
CBucket: &req.CBucket.compress(),
|
||||
CSince: &req.CSince.compress(),
|
||||
V: &Vprime.compress(),
|
||||
Xbucket: &self.lox_pub.X[2].compress(),
|
||||
Xsince: &self.lox_pub.X[4].compress(),
|
||||
EncBucket0: &req.EncBucket.0.compress(),
|
||||
EncBucket1: &req.EncBucket.1.compress(),
|
||||
D: &req.D.compress(),
|
||||
CG0: &CG0prime.compress(),
|
||||
CG1: &req.CG1.compress(),
|
||||
CG2: &req.CG2.compress(),
|
||||
CG3: &req.CG3.compress(),
|
||||
CG4: &req.CG4.compress(),
|
||||
CG5: &req.CG5.compress(),
|
||||
CG6: &req.CG6.compress(),
|
||||
CG7: &req.CG7.compress(),
|
||||
CG8: &req.CG8.compress(),
|
||||
CG0sq: &req.CG0sq.compress(),
|
||||
CG1sq: &req.CG1sq.compress(),
|
||||
CG2sq: &req.CG2sq.compress(),
|
||||
CG3sq: &req.CG3sq.compress(),
|
||||
CG4sq: &req.CG4sq.compress(),
|
||||
CG5sq: &req.CG5sq.compress(),
|
||||
CG6sq: &req.CG6sq.compress(),
|
||||
CG7sq: &req.CG7sq.compress(),
|
||||
CG8sq: &req.CG8sq.compress(),
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,11 +45,3 @@ fn test_dup_filter() {
|
|||
println!("df1 = {:?}", df1);
|
||||
println!("df2 = {:?}", df2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bridgeauth() {
|
||||
let bdb = BridgeDb::new(20);
|
||||
let mut ba = BridgeAuth::new(bdb.pubkey);
|
||||
ba.advance_day();
|
||||
ba.advance_days(30);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue