Browse Source

Change H each day

Vecna 2 weeks ago
parent
commit
47f0dbfaad

File diff suppressed because it is too large
+ 0 - 0
crates/lox-distributor/db_test_file.json


+ 29 - 1
crates/lox-extensions/src/bridge_table.rs

@@ -279,12 +279,25 @@ pub struct BridgeTable {
     /// the Hash trait.
     #[cfg(any(feature = "bridgeauth", test))]
     pub bucket_H_map: HashMap<String, Scalar>,
+    /// The date when the bucket_H_map was last generated.
+    #[cfg(any(feature = "bridgeauth", test))]
+    bucket_H_map_date: u32,
 }
 
 // Invariant: the lengths of the keys and bucket hashmap are the same.
 // The encbuckets hashmap only gets updated when encrypt_table is called.
 
 impl BridgeTable {
+    /// Helper function to get the date today
+    #[cfg(any(feature = "bridgeauth", test))]
+    fn today() -> u32 {
+        time::OffsetDateTime::now_utc()
+            .date()
+            .to_julian_day()
+            .try_into()
+            .unwrap()
+    }
+
     /// Get the number of buckets in the bridge table
     #[cfg(any(feature = "bridgeauth", test))]
     pub fn num_buckets(&self) -> usize {
@@ -294,6 +307,12 @@ impl BridgeTable {
     /// Insert a new bucket into the bridge table, returning its index
     #[cfg(any(feature = "bridgeauth", test))]
     pub fn new_bucket(&mut self, index: u32, bucket: &[BridgeLine; MAX_BRIDGES_PER_BUCKET]) {
+        // If we haven't already generated the bucket_H_map for today,
+        // do so now
+        if self.bucket_H_map_date != Self::today() {
+            self.generate_bucket_H_map();
+        }
+
         // Pick a random key to encrypt this bucket
         let mut rng = rand::rngs::OsRng;
         let mut key: [u8; 16] = [0; 16];
@@ -412,12 +431,21 @@ impl BridgeTable {
             );
         }
         self.bucket_H_map = bucket_H_map;
+        self.bucket_H_map_date = Self::today();
     }
 
     /// Given D = bucket * H, return the bucket scalar and the hashed
     /// fingerprints of the bridges in the bucket
     #[cfg(feature = "bridgeauth")]
-    pub fn get_bucket_and_bridges(&self, D: G) -> Result<(Scalar, Vec<[u8; 20]>), CredentialError> {
+    pub fn get_bucket_and_bridges(
+        &mut self,
+        D: G,
+    ) -> Result<(Scalar, Vec<[u8; 20]>), CredentialError> {
+        // Regenerate table if date has changed
+        if self.bucket_H_map_date != Self::today() {
+            self.generate_bucket_H_map();
+        }
+
         let bucket = match self.bucket_H_map.get(&serde_json::to_string(&D).unwrap()) {
             Some(bucket_scalar) => *bucket_scalar,
             None => {

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

@@ -82,14 +82,17 @@ use thiserror::Error;
 use std::time::SystemTime;
 
 // Users can multiply their bucket values times H to identify their
-// bucket to the server without revealing it in the clear. We do not
-// need to change H periodically because we are not using it to restrict
-// anything to per-day events. Knowledge of a bucket*H value does not
-// give the user any access; it is just used as an indicator for the
-// user's Lox credential's bucket value, which should be checked
-// elsewhere.
+// bucket to the server without revealing it in the clear. We change H
+// daily (by generating it based on the date) so that a passive observer
+// who sees bucket * H values for two different days doesn't know
+// whether they're the same or different buckets.
 pub fn get_H() -> G {
-    G::hash_from_bytes::<Sha512>("Bucket product point H".as_bytes())
+    let today: u32 = time::OffsetDateTime::now_utc()
+        .date()
+        .to_julian_day()
+        .try_into()
+        .unwrap();
+    G::hash_from_bytes::<Sha512>(format!("Bucket product point H for date {}", today).as_bytes())
 }
 
 // EXPIRY_DATE is set to EXPIRY_DATE days for open-entry and blocked buckets in order to match

Some files were not shown because too many files changed in this diff