mirror of
https://github.com/saymrwulf/fips205-source.git
synced 2026-09-03 19:53:49 +00:00
working traits
This commit is contained in:
parent
69f94c55fe
commit
6c449f3e36
6 changed files with 334 additions and 122 deletions
|
|
@ -704,7 +704,7 @@ pub(crate) fn ht_verify<
|
|||
for j in 1..D::to_u32() {
|
||||
//
|
||||
// 7: idx_leaf ← idx_tree mod 2^{h′} ▷ h′ least significant bits of idx_tree
|
||||
let idx_leaf = u32::try_from(idx_tree % 2u64.pow(HP::to_u32())); // TODO: clean
|
||||
let idx_leaf = u32::try_from(idx_tree % 2u64.pow(HP::to_u32())); // TODO: clean
|
||||
if idx_leaf.is_err() {
|
||||
return false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ pub(crate) mod shake {
|
|||
}
|
||||
|
||||
|
||||
#[allow(clippy::similar_names)] // pk_seed and sk_seed
|
||||
#[allow(clippy::similar_names)] // pk_seed and sk_seed
|
||||
pub(crate) fn prf<N: ArrayLength>(
|
||||
pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs,
|
||||
) -> GenericArray<u8, N> {
|
||||
|
|
@ -103,10 +103,7 @@ pub(crate) mod shake {
|
|||
}
|
||||
|
||||
|
||||
#[cfg(any(
|
||||
feature = "slh_dsa_sha2_128f",
|
||||
feature = "slh_dsa_sha2_128s"
|
||||
))]
|
||||
#[cfg(any(feature = "slh_dsa_sha2_128f", feature = "slh_dsa_sha2_128s"))]
|
||||
pub(crate) mod sha2_cat_1 {
|
||||
use crate::types::Adrs;
|
||||
use core::cmp::min;
|
||||
|
|
@ -143,7 +140,7 @@ pub(crate) mod sha2_cat_1 {
|
|||
}
|
||||
|
||||
|
||||
#[allow(clippy::similar_names)] // pk_seed and sk_seed
|
||||
#[allow(clippy::similar_names)] // pk_seed and sk_seed
|
||||
pub(crate) fn prf<N: ArrayLength>(
|
||||
pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs,
|
||||
) -> GenericArray<u8, N> {
|
||||
|
|
@ -247,10 +244,10 @@ pub(crate) mod sha2_cat_1 {
|
|||
|
||||
|
||||
#[cfg(any(
|
||||
feature = "slh_dsa_sha2_192f",
|
||||
feature = "slh_dsa_sha2_192s",
|
||||
feature = "slh_dsa_sha2_256f",
|
||||
feature = "slh_dsa_sha2_256s"
|
||||
feature = "slh_dsa_sha2_192f",
|
||||
feature = "slh_dsa_sha2_192s",
|
||||
feature = "slh_dsa_sha2_256f",
|
||||
feature = "slh_dsa_sha2_256s"
|
||||
))]
|
||||
pub(crate) mod sha2_cat_3_5 {
|
||||
use crate::types::Adrs;
|
||||
|
|
@ -297,7 +294,7 @@ pub(crate) mod sha2_cat_3_5 {
|
|||
}
|
||||
|
||||
|
||||
#[allow(clippy::similar_names)] // pk_seed and sk_seed
|
||||
#[allow(clippy::similar_names)] // pk_seed and sk_seed
|
||||
pub(crate) fn prf<N: ArrayLength>(
|
||||
pk_seed: &[u8], sk_seed: &[u8], adrs: &Adrs,
|
||||
) -> GenericArray<u8, N> {
|
||||
|
|
|
|||
199
src/lib.rs
199
src/lib.rs
|
|
@ -9,7 +9,6 @@
|
|||
// 2. SerDes on keys
|
||||
// 3. Proper traits and non-rng functions
|
||||
// 4. Adrs as raw bytes
|
||||
// 5. clippy
|
||||
// 6. Separate into proper files
|
||||
// 7. Doc, of course!
|
||||
mod algs;
|
||||
|
|
@ -27,33 +26,111 @@ const LEN2: u32 = 3;
|
|||
/// blah
|
||||
macro_rules! functionality {
|
||||
() => {
|
||||
use crate::traits::{KeyGen, SerDes, Signer, Verifier};
|
||||
use crate::types::{SlhDsaSig, SlhPrivateKey, SlhPublicKey};
|
||||
use rand_core::CryptoRngCore;
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct PublicKey(SlhPublicKey<N>);
|
||||
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct PrivateKey(SlhPrivateKey<N>);
|
||||
|
||||
#[derive(Zeroize, ZeroizeOnDrop)]
|
||||
pub struct KG(); // Arguable how useful an empty struct+trait is...
|
||||
|
||||
/// blah
|
||||
/// # Errors
|
||||
pub fn slh_keygen_with_rng(
|
||||
rng: &mut impl CryptoRngCore,
|
||||
) -> Result<(SlhPrivateKey<N>, SlhPublicKey<N>), &'static str> {
|
||||
crate::algs::slh_keygen_with_rng::<D, H, HP, K, Len, M, N>(rng, &HASHERS)
|
||||
impl KeyGen for KG {
|
||||
type PrivateKey = PrivateKey;
|
||||
type PublicKey = PublicKey;
|
||||
|
||||
fn try_keygen_with_rng_vt(
|
||||
rng: &mut impl CryptoRngCore,
|
||||
) -> Result<(PublicKey, PrivateKey), &'static str> {
|
||||
let res = crate::algs::slh_keygen_with_rng::<D, H, HP, K, Len, M, N>(rng, &HASHERS);
|
||||
res.map(|(sk, pk)| (PublicKey(pk), PrivateKey(sk)))
|
||||
}
|
||||
}
|
||||
|
||||
/// blah
|
||||
/// # Errors
|
||||
pub fn slh_sign_with_rng(
|
||||
rng: &mut impl CryptoRngCore, m: &[u8], sk: &SlhPrivateKey<N>, randomize: bool,
|
||||
) -> Result<[u8; SIG_LEN], &'static str> {
|
||||
let sig = crate::algs::slh_sign_with_rng::<A, D, H, HP, K, Len, M, N>(
|
||||
rng, &HASHERS, &m, &sk, randomize,
|
||||
);
|
||||
sig.map(|s| s.deserialize())
|
||||
#[cfg(feature = "default-rng")]
|
||||
pub fn try_keygen_vt() -> Result<(PublicKey, PrivateKey), &'static str> {
|
||||
KG::try_keygen_vt()
|
||||
}
|
||||
|
||||
/// blah
|
||||
#[must_use]
|
||||
pub fn slh_verify(m: &[u8], sig_bytes: &[u8; SIG_LEN], pk: &SlhPublicKey<N>) -> bool {
|
||||
let sig = SlhDsaSig::<A, D, HP, K, Len, N>::serialize(sig_bytes);
|
||||
crate::algs::slh_verify::<A, D, H, HP, K, Len, M, N>(&HASHERS, &m, &sig, &pk)
|
||||
impl Signer for PrivateKey {
|
||||
type Signature = [u8; SIG_LEN];
|
||||
|
||||
/// blah
|
||||
/// # Errors
|
||||
fn try_sign_with_rng_ct(
|
||||
&self, rng: &mut impl CryptoRngCore, m: &[u8], randomize: bool,
|
||||
) -> Result<[u8; SIG_LEN], &'static str> {
|
||||
let sig = crate::algs::slh_sign_with_rng::<A, D, H, HP, K, Len, M, N>(
|
||||
rng, &HASHERS, &m, &self.0, randomize,
|
||||
);
|
||||
sig.map(|s| s.deserialize())
|
||||
}
|
||||
}
|
||||
|
||||
impl Verifier for PublicKey {
|
||||
type Signature = [u8; SIG_LEN];
|
||||
|
||||
/// blah
|
||||
#[must_use]
|
||||
fn try_verify_vt(&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::algs::slh_verify::<A, D, H, HP, K, Len, M, N>(&HASHERS, &m, &sig, &self.0);
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl SerDes for PublicKey {
|
||||
type ByteArray = [u8; PK_LEN];
|
||||
|
||||
fn into_bytes(self) -> Self::ByteArray {
|
||||
let mut out = [0u8; PK_LEN];
|
||||
out[0..(PK_LEN / 2)].copy_from_slice(&self.0.pk_seed);
|
||||
out[(PK_LEN / 2)..].copy_from_slice(&self.0.pk_root);
|
||||
out
|
||||
}
|
||||
|
||||
fn try_from_bytes(bytes: &Self::ByteArray) -> Result<Self, &'static str> {
|
||||
// Result: opportunity for validation
|
||||
let mut pk = SlhPublicKey::default();
|
||||
pk.pk_seed.copy_from_slice(&bytes[..(PK_LEN / 2)]);
|
||||
pk.pk_root.copy_from_slice(&bytes[(PK_LEN / 2)..]);
|
||||
Ok(PublicKey(pk))
|
||||
}
|
||||
}
|
||||
|
||||
impl SerDes for PrivateKey {
|
||||
type ByteArray = [u8; SK_LEN];
|
||||
|
||||
fn into_bytes(self) -> Self::ByteArray {
|
||||
let mut bytes = [0u8; SK_LEN];
|
||||
bytes[0..(SK_LEN / 4)].copy_from_slice(&self.0.sk_seed);
|
||||
bytes[(SK_LEN / 4)..(SK_LEN / 2)].copy_from_slice(&self.0.sk_prf);
|
||||
bytes[(SK_LEN / 2)..(3 * SK_LEN / 4)].copy_from_slice(&self.0.pk_seed);
|
||||
bytes[(3 * SK_LEN / 4)..].copy_from_slice(&self.0.pk_root);
|
||||
bytes
|
||||
}
|
||||
|
||||
fn try_from_bytes(bytes: &Self::ByteArray) -> Result<Self, &'static str> {
|
||||
// Result: opportunity for validation
|
||||
let mut sk = SlhPrivateKey::default();
|
||||
sk.sk_seed.copy_from_slice(&bytes[0..(SK_LEN / 4)]);
|
||||
sk.sk_prf
|
||||
.copy_from_slice(&bytes[(SK_LEN / 4)..(SK_LEN / 2)]);
|
||||
sk.pk_seed
|
||||
.copy_from_slice(&bytes[(SK_LEN / 2)..(3 * SK_LEN / 4)]);
|
||||
sk.pk_root.copy_from_slice(&bytes[(3 * SK_LEN / 4)..]);
|
||||
Ok(PrivateKey(sk))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -67,12 +144,16 @@ macro_rules! functionality {
|
|||
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(123);
|
||||
for i in 0..5 {
|
||||
message[3] = i as u8;
|
||||
let (sk, pk) = slh_keygen_with_rng(&mut rng).unwrap();
|
||||
let sig = slh_sign_with_rng(&mut rng, &message, &sk, true).unwrap();
|
||||
let result = slh_verify(&message, &sig, &pk);
|
||||
let (pk1, sk1) = KG::try_keygen_with_rng_vt(&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();
|
||||
assert_eq!(result, true, "Signature failed to verify");
|
||||
message[3] = (i + 1) as u8;
|
||||
let result = slh_verify(&message, &sig, &pk);
|
||||
let result = pk2.try_verify_vt(&message, &sig).unwrap();
|
||||
assert_eq!(result, false, "Signature should not have verified");
|
||||
}
|
||||
}
|
||||
|
|
@ -96,9 +177,9 @@ pub mod slh_dsa_sha2_128s {
|
|||
type K = U14;
|
||||
type M = U30;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 7856;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 32;
|
||||
pub const SIG_LEN: usize = 7856;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -121,9 +202,9 @@ pub mod slh_dsa_shake_128s {
|
|||
type K = U14;
|
||||
type M = U30;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 7856;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 32;
|
||||
pub const SIG_LEN: usize = 7856;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -146,9 +227,9 @@ pub mod slh_dsa_sha2_128f {
|
|||
type K = U33;
|
||||
type M = U34;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 17088;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 32;
|
||||
pub const SIG_LEN: usize = 17088;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -171,9 +252,9 @@ pub mod slh_dsa_shake_128f {
|
|||
type K = U33;
|
||||
type M = U34;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 17088;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 32;
|
||||
pub const SIG_LEN: usize = 17088;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -196,9 +277,9 @@ pub mod slh_dsa_sha2_192s {
|
|||
type K = U17;
|
||||
type M = U39;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 16224;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 48;
|
||||
pub const SIG_LEN: usize = 16224;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -221,9 +302,9 @@ pub mod slh_dsa_shake_192s {
|
|||
type K = U17;
|
||||
type M = U39;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 16224;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 48;
|
||||
pub const SIG_LEN: usize = 16224;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -246,9 +327,9 @@ pub mod slh_dsa_sha2_192f {
|
|||
type K = U33;
|
||||
type M = U42;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 35664;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 48;
|
||||
pub const SIG_LEN: usize = 35664;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -271,9 +352,9 @@ pub mod slh_dsa_shake_192f {
|
|||
type K = U33;
|
||||
type M = U42;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 35664;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 48;
|
||||
pub const SIG_LEN: usize = 35664;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -296,9 +377,9 @@ pub mod slh_dsa_sha2_256s {
|
|||
type K = U22;
|
||||
type M = U47;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 29792;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 64;
|
||||
pub const SIG_LEN: usize = 29792;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -321,9 +402,9 @@ pub mod slh_dsa_shake_256s {
|
|||
type K = U22;
|
||||
type M = U47;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 29792;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 64;
|
||||
pub const SIG_LEN: usize = 29792;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -346,9 +427,9 @@ pub mod slh_dsa_sha2_256f {
|
|||
type K = U35;
|
||||
type M = U49;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 49856;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 64;
|
||||
pub const SIG_LEN: usize = 49856;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
@ -371,9 +452,9 @@ pub mod slh_dsa_shake_256f {
|
|||
type K = U35;
|
||||
type M = U49;
|
||||
type Len = Sum<Prod<U2, N>, U3>;
|
||||
//const PK_LEN: usize = 32;
|
||||
const SIG_LEN: usize = 49856;
|
||||
//const SK_LEN: usize = 0000;
|
||||
pub const PK_LEN: usize = 64;
|
||||
pub const SIG_LEN: usize = 49856;
|
||||
pub const SK_LEN: usize = PK_LEN * 2;
|
||||
static HASHERS: Hashers<K, Len, M, N> =
|
||||
Hashers::<K, Len, M, N> { h_msg, prf, prf_msg, f, h, t_l, t_len: t_l };
|
||||
|
||||
|
|
|
|||
97
src/test.rs
97
src/test.rs
File diff suppressed because one or more lines are too long
118
src/traits.rs
118
src/traits.rs
|
|
@ -1,4 +1,116 @@
|
|||
pub trait PK {
|
||||
type Seed;
|
||||
fn seed(&self) -> Self::Seed;
|
||||
use rand_core::CryptoRngCore;
|
||||
#[cfg(feature = "default-rng")]
|
||||
use rand_core::OsRng;
|
||||
|
||||
|
||||
/// The `SerDes` trait provides for validated serialization and deserialization of fixed size elements
|
||||
pub trait SerDes {
|
||||
/// The fixed-size byte array to be serialized or deserialized
|
||||
type ByteArray;
|
||||
|
||||
/// Produces a byte array of fixed-size specific to the struct being serialized.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// ```
|
||||
fn into_bytes(self) -> Self::ByteArray;
|
||||
|
||||
/// Consumes a byte array of fixed-size specific to the struct being deserialized; performs validation
|
||||
/// # Errors
|
||||
/// Returns an error on malformed input.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// ```
|
||||
fn try_from_bytes(bytes: &Self::ByteArray) -> Result<Self, &'static str>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
|
||||
/// The `KeyGen` trait is defined to allow trait objects.
|
||||
pub trait KeyGen {
|
||||
/// A public key specific to the chosen security parameter set, e.g., ml-dsa-44, ml-dsa-65 or ml-dsa-87
|
||||
type PublicKey;
|
||||
/// A private (secret) key specific to the chosen security parameter set, e.g., ml-dsa-44, ml-dsa-65 or ml-dsa-87
|
||||
type PrivateKey;
|
||||
|
||||
/// Generates a public and private key pair specific to this security parameter set. <br>
|
||||
/// This function utilizes the OS default random number generator, and makes no (constant)
|
||||
/// timing assurances.
|
||||
/// # Errors
|
||||
/// Returns an error when the random number generator fails; propagates internal errors.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// ```
|
||||
#[cfg(feature = "default-rng")]
|
||||
fn try_keygen_vt() -> Result<(Self::PublicKey, Self::PrivateKey), &'static str> {
|
||||
Self::try_keygen_with_rng_vt(&mut OsRng)
|
||||
}
|
||||
|
||||
/// Generates a public and private key pair specific to this security parameter set. <br>
|
||||
/// This function utilizes a supplied random number generator, and makes no (constant)
|
||||
/// timing assurances..
|
||||
/// # Errors
|
||||
/// Returns an error when the random number generator fails; propagates internal errors.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// ```
|
||||
fn try_keygen_with_rng_vt(
|
||||
rng: &mut impl CryptoRngCore,
|
||||
) -> Result<(Self::PublicKey, Self::PrivateKey), &'static str>;
|
||||
}
|
||||
|
||||
|
||||
/// The Signer trait is implemented for the `PrivateKey` struct on each of the security parameter sets
|
||||
pub trait Signer {
|
||||
/// The signature is specific to the chosen security parameter set, e.g., ml-dsa-44, ml-dsa-65 or ml-dsa-87
|
||||
type Signature;
|
||||
|
||||
/// Attempt to sign the given message, returning a digital signature on success, or an error if
|
||||
/// something went wrong. This function utilizes the default OS RNG and operates in constant time
|
||||
/// with respect to the `PrivateKey` only (not including rejection loop; work in progress).
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error when the random number generator fails; propagates internal errors.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// ```
|
||||
#[cfg(feature = "default-rng")]
|
||||
fn try_sign_ct(
|
||||
&self, message: &[u8], randomize: bool,
|
||||
) -> Result<Self::Signature, &'static str> {
|
||||
self.try_sign_with_rng_ct(&mut OsRng, message, 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).
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns an error when the random number generator fails; propagates internal errors.
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// ```
|
||||
fn try_sign_with_rng_ct(
|
||||
&self, rng: &mut impl CryptoRngCore, message: &[u8], randomize: bool,
|
||||
) -> Result<Self::Signature, &'static str>;
|
||||
}
|
||||
|
||||
|
||||
/// The Verifier trait is implemented for `PublicKey` on each of the security parameter sets
|
||||
pub trait Verifier {
|
||||
/// The signature is specific to the chosen security parameter set, e.g., ml-dsa-44, ml-dsa-65
|
||||
/// or ml-dsa-87
|
||||
type Signature;
|
||||
|
||||
/// 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
|
||||
/// ```
|
||||
fn try_verify_vt(
|
||||
&self, message: &[u8], signature: &Self::Signature,
|
||||
) -> Result<bool, &'static str>;
|
||||
}
|
||||
|
|
|
|||
21
src/types.rs
21
src/types.rs
|
|
@ -106,6 +106,27 @@ pub struct SlhPublicKey<N: ArrayLength> {
|
|||
pub(crate) pk_root: GenericArray<u8, N>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl<N: ArrayLength> SlhPublicKey<N> {
|
||||
pub fn serialize<const PK_LEN: usize>(self) -> [u8; PK_LEN] {
|
||||
let mut out = [0u8; PK_LEN];
|
||||
debug_assert_eq!(out.len(), 2 * N::to_usize());
|
||||
out[0..N::to_usize()].copy_from_slice(&self.pk_seed);
|
||||
out[N::to_usize()..2 * N::to_usize()].copy_from_slice(&self.pk_root);
|
||||
out
|
||||
}
|
||||
|
||||
pub fn deserialize<const PK_LEN: usize>(bytes: [u8; PK_LEN]) -> Self {
|
||||
let mut pub_key = Self::default();
|
||||
pub_key.pk_seed.copy_from_slice(&bytes[0..N::to_usize()]);
|
||||
pub_key
|
||||
.pk_root
|
||||
.copy_from_slice(&bytes[N::to_usize()..2 * N::to_usize()]);
|
||||
pub_key
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Zeroize, ZeroizeOnDrop)]
|
||||
pub struct SlhPrivateKey<N: ArrayLength> {
|
||||
pub(crate) sk_seed: GenericArray<u8, N>,
|
||||
pub(crate) sk_prf: GenericArray<u8, N>,
|
||||
|
|
|
|||
Loading…
Reference in a new issue