Kaynağa Gözat

Add level up proto

onyinyang 1 yıl önce
ebeveyn
işleme
39b7e44ded
6 değiştirilmiş dosya ile 200 ekleme ve 29 silme
  1. 1 25
      Cargo.lock
  2. 1 1
      Cargo.toml
  3. 20 0
      src/lib.rs
  4. 4 3
      src/lox_creds.rs
  5. 21 0
      src/proto/errors.rs
  6. 153 0
      src/proto/level_up.rs

+ 1 - 25
Cargo.lock

@@ -237,28 +237,10 @@ dependencies = [
  "curve25519-dalek",
  "group",
  "lazy_static",
- "phf",
  "rand",
  "serde",
  "sha2",
-]
-
-[[package]]
-name = "phf"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
-dependencies = [
- "phf_shared",
-]
-
-[[package]]
-name = "phf_shared"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
-dependencies = [
- "siphasher",
+ "subtle",
 ]
 
 [[package]]
@@ -370,12 +352,6 @@ dependencies = [
  "digest",
 ]
 
-[[package]]
-name = "siphasher"
-version = "0.3.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
-
 [[package]]
 name = "strsim"
 version = "0.11.1"

+ 1 - 1
Cargo.toml

@@ -9,6 +9,6 @@ lazy_static = "1.5.0"
 rand = {version = "0.8.0", features = ["std_rng"] }
 serde = "1.0.217"
 sha2 = "0.10.8"
+subtle = "2.5"
 cmz = {git = "ssh://gogs@git-crysp.uwaterloo.ca/SigmaProtocol/cmz.git"}
-phf = "0.8.0"
 group = "0.13"

+ 20 - 0
src/lib.rs

@@ -0,0 +1,20 @@
+use curve25519_dalek::scalar::Scalar;
+use subtle::ConstantTimeEq;
+
+pub mod lox_creds;
+pub mod proto {
+    pub mod errors;
+    pub mod level_up;
+}
+
+// Try to extract a u32 from a Scalar
+pub fn scalar_u32(s: &Scalar) -> Option<u32> {
+    // Check that the top 28 bytes of the Scalar are 0
+    let sbytes: &[u8; 32] = s.as_bytes();
+    if sbytes[4..].ct_eq(&[0u8; 28]).unwrap_u8() == 0 {
+        return None;
+    }
+    Some(u32::from_le_bytes(sbytes[..4].try_into().unwrap()))
+}
+
+//pub mod open_invite;

+ 4 - 3
src/lox_creds.rs

@@ -1,8 +1,9 @@
 // The various credentials used by the system.
 
-use cmz::{CMZMac, CMZ};
+use cmz::*;
 use curve25519_dalek::ristretto::RistrettoPoint as G;
-use group::Group;
+use group::{ff, Group};
+use rand::RngCore;
 
 // A migration credential.
 //
@@ -13,7 +14,7 @@ use group::Group;
 // for blockage migrations (moving buckets because the from_bucket has
 // been blocked).
 // Annotated to "M"
