Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ctx string to DPF computation #1146

Merged
merged 6 commits into from
Nov 27, 2024
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: 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