Skip to content

Commit

Permalink
Added ctx string to DPF computation (#1146)
Browse files Browse the repository at this point in the history
  • Loading branch information
rozbb authored Nov 27, 2024
1 parent c85e537 commit 1ac481f
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 48 deletions.
5 changes: 3 additions & 2 deletions benches/cycle_counts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ fn idpf_poplar_gen(
leaf_value: Poplar1IdpfValue<Field255>,
) {
let idpf = Idpf::new((), ());
idpf.gen(input, inner_values, leaf_value, &[0; 16]).unwrap();
idpf.gen(input, inner_values, leaf_value, b"", &[0; 16])
.unwrap();
}

#[cfg(feature = "experimental")]
Expand Down Expand Up @@ -209,7 +210,7 @@ fn idpf_poplar_eval(
) {
let mut cache = RingBufferCache::new(1);
let idpf = Idpf::new((), ());
idpf.eval(0, public_share, key, input, &[0; 16], &mut cache)
idpf.eval(0, public_share, key, input, b"", &[0; 16], &mut cache)
.unwrap();
}

Expand Down
16 changes: 12 additions & 4 deletions benches/speed_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ fn idpf(c: &mut Criterion) {

let idpf = Idpf::new((), ());
b.iter(|| {
idpf.gen(&input, inner_values.clone(), leaf_value, &[0; 16])
idpf.gen(&input, inner_values.clone(), leaf_value, b"", &[0; 16])
.unwrap();
});
});
Expand All @@ -735,7 +735,7 @@ fn idpf(c: &mut Criterion) {

let idpf = Idpf::new((), ());
let (public_share, keys) = idpf
.gen(&input, inner_values, leaf_value, &[0; 16])
.gen(&input, inner_values, leaf_value, b"", &[0; 16])
.unwrap();

b.iter(|| {
Expand All @@ -747,8 +747,16 @@ fn idpf(c: &mut Criterion) {

for prefix_length in 1..=size {
let prefix = input[..prefix_length].to_owned().into();
idpf.eval(0, &public_share, &keys[0], &prefix, &[0; 16], &mut cache)
.unwrap();
idpf.eval(
0,
&public_share,
&keys[0],
&prefix,
b"",
&[0; 16],
&mut cache,
)
.unwrap();
}
});
});
Expand Down
75 changes: 45 additions & 30 deletions src/idpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ use std::{
};
use subtle::{Choice, ConditionallyNegatable, ConditionallySelectable, ConstantTimeEq};

const EXTEND_DOMAIN_SEP: &[u8; 8] = &[
VERSION, 1, /* algorithm class */
0, 0, 0, 0, /* algorithm ID */
0, 0, /* usage */
];

const CONVERT_DOMAIN_SEP: &[u8; 8] = &[
VERSION, 1, /* algorithm class */
0, 0, 0, 0, /* algorithm ID */
0, 1, /* usage */
];

/// IDPF-related errors.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
Expand Down Expand Up @@ -394,6 +406,7 @@ where
input: &IdpfInput,
inner_values: M,
leaf_value: VL,
ctx: &[u8],
binder: &[u8],
random: &[[u8; 16]; 2],
) -> Result<(IdpfPublicShare<VI, VL>, [Seed<16>; 2]), VdafError> {
Expand All @@ -402,18 +415,8 @@ where
let initial_keys: [Seed<16>; 2] =
[Seed::from_bytes(random[0]), Seed::from_bytes(random[1])];

let extend_dst = [
VERSION, 1, /* algorithm class */
0, 0, 0, 0, /* algorithm ID */
0, 0, /* usage */
];
let convert_dst = [
VERSION, 1, /* algorithm class */
0, 0, 0, 0, /* algorithm ID */
0, 1, /* usage */
];
let extend_xof_fixed_key = XofFixedKeyAes128Key::new(&extend_dst, binder);
let convert_xof_fixed_key = XofFixedKeyAes128Key::new(&convert_dst, binder);
let extend_xof_fixed_key = XofFixedKeyAes128Key::new(&[EXTEND_DOMAIN_SEP, ctx], binder);
let convert_xof_fixed_key = XofFixedKeyAes128Key::new(&[CONVERT_DOMAIN_SEP, ctx], binder);

let mut keys = [initial_keys[0].0, initial_keys[1].0];
let mut control_bits = [Choice::from(0u8), Choice::from(1u8)];
Expand Down Expand Up @@ -467,6 +470,7 @@ where
input: &IdpfInput,
inner_values: M,
leaf_value: VL,
ctx: &[u8],
binder: &[u8],
) -> Result<(IdpfPublicShare<VI, VL>, [Seed<16>; 2]), VdafError>
where
Expand All @@ -481,7 +485,7 @@ where
for random_seed in random.iter_mut() {
getrandom::getrandom(random_seed)?;
}
self.gen_with_random(input, inner_values, leaf_value, binder, &random)
self.gen_with_random(input, inner_values, leaf_value, ctx, binder, &random)
}

