From eb8a6e31dc6efbe4eb90d3fdfd602d450760bb7d Mon Sep 17 00:00:00 2001 From: Christopher Patton Date: Tue, 31 Dec 2024 10:33:30 -0500 Subject: [PATCH] xof: Pass domain separation tag in parts Modify the `Xof` trait by allowing the user to pass the domain separation tag in parts. This saves us from allocating a `Vec` in many cases. --- src/flp/szk.rs | 12 +++---- src/idpf.rs | 10 ++---- src/prng.rs | 10 +++--- src/vdaf.rs | 15 ++++----- src/vdaf/mastic.rs | 4 +-- src/vdaf/poplar1.rs | 2 +- src/vdaf/prio3.rs | 40 ++++++++++++----------- src/vdaf/xof.rs | 79 +++++++++++++++++++++++++++++---------------- src/vidpf.rs | 12 ++++--- 9 files changed, 102 insertions(+), 82 deletions(-) diff --git a/src/flp/szk.rs b/src/flp/szk.rs index 39dcbf1a..ee3633d3 100644 --- a/src/flp/szk.rs +++ b/src/flp/szk.rs @@ -348,7 +348,7 @@ where fn derive_prove_rand(&self, prove_rand_seed: &Seed) -> Vec { P::seed_stream( prove_rand_seed, - &self.domain_separation_tag(DST_PROVE_RANDOMNESS), + &[&self.domain_separation_tag(DST_PROVE_RANDOMNESS)], &[], ) .into_field_vec(self.typ.prove_rand_len()) @@ -362,7 +362,7 @@ where ) -> Result, SzkError> { let mut xof = P::init( aggregator_blind.as_ref(), - &self.domain_separation_tag(DST_JOINT_RAND_PART), + &[&self.domain_separation_tag(DST_JOINT_RAND_PART)], ); xof.update(nonce); // Encode measurement_share (currently an array of field elements) into @@ -383,7 +383,7 @@ where ) -> Seed { let mut xof = P::init( &[0; SEED_SIZE], - &self.domain_separation_tag(DST_JOINT_RAND_SEED), + &[&self.domain_separation_tag(DST_JOINT_RAND_SEED)], ); xof.update(&leader_joint_rand_part.0); xof.update(&helper_joint_rand_part.0); @@ -399,7 +399,7 @@ where self.derive_joint_rand_seed(leader_joint_rand_part, helper_joint_rand_part); let joint_rand = P::seed_stream( &joint_rand_seed, - &self.domain_separation_tag(DST_JOINT_RANDOMNESS), + &[&self.domain_separation_tag(DST_JOINT_RANDOMNESS)], &[], ) .into_field_vec(self.typ.joint_rand_len()); @@ -410,7 +410,7 @@ where fn derive_helper_proof_share(&self, proof_share_seed: &Seed) -> Vec { Prng::from_seed_stream(P::seed_stream( proof_share_seed, - &self.domain_separation_tag(DST_PROOF_SHARE), + &[&self.domain_separation_tag(DST_PROOF_SHARE)], &[], )) .take(self.typ.proof_len()) @@ -420,7 +420,7 @@ where fn derive_query_rand(&self, verify_key: &[u8; SEED_SIZE], nonce: &[u8; 16]) -> Vec { let mut xof = P::init( verify_key, - &self.domain_separation_tag(DST_QUERY_RANDOMNESS), + &[&self.domain_separation_tag(DST_QUERY_RANDOMNESS)], ); xof.update(nonce); xof.into_seed_stream() diff --git a/src/idpf.rs b/src/idpf.rs index c38b36d9..9351df3c 100644 --- a/src/idpf.rs +++ b/src/idpf.rs @@ -248,10 +248,7 @@ fn extend(seed: &[u8; 16], xof_mode: &XofMode<'_>) -> ([[u8; 16]; 2], [Choice; 2 seed_stream.fill_bytes(&mut seeds[1]); } XofMode::Leaf(ctx, nonce) => { - let mut dst = Vec::with_capacity(EXTEND_DOMAIN_SEP.len() + ctx.len()); - dst.extend(EXTEND_DOMAIN_SEP); - dst.extend(*ctx); - let mut xof = XofTurboShake128::from_seed_slice(seed, &dst); + let mut xof = XofTurboShake128::from_seed_slice(seed, &[EXTEND_DOMAIN_SEP, ctx]); xof.update(nonce); let mut seed_stream = xof.into_seed_stream(); seed_stream.fill_bytes(&mut seeds[0]); @@ -284,10 +281,7 @@ where (next_seed, V::generate(&mut seed_stream, parameter)) } XofMode::Leaf(ctx, nonce) => { - let mut dst = Vec::with_capacity(CONVERT_DOMAIN_SEP.len() + ctx.len()); - dst.extend(CONVERT_DOMAIN_SEP); - dst.extend(*ctx); - let mut xof = XofTurboShake128::from_seed_slice(seed, &dst); + let mut xof = XofTurboShake128::from_seed_slice(seed, &[CONVERT_DOMAIN_SEP, ctx]); xof.update(nonce); let mut seed_stream = xof.into_seed_stream(); seed_stream.fill_bytes(&mut next_seed); diff --git a/src/prng.rs b/src/prng.rs index d6009a00..77c41657 100644 --- a/src/prng.rs +++ b/src/prng.rs @@ -234,14 +234,14 @@ mod tests { .unwrap(); let expected = Field64::from(4857131209231097247); - let seed_stream = XofTurboShake128::seed_stream(&seed, b"", b""); + let seed_stream = XofTurboShake128::seed_stream(&seed, &[], &[]); let mut prng = Prng::::from_seed_stream(seed_stream); let actual = prng.nth(13882).unwrap(); assert_eq!(actual, expected); #[cfg(all(feature = "crypto-dependencies", feature = "experimental"))] { - let mut seed_stream = XofTurboShake128::seed_stream(&seed, b"", b""); + let mut seed_stream = XofTurboShake128::seed_stream(&seed, &[], &[]); let mut actual = ::zero(); for _ in 0..=13882 { actual = ::generate(&mut seed_stream, &()); @@ -257,11 +257,11 @@ mod tests { let seed = Seed::generate().unwrap(); let mut prng: Prng = - Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b"")); + Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, &[], &[])); // Construct a `Prng` with a longer-than-usual buffer. let mut prng_weird_buffer_size: Prng = - Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b"")); + Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, &[], &[])); let mut extra = [0; 7]; prng_weird_buffer_size.seed_stream.fill_bytes(&mut extra); prng_weird_buffer_size.buffer.extend_from_slice(&extra); @@ -278,7 +278,7 @@ mod tests { fn into_different_field() { let seed = Seed::generate().unwrap(); let want: Prng = - Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, b"", b"")); + Prng::from_seed_stream(XofTurboShake128::seed_stream(&seed, &[], &[])); let want_buffer = want.buffer.clone(); let got: Prng = want.into_new_field(); diff --git a/src/vdaf.rs b/src/vdaf.rs index 035ef425..8ea17b71 100644 --- a/src/vdaf.rs +++ b/src/vdaf.rs @@ -200,16 +200,13 @@ pub trait Vdaf: Clone + Debug { /// Generate the domain separation tag for this VDAF. The output is used for domain separation /// by the XOF. - fn domain_separation_tag(&self, usage: u16, ctx: &[u8]) -> Vec { + fn domain_separation_tag(&self, usage: u16) -> [u8; 8] { // Prefix is 8 bytes and defined by the spec. Copy these values in - let mut dst = Vec::with_capacity(ctx.len() + 8); - dst.push(VERSION); - dst.push(0); // algorithm class - dst.extend_from_slice(self.algorithm_id().to_be_bytes().as_slice()); - dst.extend_from_slice(usage.to_be_bytes().as_slice()); - // Finally, append user-chosen `ctx` - dst.extend_from_slice(ctx); - + let mut dst = [0; 8]; + dst[0] = VERSION; + dst[1] = 0; // algorithm class + dst[2..6].clone_from_slice(self.algorithm_id().to_be_bytes().as_slice()); + dst[6..8].clone_from_slice(usage.to_be_bytes().as_slice()); dst } } diff --git a/src/vdaf/mastic.rs b/src/vdaf/mastic.rs index 218a4458..fd0fca91 100644 --- a/src/vdaf/mastic.rs +++ b/src/vdaf/mastic.rs @@ -519,7 +519,7 @@ where // Onehot and payload checks let (payload_check, onehot_proof) = { - let mut payload_check_xof = P::init(&[0; SEED_SIZE], b""); + let mut payload_check_xof = P::init(&[0; SEED_SIZE], &[]); let mut payload_check_buf = Vec::with_capacity(T::Field::ENCODED_SIZE); let mut onehot_proof = ONEHOT_PROOF_INIT; @@ -580,7 +580,7 @@ where }; let eval_proof = { - let mut eval_proof_xof = P::init(&[0; SEED_SIZE], b""); + let mut eval_proof_xof = P::init(&[0; SEED_SIZE], &[]); eval_proof_xof.update(&onehot_proof); eval_proof_xof.update(&payload_check); eval_proof_xof.update(&counter_check); diff --git a/src/vdaf/poplar1.rs b/src/vdaf/poplar1.rs index b67c850c..5a54eabd 100644 --- a/src/vdaf/poplar1.rs +++ b/src/vdaf/poplar1.rs @@ -77,7 +77,7 @@ impl, const SEED_SIZE: usize> Poplar1 { P: Xof, F: FieldElement, { - let mut xof = P::init(seed, &self.domain_separation_tag(usage, ctx)); + let mut xof = P::init(seed, &[&self.domain_separation_tag(usage), ctx]); for binder_chunk in binder_chunks.into_iter() { xof.update(binder_chunk.as_ref()); } diff --git a/src/vdaf/prio3.rs b/src/vdaf/prio3.rs index 9d0d65b8..0cd9973a 100644 --- a/src/vdaf/prio3.rs +++ b/src/vdaf/prio3.rs @@ -482,8 +482,8 @@ where fn derive_prove_rands(&self, ctx: &[u8], prove_rand_seed: &Seed) -> Vec { P::seed_stream( prove_rand_seed, - &self.domain_separation_tag(DST_PROVE_RANDOMNESS, ctx), - &[self.num_proofs], + &[&self.domain_separation_tag(DST_PROVE_RANDOMNESS), ctx], + &[&[self.num_proofs]], ) .into_field_vec(self.typ.prove_rand_len() * self.num_proofs()) } @@ -495,7 +495,7 @@ where ) -> Seed { let mut xof = P::init( &[0; SEED_SIZE], - &self.domain_separation_tag(DST_JOINT_RAND_SEED, ctx), + &[&self.domain_separation_tag(DST_JOINT_RAND_SEED), ctx], ); for part in joint_rand_parts { xof.update(part.as_ref()); @@ -511,8 +511,8 @@ where let joint_rand_seed = self.derive_joint_rand_seed(ctx, joint_rand_parts); let joint_rands = P::seed_stream( &joint_rand_seed, - &self.domain_separation_tag(DST_JOINT_RANDOMNESS, ctx), - &[self.num_proofs], + &[&self.domain_separation_tag(DST_JOINT_RANDOMNESS), ctx], + &[&[self.num_proofs]], ) .into_field_vec(self.typ.joint_rand_len() * self.num_proofs()); @@ -527,8 +527,8 @@ where ) -> Prng { Prng::from_seed_stream(P::seed_stream( proofs_share_seed, - &self.domain_separation_tag(DST_PROOF_SHARE, ctx), - &[self.num_proofs, agg_id], + &[&self.domain_separation_tag(DST_PROOF_SHARE), ctx], + &[&[self.num_proofs, agg_id]], )) } @@ -540,7 +540,7 @@ where ) -> Vec { let mut xof = P::init( verify_key, - &self.domain_separation_tag(DST_QUERY_RANDOMNESS, ctx), + &[&self.domain_separation_tag(DST_QUERY_RANDOMNESS), ctx], ); xof.update(&[self.num_proofs]); xof.update(nonce); @@ -605,8 +605,8 @@ where let proof_share_seed = random_seeds.next().unwrap().try_into().unwrap(); let measurement_share_prng: Prng = Prng::from_seed_stream(P::seed_stream( &Seed(measurement_share_seed), - &self.domain_separation_tag(DST_MEASUREMENT_SHARE, ctx), - &[agg_id], + &[&self.domain_separation_tag(DST_MEASUREMENT_SHARE), ctx], + &[&[agg_id]], )); let joint_rand_blind = if let Some(helper_joint_rand_parts) = helper_joint_rand_parts.as_mut() @@ -614,7 +614,7 @@ where let joint_rand_blind = random_seeds.next().unwrap().try_into().unwrap(); let mut joint_rand_part_xof = P::init( &joint_rand_blind, - &self.domain_separation_tag(DST_JOINT_RAND_PART, ctx), + &[&self.domain_separation_tag(DST_JOINT_RAND_PART), ctx], ); joint_rand_part_xof.update(&[agg_id]); // Aggregator ID joint_rand_part_xof.update(nonce); @@ -660,7 +660,7 @@ where let mut joint_rand_part_xof = P::init( leader_blind.as_ref(), - &self.domain_separation_tag(DST_JOINT_RAND_PART, ctx), + &[&self.domain_separation_tag(DST_JOINT_RAND_PART), ctx], ); joint_rand_part_xof.update(&[0]); // Aggregator ID joint_rand_part_xof.update(nonce); @@ -1242,8 +1242,8 @@ where Share::Helper(ref seed) => Cow::Owned( P::seed_stream( seed, - &self.domain_separation_tag(DST_MEASUREMENT_SHARE, ctx), - &[agg_id], + &[&self.domain_separation_tag(DST_MEASUREMENT_SHARE), ctx], + &[&[agg_id]], ) .into_field_vec(self.typ.input_len()), ), @@ -1262,7 +1262,7 @@ where let (joint_rand_seed, joint_rand_part, joint_rands) = if self.typ.joint_rand_len() > 0 { let mut joint_rand_part_xof = P::init( msg.joint_rand_blind.as_ref().unwrap().as_ref(), - &self.domain_separation_tag(DST_JOINT_RAND_PART, ctx), + &[&self.domain_separation_tag(DST_JOINT_RAND_PART), ctx], ); joint_rand_part_xof.update(&[agg_id]); joint_rand_part_xof.update(nonce); @@ -1424,10 +1424,12 @@ where // Compute the output share. let measurement_share = match step.measurement_share { Share::Leader(data) => data, - Share::Helper(seed) => { - let dst = self.domain_separation_tag(DST_MEASUREMENT_SHARE, ctx); - P::seed_stream(&seed, &dst, &[step.agg_id]).into_field_vec(self.typ.input_len()) - } + Share::Helper(seed) => P::seed_stream( + &seed, + &[&self.domain_separation_tag(DST_MEASUREMENT_SHARE), ctx], + &[&[step.agg_id]], + ) + .into_field_vec(self.typ.input_len()), }; let output_share = match self.typ.truncate(measurement_share) { diff --git a/src/vdaf/xof.rs b/src/vdaf/xof.rs index 775445f7..5ed1f0fe 100644 --- a/src/vdaf/xof.rs +++ b/src/vdaf/xof.rs @@ -124,11 +124,11 @@ pub trait Xof: Clone + Debug { type SeedStream: RngCore + Sized; /// Construct an instance of [`Xof`] with the given seed. - fn init(seed_bytes: &[u8; SEED_SIZE], dst: &[u8]) -> Self; + fn init(seed_bytes: &[u8; SEED_SIZE], dst_parts: &[&[u8]]) -> Self; /// Update the XOF state by passing in the next fragment of the info string. The final info /// string is assembled from the concatenation of sequence of fragments passed to this method. - fn update(&mut self, data: &[u8]); + fn update(&mut self, binder_part: &[u8]); /// Finalize the XOF state, producing a seed stream. fn into_seed_stream(self) -> Self::SeedStream; @@ -142,9 +142,15 @@ pub trait Xof: Clone + Debug { } /// Construct a seed stream from the given seed and info string. - fn seed_stream(seed: &Seed, dst: &[u8], binder: &[u8]) -> Self::SeedStream { - let mut xof = Self::init(seed.as_ref(), dst); - xof.update(binder); + fn seed_stream( + seed: &Seed, + dst_parts: &[&[u8]], + binder_parts: &[&[u8]], + ) -> Self::SeedStream { + let mut xof = Self::init(seed.as_ref(), dst_parts); + for binder_part in binder_parts { + xof.update(binder_part); + } xof.into_seed_stream() } } @@ -207,12 +213,16 @@ impl Debug for SeedStreamAes128 { pub struct XofTurboShake128(TurboShake128); impl XofTurboShake128 { - pub(crate) fn from_seed_slice(seed_bytes: &[u8], dst: &[u8]) -> Self { + pub(crate) fn from_seed_slice(seed_bytes: &[u8], dst_parts: &[&[u8]]) -> Self { let mut xof = Self(TurboShake128::from_core(TurboShake128Core::new( XOF_TURBO_SHAKE_128_DOMAIN_SEPARATION, ))); - let Ok(dst_len) = u16::try_from(dst.len()) else { + let dst_len = dst_parts + .iter() + .map(|dst_part| dst_part.len()) + .sum::(); + let Ok(dst_len) = u16::try_from(dst_len) else { panic!("dst must not exceed 65535 bytes"); }; @@ -221,7 +231,9 @@ impl XofTurboShake128 { }; Update::update(&mut xof.0, &dst_len.to_le_bytes()); - Update::update(&mut xof.0, dst); + for dst_part in dst_parts { + Update::update(&mut xof.0, dst_part); + } Update::update(&mut xof.0, &seed_len.to_le_bytes()); Update::update(&mut xof.0, seed_bytes); xof @@ -231,8 +243,8 @@ impl XofTurboShake128 { impl Xof<32> for XofTurboShake128 { type SeedStream = SeedStreamTurboShake128; - fn init(seed_bytes: &[u8; 32], dst: &[u8]) -> Self { - Self::from_seed_slice(&seed_bytes[..], dst) + fn init(seed_bytes: &[u8; 32], dst_parts: &[&[u8]]) -> Self { + Self::from_seed_slice(&seed_bytes[..], dst_parts) } fn update(&mut self, data: &[u8]) { @@ -278,7 +290,7 @@ impl SeedableRng for SeedStreamTurboShake128 { type Seed = [u8; 32]; fn from_seed(seed: Self::Seed) -> Self { - XofTurboShake128::init(&seed, b"").into_seed_stream() + XofTurboShake128::init(&seed, &[]).into_seed_stream() } } @@ -370,16 +382,22 @@ pub struct XofFixedKeyAes128 { impl Xof<16> for XofFixedKeyAes128 { type SeedStream = SeedStreamFixedKeyAes128; - fn init(seed_bytes: &[u8; 16], dst: &[u8]) -> Self { + fn init(seed_bytes: &[u8; 16], dst_parts: &[&[u8]]) -> Self { let mut fixed_key_deriver = TurboShake128::from_core(TurboShake128Core::new(2u8)); + let dst_len = dst_parts + .iter() + .map(|dst_part| dst_part.len()) + .sum::(); Update::update( &mut fixed_key_deriver, - u16::try_from(dst.len()) + u16::try_from(dst_len) .expect("dst must be at most 65535 bytes") .to_le_bytes() .as_slice(), ); - Update::update(&mut fixed_key_deriver, dst); + for dst_part in dst_parts { + Update::update(&mut fixed_key_deriver, dst_part); + } Self { fixed_key_deriver, base_block: (*seed_bytes).into(), @@ -499,13 +517,19 @@ pub struct XofHmacSha256Aes128(Hmac); impl Xof<32> for XofHmacSha256Aes128 { type SeedStream = SeedStreamAes128; - fn init(seed_bytes: &[u8; 32], dst: &[u8]) -> Self { + fn init(seed_bytes: &[u8; 32], dst_parts: &[&[u8]]) -> Self { let mut mac = as Mac>::new_from_slice(seed_bytes).unwrap(); + let dst_len = dst_parts + .iter() + .map(|dst_part| dst_part.len()) + .sum::(); Mac::update( &mut mac, - &[dst.len().try_into().expect("dst must be at most 255 bytes")], + &[dst_len.try_into().expect("dst must be at most 255 bytes")], ); - Mac::update(&mut mac, dst); + for dst_part in dst_parts { + Mac::update(&mut mac, dst_part); + } Self(mac) } @@ -551,7 +575,7 @@ mod tests { let dst = b"algorithm and usage"; let binder = b"bind to artifact"; - let mut xof = P::init(seed.as_ref(), dst); + let mut xof = P::init(seed.as_ref(), &[dst]); xof.update(binder); let mut want = Seed([0; SEED_SIZE]); @@ -562,7 +586,7 @@ mod tests { let mut want = [0; 45]; xof.clone().into_seed_stream().fill_bytes(&mut want); let mut got = [0; 45]; - P::seed_stream(&seed, dst, binder).fill_bytes(&mut got); + P::seed_stream(&seed, &[dst], &[binder]).fill_bytes(&mut got); assert_eq!(got, want); } @@ -570,7 +594,7 @@ mod tests { fn xof_turboshake128() { let t: XofTestVector = serde_json::from_str(include_str!("test_vec/13/XofTurboShake128.json")).unwrap(); - let mut xof = XofTurboShake128::init(&t.seed.try_into().unwrap(), &t.dst); + let mut xof = XofTurboShake128::init(&t.seed.try_into().unwrap(), &[&t.dst]); xof.update(&t.binder); assert_eq!( @@ -594,7 +618,7 @@ mod tests { let t: XofTestVector = serde_json::from_str(include_str!("test_vec/XofHmacSha256Aes128.json")).unwrap(); - let mut xof = XofHmacSha256Aes128::init(&t.seed.try_into().unwrap(), &t.dst); + let mut xof = XofHmacSha256Aes128::init(&t.seed.try_into().unwrap(), &[&t.dst]); xof.update(&t.binder); assert_eq!( @@ -618,7 +642,7 @@ mod tests { fn xof_fixed_key_aes128() { let t: XofTestVector = serde_json::from_str(include_str!("test_vec/13/XofFixedKeyAes128.json")).unwrap(); - let mut xof = XofFixedKeyAes128::init(&t.seed.try_into().unwrap(), &t.dst); + let mut xof = XofFixedKeyAes128::init(&t.seed.try_into().unwrap(), &[&t.dst]); xof.update(&t.binder); assert_eq!( @@ -642,11 +666,11 @@ mod tests { fn xof_fixed_key_aes128_incomplete_block() { let seed = Seed::generate().unwrap(); let mut expected = [0; 32]; - XofFixedKeyAes128::seed_stream(&seed, b"dst", b"binder").fill(&mut expected); + XofFixedKeyAes128::seed_stream(&seed, &[b"dst"], &[b"binder"]).fill(&mut expected); for len in 0..=32 { let mut buf = vec![0; len]; - XofFixedKeyAes128::seed_stream(&seed, b"dst", b"binder").fill(&mut buf); + XofFixedKeyAes128::seed_stream(&seed, &[b"dst"], &[b"binder"]).fill(&mut buf); assert_eq!(buf, &expected[..len]); } } @@ -656,15 +680,16 @@ mod tests { fn xof_fixed_key_aes128_alternate_apis() { let fixed_dst = b"domain separation tag"; let ctx = b"context string"; - let full_dst = [fixed_dst.as_slice(), ctx.as_slice()].concat(); let binder = b"AAAAAAAAAAAAAAAAAAAAAAAA"; let seed_1 = Seed::generate().unwrap(); let seed_2 = Seed::generate().unwrap(); - let mut stream_1_trait_api = XofFixedKeyAes128::seed_stream(&seed_1, &full_dst, binder); + let mut stream_1_trait_api = + XofFixedKeyAes128::seed_stream(&seed_1, &[fixed_dst, ctx], &[binder]); let mut output_1_trait_api = [0u8; 32]; stream_1_trait_api.fill(&mut output_1_trait_api); - let mut stream_2_trait_api = XofFixedKeyAes128::seed_stream(&seed_2, &full_dst, binder); + let mut stream_2_trait_api = + XofFixedKeyAes128::seed_stream(&seed_2, &[fixed_dst, ctx], &[binder]); let mut output_2_trait_api = [0u8; 32]; stream_2_trait_api.fill(&mut output_2_trait_api); diff --git a/src/vidpf.rs b/src/vidpf.rs index 7ffc5165..500bb855 100644 --- a/src/vidpf.rs +++ b/src/vidpf.rs @@ -286,7 +286,8 @@ impl Vidpf { } fn extend(seed: &VidpfSeed, nonce: &[u8]) -> ExtendedSeed { - let mut rng = XofFixedKeyAes128::seed_stream(&Seed(*seed), VidpfDomainSepTag::PRG, nonce); + let mut rng = + XofFixedKeyAes128::seed_stream(&Seed(*seed), &[VidpfDomainSepTag::PRG], &[nonce]); let mut seed_left = VidpfSeed::default(); let mut seed_right = VidpfSeed::default(); @@ -310,7 +311,7 @@ impl Vidpf { fn convert(&self, seed: VidpfSeed, nonce: &[u8]) -> (VidpfSeed, W) { let mut rng = - XofFixedKeyAes128::seed_stream(&Seed(seed), VidpfDomainSepTag::CONVERT, nonce); + XofFixedKeyAes128::seed_stream(&Seed(seed), &[VidpfDomainSepTag::CONVERT], &[nonce]); let mut out_seed = VidpfSeed::default(); rng.fill_bytes(&mut out_seed); @@ -322,8 +323,8 @@ impl Vidpf { pub(crate) fn hash_proof(mut proof: VidpfProof) -> VidpfProof { let mut rng = XofTurboShake128::seed_stream( &Seed(Default::default()), - VidpfDomainSepTag::NODE_PROOF_ADJUST, - &proof, + &[VidpfDomainSepTag::NODE_PROOF_ADJUST], + &[&proof], ); rng.fill_bytes(&mut proof); @@ -763,7 +764,8 @@ impl<'a> VidpfEvalIndex<'a> { } fn node_proof(&self, seed: &VidpfSeed) -> VidpfProof { - let mut xof = XofTurboShake128::from_seed_slice(&seed[..], VidpfDomainSepTag::NODE_PROOF); + let mut xof = + XofTurboShake128::from_seed_slice(&seed[..], &[VidpfDomainSepTag::NODE_PROOF]); xof.update(&self.level.to_le_bytes()); for byte in self