Browse Source

Change encbuckets to HashMap with EncryptedBucket

onyinyang 2 years ago
parent
commit
69e4579450

+ 40 - 41
Cargo.lock

@@ -223,9 +223,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
 
 [[package]]
 name = "cpufeatures"
-version = "0.2.7"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
+checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
 dependencies = [
  "libc",
 ]
@@ -701,9 +701,9 @@ dependencies = [
 
 [[package]]
 name = "iana-time-zone"
-version = "0.1.56"
+version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c"
+checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
 dependencies = [
  "android_system_properties",
  "core-foundation-sys",
@@ -783,9 +783,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
 
 [[package]]
 name = "js-sys"
-version = "0.3.61"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -844,9 +844,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.18"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de"
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
 
 [[package]]
 name = "lox-distributor"
@@ -865,7 +865,7 @@ dependencies = [
  "serde",
  "serde_json",
  "serde_with",
- "time 0.3.21",
+ "time 0.3.22",
  "tokio",
  "zkp",
 ]
@@ -889,7 +889,7 @@ dependencies = [
  "statistical",
  "subtle",
  "thiserror",
- "time 0.3.21",
+ "time 0.3.22",
  "zkp",
 ]
 
@@ -906,7 +906,7 @@ dependencies = [
  "lox_utils",
  "rand 0.7.3",
  "serde_json",
- "time 0.3.21",
+ "time 0.3.22",
  "wasm-bindgen",
  "zkp",
 ]
@@ -1075,9 +1075,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.54"
+version = "0.10.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019"
+checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
 dependencies = [
  "bitflags",
  "cfg-if",
@@ -1107,9 +1107,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.88"
+version = "0.9.90"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617"
+checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
 dependencies = [
  "cc",
  "libc",
@@ -1193,9 +1193,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.59"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
@@ -1464,9 +1464,9 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.37.19"
+version = "0.37.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
 dependencies = [
  "bitflags",
  "errno",
@@ -1551,9 +1551,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.96"
+version = "1.0.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a"
 dependencies = [
  "itoa",
  "ryu",
@@ -1585,7 +1585,7 @@ dependencies = [
  "serde",
  "serde_json",
  "serde_with_macros",
- "time 0.3.21",
+ "time 0.3.22",
 ]
 
 [[package]]
@@ -1750,9 +1750,9 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.21"
+version = "0.3.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc"
+checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd"
 dependencies = [
  "itoa",
  "serde",
@@ -1949,11 +1949,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "want"
-version = "0.3.0"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
 dependencies = [
- "log",
  "try-lock",
 ]
 
@@ -1977,9 +1976,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
 
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
 dependencies = [
  "cfg-if",
  "wasm-bindgen-macro",
@@ -1987,9 +1986,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
 dependencies = [
  "bumpalo",
  "log",
@@ -2002,9 +2001,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.34"
+version = "0.4.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
 dependencies = [
  "cfg-if",
  "js-sys",
@@ -2014,9 +2013,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
 dependencies = [
  "quote",
  "wasm-bindgen-macro-support",
@@ -2024,9 +2023,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2037,9 +2036,9 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.86"
+version = "0.2.87"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
 
 [[package]]
 name = "wasm-streams"
@@ -2056,9 +2055,9 @@ dependencies = [
 
 [[package]]
 name = "web-sys"
-version = "0.3.61"
+version = "0.3.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
 dependencies = [
  "js-sys",
  "wasm-bindgen",

+ 3 - 3
crates/lox-distributor/src/lox_context.rs

@@ -1,7 +1,7 @@
 use hyper::{body::Bytes, header::HeaderValue, Body, Response};
 
 use lox_library::{
-    bridge_table::{BridgeLine, ENC_BUCKET_BYTES, MAX_BRIDGES_PER_BUCKET},
+    bridge_table::{BridgeLine, EncryptedBucket, MAX_BRIDGES_PER_BUCKET},
     proto::{
         blockage_migration, check_blockage, issue_invite, level_up, migration, open_invite,
         redeem_invite, trust_promotion,
@@ -9,7 +9,7 @@ use lox_library::{
     BridgeAuth, BridgeDb, IssuerPubKey,
 };
 use lox_utils;
-use std::sync::{Arc, Mutex};
+use std::{sync::{Arc, Mutex}, collections::HashMap};
 use zkp::ProofError;
 
 #[derive(Clone)]
@@ -99,7 +99,7 @@ impl LoxServerContext {
         println!("Today's date according to server: {}", ba_obj.today());
     }
 
-    pub fn encrypt_table(&self) -> Vec<[u8; ENC_BUCKET_BYTES]> {
+    pub fn encrypt_table(&self) -> HashMap<u32, EncryptedBucket> {
         let mut ba_obj = self.ba.lock().unwrap();
         ba_obj.enc_bridge_table().clone()
     }

+ 2 - 2
crates/lox-distributor/src/request_handler.rs

@@ -258,7 +258,7 @@ mod tests {
             let mut lox_auth = self.context.ba.lock().unwrap();
             let encbuckets = lox_auth.enc_bridge_table();
             let bucket =
-                bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize])
+                bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets.get(&id).unwrap())
                     .unwrap();
             assert!(bucket.1.is_some());
             // Block two of our bridges
@@ -272,7 +272,7 @@ mod tests {
             let mut lox_auth = self.context.ba.lock().unwrap();
             let encbuckets2 = lox_auth.enc_bridge_table();
             let bucket2 =
-                bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets2[id as usize])
+                bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets2.get(&id).unwrap())
                     .unwrap();
             // We should no longer have a Bridge Reachability credential
             assert!(bucket2.1.is_none());

+ 53 - 13
crates/lox-library/src/bridge_table.rs

@@ -7,7 +7,6 @@ with a bucket key.  Users will have a credential containing a bucket
 buckets.  Users will either download the whole encrypted bucket list or
 use PIR to download a piece of it, so that the bridge authority does not
 learn which bucket the user has access to. */
-
 use super::cred;
 use super::IssuerPrivKey;
 use super::CMZ_B_TABLE;
@@ -21,7 +20,7 @@ use rand::RngCore;
 use serde::{Deserialize, Serialize};
 use serde_with::serde_as;
 use std::collections::{HashMap, HashSet};
-use std::convert::TryInto;
+use std::convert::{TryInto, TryFrom};
 use subtle::ConstantTimeEq;
 
 /// Each bridge information line is serialized into this many bytes
@@ -205,20 +204,47 @@ impl BridgeLine {
     }
 }
 
+#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
+#[serde(try_from="Vec<u8>", into="Vec<u8>")]
+pub struct EncryptedBucket([u8; ENC_BUCKET_BYTES]);
+
+impl From<EncryptedBucket> for Vec<u8> {
+    fn from(e: EncryptedBucket) -> Vec<u8> {
+        e.0.into()
+    }
+}
+
+#[derive(thiserror::Error, Debug)]
+#[error("wrong slice length")]
+pub struct WrongSliceLengthError;
+
+impl TryFrom<Vec<u8>> for EncryptedBucket {
+    type Error = WrongSliceLengthError;
+    fn try_from(v: Vec<u8>) -> Result<EncryptedBucket, Self::Error> {
+        Ok(EncryptedBucket(*Box::<[u8; ENC_BUCKET_BYTES]>::try_from(v).map_err(|_| WrongSliceLengthError)?))
+    }
+}
+
+#[derive(Serialize, Deserialize)]
+struct K {
+    encbucket: EncryptedBucket,
+    vec: Vec<u8>,
+}
+
+
 /// A BridgeTable is the internal structure holding the buckets
 /// containing the bridges, the keys used to encrypt the buckets, and
 /// the encrypted buckets.  The encrypted buckets will be exposed to the
 /// users of the system, and each user credential will contain the
 /// decryption key for one bucket.
-#[serde_as]
+//#[serde_as]
 #[derive(Debug, Default, Serialize, Deserialize)]
 pub struct BridgeTable {
     // All structures in the bridgetable are indexed by counter
     pub counter: u32,
     pub keys: HashMap<u32, [u8; 16]>,
     pub buckets: HashMap<u32, [BridgeLine; MAX_BRIDGES_PER_BUCKET]>,
-    #[serde_as(as = "Vec<[_; ENC_BUCKET_BYTES]>")]
-    pub encbuckets: Vec<[u8; ENC_BUCKET_BYTES]>,
+    pub encbuckets: HashMap<u32, EncryptedBucket>,
     /// Individual bridges that are reachable
     pub reachable: HashMap<BridgeLine, Vec<(u32, usize)>>,
     /// bucket ids of "hot spare" buckets.  These buckets are not handed
@@ -279,8 +305,6 @@ impl BridgeTable {
     pub fn encrypt_table(&mut self, today: u32, reachability_priv: &IssuerPrivKey) {
         let mut rng = rand::thread_rng();
         self.encbuckets.clear();
-        // We want id to be a u32, so we use .zip(0u32..) instead of
-        // enumerate()
         for (uid, key) in self.keys.iter() {
             let bucket = self.buckets.get(uid).unwrap();
             let mut encbucket: [u8; ENC_BUCKET_BYTES] = [0; ENC_BUCKET_BYTES];
@@ -302,7 +326,8 @@ impl BridgeTable {
             let ciphertext: Vec<u8> = cipher.encrypt(nonce, plainbucket.as_ref()).unwrap();
             encbucket[0..12].copy_from_slice(&noncebytes);
             encbucket[12..].copy_from_slice(ciphertext.as_slice());
-            self.encbuckets.push(encbucket);
+            let k = EncryptedBucket(encbucket);
+            self.encbuckets.insert(*uid, k);
         }
         self.date_last_enc = today;
     }
@@ -312,14 +337,24 @@ impl BridgeTable {
     pub fn decrypt_bucket(
         id: u32,
         key: &[u8; 16],
-        encbucket: &[u8; ENC_BUCKET_BYTES],
+        encbucket: &EncryptedBucket,
     ) -> Result<Bucket, aead::Error> {
         // Set the nonce and the key
-        let nonce = GenericArray::from_slice(&encbucket[0..12]);
+        println!("Trying to decrypt");
+        let k = K {
+            encbucket: *encbucket,
+            vec: (0x20..0x30).collect(),
+        };
+        println!("Made EncryptedBucket");
+        let nonce = GenericArray::from_slice(&k.vec[0..12]);
+        println!("got nonce: {:?}", nonce);
         let aeskey = GenericArray::from_slice(key);
+        println!("got aeskey: {:?}", aeskey);
         // Decrypt
         let cipher = Aes128Gcm::new(aeskey);
-        let plaintext: Vec<u8> = cipher.decrypt(nonce, encbucket[12..].as_ref())?;
+        println!("got cipher");
+        let plaintext: Vec<u8> = cipher.decrypt(nonce,k.vec[12..].as_ref())?;
+        println!("got plaintext {:?}", plaintext);
         // Convert the plaintext bytes to an array of BridgeLines
         Ok(BridgeLine::bucket_decode(
             plaintext.as_slice().try_into().unwrap(),
@@ -329,8 +364,11 @@ impl BridgeTable {
 
     /// Decrypt an individual encrypted bucket, given its id and key
     pub fn decrypt_bucket_id(&self, id: u32, key: &[u8; 16]) -> Result<Bucket, aead::Error> {
-        let encbucket = self.encbuckets[id as usize];
-        BridgeTable::decrypt_bucket(id, key, &encbucket)
+        let encbucket:&EncryptedBucket = match self.encbuckets.get(&id) {
+            Some(encbucket) => encbucket,
+            None => panic!("Provided ID not found"),
+        };
+        BridgeTable::decrypt_bucket(id, key, encbucket)
     }
 }
 
@@ -370,7 +408,9 @@ mod tests {
         btable.encrypt_table(today, &reachability_priv);
         // Try to decrypt a 1-bridge bucket
         let key7 = btable.keys[&7u32];
+        println!("Got Key");
         let bucket7 = btable.decrypt_bucket_id(7, &key7)?;
+        println!("Decrypted");
         println!("bucket 7 = {:?}", bucket7);
         // Try to decrypt a 3-bridge bucket
         let key24 = btable.keys[&24u32];

+ 10 - 7
crates/lox-library/src/lib.rs

@@ -27,7 +27,7 @@ use sha2::Sha512;
 use rand::rngs::OsRng;
 use rand::Rng;
 use std::convert::{TryFrom, TryInto};
-
+use std::collections::HashMap;
 use curve25519_dalek::constants as dalek_constants;
 use curve25519_dalek::ristretto::RistrettoBasepointTable;
 use curve25519_dalek::ristretto::RistrettoPoint;
@@ -41,7 +41,7 @@ use subtle::ConstantTimeEq;
 use std::collections::HashSet;
 
 use bridge_table::{
-    BridgeLine, BridgeTable, ENC_BUCKET_BYTES, MAX_BRIDGES_PER_BUCKET, MIN_BUCKET_REACHABILITY,
+    BridgeLine, BridgeTable, EncryptedBucket, MAX_BRIDGES_PER_BUCKET, MIN_BUCKET_REACHABILITY,
 };
 use migration_table::{MigrationTable, MigrationType};
 
@@ -410,7 +410,7 @@ impl BridgeAuth {
             Some(positions) => {
                 if let Some(replacement) = available_bridge {
                     for (bucketnum, offset) in positions.iter() {
-                        let bridgelines = match self.bridge_table.buckets.get(bucketnum) {
+                        let mut bridgelines = match self.bridge_table.buckets.get(bucketnum) {
                             Some(bridgelines) => *bridgelines,
                             None => return ReplaceSuccess::NotFound,
                         };
@@ -428,7 +428,7 @@ impl BridgeAuth {
                 } else if !self.bridge_table.unallocated_bridges.is_empty() {
                     let replacement = &self.bridge_table.unallocated_bridges.pop().unwrap();
                     for (bucketnum, offset) in positions.iter() {
-                        let bridgelines = match self.bridge_table.buckets.get(bucketnum) {
+                        let mut bridgelines = match self.bridge_table.buckets.get(bucketnum) {
                             Some(bridgelines) => *bridgelines,
                             // This should not happen if the rest of the function is correct, we can assume unwrap will succeed
                             None => return ReplaceSuccess::NotReplaced,
@@ -468,7 +468,7 @@ impl BridgeAuth {
                         }
                     }
                     for (bucketnum, offset) in positions.iter() {
-                        let bridgelines = match self.bridge_table.buckets.get(&bucketnum) {
+                        let mut bridgelines = match self.bridge_table.buckets.get(&bucketnum) {
                             Some(bridgelines) => *bridgelines,
                             None => return ReplaceSuccess::NotReplaced,
                         };
@@ -526,7 +526,10 @@ impl BridgeAuth {
             if let Some(v) = positions {
                 for (bucketnum, offset) in v.iter() {
                     // Count how many bridges in this bucket are reachable
-                    let mut bucket = self.bridge_table.buckets.get(bucketnum).unwrap();
+                    let mut bucket = match self.bridge_table.buckets.get(&bucketnum) {
+                        Some(bridgelines) => *bridgelines,
+                        None => return false,
+                    };
                     let numreachable = bucket
                         .iter()
                         .filter(|br| self.bridge_table.reachable.get(br).is_some())
@@ -619,7 +622,7 @@ impl BridgeAuth {
     /// Be sure to call this function when you want the latest version
     /// of the table, since it will put fresh Bucket Reachability
     /// credentials in the buckets each day.
-    pub fn enc_bridge_table(&mut self) -> &Vec<[u8; ENC_BUCKET_BYTES]> {
+    pub fn enc_bridge_table(&mut self) -> &HashMap<u32, EncryptedBucket>{
         let today = self.today();
         if self.bridge_table.date_last_enc != today {
             self.bridge_table

+ 7 - 7
crates/lox-library/src/tests.rs

@@ -171,7 +171,7 @@ impl TestHarness {
         let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
         let encbuckets = self.ba.enc_bridge_table();
         let bucket =
-            bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
+            bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets.get(&id).unwrap()).unwrap();
         let reachcred = bucket.1.unwrap();
 
         // Use the Bucket Reachability credential to advance to the next
@@ -219,7 +219,7 @@ impl TestHarness {
         let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
         let encbuckets = self.ba.enc_bridge_table();
         let bucket =
-            bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
+            bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets.get(&id).unwrap()).unwrap();
         let reachcred = bucket.1.unwrap();
 
         let req_start = Instant::now();
@@ -379,7 +379,7 @@ fn test_open_invite() {
     let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
     let encbuckets = th.ba.enc_bridge_table();
     let bucket =
-        bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
+        bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets.get(&id).unwrap()).unwrap();
     print_test_results(perf_stat);
     println!("cred = {:?}", cred);
     println!("bucket = {:?}", bucket);
@@ -407,7 +407,7 @@ fn test_trust_promotion() {
     let (id, key) = bridge_table::from_scalar(migcred.to_bucket).unwrap();
     let encbuckets = th.ba.enc_bridge_table();
     let bucket =
-        bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
+        bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets.get(&id).unwrap()).unwrap();
     print_test_results(perf_stat);
     println!("bucket = {:?}", bucket);
     assert!(th.ba.verify_reachability(&bucket.1.unwrap()));
@@ -439,7 +439,7 @@ fn test_level0_migration() {
     let (id, key) = bridge_table::from_scalar(newloxcred.bucket).unwrap();
     let encbuckets = th.ba.enc_bridge_table();
     let bucket =
-        bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
+        bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets.get(&id).unwrap()).unwrap();
     println!("bucket = {:?}", bucket);
     assert!(th.ba.verify_reachability(&bucket.1.unwrap()));
 }
@@ -999,7 +999,7 @@ fn test_blockage_migration() {
     let (id, key) = bridge_table::from_scalar(cred3.bucket).unwrap();
     let encbuckets = th.ba.enc_bridge_table();
     let bucket =
-        bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
+        bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets.get(&id).unwrap()).unwrap();
     // We should have a Bridge Reachability credential
     assert!(bucket.1.is_some());
 
@@ -1017,7 +1017,7 @@ fn test_blockage_migration() {
 
     let encbuckets2 = th.ba.enc_bridge_table();
     let bucket2 =
-        bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets2[id as usize]).unwrap();
+        bridge_table::BridgeTable::decrypt_bucket(id, &key, encbuckets2.get(&id).unwrap()).unwrap();
     // We should no longer have a Bridge Reachability credential
     assert!(bucket2.1.is_none());
 

+ 4 - 4
crates/lox-utils/src/lib.rs

@@ -1,10 +1,11 @@
-use lox_library::bridge_table::{from_scalar, BridgeLine, BridgeTable, ENC_BUCKET_BYTES};
+use lox_library::bridge_table::{from_scalar, BridgeLine, BridgeTable, EncryptedBucket};
 use lox_library::cred::{BucketReachability, Invitation, Lox};
 use lox_library::proto;
 use lox_library::{IssuerPubKey, OPENINV_LENGTH};
 use serde::{Deserialize, Serialize};
 use serde_with::serde_as;
 use std::array::TryFromSliceError;
+use std::collections::HashMap;
 
 #[serde_as]
 #[derive(Serialize, Deserialize)]
@@ -73,8 +74,7 @@ pub struct PubKeys {
 #[serde_as]
 #[derive(Serialize, Deserialize)]
 pub struct EncBridgeTable {
-    #[serde_as(as = "Vec<[_; ENC_BUCKET_BYTES]>")]
-    pub etable: Vec<[u8; ENC_BUCKET_BYTES]>,
+    pub etable: HashMap<u32, EncryptedBucket>,
 }
 
 #[derive(Debug, Deserialize, Serialize)]
@@ -92,7 +92,7 @@ pub fn validate(invite: &[u8]) -> Result<[u8; OPENINV_LENGTH], TryFromSliceError
 pub fn generate_reachability_cred(lox_cred: &Lox, encrypted_table: String) -> BucketReachability {
     let (id, key) = from_scalar(lox_cred.bucket).unwrap();
     let enc_buckets: EncBridgeTable = serde_json::from_str(&encrypted_table).unwrap();
-    let bucket = BridgeTable::decrypt_bucket(id, &key, &enc_buckets.etable[id as usize]).unwrap();
+    let bucket = BridgeTable::decrypt_bucket(id, &key, enc_buckets.etable.get(&id).unwrap()).unwrap();
     bucket.1.unwrap()
 }