This commit is contained in:
eschorn1 2024-10-01 17:17:27 -05:00
parent 899179a1e1
commit f0576386fc
9 changed files with 235 additions and 88 deletions

View file

@ -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(&msg_recv, &sig_recv, b"context")?;
let v = pk2.verify(&msg_recv, &sig_recv, b"context");
assert!(v);
# Ok(())
# }

View file

@ -25,18 +25,42 @@ pub fn criterion_benchmark(c: &mut Criterion) {
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(&message, b"context", randomize).unwrap();
let sig_sha2_128f = sk_sha2_128f.try_sign(&message, b"context", randomize).unwrap();
let sig_sha2_192s = sk_sha2_192s.try_sign(&message, b"context", randomize).unwrap();
let sig_sha2_192f = sk_sha2_192f.try_sign(&message, b"context", randomize).unwrap();
let sig_sha2_256s = sk_sha2_256s.try_sign(&message, b"context", randomize).unwrap();
let sig_sha2_256f = sk_sha2_256f.try_sign(&message, b"context", randomize).unwrap();
let sig_shake_128s = sk_shake_128s.try_sign(&message, b"context", randomize).unwrap();
let sig_shake_128f = sk_shake_128f.try_sign(&message, b"context", randomize).unwrap();
let sig_shake_192s = sk_shake_192s.try_sign(&message, b"context", randomize).unwrap();
let sig_shake_192f = sk_shake_192f.try_sign(&message, b"context", randomize).unwrap();
let sig_shake_256s = sk_shake_256s.try_sign(&message, b"context", randomize).unwrap();
let sig_shake_256f = sk_shake_256f.try_sign(&message, b"context", randomize).unwrap();
let sig_sha2_128s = sk_sha2_128s
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_sha2_128f = sk_sha2_128f
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_sha2_192s = sk_sha2_192s
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_sha2_192f = sk_sha2_192f
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_sha2_256s = sk_sha2_256s
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_sha2_256f = sk_sha2_256f
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_shake_128s = sk_shake_128s
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_shake_128f = sk_shake_128f
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_shake_192s = sk_shake_192s
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_shake_192f = sk_shake_192f
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_shake_256s = sk_shake_256s
.try_sign(&message, b"context", randomize)
.unwrap();
let sig_shake_256f = sk_shake_256f
.try_sign(&message, b"context", randomize)
.unwrap();
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()));
@ -89,40 +113,40 @@ pub fn criterion_benchmark(c: &mut Criterion) {
});
//
c.bench_function("sha2_128f verify", |b| {
b.iter(|| pk_sha2_128f.try_verify(&message, &sig_sha2_128f, b"context"))
b.iter(|| pk_sha2_128f.verify(&message, &sig_sha2_128f, b"context"))
});
c.bench_function("sha2_192f verify", |b| {
b.iter(|| pk_sha2_192f.try_verify(&message, &sig_sha2_192f, b"context"))
b.iter(|| pk_sha2_192f.verify(&message, &sig_sha2_192f, b"context"))
});
c.bench_function("sha2_256f verify", |b| {
b.iter(|| pk_sha2_256f.try_verify(&message, &sig_sha2_256f, b"context"))
b.iter(|| pk_sha2_256f.verify(&message, &sig_sha2_256f, b"context"))
});
c.bench_function("shake_128f verify", |b| {
b.iter(|| pk_shake_128f.try_verify(&message, &sig_shake_128f, b"context"))
b.iter(|| pk_shake_128f.verify(&message, &sig_shake_128f, b"context"))
});
c.bench_function("shake_192f verify", |b| {
b.iter(|| pk_shake_192f.try_verify(&message, &sig_shake_192f, b"context"))
b.iter(|| pk_shake_192f.verify(&message, &sig_shake_192f, b"context"))
});
c.bench_function("shake_256f verify", |b| {
b.iter(|| pk_shake_256f.try_verify(&message, &sig_shake_256f, b"context"))
b.iter(|| pk_shake_256f.verify(&message, &sig_shake_256f, b"context"))
});
c.bench_function("sha2_128s verify", |b| {
b.iter(|| pk_sha2_128s.try_verify(&message, &sig_sha2_128s, b"context"))
b.iter(|| pk_sha2_128s.verify(&message, &sig_sha2_128s, b"context"))
});
c.bench_function("sha2_192s verify", |b| {
b.iter(|| pk_sha2_192s.try_verify(&message, &sig_sha2_192s, b"context"))
b.iter(|| pk_sha2_192s.verify(&message, &sig_sha2_192s, b"context"))
});
c.bench_function("sha2_256s verify", |b| {
b.iter(|| pk_sha2_256s.try_verify(&message, &sig_sha2_256s, b"context"))
b.iter(|| pk_sha2_256s.verify(&message, &sig_sha2_256s, b"context"))
});
c.bench_function("shake_128s verify", |b| {
b.iter(|| pk_shake_128s.try_verify(&message, &sig_shake_128s, b"context"))
b.iter(|| pk_shake_128s.verify(&message, &sig_shake_128s, b"context"))
});
c.bench_function("shake_192s verify", |b| {
b.iter(|| pk_shake_192s.try_verify(&message, &sig_shake_192s, b"context"))
b.iter(|| pk_shake_192s.verify(&message, &sig_shake_192s, b"context"))
});
c.bench_function("shake_256s verify", |b| {
b.iter(|| pk_shake_256s.try_verify(&message, &sig_shake_256s, b"context"))
b.iter(|| pk_shake_256s.verify(&message, &sig_shake_256s, b"context"))
});
}

