Просмотр исходного кода

Accommodate cmz and sigma-compiler crate updates

onyinyang 9 месяцев назад
Родитель
Сommit
5ce1b9c933

+ 48 - 237
Cargo.lock

@@ -48,18 +48,6 @@ dependencies = [
  "subtle",
 ]
 
-[[package]]
-name = "ahash"
-version = "0.8.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
-dependencies = [
- "cfg-if",
- "once_cell",
- "version_check",
- "zerocopy",
-]
-
 [[package]]
 name = "android-tzdata"
 version = "0.1.1"
@@ -75,56 +63,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "anstream"
-version = "0.6.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
-dependencies = [
- "anstyle",
- "anstyle-parse",
- "anstyle-query",
- "anstyle-wincon",
- "colorchoice",
- "is_terminal_polyfill",
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle"
-version = "1.0.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
-
-[[package]]
-name = "anstyle-parse"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
-dependencies = [
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle-query"
-version = "1.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
-dependencies = [
- "windows-sys",
-]
-
-[[package]]
-name = "anstyle-wincon"
-version = "3.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
-dependencies = [
- "anstyle",
- "once_cell_polyfill",
- "windows-sys",
-]
-
 [[package]]
 name = "autocfg"
 version = "1.5.0"
@@ -175,9 +113,9 @@ dependencies = [
 
 [[package]]
 name = "bumpalo"
-version = "3.18.1"
+version = "3.19.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
+checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
 
 [[package]]
 name = "byteorder"
@@ -210,7 +148,7 @@ dependencies = [
  "iana-time-zone",
  "num-traits",
  "serde",
- "windows-link 0.1.3",
+ "windows-link",
 ]
 
 [[package]]
@@ -223,51 +161,11 @@ dependencies = [
  "inout",
 ]
 
-[[package]]
-name = "clap"
-version = "4.5.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a"
-dependencies = [
- "clap_builder",
- "clap_derive",
-]
-
-[[package]]
-name = "clap_builder"
-version = "4.5.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876"
-dependencies = [
- "anstream",
- "anstyle",
- "clap_lex",
- "strsim",
-]
-
-[[package]]
-name = "clap_derive"
-version = "4.5.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "syn 2.0.104",
-]
-
-[[package]]
-name = "clap_lex"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
-
 [[package]]
 name = "cmz"
-version = "0.1.0-rc1"
+version = "0.1.0"
 dependencies = [
- "cmz-derive",
+ "cmzcred_derive",
  "ff",
  "generic_static",
  "group",
@@ -277,43 +175,20 @@ dependencies = [
  "serde",
  "serde_bytes",
  "serde_with",
- "sigma-compiler",
+ "sigma_compiler",
  "thiserror 2.0.12",
 ]
 
 [[package]]
-name = "cmz-core"
+name = "cmzcred_derive"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d44996d931fb4b23721bbbec00396fec6f7505fc0534da8891bb1a3d10ec1490"
-dependencies = [
- "clap",
- "darling",
- "prettyplease",
- "proc-macro2",
- "quote",
- "syn 2.0.104",
-]
-
-[[package]]
-name = "cmz-derive"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1910788dc7a1e8d23bbeacd98162eb440a01d28914e7b935a7a49db2a208da1"
 dependencies = [
- "cmz-core",
  "darling",
  "proc-macro2",
  "quote",
  "syn 2.0.104",
 ]
 
-[[package]]
-name = "colorchoice"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
-
 [[package]]
 name = "core-foundation-sys"
 version = "0.8.7"
@@ -329,6 +204,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "crunchy"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
+
 [[package]]
 name = "crypto-common"
 version = "0.1.6"
@@ -578,12 +459,6 @@ version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
 
-[[package]]
-name = "heck"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
-
 [[package]]
 name = "hex"
 version = "0.4.3"
@@ -636,9 +511,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "2.9.0"
+version = "2.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
+checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
 dependencies = [
  "equivalent",
  "hashbrown 0.15.4",
@@ -654,12 +529,6 @@ dependencies = [
  "generic-array",
 ]
 
-[[package]]
-name = "is_terminal_polyfill"
-version = "1.70.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
-
 [[package]]
 name = "itoa"
 version = "1.0.15"
@@ -697,12 +566,6 @@ version = "0.2.174"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
 
-[[package]]
-name = "libm"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
-
 [[package]]
 name = "log"
 version = "0.4.27"
@@ -723,12 +586,12 @@ dependencies = [
  "ff",
  "group",
  "rand",
- "rand_core",
  "serde",
  "serde_bytes",
  "serde_with",
  "sha1",
  "sha2",
+ "sigma_compiler",
  "subtle",
  "thiserror 2.0.12",
  "time",
@@ -783,7 +646,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
 dependencies = [
  "autocfg",
- "libm",
 ]
 
 [[package]]
@@ -792,12 +654,6 @@ version = "1.21.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
-[[package]]
-name = "once_cell_polyfill"
-version = "1.70.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
-
 [[package]]
 name = "opaque-debug"
 version = "0.3.1"
@@ -831,16 +687,6 @@ dependencies = [
  "zerocopy",
 ]
 
-[[package]]
-name = "prettyplease"
-version = "0.2.36"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2"
-dependencies = [
- "proc-macro2",
- "syn 2.0.104",
-]
-
 [[package]]
 name = "proc-macro2"
 version = "1.0.95"
@@ -1005,7 +851,7 @@ dependencies = [
  "chrono",
  "hex",
  "indexmap 1.9.3",
- "indexmap 2.9.0",
+ "indexmap 2.10.0",
  "schemars",
  "serde",
  "serde_derive",
@@ -1065,61 +911,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
 
 [[package]]
-name = "sigma-compiler"
+name = "sigma-rs"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "736016d29725f54ee767083ded55e1ddf46b9aa081ae0005423c2b36587ea0be"
 dependencies = [
+ "ff",
  "group",
+ "num-bigint 0.4.6",
+ "num-traits",
  "rand",
- "sigma-compiler-derive",
- "sigma-proofs",
- "subtle",
+ "sha3",
+ "thiserror 1.0.69",
+ "tiny-keccak",
 ]
 
 [[package]]
-name = "sigma-compiler-core"
+name = "sigma_compiler"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a96f60157d659e1f7ac2f04999490ca684cfc20c06a6de5aa5502880fa03b7"
 dependencies = [
- "clap",
- "prettyplease",
- "proc-macro2",
- "quote",
- "syn 2.0.104",
+ "group",
+ "rand",
+ "sigma-rs",
+ "sigma_compiler_derive",
 ]
 
 [[package]]
-name = "sigma-compiler-derive"
+name = "sigma_compiler_core"
 version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c11631f78f12c1eb5e424a6322f173f2ab37d2643de397fe605dfb9b06d4f86"
 dependencies = [
- "sigma-compiler-core",
+ "proc-macro2",
+ "quote",
  "syn 2.0.104",
 ]
 
 [[package]]
-name = "sigma-proofs"
-version = "0.1.0-sigma"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fe0d134228911458aa039f90582b9e512b06d193aa8fc460c78135367a18388"
+name = "sigma_compiler_derive"
+version = "0.1.0"
 dependencies = [
- "ahash",
- "ff",
- "group",
- "hashbrown 0.15.4",
- "keccak",
- "num-bigint 0.4.6",
- "num-traits",
- "rand",
- "rand_core",
- "sha3",
- "subtle",
- "thiserror 1.0.69",
- "zerocopy",
- "zeroize",
+ "sigma_compiler_core",
+ "syn 2.0.104",
 ]
 
 [[package]]
@@ -1239,6 +1068,15 @@ dependencies = [
  "time-core",
 ]
 
+[[package]]
+name = "tiny-keccak"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
+dependencies = [
+ "crunchy",
+]
+
 [[package]]
 name = "typenum"
 version = "1.18.0"
@@ -1261,12 +1099,6 @@ dependencies = [
  "subtle",
 ]
 
-[[package]]
-name = "utf8parse"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
-
 [[package]]
 name = "version_check"
 version = "0.9.5"
@@ -1345,7 +1177,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
 dependencies = [
  "windows-implement",
  "windows-interface",
- "windows-link 0.1.3",
+ "windows-link",
  "windows-result",
  "windows-strings",
 ]
@@ -1378,19 +1210,13 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
 
-[[package]]
-name = "windows-link"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
-
 [[package]]
 name = "windows-result"
 version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
 dependencies = [
- "windows-link 0.1.3",
+ "windows-link",
 ]
 
 [[package]]
@@ -1399,16 +1225,7 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
 dependencies = [
- "windows-link 0.1.3",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.61.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
-dependencies = [
- "windows-link 0.2.1",
+ "windows-link",
 ]
 
 [[package]]
@@ -1439,9 +1256,3 @@ dependencies = [
  "quote",
  "syn 2.0.104",
 ]
-
-[[package]]
-name = "zeroize"
-version = "1.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"

+ 2 - 2
Cargo.toml

@@ -9,7 +9,7 @@ base64 = "0.21.0"
 chrono = { version = "0.4.38", default-features = false, features = ["now"], optional = true }
 curve25519-dalek = {version = "4.1.3", default-features = false, features = ["serde", "group", "rand_core", "digest", "precomputed-tables"] }
 ed25519-dalek = { version = "2.1.1", default-features = false, features = ["serde", "rand_core"] }
-rand = {version = "0.8.0", features = ["std_rng"] }
+rand = {version = "0.8.5", features = ["std_rng"] }
 serde = "1.0.217"
 serde_with = { version = "3.0.0", features = ["json"] }
 sha1 = "0.10"
@@ -17,10 +17,10 @@ sha2 = "0.10.9"
 subtle = "2.5"
 time = "0.3.36"
 cmz = {path = "../cmz"}
+sigma_compiler = {path = "../sigma_compiler"}
 group = "0.13"
 ff = "0.13.1"
 bincode = "1"
-rand_core = "0.6"
 thiserror = "2.0.12"
 serde_bytes = "0.11.17"
 

+ 1 - 1
src/bridge_table.rs

@@ -18,7 +18,7 @@ use base64::{engine::general_purpose, Engine as _};
 use cmz::{CMZCredential, CMZPrivkey, CMZPubkey};
 use curve25519_dalek::ristretto::CompressedRistretto;
 #[allow(unused_imports)]
-use rand::RngCore;
+use rand::{CryptoRng, RngCore};
 use serde::{Deserialize, Serialize};
 use serde_with::{serde_as, DisplayFromStr};
 use sha1::{Digest, Sha1};

+ 7 - 8
src/lib.rs

@@ -26,7 +26,7 @@ use cmz::*;
 use curve25519_dalek::ristretto::RistrettoPoint as G;
 use group::Group;
 #[cfg(feature = "bridgeauth")]
-use rand::{rngs::OsRng, Rng};
+use rand::{rngs::OsRng, CryptoRng, Rng, RngCore};
 #[cfg(feature = "bridgeauth")]
 use std::collections::HashMap;
 type Scalar = <G as Group>::Scalar;
@@ -363,17 +363,16 @@ pub struct BridgeAuth {
 
 #[cfg(feature = "bridgeauth")]
 impl BridgeAuth {
-    pub fn new(bridgedb_pub: VerifyingKey) -> Self {
+    pub fn new(bridgedb_pub: VerifyingKey, rng: &mut (impl CryptoRng + RngCore)) -> Self {
         // Initialization
-        let mut rng = rand::thread_rng();
         cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
         // Create the private and public keys for each of the types of
         // credential with 'true' to indicate uCMZ
-        let (lox_priv, lox_pub) = Lox::gen_keys(&mut rng, true);
-        let (migration_priv, migration_pub) = Migration::gen_keys(&mut rng, true);
-        let (migrationkey_priv, migrationkey_pub) = MigrationKey::gen_keys(&mut rng, true);
-        let (reachability_priv, reachability_pub) = BucketReachability::gen_keys(&mut rng, true);
-        let (invitation_priv, invitation_pub) = Invitation::gen_keys(&mut rng, true);
+        let (lox_priv, lox_pub) = Lox::gen_keys(rng, true);
+        let (migration_priv, migration_pub) = Migration::gen_keys(rng, true);
+        let (migrationkey_priv, migrationkey_pub) = MigrationKey::gen_keys(rng, true);
+        let (reachability_priv, reachability_pub) = BucketReachability::gen_keys(rng, true);
+        let (invitation_priv, invitation_pub) = Invitation::gen_keys(rng, true);
         Self {
             lox_priv,
             lox_pub,

+ 64 - 1
src/mock_auth.rs

@@ -27,8 +27,9 @@ impl TestHarness {
     pub fn new_buckets(num_buckets: u16, hot_spare: u16) -> Self {
         // Create a BridegDb
         let mut bdb = BridgeDb::new();
+        let mut rng = rand::thread_rng();
         // Create a BridgeAuth
-        let mut ba = BridgeAuth::new(bdb.pubkey.clone());
+        let mut ba = BridgeAuth::new(bdb.pubkey.clone(), &mut rng);
 
         // Make 3 x num_buckets open invitation bridges, in sets of 3
         for _ in 0..num_buckets {
@@ -49,6 +50,68 @@ impl TestHarness {
     // pub fn advance_days(&mut self, days: u16) {
     //     self.ba.advance_days(days);
     // }
+
+    /// Verify the two MACs on a Lox credential
+    pub fn verify_lox(&self, cred: &lox_creds::Lox) {
+        assert!(
+            !bool::from(cred.MAC.P.is_identity()),
+            "Lox cred MAC P should not be identity"
+        );
+
+        let Q = (self.ba.lox_priv.x[0]
+            + cred.id.unwrap() * self.ba.lox_priv.x[1]
+            + cred.bucket.unwrap() * self.ba.lox_priv.x[2]
+            + cred.trust_level.unwrap() * self.ba.lox_priv.x[3]
+            + cred.level_since.unwrap() * self.ba.lox_priv.x[4]
+            + cred.invites_remaining.unwrap() * self.ba.lox_priv.x[5]
+            + cred.blockages.unwrap() * self.ba.lox_priv.x[6])
+            * cred.MAC.P;
+
+        assert_eq!(Q, cred.MAC.Q, "Lox MAC Q should match computation");
+    }
+
+    /// Verify the MAC on a Migration credential
+    /*    pub fn verify_migration(&self, cred: &lox_creds::Migration) {
+            if cred.P.is_identity() {
+            }
+
+            let Q = (self.migration_priv.x[0]
+                + cred.lox_id * self.migration_priv.x[1]
+                + cred.from_bucket * self.migration_priv.x[2]
+                + cred.to_bucket * self.migration_priv.x[3])
+                * cred.P;
+
+            Q == cred.Q
+        }
+
+        /// Verify the MAC on a Bucket Reachability credential
+        pub fn verify_reachability(&self, cred: &lox_creds::BucketReachability) {
+            if cred.MAC.P.is_identity() {
+                return false;
+            }
+
+            let Q = (self.reachability_priv.x[0]
+                + cred.date * self.reachability_priv.x[1]
+                + cred.bucket * self.reachability_priv.x[2])
+                * cred.P;
+
+            Q == cred.Q
+        }
+    */
+    /// Verify the MAC on a Invitation credential
+    pub fn verify_invitation(&mut self, cred: &lox_creds::Invitation) {
+        assert!(
+            !bool::from(cred.MAC.P.is_identity()),
+            "Invitation MAC P should not be identity"
+        );
+        let Q = (self.ba.invitation_priv.x[0]
+            + cred.inv_id.unwrap() * self.ba.invitation_priv.x[1]
+            + cred.date.unwrap() * self.ba.invitation_priv.x[2]
+            + cred.bucket.unwrap() * self.ba.invitation_priv.x[3]
+            + cred.blockages.unwrap() * self.ba.invitation_priv.x[4])
+            * cred.MAC.P;
+        assert_eq!(Q, cred.MAC.Q, "Invitation MAC Q should match");
+    }
 }
 
 /// Create a random BridgeLine for testing

+ 18 - 16
src/proto/blockage_migration.rs

@@ -5,29 +5,28 @@ blocked.  Their trust level will go down by 2.
 The user presents their current Lox credential:
 
 - id: revealed
-- bucket: blinded
+- bucket: hidden
 - trust_level: revealed to be 3 or higher
-- level_since: blinded
-- invites_remaining: blinded
-- blockages: blinded
+- level_since: hidden
+- invites_remaining: hidden
+- blockages: hidden
 
 and a Migration credential:
 
 - id: revealed as the same as the Lox credential id above
-- from_bucket: blinded, but proved in ZK that it's the same as the
+- from_bucket: hidden, but proved in ZK that it's the same as the
   bucket in the Lox credential above
-- to_bucket: blinded
+- to_bucket: hidden
 
 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 the to_bucket
+- bucket: hidden, but proved in ZK that it's the same as the to_bucket
   in the Migration credential above
 - trust_level: revealed to be 2 less than the trust_level above
-- level_since: today
-- invites_remaining: revealed to be LEVEL_INVITATIONS for the new trust
-  level
-- blockages: blinded, but proved in ZK that it's one more than the
+- level_since: set by the server to today
+- invites_remaining: implicit to both the client and server as LEVEL_INVITATIONS for the new trust level
+- blockages: hidden, but proved in ZK that it's one more than the
   blockages above
 
 */
@@ -45,18 +44,16 @@ use super::level_up::MAX_LEVEL;
 pub use crate::lox_creds::{Lox, Migration};
 use cmz::*;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 muCMZProtocol! { blockage_migration<min_trust_level>,
     [ L: Lox { id: R, bucket: H, trust_level: R, level_since: H, invites_remaining: H, blockages: H },
     M: Migration { lox_id: R, from_bucket: H, to_bucket: H } ],
     N: Lox {id: J, bucket: H, trust_level: R, level_since: S, invites_remaining: I, blockages: H },
-    //L.trust_level > min_trust_level,
     L.bucket = M.from_bucket,
     N.bucket = M.to_bucket,
-    N.trust_level = L.trust_level - (Scalar::ONE + Scalar::ONE),
-    N.blockages = L.blockages + Scalar::ONE,
+    N.blockages = L.blockages + 1,
 }
 
 pub fn request(
@@ -140,7 +137,12 @@ impl BridgeAuth {
                     }
                 };
                 if L.id.is_some_and(|b| b != M.lox_id.unwrap()) {
-                    return Err(CMZError::RevealAttrMissing("id", "mismatch"));
+                    return Err(CMZError::IssProofFailed);
+                }
+                if L.trust_level
+                    .is_some_and(|b| scalar_u32(&b).unwrap() < MIN_TRUST_LEVEL)
+                {
+                    return Err(CMZError::IssProofFailed);
                 }
                 L.set_privkey(&self.lox_priv);
                 M.set_privkey(&self.migration_priv);

+ 12 - 5
src/proto/check_blockage.rs

@@ -34,6 +34,7 @@ use super::super::dup_filter::SeenType;
 use super::super::BridgeAuth;
 use super::super::{scalar_u32, G};
 use super::errors::CredentialError;
+use super::level_up::MAX_LEVEL;
 use crate::lox_creds::{Lox, Migration, MigrationKey};
 use crate::migration_table;
 use crate::migration_table::ENC_MIGRATION_BYTES;
@@ -43,7 +44,7 @@ use cmz::*;
 use group::Group;
 #[cfg(feature = "bridgeauth")]
 use group::WnafBase;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 use std::collections::HashMap;
 
@@ -51,11 +52,11 @@ use std::collections::HashMap;
 /// perform this protocol.
 pub const MIN_TRUST_LEVEL: u32 = 3;
 
-muCMZProtocol! { check_blockage<min_trust_level>,
+muCMZProtocol! { check_blockage<min_trust_level, max_trust_level>,
     L: Lox { id: R, bucket: H, trust_level: R, level_since: H, invites_remaining: R, blockages: R },
     M: MigrationKey { lox_id: J, from_bucket: H} ,
     L.bucket = M.from_bucket,
-    // L.trust_level > min_trust_level,
+    [min_trust_level..max_trust_leve].contains(L.trust_level),
 }
 
 pub fn request(
@@ -91,12 +92,17 @@ pub fn request(
         }
     }
 
-    let M = MigrationKey::using_pubkey(&mig_pubkeys);
     let params = check_blockage::Params {
         min_trust_level: MIN_TRUST_LEVEL.into(),
+        max_trust_level: (MAX_LEVEL as u32).into(),
     };
 
-    match check_blockage::prepare(&mut rng, &L, M, &params) {
+    match check_blockage::prepare(
+        &mut rng,
+        &L,
+        MigrationKey::using_pubkey(&mig_pubkeys),
+        &params,
+    ) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }
@@ -128,6 +134,7 @@ impl BridgeAuth {
                 M.from_bucket = L.bucket;
                 Ok(check_blockage::Params {
                     min_trust_level: MIN_TRUST_LEVEL.into(),
+                    max_trust_level: (MAX_LEVEL as u32).into(),
                 })
             },
             |L: &Lox, _M: &MigrationKey| {

+ 22 - 27
src/proto/issue_invite.rs

@@ -9,38 +9,38 @@ encrypted bridge table.)
 
 The user presents their current Lox credential:
 - id: revealed
-- bucket: blinded
-- trust_level: blinded
-- level_since: blinded
-- invites_remaining: blinded, but proved in ZK that it's not zero
-- blockages: blinded
+- bucket: hidden
+- trust_level: hidden
+- level_since: hidden
+- invites_remaining: hidden, but proved in ZK that it's not zero
+- blockages: hidden
 
 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
+- bucket: hidden, 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
+- bucket: hidden, but proved in ZK that it's the same as in the Lox
   credential above
-- trust_level: blinded, but proved in ZK that it's the same as in the
+- trust_level: hidden, but proved in ZK that it's the same as in the
   Lox credential above
-- level_since: blinded, but proved in ZK that it's the same as in the
+- level_since: hidden, but proved in ZK that it's the same as in the
   Lox credential above
-- invites_remaining: blinded, but proved in ZK that it's one less than
+- invites_remaining: hidden, but proved in ZK that it's one less than
   the number in the Lox credential above
-- blockages: blinded, but proved in ZK that it's the same as in the
+- blockages: hidden, but proved in ZK that it's the same as in the
   Lox credential above
 
 and a new Invitation credential to be issued:
 
 - inv_id: jointly chosen by the user and BA
-- date: revealed to be today
-- bucket: blinded, but proved in ZK that it's the same as in the Lox
+- date: selected by the server to be today's date
+- bucket: hidden, but proved in ZK that it's the same as in the Lox
   credential above
-- blockages: blinded, but proved in ZK that it's the same as in the Lox
+- blockages: hidden, but proved in ZK that it's the same as in the Lox
   credential above
 
 */
@@ -54,7 +54,7 @@ use super::errors::CredentialError;
 use crate::lox_creds::{BucketReachability, Invitation, Lox};
 use cmz::*;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 /// Invitations must be used within this many days of being issued.
@@ -121,18 +121,13 @@ pub fn request(
         ));
     }
 
-    //TODO check all values are not None
-    let mut I = Invitation::using_pubkey(&inv_pub);
-    let mut N = Lox::using_pubkey(&lox_pubkeys);
-    N.bucket = L.bucket;
-    N.trust_level = L.trust_level;
-    N.level_since = L.level_since;
-    N.invites_remaining = Some(L.invites_remaining.unwrap() - Scalar::ONE);
-    N.blockages = L.blockages;
-    I.bucket = L.bucket;
-    I.blockages = L.blockages;
-
-    match issue_invite::prepare(&mut rng, &L, &B, I, N) {
+    match issue_invite::prepare(
+        &mut rng,
+        &L,
+        &B,
+        Invitation::using_pubkey(&inv_pub),
+        Lox::using_pubkey(&lox_pubkeys),
+    ) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }

+ 6 - 11
src/proto/level_up.rs

@@ -46,7 +46,7 @@ use super::errors::CredentialError;
 use crate::lox_creds::{BucketReachability, Lox};
 use cmz::*;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 /// The maximum trust level in the system.  A user can run this level
@@ -80,25 +80,22 @@ muCMZProtocol! { level_up<credential_expiry, eligibility_max_age, max_blockage>,
     [ 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 <= L.level_since,
-   // L.level_since <= eligibility_max_age,
-   // 0 <= L.blockages,
-   // L.blockages <= max_blockage,
+    [credential_expiry.. eligibility_max_age].contains(L.level_since),
+    [0..max_blockage].contains(L.blockages),
     B.bucket = L.bucket,
     N.bucket = L.bucket,
-    N.trust_level = L.trust_level + Scalar::ONE,
+    N.trust_level = L.trust_level + 1,
     N.blockages = L.blockages,
 }
 
 pub fn request(
+    rng: &mut (impl CryptoRng + RngCore),
     L: Lox,
     B: BucketReachability,
     pubkeys: CMZPubkey<G>,
     today: u32,
 ) -> Result<(level_up::Request, level_up::ClientState), CredentialError> {
-    let mut rng = rand::thread_rng();
     cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
-
     // Ensure the credential can be correctly shown: it must be the case
     // that level_since + LEVEL_INTERVAL[level] <= today.
     let level_since: u32 = match scalar_u32(&L.level_since.unwrap()) {
@@ -189,15 +186,13 @@ pub fn request(
 
     let eligibility_max_age = today - (LEVEL_INTERVAL[trust_level as usize]);
 
-    let mut N = Lox::using_pubkey(&pubkeys);
-    N.invites_remaining = Some(LEVEL_INVITATIONS[new_level as usize].into());
     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(),
     };
 
-    match level_up::prepare(&mut rng, &L, &B, N, &params) {
+    match level_up::prepare(rng, &L, &B, Lox::using_pubkey(&pubkeys), &params) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }

+ 1 - 1
src/proto/migration.rs

@@ -42,7 +42,7 @@ use cmz::*;
 use curve25519_dalek::ristretto::RistrettoPoint as G;
 use curve25519_dalek::scalar::Scalar;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 muCMZProtocol! { migration,

+ 9 - 7
src/proto/open_invite.rs

@@ -23,7 +23,7 @@ use super::super::{Scalar, G};
 use super::errors::CredentialError;
 use crate::lox_creds::Lox;
 use cmz::*;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 muCMZProtocol! { open_invitation,
@@ -35,19 +35,19 @@ muCMZProtocol! { open_invitation,
 /// Note that preparing the request does not require an open invitation, but an invitation
 /// must be sent along with the prepared open_inivtation::Request to the Lox authority
 pub fn request(
+    rng: &mut (impl CryptoRng + RngCore),
     pubkeys: CMZPubkey<G>,
 ) -> Result<(open_invitation::Request, open_invitation::ClientState), CredentialError> {
-    let mut rng = rand::thread_rng();
     cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
 
     let mut L = Lox::using_pubkey(&pubkeys);
-    L.id = Some(Scalar::random(&mut rng));
+    L.id = Some(Scalar::ZERO);
     L.bucket = Some(Scalar::ZERO);
     L.trust_level = Some(Scalar::ZERO);
     L.level_since = Some(Scalar::ZERO);
     L.invites_remaining = Some(Scalar::ZERO);
     L.blockages = Some(Scalar::ZERO);
-    match open_invitation::prepare(&mut rng, L) {
+    match open_invitation::prepare(&mut *rng, L) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }
@@ -63,6 +63,7 @@ impl BridgeAuth {
         // Check the signature on the open_invite, first with the old key, then with the new key.
         // We manually match here because we're changing the Err type from SignatureError
         // to ProofError
+        let mut rng = rand::thread_rng();
         let mut old_token: Option<((Scalar, u32), usize)> = Default::default();
         let invite_id: Scalar;
         let bucket_id: u32;
@@ -114,7 +115,6 @@ impl BridgeAuth {
             ));
         }
 
-        let mut rng = rand::thread_rng();
         let reqbytes = req.as_bytes();
         // Create the bucket attribute (Scalar), which is a combination
         // of the bucket id (u32) and the bucket's decryption key ([u8; 16])
@@ -161,7 +161,8 @@ mod tests {
     #[test]
     fn test_open_invitation() {
         let mut th = TestHarness::new();
-        let open_invitation_request = request(th.ba.lox_pub.clone());
+        let mut rng = rand::thread_rng();
+        let open_invitation_request = request(&mut rng, th.ba.lox_pub.clone());
         assert!(
             open_invitation_request.is_ok(),
             "Open invitation request should succeed"
@@ -173,8 +174,9 @@ mod tests {
             open_invitation_response.is_ok(),
             "Open invitation response from server should succeed"
         );
-        let (response, bridgeline) = open_invitation_response.unwrap();
+        let (response, _) = open_invitation_response.unwrap();
         let creds = handle_response(client_state, response);
         assert!(creds.is_ok(), "Handle response should succeed");
+        th.verify_lox(&creds.unwrap());
     }
 }

+ 4 - 7
src/proto/redeem_invite.rs

@@ -27,11 +27,12 @@ use super::super::dup_filter::SeenType;
 use super::super::BridgeAuth;
 use super::super::{scalar_u32, Scalar, G};
 use super::errors::CredentialError;
+#[cfg(feature = "bridgeauth")]
 use super::level_up::LEVEL_INVITATIONS;
 use crate::lox_creds::{Invitation, Lox};
 use cmz::*;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 /// Invitations must be used within this many days of being issued.
@@ -42,8 +43,7 @@ pub const INVITATION_EXPIRY: u32 = 15;
 muCMZProtocol! { redeem_invite<credential_expiry, today>,
     [ I: Invitation { inv_id: R, date: H, bucket: H, blockages: H } ],
     N: Lox {id: J, bucket: H, trust_level: I, level_since: S, invites_remaining: I, blockages: H },
-    //credential_expiry <= I.date,
-    //I.date <= today,
+    [credential_expiry..today].contains(I.date),
     N.bucket = I.bucket,
     N.blockages = I.blockages,
 }
@@ -79,15 +79,12 @@ pub fn request(
         ));
     }
 
-    let mut N = Lox::using_pubkey(&lox_pubkeys);
-    N.trust_level = Some(Scalar::ONE);
-    N.invites_remaining = Some(LEVEL_INVITATIONS[1].into());
     let params = redeem_invite::Params {
         credential_expiry: (today - INVITATION_EXPIRY).into(),
         today: today.into(),
     };
 
-    match redeem_invite::prepare(&mut rng, &I, N, &params) {
+    match redeem_invite::prepare(&mut rng, &I, Lox::using_pubkey(&lox_pubkeys), &params) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }

+ 3 - 5
src/proto/trust_promotion.rs

@@ -42,7 +42,7 @@ use cmz::*;
 use group::Group;
 #[cfg(feature = "bridgeauth")]
 use group::WnafBase;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 use std::collections::HashMap;
 
@@ -64,11 +64,11 @@ muCMZProtocol! { trust_promotion<credential_expiry, eligibility_max_age>,
 }
 
 pub fn request(
+    rng: &mut (impl CryptoRng + RngCore),
     L: Lox,
     mig_pubkeys: CMZPubkey<G>,
     today: u32,
 ) -> Result<(trust_promotion::Request, trust_promotion::ClientState), CredentialError> {
-    let mut rng = rand::thread_rng();
     cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
 
     // Ensure that the credenials can be correctly shown; that is, the
@@ -102,13 +102,12 @@ pub fn request(
     }
     let eligibility_max_age = today - UNTRUSTED_INTERVAL;
 
-    let M = MigrationKey::using_pubkey(&mig_pubkeys);
     let params = trust_promotion::Params {
         credential_expiry: (eligibility_max_age - 511).into(),
         eligibility_max_age: eligibility_max_age.into(),
     };
 
-    match trust_promotion::prepare(&mut rng, &L, M, &params) {
+    match trust_promotion::prepare(rng, &L, MigrationKey::using_pubkey(&mig_pubkeys), &params) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }
@@ -129,7 +128,6 @@ impl BridgeAuth {
         let mut rng = rand::thread_rng();
         let reqbytes = req.as_bytes();
         let recvreq = trust_promotion::Request::try_from(&reqbytes[..]).unwrap();
-
         let today = self.today();
         match trust_promotion::handle(
             &mut rng,

+ 5 - 7
src/proto/update_cred.rs

@@ -34,7 +34,7 @@ use crate::lox_creds::Lox;
 use cmz::*;
 use curve25519_dalek::ristretto::RistrettoPoint as G;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 muCMZProtocol! { update_cred,
@@ -48,14 +48,13 @@ muCMZProtocol! { update_cred,
 }
 
 pub fn request(
+    rng: &mut (impl CryptoRng + RngCore),
     L: Lox,
     pubkeys: CMZPubkey<G>,
 ) -> Result<(update_cred::Request, update_cred::ClientState), CredentialError> {
-    let mut rng = rand::thread_rng();
     cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
 
-    let N = Lox::using_pubkey(&pubkeys);
-    match update_cred::prepare(&mut rng, &L, N) {
+    match update_cred::prepare(&mut *rng, &L, Lox::using_pubkey(&pubkeys)) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }
@@ -65,10 +64,9 @@ pub fn request(
 impl BridgeAuth {
     pub fn handle_update_cred(
         &mut self,
+        rng: &mut (impl CryptoRng + RngCore),
         req: update_cred::Request,
     ) -> Result<update_cred::Reply, CredentialError> {
-        let mut rng = rand::thread_rng();
-
         // Both of these must be true and should be true after rotate_lox_keys is called
         if self.old_keys.lox_keys.is_empty() || self.old_filters.lox_filter.is_empty() {
             return Err(CredentialError::CredentialMismatch);
@@ -77,7 +75,7 @@ impl BridgeAuth {
         let reqbytes = req.as_bytes();
         let recvreq = update_cred::Request::try_from(&reqbytes[..]).unwrap();
         match update_cred::handle(
-            &mut rng,
+            &mut *rng,
             recvreq,
             |L: &mut Lox, N: &mut Lox| {
                 // calling this function will automatically use the most recent old private key for

+ 5 - 6
src/proto/update_invite.rs

@@ -28,7 +28,7 @@ use crate::lox_creds::Invitation;
 use cmz::*;
 use curve25519_dalek::ristretto::RistrettoPoint as G;
 use group::Group;
-use rand_core::RngCore;
+use rand::{CryptoRng, RngCore};
 use sha2::Sha512;
 
 muCMZProtocol! { update_invite,
@@ -40,14 +40,13 @@ muCMZProtocol! { update_invite,
 }
 
 pub fn request(
+    rng: &mut (impl CryptoRng + RngCore),
     I: Invitation,
     new_pubkeys: CMZPubkey<G>,
 ) -> Result<(update_invite::Request, update_invite::ClientState), CredentialError> {
-    let mut rng = rand::thread_rng();
     cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
 
-    let N = Invitation::using_pubkey(&new_pubkeys);
-    match update_invite::prepare(&mut rng, &I, N) {
+    match update_invite::prepare(&mut *rng, &I, Invitation::using_pubkey(&new_pubkeys)) {
         Ok(req_state) => Ok(req_state),
         Err(e) => Err(CredentialError::CMZError(e)),
     }
@@ -57,9 +56,9 @@ pub fn request(
 impl BridgeAuth {
     pub fn handle_update_invite(
         &mut self,
+        rng: &mut (impl CryptoRng + RngCore),
         req: update_invite::Request,
     ) -> Result<update_invite::Reply, CredentialError> {
-        let mut rng = rand::thread_rng();
         // Both of these must be true and should be true after rotate_lox_keys is called
         if self.old_keys.invitation_keys.is_empty() || self.old_filters.invitation_filter.is_empty()
         {
@@ -69,7 +68,7 @@ impl BridgeAuth {
         let reqbytes = req.as_bytes();
         let recvreq = update_invite::Request::try_from(&reqbytes[..]).unwrap();
         match update_invite::handle(
-            &mut rng,
+            &mut *rng,
             recvreq,
             |I: &mut Invitation, N: &mut Invitation| {
                 // calling this function will automatically use the most recent old private key for