mirror of
https://github.com/saymrwulf/fips205-source.git
synced 2026-09-03 19:53:49 +00:00
shaky, shaky
This commit is contained in:
parent
8c03d1f9c3
commit
ab0f62369a
13 changed files with 421 additions and 226 deletions
|
|
@ -30,8 +30,8 @@ use fips205::traits::{SerDes, Signer, Verifier};
|
|||
let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
// Generate key pair and signature
|
||||
let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate signature
|
||||
let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate signature
|
||||
|
||||
// Serialize the public key, and send with message and signature bytes
|
||||
let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -39,7 +39,7 @@ let (pk_recv, msg_recv, sig_recv) = (pk_send, msg_send, sig_send);
|
|||
|
||||
// Deserialize the public key, then use it to verify the msg signature
|
||||
let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
assert!(v);
|
||||
# Ok(())
|
||||
# }
|
||||
|
|
|
|||
|
|
@ -12,117 +12,117 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
let message = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
let randomize = false;
|
||||
|
||||
let (pk_sha2_128s, sk_sha2_128s) = slh_dsa_sha2_128s::KG::try_keygen_vt().unwrap();
|
||||
let (pk_sha2_128f, sk_sha2_128f) = slh_dsa_sha2_128f::KG::try_keygen_vt().unwrap();
|
||||
let (pk_sha2_192s, sk_sha2_192s) = slh_dsa_sha2_192s::KG::try_keygen_vt().unwrap();
|
||||
let (pk_sha2_192f, sk_sha2_192f) = slh_dsa_sha2_192f::KG::try_keygen_vt().unwrap();
|
||||
let (pk_sha2_256s, sk_sha2_256s) = slh_dsa_sha2_256s::KG::try_keygen_vt().unwrap();
|
||||
let (pk_sha2_256f, sk_sha2_256f) = slh_dsa_sha2_256f::KG::try_keygen_vt().unwrap();
|
||||
let (pk_shake_128s, sk_shake_128s) = slh_dsa_shake_128s::KG::try_keygen_vt().unwrap();
|
||||
let (pk_shake_128f, sk_shake_128f) = slh_dsa_shake_128f::KG::try_keygen_vt().unwrap();
|
||||
let (pk_shake_192s, sk_shake_192s) = slh_dsa_shake_192s::KG::try_keygen_vt().unwrap();
|
||||
let (pk_shake_192f, sk_shake_192f) = slh_dsa_shake_192f::KG::try_keygen_vt().unwrap();
|
||||
let (pk_shake_256s, sk_shake_256s) = slh_dsa_shake_256s::KG::try_keygen_vt().unwrap();
|
||||
let (pk_shake_256f, sk_shake_256f) = slh_dsa_shake_256f::KG::try_keygen_vt().unwrap();
|
||||
let (pk_sha2_128s, sk_sha2_128s) = slh_dsa_sha2_128s::KG::try_keygen().unwrap();
|
||||
let (pk_sha2_128f, sk_sha2_128f) = slh_dsa_sha2_128f::KG::try_keygen().unwrap();
|
||||
let (pk_sha2_192s, sk_sha2_192s) = slh_dsa_sha2_192s::KG::try_keygen().unwrap();
|
||||
let (pk_sha2_192f, sk_sha2_192f) = slh_dsa_sha2_192f::KG::try_keygen().unwrap();
|
||||
let (pk_sha2_256s, sk_sha2_256s) = slh_dsa_sha2_256s::KG::try_keygen().unwrap();
|
||||
let (pk_sha2_256f, sk_sha2_256f) = slh_dsa_sha2_256f::KG::try_keygen().unwrap();
|
||||
let (pk_shake_128s, sk_shake_128s) = slh_dsa_shake_128s::KG::try_keygen().unwrap();
|
||||
let (pk_shake_128f, sk_shake_128f) = slh_dsa_shake_128f::KG::try_keygen().unwrap();
|
||||
let (pk_shake_192s, sk_shake_192s) = slh_dsa_shake_192s::KG::try_keygen().unwrap();
|
||||
let (pk_shake_192f, sk_shake_192f) = slh_dsa_shake_192f::KG::try_keygen().unwrap();
|
||||
let (pk_shake_256s, sk_shake_256s) = slh_dsa_shake_256s::KG::try_keygen().unwrap();
|
||||
let (pk_shake_256f, sk_shake_256f) = slh_dsa_shake_256f::KG::try_keygen().unwrap();
|
||||
|
||||
let sig_sha2_128s = sk_sha2_128s.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_sha2_128f = sk_sha2_128f.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_sha2_192s = sk_sha2_192s.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_sha2_192f = sk_sha2_192f.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_sha2_256s = sk_sha2_256s.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_sha2_256f = sk_sha2_256f.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_shake_128s = sk_shake_128s.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_shake_128f = sk_shake_128f.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_shake_192s = sk_shake_192s.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_shake_192f = sk_shake_192f.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_shake_256s = sk_shake_256s.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_shake_256f = sk_shake_256f.try_sign_ct(&message, randomize).unwrap();
|
||||
let sig_sha2_128s = sk_sha2_128s.try_sign(&message, randomize).unwrap();
|
||||
let sig_sha2_128f = sk_sha2_128f.try_sign(&message, randomize).unwrap();
|
||||
let sig_sha2_192s = sk_sha2_192s.try_sign(&message, randomize).unwrap();
|
||||
let sig_sha2_192f = sk_sha2_192f.try_sign(&message, randomize).unwrap();
|
||||
let sig_sha2_256s = sk_sha2_256s.try_sign(&message, randomize).unwrap();
|
||||
let sig_sha2_256f = sk_sha2_256f.try_sign(&message, randomize).unwrap();
|
||||
let sig_shake_128s = sk_shake_128s.try_sign(&message, randomize).unwrap();
|
||||
let sig_shake_128f = sk_shake_128f.try_sign(&message, randomize).unwrap();
|
||||
let sig_shake_192s = sk_shake_192s.try_sign(&message, randomize).unwrap();
|
||||
let sig_shake_192f = sk_shake_192f.try_sign(&message, randomize).unwrap();
|
||||
let sig_shake_256s = sk_shake_256s.try_sign(&message, randomize).unwrap();
|
||||
let sig_shake_256f = sk_shake_256f.try_sign(&message, randomize).unwrap();
|
||||
|
||||
c.bench_function("sha2_128f keygen", |b| b.iter(|| slh_dsa_sha2_128f::KG::try_keygen_vt()));
|
||||
c.bench_function("sha2_192f keygen", |b| b.iter(|| slh_dsa_sha2_192f::KG::try_keygen_vt()));
|
||||
c.bench_function("sha2_256f keygen", |b| b.iter(|| slh_dsa_sha2_256f::KG::try_keygen_vt()));
|
||||
c.bench_function("shake_128f keygen", |b| b.iter(|| slh_dsa_shake_128f::KG::try_keygen_vt()));
|
||||
c.bench_function("shake_192f keygen", |b| b.iter(|| slh_dsa_shake_192f::KG::try_keygen_vt()));
|
||||
c.bench_function("shake_256f keygen", |b| b.iter(|| slh_dsa_shake_256f::KG::try_keygen_vt()));
|
||||
c.bench_function("sha2_128s keygen", |b| b.iter(|| slh_dsa_sha2_128s::KG::try_keygen_vt()));
|
||||
c.bench_function("sha2_192s keygen", |b| b.iter(|| slh_dsa_sha2_192s::KG::try_keygen_vt()));
|
||||
c.bench_function("sha2_256s keygen", |b| b.iter(|| slh_dsa_sha2_256s::KG::try_keygen_vt()));
|
||||
c.bench_function("shake_128s keygen", |b| b.iter(|| slh_dsa_shake_128s::KG::try_keygen_vt()));
|
||||
c.bench_function("shake_192s keygen", |b| b.iter(|| slh_dsa_shake_192s::KG::try_keygen_vt()));
|
||||
c.bench_function("shake_256s keygen", |b| b.iter(|| slh_dsa_shake_256s::KG::try_keygen_vt()));
|
||||
c.bench_function("sha2_128f keygen", |b| b.iter(|| slh_dsa_sha2_128f::KG::try_keygen()));
|
||||
c.bench_function("sha2_192f keygen", |b| b.iter(|| slh_dsa_sha2_192f::KG::try_keygen()));
|
||||
c.bench_function("sha2_256f keygen", |b| b.iter(|| slh_dsa_sha2_256f::KG::try_keygen()));
|
||||
c.bench_function("shake_128f keygen", |b| b.iter(|| slh_dsa_shake_128f::KG::try_keygen()));
|
||||
c.bench_function("shake_192f keygen", |b| b.iter(|| slh_dsa_shake_192f::KG::try_keygen()));
|
||||
c.bench_function("shake_256f keygen", |b| b.iter(|| slh_dsa_shake_256f::KG::try_keygen()));
|
||||
c.bench_function("sha2_128s keygen", |b| b.iter(|| slh_dsa_sha2_128s::KG::try_keygen()));
|
||||
c.bench_function("sha2_192s keygen", |b| b.iter(|| slh_dsa_sha2_192s::KG::try_keygen()));
|
||||
c.bench_function("sha2_256s keygen", |b| b.iter(|| slh_dsa_sha2_256s::KG::try_keygen()));
|
||||
c.bench_function("shake_128s keygen", |b| b.iter(|| slh_dsa_shake_128s::KG::try_keygen()));
|
||||
c.bench_function("shake_192s keygen", |b| b.iter(|| slh_dsa_shake_192s::KG::try_keygen()));
|
||||
c.bench_function("shake_256s keygen", |b| b.iter(|| slh_dsa_shake_256s::KG::try_keygen()));
|
||||
//
|
||||
c.bench_function("sha2_128f sign ", |b| {
|
||||
b.iter(|| sk_sha2_128f.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_sha2_128f.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("sha2_192f sign ", |b| {
|
||||
b.iter(|| sk_sha2_192f.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_sha2_192f.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("sha2_256f sign ", |b| {
|
||||
b.iter(|| sk_sha2_256f.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_sha2_256f.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("shake_128f sign ", |b| {
|
||||
b.iter(|| sk_shake_128f.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_shake_128f.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("shake_192f sign ", |b| {
|
||||
b.iter(|| sk_shake_192f.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_shake_192f.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("shake_256f sign ", |b| {
|
||||
b.iter(|| sk_shake_256f.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_shake_256f.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("sha2_128s sign ", |b| {
|
||||
b.iter(|| sk_sha2_128s.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_sha2_128s.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("sha2_192s sign ", |b| {
|
||||
b.iter(|| sk_sha2_192s.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_sha2_192s.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("sha2_256s sign ", |b| {
|
||||
b.iter(|| sk_sha2_256s.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_sha2_256s.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("shake_128s sign ", |b| {
|
||||
b.iter(|| sk_shake_128s.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_shake_128s.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("shake_192s sign ", |b| {
|
||||
b.iter(|| sk_shake_192s.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_shake_192s.try_sign(&message, randomize))
|
||||
});
|
||||
c.bench_function("shake_256s sign ", |b| {
|
||||
b.iter(|| sk_shake_256s.try_sign_ct(&message, randomize))
|
||||
b.iter(|| sk_shake_256s.try_sign(&message, randomize))
|
||||
});
|
||||
//
|
||||
c.bench_function("sha2_128f verify", |b| {
|
||||
b.iter(|| pk_sha2_128f.try_verify_vt(&message, &sig_sha2_128f))
|
||||
b.iter(|| pk_sha2_128f.try_verify(&message, &sig_sha2_128f))
|
||||
});
|
||||
c.bench_function("sha2_192f verify", |b| {
|
||||
b.iter(|| pk_sha2_192f.try_verify_vt(&message, &sig_sha2_192f))
|
||||
b.iter(|| pk_sha2_192f.try_verify(&message, &sig_sha2_192f))
|
||||
});
|
||||
c.bench_function("sha2_256f verify", |b| {
|
||||
b.iter(|| pk_sha2_256f.try_verify_vt(&message, &sig_sha2_256f))
|
||||
b.iter(|| pk_sha2_256f.try_verify(&message, &sig_sha2_256f))
|
||||
});
|
||||
c.bench_function("shake_128f verify", |b| {
|
||||
b.iter(|| pk_shake_128f.try_verify_vt(&message, &sig_shake_128f))
|
||||
b.iter(|| pk_shake_128f.try_verify(&message, &sig_shake_128f))
|
||||
});
|
||||
c.bench_function("shake_192f verify", |b| {
|
||||
b.iter(|| pk_shake_192f.try_verify_vt(&message, &sig_shake_192f))
|
||||
b.iter(|| pk_shake_192f.try_verify(&message, &sig_shake_192f))
|
||||
});
|
||||
c.bench_function("shake_256f verify", |b| {
|
||||
b.iter(|| pk_shake_256f.try_verify_vt(&message, &sig_shake_256f))
|
||||
b.iter(|| pk_shake_256f.try_verify(&message, &sig_shake_256f))
|
||||
});
|
||||
c.bench_function("sha2_128s verify", |b| {
|
||||
b.iter(|| pk_sha2_128s.try_verify_vt(&message, &sig_sha2_128s))
|
||||
b.iter(|| pk_sha2_128s.try_verify(&message, &sig_sha2_128s))
|
||||
});
|
||||
c.bench_function("sha2_192s verify", |b| {
|
||||
b.iter(|| pk_sha2_192s.try_verify_vt(&message, &sig_sha2_192s))
|
||||
b.iter(|| pk_sha2_192s.try_verify(&message, &sig_sha2_192s))
|
||||
});
|
||||
c.bench_function("sha2_256s verify", |b| {
|
||||
b.iter(|| pk_sha2_256s.try_verify_vt(&message, &sig_sha2_256s))
|
||||
b.iter(|| pk_sha2_256s.try_verify(&message, &sig_sha2_256s))
|
||||
});
|
||||
c.bench_function("shake_128s verify", |b| {
|
||||
b.iter(|| pk_shake_128s.try_verify_vt(&message, &sig_shake_128s))
|
||||
b.iter(|| pk_shake_128s.try_verify(&message, &sig_shake_128s))
|
||||
});
|
||||
c.bench_function("shake_192s verify", |b| {
|
||||
b.iter(|| pk_shake_192s.try_verify_vt(&message, &sig_shake_192s))
|
||||
b.iter(|| pk_shake_192s.try_verify(&message, &sig_shake_192s))
|
||||
});
|
||||
c.bench_function("shake_256s verify", |b| {
|
||||
b.iter(|| pk_shake_256s.try_verify_vt(&message, &sig_shake_256s))
|
||||
b.iter(|| pk_shake_256s.try_verify(&message, &sig_shake_256s))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ fn sign(runner: &mut CtRunner, mut _rng: &mut BenchRng) {
|
|||
|
||||
let message = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
let (_pk1, sk1) = slh_dsa_shake_128s::try_keygen_vt().unwrap(); // Generate both public and secret keys
|
||||
let (_pk2, sk2) = slh_dsa_shake_128s::try_keygen_vt().unwrap(); // Generate both public and secret keys
|
||||
let (_pk1, sk1) = slh_dsa_shake_128s::try_keygen().unwrap(); // Generate both public and secret keys
|
||||
let (_pk2, sk2) = slh_dsa_shake_128s::try_keygen().unwrap(); // Generate both public and secret keys
|
||||
|
||||
let mut inputs: Vec<slh_dsa_shake_128s::PrivateKey> = Vec::new();
|
||||
let mut classes = Vec::new();
|
||||
|
|
@ -27,7 +27,7 @@ fn sign(runner: &mut CtRunner, mut _rng: &mut BenchRng) {
|
|||
for (class, input) in classes.into_iter().zip(inputs.into_iter()) {
|
||||
runner.run_one(class, || {
|
||||
for _ in 0..ITERATIONS_INNER {
|
||||
let _ = input.try_sign_ct(&message, true);
|
||||
let _ = input.try_sign(&message, true);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub extern "C" fn slh_dsa_sha2_128f_keygen(
|
|||
let (Some(public_out), Some(private_out)) = (public_out, private_out) else {
|
||||
return SLH_DSA_NULL_PTR_ERROR;
|
||||
};
|
||||
let Ok((pk, sk)) = fips205::slh_dsa_sha2_128f::KG::try_keygen_vt() else {
|
||||
let Ok((pk, sk)) = fips205::slh_dsa_sha2_128f::KG::try_keygen() else {
|
||||
return SLH_DSA_KEYGEN_ERROR;
|
||||
};
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ pub extern "C" fn slh_dsa_sha2_128f_sign(
|
|||
let Ok(sk) = fips205::slh_dsa_sha2_128f::PrivateKey::try_from_bytes(&private_key.data) else {
|
||||
return SLH_DSA_DESERIALIZATION_ERROR;
|
||||
};
|
||||
let Ok(sig) = sk.try_sign_ct(&message, true) else {
|
||||
let Ok(sig) = sk.try_sign(&message, true) else {
|
||||
return SLH_DSA_SIGN_ERROR;
|
||||
};
|
||||
signature_out.data = sig;
|
||||
|
|
@ -98,7 +98,7 @@ pub extern "C" fn slh_dsa_sha2_128f_verify(
|
|||
let Ok(sk) = fips205::slh_dsa_sha2_128f::PublicKey::try_from_bytes(&public_key.data) else {
|
||||
return SLH_DSA_DESERIALIZATION_ERROR;
|
||||
};
|
||||
let res = sk.try_verify_vt(&message, &signature.data);
|
||||
let res = sk.try_verify(&message, &signature.data);
|
||||
|
||||
if res.is_ok() && res.unwrap() {
|
||||
SLH_DSA_OK
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use crate::types::Adrs;
|
|||
// Holds hasher function references; constructed by each security parameter set wrapper
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) struct Hashers<const K: usize, const LEN: usize, const M: usize, const N: usize> {
|
||||
pub(crate) h_msg: fn(&[u8], &[u8], &[u8], &[u8]) -> [u8; M],
|
||||
pub(crate) h_msg: fn(&[u8], &[u8], &[u8], &[&[u8]]) -> [u8; M],
|
||||
pub(crate) prf: fn(&[u8], &[u8], &Adrs) -> [u8; N],
|
||||
pub(crate) prf_msg: fn(&[u8], &[u8], &[u8]) -> [u8; N],
|
||||
pub(crate) prf_msg: fn(&[u8], &[u8], &[&[u8]]) -> [u8; N],
|
||||
pub(crate) f: fn(&[u8], &Adrs, &[u8]) -> [u8; N],
|
||||
pub(crate) h: fn(&[u8], &Adrs, &[u8], &[u8]) -> [u8; N],
|
||||
pub(crate) t_l: fn(&[u8], &Adrs, &[[u8; N]; LEN]) -> [u8; N],
|
||||
|
|
@ -37,10 +37,12 @@ pub(crate) mod shake {
|
|||
|
||||
|
||||
pub(crate) fn h_msg<const M: usize>(
|
||||
r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[u8],
|
||||
r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[&[u8]],
|
||||
) -> [u8; M] {
|
||||
let mut digest = [0u8; M];
|
||||
shake256(&[r, pk_seed, pk_root, m], &mut digest);
|
||||
let mut inp = [r, pk_seed, pk_root, &[], &[], &[], &[], &[]];
|
||||
inp[3..3 + m.len()].copy_from_slice(m); // m can have up to 5 elements
|
||||
shake256(&inp, &mut digest);
|
||||
digest
|
||||
}
|
||||
|
||||
|
|
@ -53,9 +55,11 @@ pub(crate) mod shake {
|
|||
}
|
||||
|
||||
|
||||
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8]) -> [u8; N] {
|
||||
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[&[u8]]) -> [u8; N] {
|
||||
let mut digest = [0u8; N];
|
||||
shake256(&[sk_prf, opt_rand, m], &mut digest);
|
||||
let mut inp = [sk_prf, opt_rand, &[], &[], &[], &[], &[]];
|
||||
inp[2..2 + m.len()].copy_from_slice(m); // m can have up to 5 elements
|
||||
shake256(&inp, &mut digest);
|
||||
digest
|
||||
}
|
||||
|
||||
|
|
@ -106,10 +110,12 @@ pub(crate) mod sha2_cat_1 {
|
|||
|
||||
|
||||
pub(crate) fn h_msg<const M: usize>(
|
||||
r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[u8],
|
||||
r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[&[u8]],
|
||||
) -> [u8; M] {
|
||||
let mut digest1 = [0u8; 32];
|
||||
sha2_256(&[r, pk_seed, pk_root, m], &mut digest1);
|
||||
let mut inp = [r, pk_seed, pk_root, &[], &[], &[], &[], &[]];
|
||||
inp[3..3 + m.len()].copy_from_slice(m); // m can have up to 5 elements
|
||||
sha2_256(&inp, &mut digest1);
|
||||
let mut result = [0u8; M];
|
||||
let mut start = 0;
|
||||
let mut counter = 0u32;
|
||||
|
|
@ -134,7 +140,7 @@ pub(crate) mod sha2_cat_1 {
|
|||
}
|
||||
|
||||
|
||||
fn hmac_sha_256(key: &[u8], a0: &[u8], b1: &[u8]) -> [u8; 32] {
|
||||
fn hmac_sha_256(key: &[u8], a0: &[u8], m: &[&[u8]]) -> [u8; 32] {
|
||||
let mut padding = [0x36; 64];
|
||||
for (p, &k) in padding.iter_mut().zip(key.iter()) {
|
||||
*p ^= k;
|
||||
|
|
@ -142,7 +148,9 @@ pub(crate) mod sha2_cat_1 {
|
|||
let mut inner_hasher = Sha256::new();
|
||||
inner_hasher.update(&padding[..]);
|
||||
inner_hasher.update(a0);
|
||||
inner_hasher.update(b1);
|
||||
for i in m {
|
||||
inner_hasher.update(i);
|
||||
}
|
||||
for p in &mut padding {
|
||||
*p ^= 0x6a;
|
||||
}
|
||||
|
|
@ -153,7 +161,7 @@ pub(crate) mod sha2_cat_1 {
|
|||
}
|
||||
|
||||
|
||||
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8]) -> [u8; N] {
|
||||
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[&[u8]]) -> [u8; N] {
|
||||
let mut digest = [0u8; N];
|
||||
let full_digest = hmac_sha_256(sk_prf, opt_rand, m);
|
||||
digest.copy_from_slice(&full_digest[0..N]);
|
||||
|
|
@ -223,10 +231,12 @@ pub(crate) mod sha2_cat_3_5 {
|
|||
|
||||
|
||||
pub(crate) fn h_msg<const M: usize>(
|
||||
r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[u8],
|
||||
r: &[u8], pk_seed: &[u8], pk_root: &[u8], m: &[&[u8]],
|
||||
) -> [u8; M] {
|
||||
let mut digest1 = [0u8; 64];
|
||||
sha2_512(&[r, pk_seed, pk_root, m], &mut digest1);
|
||||
let mut inp = [r, pk_seed, pk_root, &[], &[], &[], &[], &[]];
|
||||
inp[3..3 + m.len()].copy_from_slice(m); // m can have up to 5 elements
|
||||
sha2_512(&inp, &mut digest1);
|
||||
let mut result = [0u8; M];
|
||||
let mut start = 0;
|
||||
let mut counter = 0u32;
|
||||
|
|
@ -251,7 +261,7 @@ pub(crate) mod sha2_cat_3_5 {
|
|||
}
|
||||
|
||||
|
||||
fn hmac_sha_512(key: &[u8], a0: &[u8], b1: &[u8]) -> [u8; 64] {
|
||||
fn hmac_sha_512(key: &[u8], a0: &[u8], m: &[&[u8]]) -> [u8; 64] {
|
||||
let mut padding = [0x36; 128];
|
||||
for (p, &k) in padding.iter_mut().zip(key.iter()) {
|
||||
*p ^= k;
|
||||
|
|
@ -259,7 +269,9 @@ pub(crate) mod sha2_cat_3_5 {
|
|||
let mut inner_hasher = Sha512::new();
|
||||
inner_hasher.update(&padding[..]);
|
||||
inner_hasher.update(a0);
|
||||
inner_hasher.update(b1);
|
||||
for i in m {
|
||||
inner_hasher.update(i);
|
||||
}
|
||||
for p in &mut padding {
|
||||
*p ^= 0x6a;
|
||||
}
|
||||
|
|
@ -270,7 +282,7 @@ pub(crate) mod sha2_cat_3_5 {
|
|||
}
|
||||
|
||||
|
||||
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[u8]) -> [u8; N] {
|
||||
pub(crate) fn prf_msg<const N: usize>(sk_prf: &[u8], opt_rand: &[u8], m: &[&[u8]]) -> [u8; N] {
|
||||
let mut digest = [0u8; N];
|
||||
let full_digest = hmac_sha_512(sk_prf, opt_rand, m);
|
||||
digest.copy_from_slice(&full_digest[0..N]);
|
||||
|
|
|
|||
151
src/lib.rs
151
src/lib.rs
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
/// All functionality is covered by traits, such that consumers can utilize trait objects as desired.
|
||||
pub mod traits;
|
||||
pub use types::Ph;
|
||||
|
||||
mod fors;
|
||||
mod hashers;
|
||||
|
|
@ -104,8 +105,8 @@ macro_rules! functionality {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -113,14 +114,14 @@ macro_rules! functionality {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(feature = "default-rng")]
|
||||
pub fn try_keygen_vt() -> Result<(PublicKey, PrivateKey), &'static str> {
|
||||
KG::try_keygen_vt()
|
||||
pub fn try_keygen() -> Result<(PublicKey, PrivateKey), &'static str> {
|
||||
KG::try_keygen()
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -142,16 +143,16 @@ macro_rules! functionality {
|
|||
/// let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(123);
|
||||
///
|
||||
/// // Generate key pair and signature
|
||||
/// let (pk, sk) = slh_dsa_shake_128s::try_keygen_with_rng_vt(&mut rng)?; // Generate both public and secret keys
|
||||
/// let sig = sk.try_sign_ct(&message, true)?; // Use the secret key to generate a message signature ///
|
||||
/// let v = pk.try_verify_vt(&message, &sig)?;
|
||||
/// let (pk, sk) = slh_dsa_shake_128s::try_keygen_with_rng(&mut rng)?; // Generate both public and secret keys
|
||||
/// let sig = sk.try_sign(&message, b"context", true)?; // Use the secret key to generate a message signature ///
|
||||
/// let v = pk.try_verify(&message, &sig, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())}
|
||||
/// ```
|
||||
pub fn try_keygen_with_rng_vt(
|
||||
pub fn try_keygen_with_rng(
|
||||
rng: &mut impl CryptoRngCore,
|
||||
) -> Result<(PublicKey, PrivateKey), &'static str> {
|
||||
KG::try_keygen_with_rng_vt(rng)
|
||||
KG::try_keygen_with_rng(rng)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -159,7 +160,7 @@ macro_rules! functionality {
|
|||
type PrivateKey = PrivateKey;
|
||||
type PublicKey = PublicKey;
|
||||
|
||||
fn try_keygen_with_rng_vt(
|
||||
fn try_keygen_with_rng(
|
||||
rng: &mut impl CryptoRngCore,
|
||||
) -> Result<(PublicKey, PrivateKey), &'static str> {
|
||||
let res = crate::slh::slh_keygen_with_rng::<D, H, HP, K, LEN, M, N>(rng, &HASHERS);
|
||||
|
|
@ -171,11 +172,35 @@ macro_rules! functionality {
|
|||
impl Signer for PrivateKey {
|
||||
type Signature = [u8; SIG_LEN];
|
||||
|
||||
fn try_sign_with_rng_ct(
|
||||
&self, rng: &mut impl CryptoRngCore, m: &[u8], randomize: bool,
|
||||
fn try_sign_with_rng(
|
||||
&self, rng: &mut impl CryptoRngCore, m: &[u8], ctx: &[u8], randomize: bool,
|
||||
) -> Result<[u8; SIG_LEN], &'static str> {
|
||||
let sig = crate::slh::slh_sign_with_rng::<A, D, H, HP, K, LEN, M, N>(
|
||||
rng, &HASHERS, &m, &self.0, randomize,
|
||||
rng, &HASHERS, &m, &self.0, ctx, randomize,
|
||||
);
|
||||
sig.map(|s| s.deserialize())
|
||||
}
|
||||
|
||||
/// blah!
|
||||
/// # Errors
|
||||
fn _test_only_raw_sign(
|
||||
&self, rng: &mut impl CryptoRngCore, m: &[u8], randomize: bool,
|
||||
) -> Result<[u8; SIG_LEN], &'static str> {
|
||||
let mut opt_rand = (self.0).pk_seed;
|
||||
|
||||
// 4: if (RANDOMIZE) then ▷ or to a random n-byte string
|
||||
if randomize {
|
||||
// 5: opt_rand ←$ Bn
|
||||
rng.try_fill_bytes(&mut opt_rand)
|
||||
.map_err(|_| "Alg17: rng failed")?;
|
||||
|
||||
// 6: end if
|
||||
}
|
||||
let sig = crate::slh::slh_sign_internal::<A, D, H, HP, K, LEN, M, N>(
|
||||
&HASHERS,
|
||||
&[m],
|
||||
&self.0,
|
||||
opt_rand,
|
||||
);
|
||||
sig.map(|s| s.deserialize())
|
||||
}
|
||||
|
|
@ -185,12 +210,22 @@ macro_rules! functionality {
|
|||
impl Verifier for PublicKey {
|
||||
type Signature = [u8; SIG_LEN];
|
||||
|
||||
fn try_verify_vt(
|
||||
&self, m: &[u8], sig_bytes: &[u8; SIG_LEN],
|
||||
fn try_verify(
|
||||
&self, m: &[u8], sig_bytes: &[u8; SIG_LEN], ctx: &[u8],
|
||||
) -> Result<bool, &'static str> {
|
||||
let sig = SlhDsaSig::<A, D, HP, K, LEN, N>::serialize(sig_bytes);
|
||||
let res = crate::slh::slh_verify::<A, D, H, HP, K, LEN, M, N>(
|
||||
&HASHERS, &m, &sig, &self.0,
|
||||
&HASHERS, &m, &sig, ctx, &self.0,
|
||||
);
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn _test_only_raw_verify(
|
||||
&self, m: &[u8], sig_bytes: &[u8; SIG_LEN],
|
||||
) -> Result<bool, &'static str> {
|
||||
let sig = SlhDsaSig::<A, D, HP, K, LEN, N>::serialize(sig_bytes);
|
||||
let res = crate::slh::slh_verify_internal::<A, D, H, HP, K, LEN, M, N>(
|
||||
&HASHERS, &[m], &sig, &self.0,
|
||||
);
|
||||
Ok(res)
|
||||
}
|
||||
|
|
@ -264,16 +299,18 @@ macro_rules! functionality {
|
|||
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(123);
|
||||
for i in 0..5u8 {
|
||||
message[3] = i;
|
||||
let (pk1, sk1) = KG::try_keygen_with_rng_vt(&mut rng).unwrap();
|
||||
let (pk1, sk1) = KG::try_keygen_with_rng(&mut rng).unwrap();
|
||||
let pk1_bytes = pk1.into_bytes();
|
||||
let pk2 = PublicKey::try_from_bytes(&pk1_bytes).unwrap();
|
||||
let sk1_bytes = sk1.into_bytes();
|
||||
let sk2 = PrivateKey::try_from_bytes(&sk1_bytes).unwrap();
|
||||
let sig = sk2.try_sign_with_rng_ct(&mut rng, &message, true).unwrap();
|
||||
let result = pk2.try_verify_vt(&message, &sig).unwrap();
|
||||
let sig = sk2
|
||||
.try_sign_with_rng(&mut rng, &message, b"context", true)
|
||||
.unwrap();
|
||||
let result = pk2.try_verify(&message, &sig, b"context").unwrap();
|
||||
assert_eq!(result, true, "Signature failed to verify");
|
||||
message[3] = (i + 1);
|
||||
let result = pk2.try_verify_vt(&message, &sig).unwrap();
|
||||
let result = pk2.try_verify(&message, &sig, b"context").unwrap();
|
||||
assert_eq!(result, false, "Signature should not have verified");
|
||||
}
|
||||
}
|
||||
|
|
@ -286,17 +323,17 @@ macro_rules! functionality {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHA2-128s parameter set is claimed to be in security strength category 1.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_128s::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_128s::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_sha2_128s::PublicKey`] and [`slh_dsa_sha2_128s::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_sha2_128s::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_sha2_128s::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -334,17 +371,17 @@ pub mod slh_dsa_sha2_128s {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHAKE-128s parameter set is claimed to be in security strength category 1.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_128s::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_128s::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_shake_128s::PublicKey`] and [`slh_dsa_shake_128s::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_shake_128s::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_shake_128s::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -382,17 +419,17 @@ pub mod slh_dsa_shake_128s {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHA2-128f parameter set is claimed to be in security strength category 1.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_128f::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_128f::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_sha2_128f::PublicKey`] and [`slh_dsa_sha2_128f::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_sha2_128f::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_sha2_128f::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -430,17 +467,17 @@ pub mod slh_dsa_sha2_128f {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHAKE-128f parameter set is claimed to be in security strength category 1.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_128f::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_128f::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_shake_128f::PublicKey`] and [`slh_dsa_shake_128f::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_shake_128f::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_shake_128f::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -478,17 +515,17 @@ pub mod slh_dsa_shake_128f {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHA2-192s parameter set is claimed to be in security strength category 3.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_192s::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_192s::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_sha2_192s::PublicKey`] and [`slh_dsa_sha2_192s::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_sha2_192s::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_sha2_192s::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -526,17 +563,17 @@ pub mod slh_dsa_sha2_192s {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHAKE-192s parameter set is claimed to be in security strength category 3.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_192s::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_192s::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_shake_192s::PublicKey`] and [`slh_dsa_shake_192s::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_shake_192s::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_shake_192s::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -574,17 +611,17 @@ pub mod slh_dsa_shake_192s {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHA2-192f parameter set is claimed to be in security strength category 3.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_192f::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_192f::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_sha2_192f::PublicKey`] and [`slh_dsa_sha2_192f::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_sha2_192f::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_sha2_192f::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -622,17 +659,17 @@ pub mod slh_dsa_sha2_192f {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHAKE-192f parameter set is claimed to be in security strength category 3.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_192f::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_192f::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_shake_192f::PublicKey`] and [`slh_dsa_shake_192f::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_shake_192f::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_shake_192f::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -670,17 +707,17 @@ pub mod slh_dsa_shake_192f {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHA2-256s parameter set is claimed to be in security strength category 5.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_256s::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_256s::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_sha2_256s::PublicKey`] and [`slh_dsa_sha2_256s::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_sha2_256s::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_sha2_256s::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -718,17 +755,17 @@ pub mod slh_dsa_sha2_256s {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHAKE_256s parameter set is claimed to be in security strength category 5.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_256s::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_256s::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_shake_256s::PublicKey`] and [`slh_dsa_shake_256s::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_shake_256s::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_shake_256s::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -766,17 +803,17 @@ pub mod slh_dsa_shake_256s {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHA2-256f parameter set is claimed to be in security strength category 5.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_256f::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_sha2_256f::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_sha2_256f::PublicKey`] and [`slh_dsa_sha2_256f::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_sha2_256f::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_sha2_256f::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
@ -814,17 +851,17 @@ pub mod slh_dsa_sha2_256f {
|
|||
/// sizes for the public key, secret key, and signature along with a number of internal constants. The
|
||||
/// SLH-DSA-SHAKE-256f parameter set is claimed to be in security strength category 5.
|
||||
///
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_256f::try_keygen_vt`] function below
|
||||
/// **1)** The basic usage is for an originator to start with the [`slh_dsa_shake_256f::try_keygen`] function below
|
||||
/// to generate both [`slh_dsa_shake_256f::PublicKey`] and [`slh_dsa_shake_256f::PrivateKey`] structs. The resulting
|
||||
/// [`slh_dsa_shake_256f::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies several functions
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign_ct()`], resulting in a Signature byte-array.
|
||||
/// to sign byte-array messages, such as [`traits::Signer::try_sign()`], resulting in a Signature byte-array.
|
||||
///
|
||||
/// **2)** Both the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait. The originator
|
||||
/// utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the `PublicKey` struct into a byte-array for
|
||||
/// distribution. The remote party utilizes the [`traits::SerDes::try_from_bytes()`] function to deserialize the
|
||||
/// `PublicKey` byte-array into its struct.
|
||||
///
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify_vt()`] function implemented on the
|
||||
/// **3)** Finally, the remote party uses the [`traits::Verifier::try_verify()`] function implemented on the
|
||||
/// [`slh_dsa_shake_256f::PublicKey`] struct to verify the message byte-array with the Signature byte-array..
|
||||
///
|
||||
/// See the top-level [crate] documentation for example code that implements the above flow.
|
||||
|
|
|
|||
126
src/slh.rs
126
src/slh.rs
|
|
@ -22,7 +22,7 @@ pub(crate) fn slh_keygen_with_rng<
|
|||
>(
|
||||
rng: &mut impl CryptoRngCore, hashers: &Hashers<K, LEN, M, N>,
|
||||
) -> Result<(SlhPrivateKey<N>, SlhPublicKey<N>), &'static str> {
|
||||
let (d32, hp32) = (u32::try_from(D).unwrap(), u32::try_from(HP).unwrap());
|
||||
//let (d32, hp32) = (u32::try_from(D).unwrap(), u32::try_from(HP).unwrap());
|
||||
|
||||
//
|
||||
// 1: SK.seed ←$ B^n ▷ Set SK.seed, SK.prf, and PK.seed to random n-byte
|
||||
|
|
@ -40,6 +40,45 @@ pub(crate) fn slh_keygen_with_rng<
|
|||
rng.try_fill_bytes(&mut pk_seed)
|
||||
.map_err(|_| "Alg17: rng failed3")?;
|
||||
|
||||
slh_keygen_internal::<D, H, HP, K, LEN, M, N>(hashers, sk_seed, sk_prf, pk_seed)
|
||||
}
|
||||
|
||||
|
||||
/// Algorithm 17: `slh_keygen()` on page 34.
|
||||
/// Generate an SLH-DSA key pair.
|
||||
///
|
||||
/// Input: (none) <br>
|
||||
/// Output: SLH-DSA key pair `(SK, PK)`.
|
||||
#[allow(clippy::similar_names)] // sk_seed and pk_seed
|
||||
pub(crate) fn slh_keygen_internal<
|
||||
const D: usize,
|
||||
const H: usize,
|
||||
const HP: usize,
|
||||
const K: usize,
|
||||
const LEN: usize,
|
||||
const M: usize,
|
||||
const N: usize,
|
||||
>(
|
||||
hashers: &Hashers<K, LEN, M, N>, sk_seed: [u8; N], sk_prf: [u8; N], pk_seed: [u8; N],
|
||||
) -> Result<(SlhPrivateKey<N>, SlhPublicKey<N>), &'static str> {
|
||||
let (d32, hp32) = (u32::try_from(D).unwrap(), u32::try_from(HP).unwrap());
|
||||
//
|
||||
// //
|
||||
// // 1: SK.seed ←$ B^n ▷ Set SK.seed, SK.prf, and PK.seed to random n-byte
|
||||
// let mut sk_seed = [0u8; N];
|
||||
// rng.try_fill_bytes(&mut sk_seed)
|
||||
// .map_err(|_| "Alg17: rng failed1")?;
|
||||
//
|
||||
// // 2: SK.prf ←$ B^n ▷ strings using an approved random bit generator
|
||||
// let mut sk_prf = [0u8; N];
|
||||
// rng.try_fill_bytes(&mut sk_prf)
|
||||
// .map_err(|_| "Alg17: rng failed2")?;
|
||||
//
|
||||
// // 3: PK.seed ←$ B^n
|
||||
// let mut pk_seed = [0u8; N];
|
||||
// rng.try_fill_bytes(&mut pk_seed)
|
||||
// .map_err(|_| "Alg17: rng failed3")?;
|
||||
|
||||
// 4:
|
||||
// 5: ADRS ← toByte(0, 32) ▷ Generate the public key for the top-level XMSS tree
|
||||
let mut adrs = Adrs::default();
|
||||
|
|
@ -77,12 +116,11 @@ pub(crate) fn slh_sign_with_rng<
|
|||
const N: usize,
|
||||
>(
|
||||
rng: &mut impl CryptoRngCore, hashers: &Hashers<K, LEN, M, N>, m: &[u8], sk: &SlhPrivateKey<N>,
|
||||
randomize: bool,
|
||||
ctx: &[u8], randomize: bool,
|
||||
) -> Result<SlhDsaSig<A, D, HP, K, LEN, N>, &'static str> {
|
||||
let (d32, h32) = (u32::try_from(D).unwrap(), u32::try_from(H).unwrap());
|
||||
//
|
||||
// 1: ADRS ← toByte(0, 32)
|
||||
let mut adrs = Adrs::default();
|
||||
//let mut adrs = Adrs::default();
|
||||
|
||||
// 2:
|
||||
// 3: opt_rand ← PK.seed ▷ Set opt_rand to either PK.seed
|
||||
|
|
@ -97,6 +135,48 @@ pub(crate) fn slh_sign_with_rng<
|
|||
// 6: end if
|
||||
}
|
||||
|
||||
let mp: &[&[u8]] = &[&[0u8], &[ctx.len().to_le_bytes()[0]], ctx, m];
|
||||
slh_sign_internal::<A, D, H, HP, K, LEN, M, N>(hashers, mp, sk, opt_rand)
|
||||
}
|
||||
|
||||
|
||||
/// Algorithm 18: `slh_sign(M, SK)` on page 35.
|
||||
/// Generate an SLH-DSA signature.
|
||||
///
|
||||
/// Input: Message `M`, private key `SK = (SK.seed, SK.prf, PK.seed, PK.root)`. <br>
|
||||
/// Output: SLH-DSA signature `SIG`.
|
||||
#[allow(clippy::similar_names)]
|
||||
#[allow(clippy::cast_possible_truncation)] // temporary, investigating idx_leaf int sizes
|
||||
pub(crate) fn slh_sign_internal<
|
||||
const A: usize,
|
||||
const D: usize,
|
||||
const H: usize,
|
||||
const HP: usize,
|
||||
const K: usize,
|
||||
const LEN: usize,
|
||||
const M: usize,
|
||||
const N: usize,
|
||||
>(
|
||||
hashers: &Hashers<K, LEN, M, N>, m: &[&[u8]], sk: &SlhPrivateKey<N>, opt_rand: [u8; N],
|
||||
) -> Result<SlhDsaSig<A, D, HP, K, LEN, N>, &'static str> {
|
||||
let (d32, h32) = (u32::try_from(D).unwrap(), u32::try_from(H).unwrap());
|
||||
//
|
||||
// 1: ADRS ← toByte(0, 32)
|
||||
let mut adrs = Adrs::default();
|
||||
//
|
||||
// // 2:
|
||||
// // 3: opt_rand ← PK.seed ▷ Set opt_rand to either PK.seed
|
||||
// let mut opt_rand = sk.pk_seed;
|
||||
//
|
||||
// // 4: if (RANDOMIZE) then ▷ or to a random n-byte string
|
||||
// if randomize {
|
||||
// // 5: opt_rand ←$ Bn
|
||||
// rng.try_fill_bytes(&mut opt_rand)
|
||||
// .map_err(|_| "Alg17: rng failed")?;
|
||||
//
|
||||
// // 6: end if
|
||||
// }
|
||||
|
||||
// 7: R ← PRF_msg(SK.prf, opt_rand, M) ▷ Generate randomizer
|
||||
let r = (hashers.prf_msg)(&sk.sk_prf, &opt_rand, m);
|
||||
|
||||
|
|
@ -175,7 +255,6 @@ pub(crate) fn slh_sign_with_rng<
|
|||
Ok(sig)
|
||||
}
|
||||
|
||||
|
||||
/// Algorithm 19: `slh_verify(M, SIG, PK)`
|
||||
/// Verify an SLH-DSA signature.
|
||||
///
|
||||
|
|
@ -193,7 +272,42 @@ pub(crate) fn slh_verify<
|
|||
const M: usize,
|
||||
const N: usize,
|
||||
>(
|
||||
hashers: &Hashers<K, LEN, M, N>, m: &[u8], sig: &SlhDsaSig<A, D, HP, K, LEN, N>,
|
||||
hashers: &Hashers<K, LEN, M, N>, m: &[u8], sig: &SlhDsaSig<A, D, HP, K, LEN, N>, ctx: &[u8],
|
||||
pk: &SlhPublicKey<N>,
|
||||
) -> bool {
|
||||
//let (d32, h32) = (u32::try_from(D).unwrap(), u32::try_from(H).unwrap());
|
||||
|
||||
// 1: if |SIG| != (1 + k(1 + a) + h + d · len) · n then
|
||||
// 2: return false
|
||||
// 3: end if
|
||||
// The above size is performed in the wrapper/adapter deserialize function
|
||||
|
||||
// 4: ADRS ← toByte(0, 32)
|
||||
//let mut adrs = Adrs::default();
|
||||
|
||||
let mp: &[&[u8]] = &[&[0u8], &[ctx.len().to_le_bytes()[0]], ctx, m];
|
||||
slh_verify_internal::<A, D, H, HP, K, LEN, M, N>(hashers, mp, sig, pk)
|
||||
}
|
||||
|
||||
|
||||
/// Algorithm 19: `slh_verify(M, SIG, PK)`
|
||||
/// Verify an SLH-DSA signature.
|
||||
///
|
||||
/// Input: Message `M`, signature `SIG`, public key `PK = (PK.seed, PK.root)`. <br>
|
||||
/// Output: Boolean.
|
||||
#[allow(clippy::cast_possible_truncation)] // TODO: temporary
|
||||
#[allow(clippy::similar_names)]
|
||||
pub(crate) fn slh_verify_internal<
|
||||
const A: usize,
|
||||
const D: usize,
|
||||
const H: usize,
|
||||
const HP: usize,
|
||||
const K: usize,
|
||||
const LEN: usize,
|
||||
const M: usize,
|
||||
const N: usize,
|
||||
>(
|
||||
hashers: &Hashers<K, LEN, M, N>, m: &[&[u8]], sig: &SlhDsaSig<A, D, HP, K, LEN, N>,
|
||||
pk: &SlhPublicKey<N>,
|
||||
) -> bool {
|
||||
let (d32, h32) = (u32::try_from(D).unwrap(), u32::try_from(H).unwrap());
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ pub trait SerDes {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -30,7 +30,7 @@ pub trait SerDes {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
|
@ -51,8 +51,8 @@ pub trait SerDes {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -60,7 +60,7 @@ pub trait SerDes {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
|
@ -94,8 +94,8 @@ pub trait KeyGen {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -103,14 +103,14 @@ pub trait KeyGen {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(feature = "default-rng")]
|
||||
fn try_keygen_vt() -> Result<(Self::PublicKey, Self::PrivateKey), &'static str> {
|
||||
Self::try_keygen_with_rng_vt(&mut OsRng)
|
||||
fn try_keygen() -> Result<(Self::PublicKey, Self::PrivateKey), &'static str> {
|
||||
Self::try_keygen_with_rng(&mut OsRng)
|
||||
}
|
||||
|
||||
/// Generates a public and private key pair specific to this security parameter set. <br>
|
||||
|
|
@ -129,8 +129,8 @@ pub trait KeyGen {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -138,12 +138,12 @@ pub trait KeyGen {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn try_keygen_with_rng_vt(
|
||||
fn try_keygen_with_rng(
|
||||
rng: &mut impl CryptoRngCore,
|
||||
) -> Result<(Self::PublicKey, Self::PrivateKey), &'static str>;
|
||||
}
|
||||
|
|
@ -171,8 +171,8 @@ pub trait Signer {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -180,16 +180,16 @@ pub trait Signer {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(feature = "default-rng")]
|
||||
fn try_sign_ct(
|
||||
&self, message: &[u8], randomize: bool,
|
||||
fn try_sign(
|
||||
&self, message: &[u8], ctx: &[u8], randomize: bool,
|
||||
) -> Result<Self::Signature, &'static str> {
|
||||
self.try_sign_with_rng_ct(&mut OsRng, message, randomize)
|
||||
self.try_sign_with_rng(&mut OsRng, message, ctx, randomize)
|
||||
}
|
||||
|
||||
/// Attempt to sign the given message, returning a digital signature on success, or an error if
|
||||
|
|
@ -209,8 +209,8 @@ pub trait Signer {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -218,13 +218,19 @@ pub trait Signer {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn try_sign_with_rng_ct(
|
||||
&self, rng: &mut impl CryptoRngCore, message: &[u8], randomize: bool,
|
||||
fn try_sign_with_rng(
|
||||
&self, rng: &mut impl CryptoRngCore, message: &[u8], ctx: &[u8], randomize: bool,
|
||||
) -> Result<Self::Signature, &'static str>;
|
||||
|
||||
/// blah
|
||||
/// # Errors
|
||||
fn _test_only_raw_sign(
|
||||
&self, rng: &mut impl CryptoRngCore, m: &[u8], randomize: bool,
|
||||
) -> Result<Self::Signature, &'static str>;
|
||||
}
|
||||
|
||||
|
|
@ -250,8 +256,8 @@ pub trait Verifier {
|
|||
/// let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];
|
||||
///
|
||||
/// // Generate public/private key pair and signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen_vt()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign_ct(&msg_bytes, true)?; // Use the secret key to generate a msg signature
|
||||
/// let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; // Generate both public and secret keys
|
||||
/// let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?; // Use the secret key to generate a msg signature
|
||||
///
|
||||
/// // Serialize the public key, and send with message and signature bytes
|
||||
/// let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
|
||||
|
|
@ -259,12 +265,18 @@ pub trait Verifier {
|
|||
///
|
||||
/// // Deserialize the public key, then use it to verify the msg signature
|
||||
/// let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
|
||||
/// let v = pk2.try_verify_vt(&msg_recv, &sig_recv)?;
|
||||
/// let v = pk2.try_verify(&msg_recv, &sig_recv, b"context")?;
|
||||
/// assert!(v);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn try_verify_vt(
|
||||
&self, message: &[u8], signature: &Self::Signature,
|
||||
fn try_verify(
|
||||
&self, message: &[u8], signature: &Self::Signature, ctx: &[u8],
|
||||
) -> Result<bool, &'static str>;
|
||||
|
||||
/// blah
|
||||
/// # Errors
|
||||
fn _test_only_raw_verify(
|
||||
&self, m: &[u8], sig_bytes: &Self::Signature,
|
||||
) -> Result<bool, &'static str>;
|
||||
}
|
||||
|
|
|
|||
13
src/types.rs
13
src/types.rs
|
|
@ -1,6 +1,19 @@
|
|||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
|
||||
/// Supported hash functions for `hash_sign()` and `hash_verify()` functions
|
||||
pub enum Ph {
|
||||
/// Use SHA256 as the pre-hash function
|
||||
SHA256,
|
||||
/// Use SHA512 as the pre-hash function
|
||||
SHA512,
|
||||
/// Use Shake128 as the pre-hash function
|
||||
SHAKE128,
|
||||
/// Use Shake256 as the pre-hash function
|
||||
SHAKE256,
|
||||
}
|
||||
|
||||
|
||||
/// Fig 16 on page 34
|
||||
#[derive(Clone, Debug, Zeroize, ZeroizeOnDrop)]
|
||||
pub(crate) struct SlhDsaSig<
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -13,6 +13,8 @@ use serde::{Deserialize, Deserializer};
|
|||
use serde_json::Value;
|
||||
use std::fs::File;
|
||||
use std::panic;
|
||||
// use fips205::slh_dsa_sha2_128f::_test_only_raw_sign;
|
||||
// use fips205::slh_dsa_shake_192f::PrivateKey;
|
||||
|
||||
fn dehex<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||
where
|
||||
|
|
@ -82,7 +84,7 @@ macro_rules! test_keygen {
|
|||
rnd.push(&test.sk_seed);
|
||||
|
||||
// Generate key
|
||||
let (pk, sk) = KG::try_keygen_with_rng_vt(&mut rnd).unwrap();
|
||||
let (pk, sk) = KG::try_keygen_with_rng(&mut rnd).unwrap();
|
||||
|
||||
// Check against known answers
|
||||
let pk_match = pk.into_bytes() == test.pk.as_slice();
|
||||
|
|
@ -197,12 +199,15 @@ macro_rules! test_sign {
|
|||
|
||||
// Calculate signature
|
||||
let sig_exp = if $deterministic {
|
||||
sk.try_sign_ct(&test.message, false)
|
||||
//sk.try_sign(&test.message, false)
|
||||
let mut rnd = TestRng::new();
|
||||
sk._test_only_raw_sign(&mut rnd, &test.message, false)
|
||||
.expect("Error signing message")
|
||||
} else {
|
||||
let mut rnd = TestRng::new();
|
||||
rnd.push(test.additional_randomness.as_slice());
|
||||
sk.try_sign_with_rng_ct(&mut rnd, &test.message, true)
|
||||
// sk.try_sign_with_rng(&mut rnd, &test.message, true)
|
||||
sk._test_only_raw_sign(&mut rnd, &test.message, true)
|
||||
.expect("Error signing message")
|
||||
};
|
||||
|
||||
|
|
@ -321,7 +326,7 @@ macro_rules! test_verify {
|
|||
.expect("Unable to load public key");
|
||||
|
||||
// Verify signature
|
||||
pk.try_verify_vt(
|
||||
pk._test_only_raw_verify(
|
||||
test.message.as_slice(),
|
||||
test.signature
|
||||
.as_slice()
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -10,9 +10,9 @@ pub fn sign(message: &str) -> String {
|
|||
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(seed);
|
||||
let randomize = true;
|
||||
|
||||
let (pk, sk) = slh_dsa_sha2_128f::try_keygen_with_rng_vt(&mut rng).expect("keygen failed");
|
||||
let sig = sk.try_sign_with_rng_ct(&mut rng, message.as_ref(), randomize).expect("sign failed");
|
||||
assert!(pk.try_verify_vt(message.as_ref(), &sig).expect("verify error"), "verify failed");
|
||||
let (pk, sk) = slh_dsa_sha2_128f::try_keygen_with_rng(&mut rng).expect("keygen failed");
|
||||
let sig = sk.try_sign_with_rng(&mut rng, message.as_ref(), randomize).expect("sign failed");
|
||||
assert!(pk.try_verify(message.as_ref(), &sig).expect("verify error"), "verify failed");
|
||||
|
||||
let sk_hex = hex::encode(&sk.into_bytes());
|
||||
let sig_hex = hex::encode(&sig);
|
||||
|
|
|
|||
Loading…
Reference in a new issue