|
@@ -41,7 +41,7 @@ and a new Lox credential to be issued:
|
|
|
use super::super::dup_filter::SeenType;
|
|
|
#[cfg(feature = "bridgeauth")]
|
|
|
use super::super::BridgeAuth;
|
|
|
-use super::super::{scalar_u32, G};
|
|
|
+use super::super::{scalar_u32, Scalar, G};
|
|
|
use super::errors::CredentialError;
|
|
|
use crate::lox_creds::{BucketReachability, Lox};
|
|
|
use cmz::*;
|
|
@@ -78,12 +78,13 @@ pub const LEVEL_INVITATIONS: [u32; MAX_LEVEL + 1] = [0, 2, 4, 6, 8];
|
|
|
// one or more bits to the ZKP.
|
|
|
pub const MAX_BLOCKAGES: [u32; MAX_LEVEL + 1] = [0, 4, 3, 2, 2];
|
|
|
|
|
|
-muCMZProtocol! { level_up<credential_expiry, eligibility_max_age, max_blockage>,
|
|
|
+muCMZProtocol! { level_up<credential_expiry, eligibility_max_age, max_blockage, today>,
|
|
|
[ L: Lox { id: R, bucket: H, trust_level: R, level_since: H, invites_remaining: H, blockages: H },
|
|
|
B: BucketReachability { date: R, bucket: H } ],
|
|
|
N: Lox {id: J, bucket: H, trust_level: R, level_since: S, invites_remaining: I, blockages: H },
|
|
|
(credential_expiry..=eligibility_max_age).contains(L.level_since),
|
|
|
(0..=max_blockage).contains(L.blockages),
|
|
|
+ B.date = today,
|
|
|
B.bucket = L.bucket,
|
|
|
N.bucket = L.bucket,
|
|
|
N.trust_level = L.trust_level + 1,
|
|
@@ -185,23 +186,22 @@ pub fn request(
|
|
|
} else {
|
|
|
trust_level
|
|
|
};
|
|
|
-
|
|
|
+ let mut N = Lox::using_pubkey(&pubkeys);
|
|
|
+ N.id = Some(Scalar::random(rng));
|
|
|
+ N.bucket = L.bucket;
|
|
|
+ N.trust_level = Some(new_level.into());
|
|
|
+ N.level_since = Some(today.into());
|
|
|
+ N.invites_remaining = Some(LEVEL_INVITATIONS[trust_level as usize].into());
|
|
|
+ N.blockages = L.blockages;
|
|
|
let eligibility_max_age = today - (LEVEL_INTERVAL[trust_level as usize]);
|
|
|
|
|
|
let params = level_up::Params {
|
|
|
credential_expiry: (eligibility_max_age - 511).into(),
|
|
|
eligibility_max_age: eligibility_max_age.into(),
|
|
|
max_blockage: MAX_BLOCKAGES[new_level as usize].into(),
|
|
|
+ today: today.into(),
|
|
|
};
|
|
|
-
|
|
|
- match level_up::prepare(
|
|
|
- rng,
|
|
|
- SESSION_ID,
|
|
|
- &L,
|
|
|
- &B,
|
|
|
- Lox::using_pubkey(&pubkeys),
|
|
|
- ¶ms,
|
|
|
- ) {
|
|
|
+ match level_up::prepare(rng, SESSION_ID, &L, &B, N, ¶ms) {
|
|
|
Ok(req_state) => Ok(req_state),
|
|
|
Err(e) => Err(CredentialError::CMZError(e)),
|
|
|
}
|
|
@@ -221,7 +221,7 @@ impl BridgeAuth {
|
|
|
&mut rng,
|
|
|
SESSION_ID,
|
|
|
recvreq,
|
|
|
- |L: &mut Lox, _B: &mut BucketReachability, N: &mut Lox| {
|
|
|
+ |L: &mut Lox, B: &mut BucketReachability, N: &mut Lox| {
|
|
|
let trust_level: u32 = match scalar_u32(&L.trust_level.unwrap()) {
|
|
|
Some(v) if v as usize >= 1 && v as usize <= MAX_LEVEL => v,
|
|
|
_ => {
|
|
@@ -233,13 +233,18 @@ impl BridgeAuth {
|
|
|
));
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
let eligibility_max_age: u32 = today - LEVEL_INTERVAL[trust_level as usize];
|
|
|
- N.invites_remaining = Some(LEVEL_INVITATIONS[(trust_level + 1) as usize].into());
|
|
|
+ L.set_privkey(&self.lox_priv);
|
|
|
+ B.set_privkey(&self.reachability_priv);
|
|
|
+ N.set_privkey(&self.lox_priv);
|
|
|
+ N.trust_level = Some((trust_level + 1).into());
|
|
|
+ N.level_since = Some(today.into());
|
|
|
+ N.invites_remaining = Some(LEVEL_INVITATIONS[trust_level as usize].into());
|
|
|
Ok(level_up::Params {
|
|
|
credential_expiry: (eligibility_max_age - 511).into(),
|
|
|
eligibility_max_age: eligibility_max_age.into(),
|
|
|
max_blockage: MAX_BLOCKAGES[(trust_level + 1) as usize].into(),
|
|
|
+ today: today.into(),
|
|
|
})
|
|
|
},
|
|
|
|L: &Lox, _B: &BucketReachability, _N: &Lox| {
|
|
@@ -266,3 +271,117 @@ pub fn handle_response(
|
|
|
Err(_e) => Err(CMZError::Unknown),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+#[cfg(all(test, feature = "bridgeauth"))]
|
|
|
+mod tests {
|
|
|
+ use super::*;
|
|
|
+ use crate::bridge_table;
|
|
|
+ use crate::mock_auth::TestHarness;
|
|
|
+ use crate::proto::{
|
|
|
+ level_up::{self, LEVEL_INTERVAL},
|
|
|
+ migration, open_invite,
|
|
|
+ trust_promotion::{self, UNTRUSTED_INTERVAL},
|
|
|
+ };
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_level_up() {
|
|
|
+ let mut th = TestHarness::new();
|
|
|
+ let rng = &mut rand::thread_rng();
|
|
|
+ let open_invitation_request = open_invite::request(rng, th.ba.lox_pub.clone());
|
|
|
+ assert!(
|
|
|
+ open_invitation_request.is_ok(),
|
|
|
+ "Open invitation request should succeed"
|
|
|
+ );
|
|
|
+ let (request, client_state) = open_invitation_request.unwrap();
|
|
|
+ let invite = th.bdb.invite();
|
|
|
+ let open_invitation_response = th.ba.open_invitation(request, &invite.unwrap());
|
|
|
+ assert!(
|
|
|
+ open_invitation_response.is_ok(),
|
|
|
+ "Open invitation response from server should succeed"
|
|
|
+ );
|
|
|
+ let (response, _) = open_invitation_response.unwrap();
|
|
|
+ let creds = open_invite::handle_response(client_state, response);
|
|
|
+ println!("{}", th.ba.today());
|
|
|
+ assert!(creds.is_ok(), "Handle response should succeed");
|
|
|
+ th.advance_days((UNTRUSTED_INTERVAL + 1).try_into().unwrap());
|
|
|
+ println!("{}", th.ba.today());
|
|
|
+ let lox_cred = creds.unwrap();
|
|
|
+ let trust_promo_request = trust_promotion::request(
|
|
|
+ rng,
|
|
|
+ lox_cred.clone(),
|
|
|
+ th.ba.migrationkey_pub.clone(),
|
|
|
+ th.ba.today(),
|
|
|
+ );
|
|
|
+ assert!(
|
|
|
+ trust_promo_request.is_ok(),
|
|
|
+ "Trust Promotion request should succeed"
|
|
|
+ );
|
|
|
+ let (tp_request, tp_client_state) = trust_promo_request.unwrap();
|
|
|
+ let trust_promo_response = th.ba.handle_trust_promotion(tp_request);
|
|
|
+ assert!(
|
|
|
+ trust_promo_response.is_ok(),
|
|
|
+ "Trust promotion response from server should succeed"
|
|
|
+ );
|
|
|
+ let (response, enc) = trust_promo_response.unwrap();
|
|
|
+ let mig_cred = trust_promotion::handle_response(
|
|
|
+ th.ba.migration_pub.clone(),
|
|
|
+ tp_client_state,
|
|
|
+ response,
|
|
|
+ enc,
|
|
|
+ );
|
|
|
+ assert!(mig_cred.is_ok(), "Handle response should succeed");
|
|
|
+ let migration_request = migration::request(
|
|
|
+ rng,
|
|
|
+ lox_cred.clone(),
|
|
|
+ mig_cred.unwrap(),
|
|
|
+ th.ba.lox_pub.clone(),
|
|
|
+ );
|
|
|
+ assert!(
|
|
|
+ migration_request.is_ok(),
|
|
|
+ "Migration request should succeed"
|
|
|
+ );
|
|
|
+ let (mig_request, mig_client_state) = migration_request.unwrap();
|
|
|
+ let migration_response = th.ba.handle_migration(mig_request);
|
|
|
+ assert!(
|
|
|
+ migration_response.is_ok(),
|
|
|
+ "Migration response from server should succeed"
|
|
|
+ );
|
|
|
+ let response = migration_response.unwrap();
|
|
|
+ let mut cred = migration::handle_response(mig_client_state, response);
|
|
|
+ assert!(cred.is_ok(), "Handle response should succeed");
|
|
|
+ let lox_cred = cred.unwrap();
|
|
|
+ let trust_level: u32 = scalar_u32(&lox_cred.clone().trust_level.unwrap()).unwrap();
|
|
|
+ th.advance_days(LEVEL_INTERVAL[trust_level as usize] + 1);
|
|
|
+ let (id, key) = bridge_table::from_scalar(lox_cred.bucket.unwrap()).unwrap();
|
|
|
+ let encbuckets = th.ba.enc_bridge_table().clone();
|
|
|
+ let reach_pub = th.ba.reachability_pub.clone();
|
|
|
+ let bucket = bridge_table::BridgeTable::decrypt_bucket(
|
|
|
+ id,
|
|
|
+ &key,
|
|
|
+ encbuckets.get(&id).unwrap(),
|
|
|
+ &reach_pub,
|
|
|
+ )
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let reachcred = bucket.1.unwrap();
|
|
|
+
|
|
|
+ let level_up_request = level_up::request(
|
|
|
+ rng,
|
|
|
+ lox_cred.clone(),
|
|
|
+ reachcred,
|
|
|
+ th.ba.lox_pub.clone(),
|
|
|
+ th.ba.today(),
|
|
|
+ );
|
|
|
+ assert!(level_up_request.is_ok(), "Level up request should succeed");
|
|
|
+ let (level_up_request, level_up_client_state) = level_up_request.unwrap();
|
|
|
+ let level_up_response = th.ba.handle_level_up(level_up_request);
|
|
|
+ assert!(
|
|
|
+ level_up_response.is_ok(),
|
|
|
+ "Level up response from server should succeed"
|
|
|
+ );
|
|
|
+ let response = level_up_response.unwrap();
|
|
|
+ cred = level_up::handle_response(level_up_client_state, response);
|
|
|
+ assert!(cred.is_ok(), "Handle response should succeed");
|
|
|
+ th.verify_lox(&cred.unwrap());
|
|
|
+ }
|
|
|
+}
|