Parcourir la source

Add level up proto

onyinyang il y a 1 an
Parent
commit
26cbe79e67
5 fichiers modifiés avec 197 ajouts et 50 suppressions
  1. 0 46
      src/credOptions.rs
  2. 19 1
      src/lib.rs
  3. 4 3
      src/lox_creds.rs
  4. 21 0
      src/proto/errors.rs
  5. 153 0
      src/proto/level_up.rs

+ 0 - 46
src/credOptions.rs

@@ -1,46 +0,0 @@
-pub enum IssueType {
-    Select,
-    Joint,
-    Reveal,
-    Hide,
-    Implicit,
-}
-
-pub enum ShowType {
-    Reveal,
-    Hide,
-    Implicit,
-}
-
-/*
-let struct AnnotatedShowCredential {
-    ///a Label for the credential, for use in the ZKP statement
-    Label: Label,
-    /// a CMZ credential, which includes the names of the attributes (as
-    /// `Label`s, which may as well just be strings), the public (for the
-    /// client) or private (for the issuer) keys, the values of the fields (if
-    /// known)
-    Credential: CMZCredential,
-    /// an annotation saying which fields are to be revealed or hidden (for
-    ///  AnnotatedShow) or which fields are to be set to a revealed value, a
-    ///  hidden value, a value set by the issuer, or a value set jointly (for
-    ///  AnnotatedIssue)
-    Shows: HashMap<Label, ShowType>,
-}
-
-
-let struct AnnotatedIssueCredential {
-    ///a Label for the credential, for use in the ZKP statement
-    Label: Label,
-    /// a CMZ credential, which includes the names of the attributes (as
-    /// `Label`s, which may as well just be strings), the public (for the
-    /// client) or private (for the issuer) keys, the values of the fields (if
-    /// known)
-    Credential: CMZCredential,
-    /// an annotation saying which fields are to be revealed or hidden (for
-    ///  AnnotatedShow) or which fields are to be set to a revealed value, a
-    ///  hidden value, a value set by the issuer, or a value set jointly (for
-    ///  AnnotatedIssue)
-    Shows: HashMap<Label, IssueType>,
-}
-*/

+ 19 - 1
src/lib.rs

@@ -1,2 +1,20 @@
-pub mod cmz;
+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),
+        }
+}