/// Evaluate an IDPF share on `prefix`, starting from a particular tree level with known
Expand All @@ -495,23 +499,14 @@ where
mut key: [u8; 16],
mut control_bit: Choice,
prefix: &IdpfInput,
ctx: &[u8],
binder: &[u8],
cache: &mut dyn IdpfCache,
) -> Result<IdpfOutputShare<VI, VL>, IdpfError> {
let bits = public_share.inner_correction_words.len() + 1;

let extend_dst = [
VERSION, 1, /* algorithm class */
0, 0, 0, 0, /* algorithm ID */
0, 0, /* usage */
];
let convert_dst = [
VERSION, 1, /* algorithm class */
0, 0, 0, 0, /* algorithm ID */
0, 1, /* usage */
];
let extend_xof_fixed_key = XofFixedKeyAes128Key::new(&extend_dst, binder);
let convert_xof_fixed_key = XofFixedKeyAes128Key::new(&convert_dst, binder);
let extend_xof_fixed_key = XofFixedKeyAes128Key::new(&[EXTEND_DOMAIN_SEP, ctx], binder);
let convert_xof_fixed_key = XofFixedKeyAes128Key::new(&[CONVERT_DOMAIN_SEP, ctx], binder);

let mut last_inner_output = None;
for ((correction_word, input_bit), level) in public_share.inner_correction_words
Expand Down Expand Up @@ -556,12 +551,14 @@ where
/// The IDPF key evaluation algorithm.
///
/// Evaluate an IDPF share on `prefix`.
#[allow(clippy::too_many_arguments)]
pub fn eval(
&self,
agg_id: usize,
public_share: &IdpfPublicShare<VI, VL>,
key: &Seed<16>,
prefix: &IdpfInput,
ctx: &[u8],
binder: &[u8],
cache: &mut dyn IdpfCache,
) -> Result<IdpfOutputShare<VI, VL>, IdpfError> {
Expand Down Expand Up @@ -602,6 +599,7 @@ where
key,
Choice::from(control_bit),
prefix,
ctx,
binder,
cache,
);
Expand All @@ -617,6 +615,7 @@ where
key.0,
/* control_bit */ Choice::from((!is_leader) as u8),
prefix,
ctx,
binder,
cache,
)
Expand Down Expand Up @@ -1075,6 +1074,8 @@ mod tests {
sync::Mutex,
};

const CTX_STR: &[u8] = b"idpf context";