View file

@ -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(&message, &signature.data);
let res = sk.verify(&message, &signature.data);
if res.is_ok() && res.unwrap() {
SLH_DSA_OK

View file

@ -1,4 +1,5 @@
use crate::types::Adrs;
use crate::Ph;
// Holds hasher function references; constructed by each security parameter set wrapper
@ -321,3 +322,58 @@ pub(crate) mod sha2_cat_3_5 {
result
}
}
pub(crate) fn hash_message(message: &[u8], ph: &Ph, phm: &mut [u8; 64]) -> ([u8; 11], usize) {
use sha2::{Digest, Sha256, Sha512};
use sha3::digest::{ExtendableOutput, Update, XofReader};
use sha3::{Shake128, Shake256};
match ph {
Ph::SHA256 => (
[
0x06u8, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
],
{
let mut hasher = Sha256::new();
Digest::update(&mut hasher, message);
phm[0..32].copy_from_slice(&hasher.finalize());
32
},
),
Ph::SHA512 => (
[
0x06u8, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
],
{
let mut hasher = Sha512::new();
Digest::update(&mut hasher, message);
phm.copy_from_slice(&hasher.finalize());
64
},
),
Ph::SHAKE128 => (
[
0x06u8, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0B,
],
{
let mut hasher = Shake128::default();
hasher.update(message);
let mut reader = hasher.finalize_xof();
reader.read(&mut phm[0..32]);
32
},
),
Ph::SHAKE256 => (
[
0x06u8, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0C,
],
{
let mut hasher = Shake256::default();
hasher.update(message);
let mut reader = hasher.finalize_xof();
reader.read(phm);
64
},
),
}
}

View file

