diff --git a/ppoprf/Cargo.toml b/ppoprf/Cargo.toml index c7a3a6d4..c7a1136f 100644 --- a/ppoprf/Cargo.toml +++ b/ppoprf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ppoprf" -version = "0.3.1" +version = "0.4.0" authors = ["Alex Davidson ", "Ralph Ankele "] description = "Puncturable Partially-Oblivious Pseudo-Random Function" documentation = "https://docs.rs/ppoprf" @@ -12,9 +12,9 @@ edition = "2021" [dependencies] rand = { version = "0.8.5", features = [ "getrandom" ] } -bitvec = "1.0.1" +bitvec = { version = "1.0.1", features = ["serde"] } curve25519-dalek = { version = "4.0.0", features = [ "rand_core", "serde" ] } -serde = "1.0.147" +serde = { version = "1.0.147", features = ["derive"] } strobe-rs = "0.8.1" base64 = "0.13.0" bincode = "1.3.3" @@ -34,3 +34,6 @@ warp = "0.3.7" [[bench]] name = "bench" harness = false + +[features] +key-sync = [] diff --git a/ppoprf/src/ggm.rs b/ppoprf/src/ggm.rs index c7e860ee..a0b7a0b3 100644 --- a/ppoprf/src/ggm.rs +++ b/ppoprf/src/ggm.rs @@ -10,11 +10,12 @@ use crate::strobe_rng::StrobeRng; use bitvec::prelude::*; use rand::rngs::OsRng; use rand::Rng; +use serde::{Deserialize, Serialize}; use strobe_rs::{SecParam, Strobe}; use zeroize::{Zeroize, ZeroizeOnDrop}; -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Serialize, Deserialize)] struct Prefix { bits: BitVec, } @@ -31,11 +32,15 @@ impl Prefix { impl fmt::Debug for Prefix { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Prefix").field("bits", &self.bits).finish() + f.debug_struct("Prefix") + .field("bits", &self.bits.as_raw_slice().to_vec()) + .finish() } } -#[derive(Clone, Zeroize, ZeroizeOnDrop)] +#[derive( + Debug, Clone, Zeroize, ZeroizeOnDrop, Serialize, Deserialize, PartialEq, Eq, +)] struct GGMPseudorandomGenerator { key: [u8; 32], } @@ -59,8 +64,10 @@ impl GGMPseudorandomGenerator { } } -#[derive(Clone, Zeroize, ZeroizeOnDrop)] -struct GGMPuncturableKey { +#[derive( + Debug, Clone, Zeroize, ZeroizeOnDrop, Serialize, Deserialize, Eq, PartialEq, +)] +pub(crate) struct GGMPuncturableKey { prgs: Vec, #[zeroize(skip)] prefixes: Vec<(Prefix, Vec)>, @@ -125,7 +132,7 @@ impl GGMPuncturableKey { #[derive(Clone, Zeroize, ZeroizeOnDrop)] pub struct GGM { inp_len: usize, - key: GGMPuncturableKey, + pub(crate) key: GGMPuncturableKey, } impl GGM { diff --git a/ppoprf/src/ppoprf.rs b/ppoprf/src/ppoprf.rs index 1efae0d2..8ad09e50 100644 --- a/ppoprf/src/ppoprf.rs +++ b/ppoprf/src/ppoprf.rs @@ -23,6 +23,8 @@ use serde::{de, ser, Deserialize, Serialize}; use std::collections::BTreeMap; use std::convert::TryInto; +#[cfg(feature = "key-sync")] +use crate::ggm::GGMPuncturableKey; use crate::strobe_rng::StrobeRng; use strobe_rs::{SecParam, Strobe}; @@ -192,7 +194,7 @@ impl ProofDLEQ { // Server public key structure for PPOPRF, contains all elements of the // form g^{sk_0},g^{t_i} for metadata tags t_i. -#[derive(Deserialize, Serialize, Clone, Debug)] +#[derive(Deserialize, Serialize, Clone, Debug, Eq, PartialEq)] pub struct ServerPublicKey { base_pk: Point, md_pks: BTreeMap, @@ -301,6 +303,39 @@ where Ok(Point(CompressedRistretto(fixed_data))) } +/// Structure containing all relevant key information +/// for syncing between Server instances. +/// To be used for deserialization. +#[cfg(feature = "key-sync")] +#[derive(Deserialize)] +pub struct ServerKeyState { + oprf_key: RistrettoScalar, + public_key: ServerPublicKey, + ggm_key: GGMPuncturableKey, +} + +/// Structure containing all relevant key information +/// for syncing between Server instances. +/// To be used for serialization. +#[cfg(feature = "key-sync")] +#[derive(Serialize, Eq, PartialEq, Debug)] +pub struct ServerKeyStateRef<'a> { + oprf_key: &'a RistrettoScalar, + public_key: &'a ServerPublicKey, + ggm_key: &'a GGMPuncturableKey, +} + +#[cfg(feature = "key-sync")] +impl ServerKeyState { + pub fn as_ref(&self) -> ServerKeyStateRef<'_> { + ServerKeyStateRef { + oprf_key: &self.oprf_key, + public_key: &self.public_key, + ggm_key: &self.ggm_key, + } + } +} + // The `Server` runs the server-side component of the PPOPRF protocol. #[derive(Clone, Zeroize, ZeroizeOnDrop)] pub struct Server { @@ -370,6 +405,22 @@ impl Server { pub fn get_public_key(&self) -> ServerPublicKey { self.public_key.clone() } + + #[cfg(feature = "key-sync")] + pub fn get_private_key(&self) -> ServerKeyStateRef<'_> { + ServerKeyStateRef { + oprf_key: &self.oprf_key, + public_key: &self.public_key, + ggm_key: &self.pprf.key, + } + } + + #[cfg(feature = "key-sync")] + pub fn set_private_key(&mut self, private_key: ServerKeyState) { + self.oprf_key = private_key.oprf_key; + self.public_key = private_key.public_key; + self.pprf.key = private_key.ggm_key; + } } // The `Client` struct is essentially a collection of static functions diff --git a/star/Cargo.toml b/star/Cargo.toml index 94d222ab..16fb13d1 100644 --- a/star/Cargo.toml +++ b/star/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [dependencies] strobe-rs = "0.8.1" adss = { path = "../adss", version = "0.2.2" } -ppoprf = { path = "../ppoprf", version = "0.3.0" } +ppoprf = { path = "../ppoprf", version = "0.4.0" } rand = "0.8.5" rand_core = "0.6.4" zeroize = "1.5.5"