Skip to content

Commit

Permalink
Add XofHmacSha256Aes128
Browse files Browse the repository at this point in the history
An XOF based on HMAC-SHA256 and AES128. This XOF does not appear in the
VDAF spec.
  • Loading branch information
cjpatton committed Jan 11, 2024
1 parent b489d33 commit af309a8
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ default = ["crypto-dependencies"]
experimental = ["bitvec", "fiat-crypto", "fixed", "num-bigint", "num-rational", "num-traits", "num-integer", "num-iter", "rand"]
multithreaded = ["rayon"]
prio2 = ["crypto-dependencies", "hmac", "sha2"]
crypto-dependencies = ["aes", "ctr"]
crypto-dependencies = ["aes", "ctr", "hmac", "sha2"]
test-util = ["hex", "rand", "serde_json"]

[workspace]
Expand Down
8 changes: 8 additions & 0 deletions src/vdaf/test_vec/XofHmacSha256Aes128.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"binder": "62696e64657220737472696e67",
"derived_seed": "e826c9564c620fb63357fbee88dc9bb3de2c41764adb44bea344024e1da124c6",
"dst": "646f6d61696e2073657061726174696f6e20746167",
"expanded_vec_field128": "e826c9564c620fb63357fbee88dc9bb3de2c41764adb44bea344024e1da124c6172f208e79762fed92c73cea422b312860008ee80e30f31d2d87840890604f39db37983f5c3483407333cecdb1b9ea550c26bc4f2d999fda91963054c6cb35a8ad8d28ee74a48e28aa475d67124e7c4417149955e506690d62e17f0730b7d4db8a9754f80603b7720205819d26bcfe4a4663d05c98c12705ea7dc333d5746d9c8ba697bb3d5be95d26ccb73052cb8fb19edfc35eaebaa22779436d3015512c9b536003d98b04a0f46feddbff762007c377c28a04039f72657650885bd40ed37acea63facd3c33d1ecb5048641053af5b4018b0c373d9ed7440da9fc6c76666c2eb8ed2943a64bbf6dae93ac91fcc26d7225c2ae42349161522fcce0b92d209411af8566b0adbaa36a8479737017efd2c359ea43924cdf432650dcd742e358af55ff6c321d0ebaae2abf5812d58b060cc147395e8137f99db58d2c425f2704da067df3a41c0443918375c177fa53545d8190d828c6045bbe5930e4762588ea14dc0a9db6cd903216ccae968ca0b11f0ac04e4dfc69a99986841dc99c851e314c7d4b10f4ef72e1244b543465fed076a7e9f50baca4ad7dccc73bfc55310f2ae6eaeaf7ee7a4d41fec76bff3b04e67d1f83e4da59f1fcb45877adfc3e4a2b1d5e3f136131ca2a02f34bdba1c5d2dafb2178674dc002d247662497b7f5818880cff308e5222e6df0bcdf6f68ebfaa8d0551530fa00ec29646441961e33b50872ada911591e16e3021baa5e7869756d3d812a63e3c7fa2c0ec2dc4cabe11c0256829b360ad9431536ab96efbe5a364cd1c323de8fbe405a2c87b9c58e5740bfb118af0ca1a23afb4a04e9cec3b9d1e57834cbc0fa17d5d7285f1f013df05e92a7343",
"length": 40,
"seed": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
}
56 changes: 56 additions & 0 deletions src/vdaf/xof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ use aes::{
};
#[cfg(feature = "crypto-dependencies")]
use ctr::Ctr64BE;
#[cfg(feature = "crypto-dependencies")]
use hmac::{Hmac, Mac};
use rand_core::{
impls::{next_u32_via_fill, next_u64_via_fill},
RngCore, SeedableRng,
};
#[cfg(feature = "crypto-dependencies")]
use sha2::Sha256;
use sha3::{
digest::{ExtendableOutput, Update, XofReader},
TurboShake128, TurboShake128Core, TurboShake128Reader,
Expand Down Expand Up @@ -446,6 +450,34 @@ impl RngCore for SeedStreamFixedKeyAes128 {
}
}

/// XOF based on HMAC-SHA256 and AES128. This XOF is not part of the VDAF spec.
#[derive(Clone, Debug)]
pub struct XofHmacSha256Aes128(Hmac<Sha256>);

impl Xof<32> for XofHmacSha256Aes128 {
type SeedStream = SeedStreamAes128;

fn init(seed_bytes: &[u8; 32], dst: &[u8]) -> Self {
let mut mac = <Hmac<Sha256> as Mac>::new_from_slice(seed_bytes).unwrap();
Mac::update(
&mut mac,
&[dst.len().try_into().expect("dst must be at most 255 bytes")],
);
Mac::update(&mut mac, dst);
Self(mac)
}

fn update(&mut self, data: &[u8]) {
Mac::update(&mut self.0, data);
}

fn into_seed_stream(self) -> SeedStreamAes128 {
let tag = Mac::finalize(self.0).into_bytes();
let (key, iv) = tag.split_at(16);
SeedStreamAes128::new(key, iv)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -515,6 +547,30 @@ mod tests {
test_xof::<XofTurboShake128, 16>();
}

#[test]
fn xof_hmac_sha256_aes128() {
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);
xof.update(&t.binder);

assert_eq!(
xof.clone().into_seed(),
Seed(t.derived_seed.try_into().unwrap())
);

let mut bytes = Cursor::new(t.expanded_vec_field128.as_slice());
let mut want = Vec::with_capacity(t.length);
while (bytes.position() as usize) < t.expanded_vec_field128.len() {
want.push(Field128::decode(&mut bytes).unwrap())
}
let got: Vec<Field128> = xof.clone().into_seed_stream().into_field_vec(t.length);
assert_eq!(got, want);

test_xof::<XofHmacSha256Aes128, 32>();
}

#[cfg(feature = "experimental")]
#[test]
fn xof_fixed_key_aes128() {
Expand Down

0 comments on commit af309a8

Please sign in to comment.