@ -63,8 +63,9 @@ const LEN2: u32 = 3;
// This common functionality is injected into each parameter set module
macro_rules! functionality {
() => {
use crate::hashers::hash_message;
use crate::traits::{KeyGen, SerDes, Signer, Verifier};
use crate::types::{SlhDsaSig, SlhPrivateKey, SlhPublicKey};
use crate::types::{Ph, SlhDsaSig, SlhPrivateKey, SlhPublicKey};
use rand_core::CryptoRngCore;
use zeroize::{Zeroize, ZeroizeOnDrop};
@ -114,15 +115,13 @@ 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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
/// ```
#[cfg(feature = "default-rng")]
pub fn try_keygen() -> Result<(PublicKey, PrivateKey), &'static str> {
KG::try_keygen()
}
pub fn try_keygen() -> Result<(PublicKey, PrivateKey), &'static str> { KG::try_keygen() }
/// Generates a public and private key pair specific to this security parameter set. <br>
@ -145,7 +144,7 @@ macro_rules! functionality {
/// // Generate key pair and signature
/// 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")?;
/// let v = pk.verify(&message, &sig, b"context");
/// assert!(v);
/// # Ok(())}
/// ```
@ -175,8 +174,29 @@ macro_rules! functionality {
fn try_sign_with_rng(
&self, rng: &mut impl CryptoRngCore, m: &[u8], ctx: &[u8], randomize: bool,
) -> Result<[u8; SIG_LEN], &'static str> {
let mp: &[&[u8]] = &[&[0u8], &[ctx.len().to_le_bytes()[0]], ctx, m];
let sig = crate::slh::slh_sign_with_rng::<A, D, H, HP, K, LEN, M, N>(
rng, &HASHERS, &m, &self.0, ctx, randomize,
rng, &HASHERS, &mp, &self.0, randomize,
);
sig.map(|s| s.deserialize())
}
/// # Errors
fn try_sign_hash_with_rng(
&self, rng: &mut impl CryptoRngCore, message: &[u8], ctx: &[u8], ph: &Ph,
randomize: bool,
) -> Result<Self::Signature, &'static str> {
let mut phm = [0u8; 64]; // hashers don't all play well with each other (varying output size)
let (oid, phm_len) = hash_message(message, ph, &mut phm);
let mp: &[&[u8]] = &[
&[1u8],
&[ctx.len().to_le_bytes()[0]],
ctx,
&oid,
&phm[0..phm_len],
];
let sig = crate::slh::slh_sign_with_rng::<A, D, H, HP, K, LEN, M, N>(
rng, &HASHERS, &mp, &self.0, randomize, // BAD
);
sig.map(|s| s.deserialize())
}
@ -210,14 +230,32 @@ macro_rules! functionality {
impl Verifier for PublicKey {
type Signature = [u8; SIG_LEN];
fn try_verify(
&self, m: &[u8], sig_bytes: &[u8; SIG_LEN], ctx: &[u8],
) -> Result<bool, &'static str> {
fn verify(&self, m: &[u8], sig_bytes: &[u8; SIG_LEN], ctx: &[u8]) -> bool {
let sig = SlhDsaSig::<A, D, HP, K, LEN, N>::serialize(sig_bytes);
let mp: &[&[u8]] = &[&[0u8], &[ctx.len().to_le_bytes()[0]], ctx, m];
let res = crate::slh::slh_verify::<A, D, H, HP, K, LEN, M, N>(
&HASHERS, &m, &sig, ctx, &self.0,
&HASHERS, &mp, &sig, &self.0,
);
Ok(res)
res
}
fn verify_hash(
&self, m: &[u8], sig_bytes: &[u8; SIG_LEN], ctx: &[u8], ph: &Ph,
) -> bool {
let sig = SlhDsaSig::<A, D, HP, K, LEN, N>::serialize(sig_bytes);
let mut phm = [0u8; 64]; // hashers don't all play well with each other (varying output size)
let (oid, phm_len) = hash_message(m, ph, &mut phm);
let mp: &[&[u8]] = &[
&[1u8],
&[ctx.len().to_le_bytes()[0]],
ctx,
&oid,
&phm[0..phm_len],
];
let res = crate::slh::slh_verify::<A, D, H, HP, K, LEN, M, N>(
&HASHERS, &mp, &sig, &self.0,
);
res
}
fn _test_only_raw_verify(
@ -225,7 +263,10 @@ macro_rules! functionality {
) -> 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,
&HASHERS,
&[m],
&sig,
&self.0,
);
Ok(res)
}
@ -295,23 +336,29 @@ macro_rules! functionality {
// Test keygen, sign, serDes everything, verify true/false
#[test]
fn simple_round_trips() {
let mut message = [0u8, 1, 2, 3];
let message = [0u8, 1, 2, 3];
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(&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 (pk1, sk1) = KG::try_keygen_with_rng(&mut rng).unwrap();
let pk1_bytes = pk1.into_bytes();
let sk1_bytes = sk1.into_bytes();
let pk2 = PublicKey::try_from_bytes(&pk1_bytes).unwrap();
let sk2 = PrivateKey::try_from_bytes(&sk1_bytes).unwrap();
let sig = sk2
.try_sign_with_rng(&mut rng, &message, b"context", true)
.unwrap();
let result = pk2.verify(&message, &sig, b"context");
assert!(result, "Signature failed to verify");
let result = pk2.verify(&message, &sig, b"some other context");
assert!(!result, "Signature should not have verified");
for ph in [Ph::SHA256, Ph::SHA512, Ph::SHAKE128, Ph::SHAKE256] {
let sig = sk2
.try_sign_with_rng(&mut rng, &message, b"context", true)
.try_sign_hash_with_rng(&mut rng, &message, b"context", &ph, 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(&message, &sig, b"context").unwrap();
assert_eq!(result, false, "Signature should not have verified");
let result = pk2.verify_hash(&message, &sig, b"context", &ph);
assert!(result, "Signature failed to verify");
let result = pk2.verify_hash(&message, &sig, b"some other context", &ph);
assert!(!result, "Signature should not have verified");
}
}
}
@ -333,7 +380,7 @@ macro_rules! functionality {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -381,7 +428,7 @@ pub mod slh_dsa_sha2_128s {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -429,7 +476,7 @@ pub mod slh_dsa_shake_128s {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -477,7 +524,7 @@ pub mod slh_dsa_sha2_128f {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -525,7 +572,7 @@ pub mod slh_dsa_shake_128f {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -573,7 +620,7 @@ pub mod slh_dsa_sha2_192s {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -621,7 +668,7 @@ pub mod slh_dsa_shake_192s {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -669,7 +716,7 @@ pub mod slh_dsa_sha2_192f {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -717,7 +764,7 @@ pub mod slh_dsa_shake_192f {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -765,7 +812,7 @@ pub mod slh_dsa_sha2_256s {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -813,7 +860,7 @@ pub mod slh_dsa_shake_256s {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.
@ -861,7 +908,7 @@ pub mod slh_dsa_sha2_256f {
/// 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()`] function implemented on the
/// **3)** Finally, the remote party uses the [`traits::Verifier::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.

View file

@ -115,8 +115,8 @@ pub(crate) fn slh_sign_with_rng<
const M: usize,
const N: usize,
>(
rng: &mut impl CryptoRngCore, hashers: &Hashers<K, LEN, M, N>, m: &[u8], sk: &SlhPrivateKey<N>,
ctx: &[u8], randomize: bool,
rng: &mut impl CryptoRngCore, hashers: &Hashers<K, LEN, M, N>, mp: &[&[u8]],
sk: &SlhPrivateKey<N>, randomize: bool,
) -> Result<SlhDsaSig<A, D, HP, K, LEN, N>, &'static str> {
//
// 1: ADRS ← toByte(0, 32)
@ -135,7 +135,7 @@ pub(crate) fn slh_sign_with_rng<
// 6: end if
}
let mp: &[&[u8]] = &[&[0u8], &[ctx.len().to_le_bytes()[0]], ctx, m];
//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)
}
@ -272,7 +272,7 @@ 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>, ctx: &[u8],
hashers: &Hashers<K, LEN, M, N>, mp: &[&[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());
@ -285,7 +285,7 @@ pub(crate) fn slh_verify<
// 4: ADRS ← toByte(0, 32)
//let mut adrs = Adrs::default();
let mp: &[&[u8]] = &[&[0u8], &[ctx.len().to_le_bytes()[0]], ctx, m];
//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)
}

View file

@ -1,5 +1,6 @@
use rand_core::CryptoRngCore;
use crate::Ph;
#[cfg(feature = "default-rng")]
use rand_core::OsRng;
@ -30,7 +31,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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
@ -60,7 +61,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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
@ -103,7 +104,7 @@ 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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
@ -138,7 +139,7 @@ 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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
@ -180,7 +181,7 @@ 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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
@ -192,6 +193,15 @@ pub trait Signer {
self.try_sign_with_rng(&mut OsRng, message, ctx, randomize)
}
/// blah
/// # Errors
#[cfg(feature = "default-rng")]
fn try_sign_hash(
&self, message: &[u8], ctx: &[u8], ph: &Ph, randomize: bool,
) -> Result<Self::Signature, &'static str> {
self.try_sign_hash_with_rng(&mut OsRng, message, ctx, ph, randomize)
}
/// Attempt to sign the given message, returning a digital signature on success, or an error if
/// something went wrong. This function utilizes a supplied RNG and operates in constant time
/// with respect to the `PrivateKey` only (not including rejection loop; work in progress).
@ -218,7 +228,7 @@ 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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
@ -227,6 +237,14 @@ pub trait Signer {
&self, rng: &mut impl CryptoRngCore, message: &[u8], ctx: &[u8], randomize: bool,
) -> Result<Self::Signature, &'static str>;
/// blah
/// # Errors
fn try_sign_hash_with_rng(
&self, rng: &mut impl CryptoRngCore, message: &[u8], ctx: &[u8], ph: &Ph, randomize: bool,
) -> Result<Self::Signature, &'static str>;
/// blah
/// # Errors
fn _test_only_raw_sign(
@ -243,8 +261,6 @@ pub trait Verifier {
/// Verifies a digital signature with respect to a `PublicKey`. This function operates in
/// variable time.
///
/// # Errors
/// Returns an error on a malformed signature; propagates internal errors.
/// # Examples
/// ```rust
/// use fips205::slh_dsa_shake_128s; // Could use any of the twelve security parameter sets.
@ -265,14 +281,20 @@ 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(&msg_recv, &sig_recv, b"context")?;
/// let v = pk2.verify(&msg_recv, &sig_recv, b"context");
/// assert!(v);
/// # Ok(())
/// # }
/// ```
fn try_verify(
&self, message: &[u8], signature: &Self::Signature, ctx: &[u8],
) -> Result<bool, &'static str>;
#[must_use]
fn verify(&self, message: &[u8], signature: &Self::Signature, ctx: &[u8]) -> bool;
/// blah
#[must_use]
fn verify_hash(&self, message: &[u8], signature: &Self::Signature, ctx: &[u8], ph: &Ph)
-> bool;
/// blah
/// # Errors

File diff suppressed because one or more lines are too long

View file

@ -12,7 +12,7 @@ pub fn sign(message: &str) -> String {
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");
assert!(pk.verify(message.as_ref(), &sig).expect("verify error"), "verify failed");
let sk_hex = hex::encode(&sk.into_bytes());
let sig_hex = hex::encode(&sig);