Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions alpha_0.1.2_release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
appropriate.
* Probably it makes sense to leave Hex and Base64 as requiring std; ... or maybe add a no_std version that uses
fixed-sized blocks?
* Make this build on the stable compiler. IE Remove the rust-toolchain.toml file that builds with nightly. Will require
some refactoring.
* Create a cargo feature #[cfg(feature='rng')] and put it around things like keygen that takes an rng so that the build
dependency on bouncycastle_rng is optional.
* Enhance the default HashDRBG instantiation to take in NIST-compatible CPU jitter entropy? Or not? Maybe this is the
Expand Down
1 change: 0 additions & 1 deletion crypto/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// todo -- this is the goal, but first need to remove all the Vec in favour of compile-time array sizing.
// #![no_std]

#![feature(adt_const_params)]
#![forbid(unsafe_code)]

pub mod errors;
Expand Down
51 changes: 31 additions & 20 deletions crypto/mldsa/src/hash_mldsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ use bouncycastle_core::traits::{
Algorithm, Hash, PHSignature, RNG, SecurityStrength, Signature, XOF,
};
use bouncycastle_rng::HashDRBG_SHA512;
use bouncycastle_sha2::{SHA256, SHA512};
use bouncycastle_sha2::{SHA256, SHA256_NAME, SHA512, SHA512_NAME};
use core::marker::PhantomData;

