Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion polyfuzzy/src/fmd2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ impl Fmd2MultikeyScheme {

impl FmdKeyGen<FmdSecretKey, FmdPublicKey> for Fmd2MultikeyScheme {
/// Generates as many subkeys as the γ parameter of `self`.
fn generate_keys<R: RngCore + CryptoRng>(&self, rng: &mut R) -> (FmdSecretKey, FmdPublicKey) {
fn generate_keys<R: RngCore + CryptoRng>(
&mut self,
rng: &mut R,
) -> (FmdSecretKey, FmdPublicKey) {
let gamma = self.gamma();

// Secret key.
Expand Down
65 changes: 45 additions & 20 deletions polyfuzzy/src/fmd2_compact/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,18 @@ struct ExpandedKeyCache {
}

impl ExpandedKeyCache {
fn new(scheme: &MultiFmd2CompactScheme, pk: &CompactPublicKey) -> Self {
fn new(scheme: &mut MultiFmd2CompactScheme, pk: &CompactPublicKey) -> Self {
Self {
fingerprint: pk.fingerprint,
randomized_key: scheme.expand_public_key(pk),
}
}

fn or_update(&mut self, scheme: &MultiFmd2CompactScheme, pk: &CompactPublicKey) -> &mut Self {
fn or_update(
&mut self,
scheme: &mut MultiFmd2CompactScheme,
pk: &CompactPublicKey,
) -> &mut Self {
if self.fingerprint.ct_ne(&pk.fingerprint).into() {
self.fingerprint = pk.fingerprint;
self.randomized_key = scheme.expand_public_key(pk);
Expand All @@ -149,6 +153,8 @@ impl ExpandedKeyCache {
/// The multi-key FMD scheme supporting key expansion and key randomization.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MultiFmd2CompactScheme {
/// The gamma parameter
gamma: usize,
/// The threshold parameter
threshold: usize,
///the γ public scalars to derive keys from.
Expand All @@ -161,28 +167,40 @@ pub struct MultiFmd2CompactScheme {

impl MultiFmd2CompactScheme {
/// Public scalars default to 1,...,γ in Z_q.
pub fn new(gamma: usize, threshold: usize) -> Self {
let mut public_scalars = Vec::new();
let mut scalar = Scalar::ONE;
for _i in 0..gamma {
// Safely assume γ << q
public_scalars.push(scalar);
scalar += Scalar::ONE;
}
pub const fn new(gamma: usize, threshold: usize) -> Self {
MultiFmd2CompactScheme {
gamma,
threshold,
public_scalars,
public_scalars: Vec::new(),
expanded_pk: None,
ciphertext_bits: CiphertextBits(Vec::with_capacity(gamma)),
ciphertext_bits: CiphertextBits(Vec::new()),
}
}

fn init_public_scalars(&mut self) {
if !self.public_scalars.is_empty() {
return;
}

let mut scalar = Scalar::ONE;

for _i in 0..self.gamma {
// Safely assume γ << q
self.public_scalars.push(scalar);
scalar += Scalar::ONE;
}
}

fn init_ciphertext_bits(&mut self) {
self.ciphertext_bits.0.reserve(self.gamma);
}
}

impl FmdKeyGen<CompactSecretKey, CompactPublicKey> for MultiFmd2CompactScheme {
/// Public keys generated have basepoint hardcoded to Ristretto basepoint.
/// Thus, the master or original public key (as opposed to diversified keys)
fn generate_keys<R: rand_core::RngCore + rand_core::CryptoRng>(
&self,
&mut self,
rng: &mut R,
) -> (CompactSecretKey, CompactPublicKey) {
let degree = self.threshold;
Expand Down Expand Up @@ -234,17 +252,21 @@ impl MultiFmdScheme<CompactPublicKey, FlagCiphertexts> for MultiFmd2CompactSchem
detection_key: &crate::DetectionKey,
flag_ciphers: &FlagCiphertexts,
) -> bool {
self.init_ciphertext_bits();
detection_key.detect(&mut self.ciphertext_bits, &flag_ciphers.0)
}
}

impl KeyExpansion<CompactSecretKey, CompactPublicKey, FmdPublicKey> for MultiFmd2CompactScheme {
fn expand_keypair(
&self,
&mut self,
parent_sk: &CompactSecretKey,
parent_pk: &CompactPublicKey,
) -> (FmdSecretKey, FmdPublicKey) {
let evaluations = parent_sk.0.evaluate(&self.public_scalars);
let evaluations = parent_sk.0.evaluate({
self.init_public_scalars();
&self.public_scalars
});
let encoded_evaluations = evaluations.encode(&parent_pk.polynomial.basepoint);

(
Expand All @@ -253,15 +275,18 @@ impl KeyExpansion<CompactSecretKey, CompactPublicKey, FmdPublicKey> for MultiFmd
)
}

fn expand_public_key(&self, parent_pk: &CompactPublicKey) -> FmdPublicKey {
let encoded_evaluations = parent_pk.polynomial.evaluate(&self.public_scalars);
fn expand_public_key(&mut self, parent_pk: &CompactPublicKey) -> FmdPublicKey {
let encoded_evaluations = parent_pk.polynomial.evaluate({
self.init_public_scalars();
&self.public_scalars
});

FmdPublicKey(encoded_evaluations)
}
}

impl KeyRandomization<CompactSecretKey, CompactPublicKey> for MultiFmd2CompactScheme {
fn randomize(&self, sk: &CompactSecretKey, tag: &[u8; 64]) -> CompactPublicKey {
fn randomize(&mut self, sk: &CompactSecretKey, tag: &[u8; 64]) -> CompactPublicKey {
let encoded_polynomial = sk.0.encode_with_hashed_basepoint(tag);

CompactPublicKey::from_poly(encoded_polynomial)
Expand Down Expand Up @@ -324,7 +349,7 @@ mod tests {
fn test_expand_is_correct() {
let mut csprng = rand_core::OsRng;

let compact_multi_fmd2 = MultiFmd2CompactScheme::new(10, 3);
let mut compact_multi_fmd2 = MultiFmd2CompactScheme::new(10, 3);
let (master_csk, master_cpk) = compact_multi_fmd2.generate_keys(&mut csprng);

let (_fmd_sk, fmd_pk) = compact_multi_fmd2.expand_keypair(&master_csk, &master_cpk);
Expand All @@ -338,7 +363,7 @@ mod tests {
fn test_expand_and_randomize_are_compatible() {
let mut csprng = rand_core::OsRng;

let compact_multi_fmd2 = MultiFmd2CompactScheme::new(10, 3);
let mut compact_multi_fmd2 = MultiFmd2CompactScheme::new(10, 3);
let (master_csk, master_cpk) = compact_multi_fmd2.generate_keys(&mut csprng);

// Randomize then expand.
Expand Down
8 changes: 4 additions & 4 deletions polyfuzzy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ pub trait MultiFmdScheme<PK, F> {
///
/// Depending on implementations, the generated keypair can be compact.
pub trait FmdKeyGen<SK, PK> {
fn generate_keys<R: RngCore + CryptoRng>(&self, rng: &mut R) -> (SK, PK);
fn generate_keys<R: RngCore + CryptoRng>(&mut self, rng: &mut R) -> (SK, PK);
}

/// A trait to derive an FMD keypair ([FmdSecretKey],DPK) from a keypair (SK,PK).
pub trait KeyExpansion<SK, PK, DPK>: FmdKeyGen<SK, PK> {
fn expand_keypair(&self, parent_sk: &SK, parent_pk: &PK) -> (FmdSecretKey, DPK);
fn expand_keypair(&mut self, parent_sk: &SK, parent_pk: &PK) -> (FmdSecretKey, DPK);

fn expand_public_key(&self, parent_pk: &PK) -> DPK;
fn expand_public_key(&mut self, parent_pk: &PK) -> DPK;
}

/// A trait to randomize public keys.
Expand All @@ -67,5 +67,5 @@ pub trait KeyRandomization<SK, PK> {
/// The randomized public key is bound to the tag. Different tags yield
/// different randomized public keys.
/// The input tag _should_ be uniform (e.g. a hash digest).
fn randomize(&self, sk: &SK, tag: &[u8; 64]) -> PK;
fn randomize(&mut self, sk: &SK, tag: &[u8; 64]) -> PK;
}