Converting bridgetable vectors to HashMaps
This commit is contained in:
parent
73c3ef8728
commit
607ecd89c7
|
@ -213,8 +213,10 @@ impl BridgeLine {
|
|||
#[serde_as]
|
||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||
pub struct BridgeTable {
|
||||
pub keys: Vec<[u8; 16]>,
|
||||
pub buckets: Vec<[BridgeLine; MAX_BRIDGES_PER_BUCKET]>,
|
||||
// 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]>,
|
||||
/// Individual bridges that are reachable
|
||||
|
@ -249,20 +251,21 @@ impl BridgeTable {
|
|||
self.buckets.len()
|
||||
}
|
||||
|
||||
// TODO Don't need with hashmaps, but remove unused buckets
|
||||
pub fn recycle_bucket(&mut self, bucket: &[BridgeLine; MAX_BRIDGES_PER_BUCKET], index: u32) {
|
||||
// Pick a random key to encrypt this bucket
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut key: [u8; 16] = [0; 16];
|
||||
rng.fill_bytes(&mut key);
|
||||
self.keys[index as usize] = key;
|
||||
self.buckets[index as usize] = *bucket;
|
||||
for (i, b) in bucket.iter().enumerate() {
|
||||
if b.port > 0 {
|
||||
if let Some(v) = self.reachable.get_mut(b) {
|
||||
let key = self.keys.get(&index).unwrap();
|
||||
let bucket = *self.buckets.get(&index).unwrap();
|
||||
for (i, bridgeline) in bucket.iter().enumerate() {
|
||||
if bridgeline.port > 0 {
|
||||
if let Some(v) = self.reachable.get_mut(bridgeline) {
|
||||
v.push((index, i));
|
||||
} else {
|
||||
let v = vec![(index, i)];
|
||||
self.reachable.insert(*b, v);
|
||||
self.reachable.insert(*bridgeline, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -274,21 +277,23 @@ impl BridgeTable {
|
|||
let mut rng = rand::thread_rng();
|
||||
let mut key: [u8; 16] = [0; 16];
|
||||
rng.fill_bytes(&mut key);
|
||||
self.keys.push(key);
|
||||
self.buckets.push(*bucket);
|
||||
let bucketnum: u32 = (self.buckets.len() - 1).try_into().unwrap();
|
||||
// Increase the counter to identify the bucket, wrap value if beyond u32::MAX
|
||||
self.counter = self.counter.wrapping_add(1);
|
||||
self.keys.insert(self.counter, key);
|
||||
self.buckets.insert(self.counter, *bucket);
|
||||
// TODO: maybe we don't need this if the hashtable can keep track of available bridges
|
||||
// Mark the new bridges as available
|
||||
for (i, b) in bucket.iter().enumerate() {
|
||||
if b.port > 0 {
|
||||
if let Some(v) = self.reachable.get_mut(b) {
|
||||
v.push((bucketnum, i));
|
||||
v.push((self.counter, i));
|
||||
} else {
|
||||
let v = vec![(bucketnum, i)];
|
||||
let v = vec![(self.counter, i)];
|
||||
self.reachable.insert(*b, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
bucketnum
|
||||
self.counter
|
||||
}
|
||||
|
||||
/// Create the vector of encrypted buckets from the keys and buckets
|
||||
|
@ -303,13 +308,14 @@ impl BridgeTable {
|
|||
self.encbuckets.clear();
|
||||
// We want id to be a u32, so we use .zip(0u32..) instead of
|
||||
// enumerate()
|
||||
for ((key, bucket), id) in self.keys.iter().zip(self.buckets.iter()).zip(0u32..) {
|
||||
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];
|
||||
let plainbucket: [u8; BUCKET_BYTES] = BridgeLine::bucket_encode(
|
||||
bucket,
|
||||
&self.reachable,
|
||||
today,
|
||||
&to_scalar(id, key),
|
||||
&to_scalar(*uid, key),
|
||||
reachability_priv,
|
||||
);
|
||||
// Set the AES key
|
||||
|
@ -390,15 +396,15 @@ mod tests {
|
|||
// Create the encrypted bridge table
|
||||
btable.encrypt_table(today, &reachability_priv);
|
||||
// Try to decrypt a 1-bridge bucket
|
||||
let key7 = btable.keys[7];
|
||||
let key7 = btable.keys[&7u32];
|
||||
let bucket7 = btable.decrypt_bucket_id(7, &key7)?;
|
||||
println!("bucket 7 = {:?}", bucket7);
|
||||
// Try to decrypt a 3-bridge bucket
|
||||
let key24 = btable.keys[24];
|
||||
let key24 = btable.keys[&24u32];
|
||||
let bucket24 = btable.decrypt_bucket_id(24, &key24)?;
|
||||
println!("bucket 24 = {:?}", bucket24);
|
||||
// Try to decrypt a bucket with the wrong key
|
||||
let key12 = btable.keys[12];
|
||||
let key12 = btable.keys[&12u32];
|
||||
let res = btable.decrypt_bucket_id(15, &key12).unwrap_err();
|
||||
println!("bucket key mismatch = {:?}", res);
|
||||
Ok(())
|
||||
|
|
|
@ -380,14 +380,22 @@ impl BridgeAuth {
|
|||
if let Some(v) = positions {
|
||||
for (bucketnum, offset) in v.iter() {
|
||||
println!("Bucket num: {:?} and offset: {:?}", bucketnum, offset);
|
||||
let bridgelines = match self.bridge_table.buckets.get(bucketnum) {
|
||||
Some(bridgelines) => *bridgelines,
|
||||
None => return res
|
||||
};
|
||||
assert!(
|
||||
self.bridge_table.buckets[*bucketnum as usize][*offset]
|
||||
bridgelines[*offset]
|
||||
== reachable_bridge.0
|
||||
);
|
||||
self.bridge_table.buckets[*bucketnum as usize][*offset] = *bridge;
|
||||
assert!(self.bridge_table.buckets[*bucketnum as usize][*offset] == *bridge);
|
||||
bridgelines[*offset] = *bridge;
|
||||
self.bridge_table.buckets.insert(*bucketnum, bridgelines);
|
||||
let bridgelines = match self.bridge_table.buckets.get(bucketnum) {
|
||||
Some(bridgelines) => *bridgelines,
|
||||
None => return res
|
||||
};
|
||||
assert!(
|
||||
self.bridge_table.buckets[*bucketnum as usize][*offset]
|
||||
bridgelines[*offset]
|
||||
!= reachable_bridge.0
|
||||
);
|
||||
}
|
||||
|
@ -418,23 +426,33 @@ impl BridgeAuth {
|
|||
let reachable_bridges = &self.bridge_table.reachable.clone();
|
||||
match reachable_bridges.get(bridge) {
|
||||
Some(positions) => {
|
||||
println!("Should not get here");
|
||||
if let Some(replacement) = available_bridge {
|
||||
for (bucketnum, offset) in positions.iter() {
|
||||
assert!(self.bridge_table.buckets[*bucketnum as usize][*offset] == *bridge);
|
||||
self.bridge_table.buckets[*bucketnum as usize][*offset] = *replacement;
|
||||
let bridgelines = match self.bridge_table.buckets.get(bucketnum) {
|
||||
Some(bridgelines) => *bridgelines,
|
||||
None => return ReplaceSuccess::NotFound,
|
||||
};
|
||||
assert!(bridgelines[*offset] == *bridge);
|
||||
bridgelines[*offset] = *replacement;
|
||||
self.bridge_table.buckets.insert(*bucketnum, bridgelines);
|
||||
// Remove the bridge from the reachable bridges and add new bridge
|
||||
self.bridge_table
|
||||
.reachable
|
||||
.insert(*replacement, positions.clone());
|
||||
// Remove the bridge from the bucket
|
||||
self.bridge_table.reachable.remove(bridge);
|
||||
res = ReplaceSuccess::Replaced
|
||||
}
|
||||
res = ReplaceSuccess::Replaced
|
||||
} else if !self.bridge_table.unallocated_bridges.is_empty() {
|
||||
let replacement = &self.bridge_table.unallocated_bridges.pop().unwrap();
|
||||
for (bucketnum, offset) in positions.iter() {
|
||||
self.bridge_table.buckets[*bucketnum as usize][*offset] = *replacement;
|
||||
let bridgelines = match self.bridge_table.buckets.get(bucketnum) {
|
||||
Some(bridgelines) => *bridgelines,
|
||||
None => return ReplaceSuccess::NotFound,
|
||||
};
|
||||
assert!(bridgelines[*offset] == *bridge);
|
||||
bridgelines[*offset] = *replacement;
|
||||
self.bridge_table.buckets.insert(*bucketnum, bridgelines);
|
||||
self.bridge_table
|
||||
.reachable
|
||||
.insert(*replacement, positions.clone());
|
||||
|
@ -446,10 +464,8 @@ impl BridgeAuth {
|
|||
// Get the first spare and remove it from the spares set.
|
||||
let spare = *self.bridge_table.spares.iter().next().unwrap();
|
||||
self.bridge_table.spares.remove(&spare);
|
||||
// Indicate the removed bucket as a recyclable bucket
|
||||
self.bridge_table.recyclable.insert(spare);
|
||||
// Get the actual bridges from the spare bucket
|
||||
let spare_bucket = self.bridge_table.buckets[spare as usize];
|
||||
let spare_bucket = self.bridge_table.buckets[&spare];
|
||||
let mut replacement: &BridgeLine = &BridgeLine::default();
|
||||
// Make the first spare the replacement bridge, add the others to the set of
|
||||
// unallocated_bridges
|
||||
|
|
|
@ -196,10 +196,11 @@ impl BridgeAuth {
|
|||
|
||||
// Create the bucket attribute (Scalar), which is a combination
|
||||
// of the bucket id (u32) and the bucket's decryption key ([u8; 16])
|
||||
let bucket_key = self.bridge_table.keys[bucket_id];
|
||||
let bucket_key = self.bridge_table.keys.get(&bucket_id_u32).unwrap();
|
||||
let bucket: Scalar = bridge_table::to_scalar(bucket_id_u32, &bucket_key);
|
||||
let bridge_line = self.bridge_table.buckets[bucket_id][0];
|
||||
|
||||
let bridge_lines = self.bridge_table.buckets.get(&bucket_id_u32).unwrap();
|
||||
let bridge_line = bridge_lines[0];
|
||||
|
||||
// Create the level_since attribute (Scalar), which is today's
|
||||
// Julian date
|
||||
let level_since: Scalar = self.today().into();
|
||||
|
|
Loading…
Reference in New Issue