// Imports needed only for docs
Expand Down Expand Up @@ -126,7 +126,6 @@ pub const HASH_ML_DSA_87_WITH_SHA512_NAME: &str = "HashML-DSA-87_with_SHA512";
pub type HashMLDSA44_with_SHA256 = HashMLDSA<
SHA256,
32,
SHA256_OID,
MLDSA44_PK_LEN,
MLDSA44_SK_LEN,
MLDSA44_SIG_LEN,
Expand Down Expand Up @@ -160,7 +159,6 @@ impl Algorithm for HashMLDSA44_with_SHA256 {
pub type HashMLDSA65_with_SHA256 = HashMLDSA<
SHA256,
32,
SHA256_OID,
MLDSA65_PK_LEN,
MLDSA65_SK_LEN,
MLDSA65_SIG_LEN,
Expand Down Expand Up @@ -194,7 +192,6 @@ impl Algorithm for HashMLDSA65_with_SHA256 {
pub type HashMLDSA87_with_SHA256 = HashMLDSA<
SHA256,
32,
SHA256_OID,
MLDSA87_PK_LEN,
MLDSA87_SK_LEN,
MLDSA87_SIG_LEN,
Expand Down Expand Up @@ -228,7 +225,6 @@ impl Algorithm for HashMLDSA87_with_SHA256 {
pub type HashMLDSA44_with_SHA512 = HashMLDSA<
SHA512,
64,
SHA512_OID,
MLDSA44_PK_LEN,
MLDSA44_SK_LEN,
MLDSA44_SIG_LEN,
Expand Down Expand Up @@ -262,7 +258,6 @@ impl Algorithm for HashMLDSA44_with_SHA512 {
pub type HashMLDSA65_with_SHA512 = HashMLDSA<
SHA512,
64,
SHA512_OID,
MLDSA65_PK_LEN,
MLDSA65_SK_LEN,
MLDSA65_SIG_LEN,
Expand Down Expand Up @@ -296,7 +291,6 @@ impl Algorithm for HashMLDSA65_with_SHA512 {
pub type HashMLDSA87_with_SHA512 = HashMLDSA<
SHA512,
64,
SHA512_OID,
MLDSA87_PK_LEN,
MLDSA87_SK_LEN,
MLDSA87_SIG_LEN,
Expand Down Expand Up @@ -332,9 +326,8 @@ impl Algorithm for HashMLDSA87_with_SHA512 {
/// by specifying the hash function to use (in the verifier), and specifying the bytes of the OID to
/// to use as its domain separator in constructing the message representative M'.
pub struct HashMLDSA<
HASH: Hash + Default,
HASH: Hash + Algorithm + Default,
const HASH_LEN: usize,
const oid: &'static [u8],
const PK_LEN: usize,
const SK_LEN: usize,
const SIG_LEN: usize,
Expand Down Expand Up @@ -381,9 +374,8 @@ pub struct HashMLDSA<
}

impl<
HASH: Hash + Default,
HASH: Hash + Algorithm + Default,
const PH_LEN: usize,
const oid: &'static [u8],
const PK_LEN: usize,
const SK_LEN: usize,
const SIG_LEN: usize,
Expand All @@ -410,7 +402,6 @@ impl<
HashMLDSA<
HASH,
PH_LEN,
oid,
PK_LEN,
SK_LEN,
SIG_LEN,
Expand Down Expand Up @@ -568,7 +559,20 @@ impl<
h.absorb(&[1u8]);
h.absorb(&[ctx.len() as u8]);
h.absorb(ctx);
h.absorb(oid);

// this is all statics, so the branch should compile out.
// Really, this should be a generic param of HashMLDSA, but unsized_const_params is currently
// a nightly-only feature.
match HASH::ALG_NAME {
SHA256_NAME => h.absorb(SHA256_OID),
SHA512_NAME => h.absorb(SHA512_OID),
_ => {
return Err(SignatureError::GenericError(
"Unsupported hash algorithm; you need to add it to the switch",
));
}
};

h.absorb(ph);
let mut mu = [0u8; MLDSA_MU_LEN];
let bytes_written = h.squeeze_out(&mut mu);
Expand Down Expand Up @@ -691,7 +695,18 @@ impl<
h.absorb(&[1u8]);
h.absorb(&[ctx.len() as u8]);
h.absorb(ctx);
h.absorb(oid);
// this is all statics, so the branch should compile out.
// Really, this should be a generic param of HashMLDSA, but unsized_const_params is currently
// a nightly-only feature.
match HASH::ALG_NAME {
SHA256_NAME => h.absorb(SHA256_OID),
SHA512_NAME => h.absorb(SHA512_OID),
_ => {
return Err(SignatureError::GenericError(
"Unsupported hash algorithm; you need to add it to the switch",
));
}
};
h.absorb(ph);
let mut mu = [0u8; MLDSA_MU_LEN];
_ = h.squeeze_out(&mut mu);
Expand Down Expand Up @@ -765,12 +780,11 @@ impl<
}

impl<
HASH: Hash + Default,
HASH: Hash + Algorithm + Default,
PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
SK: MLDSAPrivateKeyTrait<k, l, ETA, SK_LEN, PK_LEN>
+ MLDSAPrivateKeyInternalTrait<k, l, ETA, SK_LEN, PK_LEN>,
const PH_LEN: usize,
const oid: &'static [u8],
const PK_LEN: usize,
const SK_LEN: usize,
const SIG_LEN: usize,
Expand All @@ -794,7 +808,6 @@ impl<
for HashMLDSA<
HASH,
PH_LEN,
oid,
PK_LEN,
SK_LEN,
SIG_LEN,
Expand Down Expand Up @@ -971,9 +984,8 @@ impl<
}

impl<
HASH: Hash + Default,
HASH: Hash + Algorithm + Default,
const PH_LEN: usize,
const oid: &'static [u8],
const PK_LEN: usize,
const SK_LEN: usize,
const SIG_LEN: usize,
Expand All @@ -1000,7 +1012,6 @@ impl<
for HashMLDSA<
HASH,
PH_LEN,
oid,
PK_LEN,
SK_LEN,
SIG_LEN,
Expand Down
11 changes: 4 additions & 7 deletions crypto/mldsa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@
#![no_std]
#![forbid(missing_docs)]
#![forbid(unsafe_code)]
#![allow(incomplete_features)] // needed because currently generic_const_exprs is experimental
#![feature(generic_const_exprs)]
#![feature(adt_const_params)]
// These are because I'm matching variable names exactly against FIPS 204, for example both 'K' and 'k',
// or 'A' and 'a' are used and have specific meanings.
// But need to tell the rust linter to not care.
Expand All @@ -127,17 +124,17 @@
// MLDSA implementation, but I don't want accessed from outside, such as FIPS-internal functions.
#![allow(private_bounds)]
#![allow(private_interfaces)]
// Used in HashMLDSA
#![feature(unsized_const_params)]
// Used in HashMLDSA for oid: &'static [u8] params.
// #![allow(incomplete_features)] // needed because currently unsized_const_params is experimental
// #![feature(adt_const_params)]
// #![feature(unsized_const_params)]

// imports needed just for docs
#[allow(unused_imports)]
use bouncycastle_core::key_material::KeyMaterialTrait;
#[allow(unused_imports)]
use bouncycastle_core::traits::Signature;

// todo -- re-run mutants

// todo -- crucible tests

mod aux_functions;
Expand Down
29 changes: 25 additions & 4 deletions crypto/rng/src/hash_drbg80090a.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use crate::Sp80090ADrbg;

use bouncycastle_core::errors::{KeyMaterialError, RNGError};
use bouncycastle_core::key_material::{KeyMaterial512, KeyType, KeyMaterialTrait};
use bouncycastle_core::key_material::{KeyMaterial512, KeyMaterialTrait, KeyType};
use bouncycastle_core::traits::{Hash, HashAlgParams, RNG, SecurityStrength};
use bouncycastle_sha2::{SHA256, SHA512};
use bouncycastle_utils::min;
Expand Down Expand Up @@ -67,6 +67,7 @@ const LARGEST_HASHER_OUTPUT_LEN: usize = 64;
#[allow(private_bounds)]
/// Implementation of the Hash_DRBG algorithm as specified in NIST SP 800-90Ar1.
pub struct HashDRBG80090A<H: HashDRBG80090AParams> {
_phantom: core::marker::PhantomData<H>,
// Rust is stupid. What's the point of having a generic parameter if we can't use constants inside it?
// state: WorkingState<H::SEED_LEN>,
state: WorkingState<LARGEST_HASHER_OUTPUT_LEN>,
Expand Down Expand Up @@ -123,6 +124,7 @@ impl<H: HashDRBG80090AParams> HashDRBG80090A<H> {
/// and relies on you to provide a strong seed.**
pub fn new_unititialized() -> Self {
Self {
_phantom: core::marker::PhantomData,
state: WorkingState::<LARGEST_HASHER_OUTPUT_LEN> {
v: [0u8; LARGEST_HASHER_OUTPUT_LEN],
c: [0u8; LARGEST_HASHER_OUTPUT_LEN],
Expand Down Expand Up @@ -266,7 +268,11 @@ impl<H: HashDRBG80090AParams> Sp80090ADrbg for HashDRBG80090A<H> {
Ok(())
}

fn reseed(&mut self, seed: &impl KeyMaterialTrait, additional_input: &[u8]) -> Result<(), RNGError> {
fn reseed(
&mut self,
seed: &impl KeyMaterialTrait,
additional_input: &[u8],
) -> Result<(), RNGError> {
// Hash_DRBG Reseed Process:
// 1. seed_material = 0x01 || V || entropy_input || additional_input.
// 2. seed = Hash_df (seed_material, seedlen).
Expand Down Expand Up @@ -475,7 +481,10 @@ impl<H: HashDRBG80090AParams> RNG for HashDRBG80090A<H> {
// todo!()
// }

fn add_seed_keymaterial(&mut self, additional_seed: impl KeyMaterialTrait) -> Result<(), RNGError> {
fn add_seed_keymaterial(
&mut self,
additional_seed: impl KeyMaterialTrait,
) -> Result<(), RNGError> {
self.reseed(&additional_seed, "add_seed_keymaterial".as_bytes())
}

Expand Down Expand Up @@ -572,7 +581,19 @@ fn test_hash_df() {
assert_ne!(out, [0u8; 100]);
// repeatability test
// println!("out: {:?}", out);
assert_eq!(out, [150u8, 177u8, 87u8, 145u8, 138u8, 4u8, 164u8, 14u8, 162u8, 43u8, 159u8, 152u8, 121u8, 117u8, 6u8, 18u8, 253u8, 84u8, 41u8, 64u8, 40u8, 209u8, 16u8, 176u8, 106u8, 115u8, 172u8, 193u8, 246u8, 228u8, 208u8, 79u8, 37u8, 31u8, 134u8, 141u8, 200u8, 7u8, 42u8, 199u8, 229u8, 236u8, 236u8, 186u8, 28u8, 87u8, 200u8, 14u8, 127u8, 36u8, 132u8, 23u8, 36u8, 150u8, 23u8, 215u8, 247u8, 121u8, 175u8, 82u8, 99u8, 187u8, 235u8, 25u8, 213u8, 18u8, 106u8, 22u8, 4u8, 99u8, 1u8, 184u8, 211u8, 160u8, 177u8, 67u8, 78u8, 181u8, 69u8, 51u8, 117u8, 2u8, 72u8, 36u8, 134u8, 72u8, 2u8, 9u8, 105u8, 149u8, 136u8, 35u8, 81u8, 114u8, 142u8, 80u8, 94u8, 42u8, 85u8, 155]);
assert_eq!(
out,
[
150u8, 177u8, 87u8, 145u8, 138u8, 4u8, 164u8, 14u8, 162u8, 43u8, 159u8, 152u8, 121u8,
117u8, 6u8, 18u8, 253u8, 84u8, 41u8, 64u8, 40u8, 209u8, 16u8, 176u8, 106u8, 115u8,
172u8, 193u8, 246u8, 228u8, 208u8, 79u8, 37u8, 31u8, 134u8, 141u8, 200u8, 7u8, 42u8,
199u8, 229u8, 236u8, 236u8, 186u8, 28u8, 87u8, 200u8, 14u8, 127u8, 36u8, 132u8, 23u8,
36u8, 150u8, 23u8, 215u8, 247u8, 121u8, 175u8, 82u8, 99u8, 187u8, 235u8, 25u8, 213u8,
18u8, 106u8, 22u8, 4u8, 99u8, 1u8, 184u8, 211u8, 160u8, 177u8, 67u8, 78u8, 181u8, 69u8,
51u8, 117u8, 2u8, 72u8, 36u8, 134u8, 72u8, 2u8, 9u8, 105u8, 149u8, 136u8, 35u8, 81u8,
114u8, 142u8, 80u8, 94u8, 42u8, 85u8, 155
]
);

// Test success with out.len() at the maximum allowed for SHA256 (255 * 32 = 8160)
let mut out_max_sha256 = vec![0u8; 255 * 32];
Expand Down
2 changes: 0 additions & 2 deletions crypto/rng/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
//! cryptographic application.

#![forbid(unsafe_code)]
#![allow(incomplete_features)] // Need this because generic_const_exprs is currently experimental.
#![feature(generic_const_exprs)]

use crate::hash_drbg80090a::{
HashDRBG80090A, HashDRBG80090AParams_SHA256, HashDRBG80090AParams_SHA512,
Expand Down
Loading