Browse Source

add dummy spdpf and mpdpf

Lennart Braun 2 years ago
parent
commit
c9b2c87689
4 changed files with 231 additions and 14 deletions
  1. 1 0
      dpf/Cargo.toml
  2. 2 14
      dpf/src/lib.rs
  3. 131 0
      dpf/src/mpdpf.rs
  4. 97 0
      dpf/src/spdpf.rs

+ 1 - 0
dpf/Cargo.toml

@@ -6,3 +6,4 @@ edition = "2021"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
+rand = "0.8.5"

+ 2 - 14
dpf/src/lib.rs

@@ -1,14 +1,2 @@
-pub fn add(left: usize, right: usize) -> usize {
-    left + right
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn it_works() {
-        let result = add(2, 2);
-        assert_eq!(result, 4);
-    }
-}
+pub mod mpdpf;
+pub mod spdpf;

+ 131 - 0
dpf/src/mpdpf.rs

@@ -0,0 +1,131 @@
+pub trait MultiPointDpfKey {
+    fn get_party_id(&self) -> usize;
+    fn get_log_domain_size(&self) -> u64;
+    fn get_number_points(&self) -> usize;
+}
+
+pub trait MultiPointDpf {
+    type Key: Clone + MultiPointDpfKey;
+
+    fn generate_keys(log_domain_size: u64, alphas: &[u64], betas: &[u64])
+        -> (Self::Key, Self::Key);
+    fn evaluate_at(key: &Self::Key, index: u64) -> u64;
+    fn evaluate_domain(key: &Self::Key) -> Vec<u64> {
+        (0..(1 << key.get_log_domain_size()))
+            .map(|x| Self::evaluate_at(&key, x))
+            .collect()
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct DummyMpDpfKey {
+    party_id: usize,
+    log_domain_size: u64,
+    number_points: usize,
+    alphas: Vec<u64>,
+    betas: Vec<u64>,
+}
+
+impl MultiPointDpfKey for DummyMpDpfKey {
+    fn get_party_id(&self) -> usize {
+        self.party_id
+    }
+    fn get_log_domain_size(&self) -> u64 {
+        self.log_domain_size
+    }
+    fn get_number_points(&self) -> usize {
+        self.number_points
+    }
+}
+
+pub struct DummyMpDpf {}
+
+impl MultiPointDpf for DummyMpDpf {
+    type Key = DummyMpDpfKey;
+
+    fn generate_keys(
+        log_domain_size: u64,
+        alphas: &[u64],
+        betas: &[u64],
+    ) -> (Self::Key, Self::Key) {
+        assert_eq!(
+            alphas.len(),
+            betas.len(),
+            "alphas and betas must be the same size"
+        );
+        assert!(
+            alphas.iter().all(|alpha| alpha < &(1 << log_domain_size)),
+            "all alphas must be in the domain"
+        );
+        assert!(alphas.windows(2).all(|w| w[0] <= w[1]));
+        let number_points = alphas.len();
+        (
+            DummyMpDpfKey {
+                party_id: 0,
+                log_domain_size,
+                number_points,
+                alphas: alphas.iter().copied().collect(),
+                betas: betas.iter().copied().collect(),
+            },
+            DummyMpDpfKey {
+                party_id: 1,
+                log_domain_size,
+                number_points,
+                alphas: alphas.iter().copied().collect(),
+                betas: betas.iter().copied().collect(),
+            },
+        )
+    }
+
+    fn evaluate_at(key: &Self::Key, index: u64) -> u64 {
+        if key.get_party_id() == 0 {
+            match key.alphas.binary_search(&index) {
+                Ok(i) => key.betas[i],
+                Err(_) => 0,
+            }
+        } else {
+            0
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use rand::{thread_rng, Rng};
+
+    fn test_mpdpf_with_param<MPDPF: MultiPointDpf>(log_domain_size: u64, number_points: usize) {
+        assert!(number_points <= (1 << log_domain_size));
+        let domain_size = 1 << log_domain_size;
+        let alphas = {
+            let mut alphas: Vec<u64> = (0..number_points)
+                .map(|_| thread_rng().gen_range(0..domain_size))
+                .collect();
+            alphas.sort();
+            alphas
+        };
+        let betas: Vec<u64> = (0..number_points).map(|_| thread_rng().gen()).collect();
+        let (key_0, key_1) = MPDPF::generate_keys(log_domain_size, &alphas, &betas);
+
+        let out_0 = MPDPF::evaluate_domain(&key_0);
+        let out_1 = MPDPF::evaluate_domain(&key_1);
+        for i in 0..domain_size {
+            let value = MPDPF::evaluate_at(&key_0, i) + MPDPF::evaluate_at(&key_1, i);
+            assert_eq!(value, out_0[i as usize] + out_1[i as usize]);
+            let expected_result = match alphas.binary_search(&i) {
+                Ok(i) => betas[i],
+                Err(_) => 0,
+            };
+            assert_eq!(value, expected_result);
+        }
+    }
+
+    #[test]
+    fn test_mpdpf() {
+        for log_domain_size in 5..10 {
+            for log_number_points in 0..5 {
+                test_mpdpf_with_param::<DummyMpDpf>(log_domain_size, 1 << log_number_points);
+            }
+        }
+    }
+}

+ 97 - 0
dpf/src/spdpf.rs

@@ -0,0 +1,97 @@
+pub trait SinglePointDpfKey {
+    fn get_party_id(&self) -> usize;
+    fn get_log_domain_size(&self) -> u64;
+}
+
+pub trait SinglePointDpf {
+    type Key: Copy + SinglePointDpfKey;
+
+    fn generate_keys(log_domain_size: u64, alpha: u64, beta: u64) -> (Self::Key, Self::Key);
+    fn evaluate_at(key: &Self::Key, index: u64) -> u64;
+    fn evaluate_domain(key: &Self::Key) -> Vec<u64> {
+        (0..(1 << key.get_log_domain_size()))
+            .map(|x| Self::evaluate_at(&key, x))
+            .collect()
+    }
+}
+
+#[derive(Clone, Copy, Debug)]
+pub struct DummySpDpfKey {
+    party_id: usize,
+    log_domain_size: u64,
+    alpha: u64,
+    beta: u64,
+}
+
+impl SinglePointDpfKey for DummySpDpfKey {
+    fn get_party_id(&self) -> usize {
+        self.party_id
+    }
+    fn get_log_domain_size(&self) -> u64 {
+        self.log_domain_size
+    }
+}
+
+pub struct DummySpDpf {}
+
+impl SinglePointDpf for DummySpDpf {
+    type Key = DummySpDpfKey;
+
+    fn generate_keys(log_domain_size: u64, alpha: u64, beta: u64) -> (Self::Key, Self::Key) {
+        assert!(alpha < (1 << log_domain_size));
+        (
+            DummySpDpfKey {
+                party_id: 0,
+                log_domain_size,
+                alpha,
+                beta,
+            },
+            DummySpDpfKey {
+                party_id: 1,
+                log_domain_size,
+                alpha,
+                beta,
+            },
+        )
+    }
+
+    fn evaluate_at(key: &Self::Key, index: u64) -> u64 {
+        if key.get_party_id() == 0 && index == key.alpha {
+            key.beta
+        } else {
+            0
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use rand::{thread_rng, Rng};
+
+    fn test_spdpf_with_param<SPDPF: SinglePointDpf>(log_domain_size: u64) {
+        let domain_size = 1 << log_domain_size;
+        let alpha = thread_rng().gen_range(0..domain_size);
+        let beta = thread_rng().gen();
+        let (key_0, key_1) = SPDPF::generate_keys(log_domain_size, alpha, beta);
+
+        let out_0 = SPDPF::evaluate_domain(&key_0);
+        let out_1 = SPDPF::evaluate_domain(&key_1);
+        for i in 0..domain_size {
+            let value = SPDPF::evaluate_at(&key_0, i) + SPDPF::evaluate_at(&key_1, i);
+            assert_eq!(value, out_0[i as usize] + out_1[i as usize]);
+            if i == alpha {
+                assert_eq!(value, beta);
+            } else {
+                assert_eq!(value, 0);
+            }
+        }
+    }
+
+    #[test]
+    fn test_spdpf() {
+        for log_domain_size in 5..10 {
+            test_spdpf_with_param::<DummySpDpf>(log_domain_size);
+        }
+    }
+}