use assert_matches::assert_matches;
use bitvec::{
bitbox,
Expand Down Expand Up @@ -1190,6 +1191,7 @@ mod tests {
&input,
Vec::from([Poplar1IdpfValue::new([Field64::one(), Field64::one()]); 4]),
Poplar1IdpfValue::new([Field255::one(), Field255::one()]),
CTX_STR,
&nonce,
)
.unwrap();
Expand Down Expand Up @@ -1306,10 +1308,10 @@ mod tests {
) {
let idpf = Idpf::new((), ());
let share_0 = idpf
.eval(0, public_share, &keys[0], prefix, binder, cache_0)
.eval(0, public_share, &keys[0], prefix, CTX_STR, binder, cache_0)
.unwrap();
let share_1 = idpf
.eval(1, public_share, &keys[1], prefix, binder, cache_1)
.eval(1, public_share, &keys[1], prefix, CTX_STR, binder, cache_1)
.unwrap();
let output = share_0.merge(share_1).unwrap();
assert_eq!(&output, expected_output);
Expand Down Expand Up @@ -1340,7 +1342,7 @@ mod tests {
let nonce: [u8; 16] = random();
let idpf = Idpf::new((), ());
let (public_share, keys) = idpf
.gen(&input, inner_values.clone(), leaf_values, &nonce)
.gen(&input, inner_values.clone(), leaf_values, CTX_STR, &nonce)
.unwrap();
let mut cache_0 = RingBufferCache::new(3);
let mut cache_1 = RingBufferCache::new(3);
Expand Down Expand Up @@ -1409,7 +1411,7 @@ mod tests {
let nonce: [u8; 16] = random();
let idpf = Idpf::new((), ());
let (public_share, keys) = idpf
.gen(&input, inner_values.clone(), leaf_values, &nonce)
.gen(&input, inner_values.clone(), leaf_values, CTX_STR, &nonce)
.unwrap();
let mut cache_0 = SnoopingCache::new(HashMapCache::new());
let mut cache_1 = HashMapCache::new();
Expand Down Expand Up @@ -1588,7 +1590,7 @@ mod tests {
let nonce: [u8; 16] = random();
let idpf = Idpf::new((), ());
let (public_share, keys) = idpf
.gen(&input, inner_values.clone(), leaf_values, &nonce)
.gen(&input, inner_values.clone(), leaf_values, CTX_STR, &nonce)
.unwrap();
let mut cache_0 = LossyCache::new();
let mut cache_1 = LossyCache::new();
Expand Down Expand Up @@ -1624,6 +1626,7 @@ mod tests {
&bitbox![].into(),
Vec::<Poplar1IdpfValue<Field64>>::new(),
Poplar1IdpfValue::new([Field255::zero(); 2]),
CTX_STR,
&nonce,
)
.unwrap_err();
Expand All @@ -1633,6 +1636,7 @@ mod tests {
&bitbox![0;10].into(),
Vec::from([Poplar1IdpfValue::new([Field64::zero(); 2]); 9]),
Poplar1IdpfValue::new([Field255::zero(); 2]),
CTX_STR,
&nonce,
)
.unwrap();
Expand All @@ -1642,13 +1646,15 @@ mod tests {
&bitbox![0; 10].into(),
Vec::from([Poplar1IdpfValue::new([Field64::zero(); 2]); 8]),
Poplar1IdpfValue::new([Field255::zero(); 2]),
CTX_STR,
&nonce,
)
.unwrap_err();
idpf.gen(
&bitbox![0; 10].into(),
Vec::from([Poplar1IdpfValue::new([Field64::zero(); 2]); 10]),
Poplar1IdpfValue::new([Field255::zero(); 2]),
CTX_STR,
&nonce,
)
.unwrap_err();
Expand All @@ -1660,6 +1666,7 @@ mod tests {
&public_share,
&keys[0],
&bitbox![].into(),
CTX_STR,
&nonce,
&mut NoCache::new(),
)
Expand All @@ -1671,6 +1678,7 @@ mod tests {
&public_share,
&keys[0],
&bitbox![0; 11].into(),
CTX_STR,
&nonce,
&mut NoCache::new(),
)
Expand Down Expand Up @@ -2016,6 +2024,7 @@ mod tests {
}
}

#[ignore]
#[test]
fn idpf_poplar_generate_test_vector() {
let test_vector = load_idpfpoplar_test_vector();
Expand All @@ -2025,6 +2034,7 @@ mod tests {
&test_vector.alpha,
test_vector.beta_inner,
test_vector.beta_leaf,
b"WRONG CTX, REPLACE ME", // TODO: Update test vectors to ones that provide ctx str
&test_vector.binder,
&test_vector.keys,
)
Expand Down Expand Up @@ -2256,6 +2266,7 @@ mod tests {
Field128::from(2),
Field128::from(3),
])),
CTX_STR,
binder,
)
.unwrap();
Expand All @@ -2266,6 +2277,7 @@ mod tests {
&public_share,
&key_0,
&IdpfInput::from_bytes(b"ou"),
CTX_STR,
binder,
&mut NoCache::new(),
)
Expand All @@ -2276,6 +2288,7 @@ mod tests {
&public_share,
&key_1,
&IdpfInput::from_bytes(b"ou"),
CTX_STR,
binder,
&mut NoCache::new(),
)
Expand All @@ -2294,6 +2307,7 @@ mod tests {
&public_share,
&key_0,
&IdpfInput::from_bytes(b"ae"),
CTX_STR,
binder,
&mut NoCache::new(),
)
Expand All @@ -2304,6 +2318,7 @@ mod tests {
&public_share,
&key_1,
&IdpfInput::from_bytes(b"ae"),
CTX_STR,
binder,
&mut NoCache::new(),
)
Expand Down
6 changes: 6 additions & 0 deletions src/vdaf/poplar1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
.iter()
.map(|auth| Poplar1IdpfValue([Field64::one(), *auth])),
Poplar1IdpfValue([Field255::one(), auth_leaf]),
ctx,
nonce,
idpf_random,
)?;
Expand Down Expand Up @@ -1009,6 +1010,7 @@ impl<P: Xof<SEED_SIZE>, const SEED_SIZE: usize> Poplar1<P, SEED_SIZE> {
public_share,
idpf_key,
prefix,
ctx,
nonce,
&mut idpf_eval_cache,
)?);
Expand Down Expand Up @@ -2386,21 +2388,25 @@ mod tests {
assert_eq!(agg_result, test_vector.agg_result);
}

#[ignore]
#[test]
fn test_vec_poplar1_0() {
check_test_vec(include_str!("test_vec/08/Poplar1_0.json"));
}

#[ignore]
#[test]
fn test_vec_poplar1_1() {
check_test_vec(include_str!("test_vec/08/Poplar1_1.json"));
}

#[ignore]
#[test]
fn test_vec_poplar1_2() {
check_test_vec(include_str!("test_vec/08/Poplar1_2.json"));
}

#[ignore]
#[test]
fn test_vec_poplar1_3() {
check_test_vec(include_str!("test_vec/08/Poplar1_3.json"));
Expand Down
Loading

0 comments on commit 1ac481f

Please sign in to comment.