-CMZ! { Migration<G>:
+CMZ! { Migration:
     lox_id,
     from_bucket,
     to_bucket,

+ 21 - 0
src/proto/errors.rs

@@ -0,0 +1,21 @@
+use thiserror::Error;
+
+/// This error is thrown if the number of buckets/keys in the bridge table
+/// exceeds u32 MAX.It is unlikely this error will ever occur.
+#[derive(Error, Debug)]
+pub enum CredentialError {
+    #[error("time threshold for operation will not be met for {0} more days")]
+    TimeThresholdNotMet(u32),
+    #[error("credential has expired")]
+    CredentialExpired,
+    #[error("invalid field {0}: {1}")]
+    InvalidField(String, String),
+    #[error("exceeded blockages threshold")]
+    ExceededBlockagesThreshold,
+    #[error("credential has no available invitations")]
+    NoInvitationsRemaining,
+    #[error("supplied credentials do not match")]
+    CredentialMismatch,
+    #[error("CMZ Error")]
+    CMZError(cmz::CMZError),
+}

+ 153 - 0
src/proto/level_up.rs

@@ -0,0 +1,153 @@
+/*! A module for the protocol for the user to increase their trust level
+(from a level at least 1; use the trust promotion protocol to go from
+untrusted (level 0) to minimally trusted (level 1).
+
+They are allowed to do this as long as some amount of time (depending on
+their current level) has elapsed since their last level change, and they
+have a Bucket Reachability credential for their current bucket and
+today's date.  (Such credentials are placed daily in the encrypted
+bridge table.)
+
+The user presents their current Lox credential:
+- id: revealed
+- bucket: blinded
+- trust_level: revealed, and must be at least 1
+- level_since: blinded, but proved in ZK that it's at least the
+  appropriate number of days ago
+- invites_remaining: blinded
+- blockages: blinded, but proved in ZK that it's at most the appropriate
+  blockage limit for the target trust level
+
+and a Bucket Reachability credential:
+- date: revealed to be today
+- bucket: blinded, but proved in ZK that it's the same as in the Lox
+  credential above
+
+and a new Lox credential to be issued:
+
+- id: jointly chosen by the user and BA
+- bucket: blinded, but proved in ZK that it's the same as in the Lox
+  credential above
+- trust_level: revealed to be one more than the trust level above
+- level_since: today
+- invites_remaining: revealed to be the number of invites for the new
+  level (note that the invites_remaining from the previous credential
+  are _not_ carried over)
+- blockages: blinded, but proved in ZK that it's the same as in the
+  Lox credential above
+
+*/
+
+use phf::{Map, phf_map};
+use super::super::cmz::{IssueType, ShowType};
+use super::super::lox_creds;
+use curve25519_dalek::ristretto::RistrettoPoint as G;
+
+/// The maximum trust level in the system.  A user can run this level
+/// upgrade protocol when they're already at the max level; they will
+/// get a fresh invites_remaining batch, and reset their level_since
+/// field to today's date, but will remain in the max level.
+pub const MAX_LEVEL: usize = 4;
+
+/// DAYS_AGO\[i\] for i >= 1 is the minimum number of days a user
+/// must be at trust level i before advancing to level i+1 (or as above,
+/// remain at level i if i == MAX_LEVEL).  Note that the
+/// DAYS_AGO\[0\] entry is a dummy; the trust_promotion protocol
+/// is used instead of this one to move from level 0 to level 1.
+pub const DAYS_AGO: [u32; MAX_LEVEL + 1] = [0, 14, 28, 56, 84];
+
+/// LEVEL_INVITATIONS\[i\] for i >= 1 is the number of invitations a
+/// user will be eligible to issue upon advancing from level i to level
+/// i+1.  Again the LEVEL_INVITATIONS\[0\] entry is a dummy, as for
+/// DAYS_AGO.
+pub const LEVEL_INVITATIONS: [u32; MAX_LEVEL + 1] = [0, 2, 4, 6, 8];
+
+/// MAX_BLOCKAGES\[i\] for i >= 1 is the maximum number of bucket
+/// blockages this credential is allowed to have recorded in order to
+/// advance from level i to level i+1.  Again the LEVEL_INVITATIONS\[0\]
+/// entry is a dummy, as for DAYS_AGO.
+// If you change this to have a number greater than 7, you need to add
+// one or more bits to the ZKP.
+pub const MAX_BLOCKAGES: [u32; MAX_LEVEL + 1] = [0, 4, 3, 2, 2];
+
+
+static LOX_LEVEL_UP_SHOW: Map<&str, ShowType> = phf_map! {
+    "id" => ShowType::Reveal,
+    "bucket" => ShowType::Hide,
+    "trust_level" => ShowType::Reveal,
+    "level_since" => ShowType::Hide,
+    "invites_remaining" => ShowType::Hide,
+    "blockages" => ShowType::Hide,
+};
+
+static REACHABILITY_SHOW: Map<&str, ShowType> = phf_map! {
+    "date" => ShowType::Reveal,
+    "bucket" => ShowType::Hide,
+};
+
+static LOX_LEVEL_UP_ISSUE: Map<&str, IssueType> = phf_map! {
+    "id" => IssueType::Joint,
+    "bucket" => IssueType::Hide,
+    "trust_level" => IssueType::Reveal,
+    "level_since" => IssueType::Server,
+    "invites_remaining" => IssueType::Implicit, // determined by trust_level
+    "blockages" => IssueType::Hide,
+};
+
+let level_up = CMZ.Protocol(
+         vec![("L", lox_creds::Lox::attrs(), LOX_LEVEL_UP_SHOW),
+             ("BR", Reachability::attrs(), REACHABILITY_SHOW)],
+         vec![("NEW", Lox::attrs(), LOX_LEVEL_UP_ISSUE)],
+         statement,
+         request_message
+);
+
+let statement = Statement! {
+    today-(DAYS_AGO[level]+511) <= L.level_since <= today-DAYS_AGO[level],
+    0 <= L.blockages <= MAX_BLOCKAGES[level+1],
+    BR.bucket = L.bucket,
+    NEW.bucket = L.bucket,
+    NEW.blockages = L.blockages,
+};
+
+pub fn request(lox_credential: lox_creds::Lox, reachability_credential: lox_cred::Bucket,
+pubkeys: IssuerPubKeys) -> Result<(Vec<u8>, State), Error> {
+
+    // TODO: Check everything required for the lox_credential to run
+    // this protocol
+    let new_lox_credential = lox_creds::Lox::default();
+    let mut rng = rand::thread_rng();
+    new_lox_credential.id = Some(<G as Group>::Scalar::random(&mut rng));
+    new_lox_credential.bucket = Some(lox_credential.bucket);
+    new_lox_credential.trust_level = Some((lox_credential.trust_level as usize + 1).into());
+    new_lox_credential.invites_remaining = Some(LEVEL_INVITATIONS[trust_level as usize].into())
+    new_lox_credential.blockages = Some(lox_credential.blockages);
+
+    // TODO: Allocate pubkeys somehow
+    match level_up.show_issue(
+        vec![&lox_credential, &reachability_credential],
+        vec![&mut new_lox_credential]) {
+        Ok(request_message, state) => Ok(request_message, state),
+        Err(e) => Error(e),
+    }
+}
+
+impl BridgeAuth {
+
+    pub fn handle_level_up(&mut self, req: Request) -> Result<Response,
+ProofError> {
+
+    let public_verify = TODO;
+    level_up.handle(
+        vec![&mut req.lox_credential, &mut req.reachability_credential],
+        vec![&mut req.new_lox_credential],
+        public_verify) 
+    }
+}
+
+pub fn handle_response(state: State, resp: Response) -> Result<Vec<Credential>, ProofError> {
+    match cmz_finalize(client_state, response_message) {
+        Ok(Vec<Credential>) => Ok(Vec<Credential>),
+        Err(e) => ProofError(e),
+        }
+}