Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 5 additions & 0 deletions alpha_0.1.2_release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
* Check the crate release checklist and run claude against the style guide (maybe Francis could cross-check me)
* Run Crucible testing
* Add factories for ML-DSA and ML-KEM (if we are keeping factories, see below)
* After merging the Signer/Verifier, Encrypter/Decrypter split, check if the keygen_from_rng() is still on the right
trait.
* Split the Signature trait into a Signer and a Verifier so that, for example, we can implement the verifier for MTC in
a different struct from the signer; or so that you can get FIPS compliance on old algorithms that are currently only
FIPS-allowed for verification of existing signatures but not for creation of new ones.
* Check out Megan's email May 13 about KeyMaterial: "I was wondering if there might be scope for a closure based
approach that could guarantee encapsulation of the state change from safe to hazardous back to safe again."
* Go back to previous algs and apply memory optimization tricks like internal functions. And add a docs section "Memory
Expand Down
84 changes: 84 additions & 0 deletions crypto/core-test-framework/src/fixed_seed_rng.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! A deterministic fake [RNG] for reproducible tests.

use bouncycastle_core::errors::RNGError;
use bouncycastle_core::key_material::{KeyMaterialTrait, KeyType};
use bouncycastle_core::traits::{RNG, SecurityStrength};

/// A test-only fake [RNG] that produces a fixed, fully deterministic byte stream.
///
/// The stream is the `SEED_LEN`-byte seed repeated indefinitely. A single internal counter is
/// shared across every [RNG] method, so each byte handed out — whether through
/// [RNG::next_bytes_out], [RNG::next_bytes], [RNG::next_int], or [RNG::fill_keymaterial_out] —
/// advances the same stream. Two instances built from the same seed therefore emit identical
/// streams, which is what makes RNG-driven operations reproducible (and comparable against their
/// seed/`m`-driven internal counterparts) in tests.
///
/// This is a deterministic stub for tests only; it is in no way a secure RNG.
pub struct FixedSeedRNG<const SEED_LEN: usize> {
seed: [u8; SEED_LEN],
counter: usize,
}

impl<const SEED_LEN: usize> FixedSeedRNG<SEED_LEN> {
/// Create an instance that emits `seed` repeated indefinitely, starting from its first byte.
pub fn new(seed: [u8; SEED_LEN]) -> Self {
Self { seed, counter: 0 }
}

/// Pull the next byte from the deterministic stream and advance the counter.
fn next_byte(&mut self) -> u8 {
let b = self.seed[self.counter % SEED_LEN];
self.counter += 1;
b
}
}

impl<const SEED_LEN: usize> RNG for FixedSeedRNG<SEED_LEN> {
/// No-op: this fake RNG ignores reseeding, since its stream is fixed by construction.
fn add_seed_keymaterial(
&mut self,
_additional_seed: &dyn KeyMaterialTrait,
) -> Result<(), RNGError> {
Ok(())
}

fn next_int(&mut self) -> Result<u32, RNGError> {
let mut buf = [0u8; 4];
for slot in buf.iter_mut() {
*slot = self.next_byte();
}
Ok(u32::from_le_bytes(buf))
}

fn next_bytes(&mut self, len: usize) -> Result<Vec<u8>, RNGError> {
let mut out = vec![0u8; len];
for slot in out.iter_mut() {
*slot = self.next_byte();
}
Ok(out)
}

fn next_bytes_out(&mut self, out: &mut [u8]) -> Result<usize, RNGError> {
for slot in out.iter_mut() {
*slot = self.next_byte();
}
Ok(out.len())
}

/// Fill `out` to capacity from the stream and mark it as a full-entropy 256-bit seed,
/// mirroring what a real DRBG's `generate_keymaterial_out` produces. A 256-bit security
/// strength is enough for every ML-KEM / ML-DSA parameter set.
fn fill_keymaterial_out(&mut self, out: &mut dyn KeyMaterialTrait) -> Result<usize, RNGError> {
out.allow_hazardous_operations();
let len = self.next_bytes_out(out.ref_to_bytes_mut()?)?;
out.set_key_len(len)?;
out.set_key_type(KeyType::Seed)?;
out.set_security_strength(SecurityStrength::_256bit)?;
out.drop_hazardous_operations();
Ok(len)
}

fn security_strength(&self) -> SecurityStrength {
SecurityStrength::_256bit
}
}
46 changes: 32 additions & 14 deletions crypto/core-test-framework/src/kem.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::FixedSeedRNG;
use bouncycastle_core::errors::KEMError;
use bouncycastle_core::traits::{KEMDecapsulator, KEMEncapsulator, KEMPrivateKey, KEMPublicKey};

Expand All @@ -24,8 +25,7 @@ impl TestFrameworkKEM {
pub fn test_kem<
PK: KEMPublicKey<PK_LEN>,
SK: KEMPrivateKey<SK_LEN>,
ENCAPSULATOR: KEMEncapsulator<PK, PK_LEN, CT_LEN, SS_LEN>,
DECAPSULATOR: KEMDecapsulator<SK, SK_LEN, CT_LEN, SS_LEN>,
KEMAlg: KEMEncapsulator<PK, PK_LEN, CT_LEN, SS_LEN> + KEMDecapsulator<SK, SK_LEN, CT_LEN, SS_LEN>,
const PK_LEN: usize,
const SK_LEN: usize,
const CT_LEN: usize,
Expand All @@ -37,27 +37,45 @@ impl TestFrameworkKEM {
) {
// Basic test
let (pk, sk) = keygen().unwrap();
let (ss, ct) = ENCAPSULATOR::encaps(&pk).unwrap();
let ss1 = DECAPSULATOR::decaps(&sk, &ct).unwrap();
let (ss, ct) = KEMAlg::encaps(&pk).unwrap();
let ss1 = KEMAlg::decaps(&sk, &ct).unwrap();
assert_eq!(ss, ss1);

// Test that encaps_rng is deterministic in its RNG input: two encapsulations against the
// same public key, each fed an RNG that emits identical bytes, must produce the same
// shared secret and ciphertext.
{
let mut rng_a = FixedSeedRNG::new([0x5A; 64]);
let mut rng_b = FixedSeedRNG::new([0x5A; 64]);
let (ss_a, ct_a) = KEMAlg::encaps_rng(&pk, &mut rng_a).unwrap();
let (ss_b, ct_b) = KEMAlg::encaps_rng(&pk, &mut rng_b).unwrap();
assert_eq!(
ss_a, ss_b,
"encaps_rng shared secret must be deterministic given fixed RNG output"
);
assert_eq!(
ct_a, ct_b,
"encaps_rng ciphertext must be deterministic given fixed RNG output"
);
}

// Test non-determinism
if !self.alg_is_deterministic {
let (ss1, ct1) = ENCAPSULATOR::encaps(&pk).unwrap();
let (ss2, ct2) = ENCAPSULATOR::encaps(&pk).unwrap();
let (ss1, ct1) = KEMAlg::encaps(&pk).unwrap();
let (ss2, ct2) = KEMAlg::encaps(&pk).unwrap();
assert_ne!(ss1, ss2);
assert_ne!(ct1, ct2);
}

// Test that decaps fails for broken ct value
let (pk, sk) = keygen().unwrap();
let (ss, mut ct) = ENCAPSULATOR::encaps(&pk).unwrap();
let (ss, mut ct) = KEMAlg::encaps(&pk).unwrap();
ct[17] ^= 0xFF;
if self.is_implicitly_rejecting {
let ss2 = DECAPSULATOR::decaps(&sk, &ct).unwrap();
let ss2 = KEMAlg::decaps(&sk, &ct).unwrap();
assert_ne!(ss, ss2);
} else {
match DECAPSULATOR::decaps(&sk, &ct) {
match KEMAlg::decaps(&sk, &ct) {
Err(KEMError::DecapsulationFailed) =>
/* good */
{
Expand All @@ -76,10 +94,10 @@ impl TestFrameworkKEM {

// should throw an Err
if self.is_implicitly_rejecting {
let ss2 = DECAPSULATOR::decaps(&sk, &ct_copy).unwrap();
let ss2 = KEMAlg::decaps(&sk, &ct_copy).unwrap();
assert_ne!(ss, ss2);
} else {
match DECAPSULATOR::decaps(&sk, &ct) {
match KEMAlg::decaps(&sk, &ct) {
Err(KEMError::DecapsulationFailed) =>
/* good */
{
Expand All @@ -94,17 +112,17 @@ impl TestFrameworkKEM {

// test ct the wrong length
let (pk, sk) = keygen().unwrap();
let (_ss, ct) = ENCAPSULATOR::encaps(&pk).unwrap();
let (_ss, ct) = KEMAlg::encaps(&pk).unwrap();
// too short
match DECAPSULATOR::decaps(&sk, &ct[..CT_LEN - 1]) {
match KEMAlg::decaps(&sk, &ct[..CT_LEN - 1]) {
Err(KEMError::LengthError(_)) => { /* good */ }
_ => panic!("This should have thrown an error but it didn't."),
};

// too long
let mut long_ct = vec![1u8; CT_LEN + 2];
long_ct.as_mut_slice()[..CT_LEN].copy_from_slice(&ct);
match DECAPSULATOR::decaps(&sk, &long_ct) {
match KEMAlg::decaps(&sk, &long_ct) {
Err(KEMError::LengthError(_)) => { /* good */ }
_ => panic!("This should have thrown an error but it didn't."),
};
Expand Down
3 changes: 3 additions & 0 deletions crypto/core-test-framework/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub mod kem;
pub mod mac;
pub mod signature;

mod fixed_seed_rng;
pub use fixed_seed_rng::FixedSeedRNG;

pub const DUMMY_SEED_512: &[u8; 512] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";

pub const DUMMY_SEED_1024: &[u8; 1024] = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
19 changes: 16 additions & 3 deletions crypto/core/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,16 @@ pub trait KEMEncapsulator<
>: Sized
{
/// Performs an encapsulation against the given public key.
/// Sources randomness from the library's default OS-backed RNG.
/// Returns the ciphertext and derived shared secret.
fn encaps(pk: &PK) -> Result<(KeyMaterial<SS_LEN>, [u8; CT_LEN]), KEMError>;
/// Performs an encapsulation against the given public key.
/// Sources randomness from the provided RNG.
/// Returns the ciphertext and derived shared secret.
fn encaps_rng(
pk: &PK,
rng: &mut dyn RNG,
) -> Result<(KeyMaterial<SS_LEN>, [u8; CT_LEN]), KEMError>;
}

/// A Key Encapsulation Mechanism (KEM) is defined as a set of three operations:
Expand Down Expand Up @@ -426,13 +434,18 @@ impl SecurityStrength {
/// be used by applications that intend to submit to FIPS certification as it more closely aligns with the
/// requirements of SP 800-90A.
/// Note: this interface produces bytes. If you want a [KeyMaterialTrait], then use [KeyMaterial::from_rng].
pub trait RNG: Default {
///
/// Implementors are expected to also implement [Default] (default-construction should produce a
/// securely OS-seeded instance), but this is intentionally *not* a supertrait bound: requiring
/// `Default` would make `RNG` not dyn-compatible, and `&mut dyn RNG` is needed so RNG instances
/// can be handed around as trait objects.
pub trait RNG {
// TODO: add back once we figure out streaming interaction with entropy sources.
// fn add_seed_bytes(&mut self, additional_seed: &[u8]) -> Result<(), RNGError>;

fn add_seed_keymaterial(
&mut self,
additional_seed: impl KeyMaterialTrait,
additional_seed: &dyn KeyMaterialTrait,
) -> Result<(), RNGError>;
fn next_int(&mut self) -> Result<u32, RNGError>;

Expand All @@ -443,7 +456,7 @@ pub trait RNG: Default {
/// The entire output buffer is zeroized before the random bytes are written.
fn next_bytes_out(&mut self, out: &mut [u8]) -> Result<usize, RNGError>;

fn fill_keymaterial_out(&mut self, out: &mut impl KeyMaterialTrait) -> Result<usize, RNGError>;
fn fill_keymaterial_out(&mut self, out: &mut dyn KeyMaterialTrait) -> Result<usize, RNGError>;

/// Returns the Security Strength of this RNG.
fn security_strength(&self) -> SecurityStrength;
Expand Down
4 changes: 2 additions & 2 deletions crypto/factory/src/rng_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl AlgorithmFactory for RNGFactory {
impl RNG for RNGFactory {
fn add_seed_keymaterial(
&mut self,
additional_seed: impl KeyMaterialTrait,
additional_seed: &dyn KeyMaterialTrait,
) -> Result<(), RNGError> {
match self {
Self::HashDRBG_SHA256(rng) => rng.add_seed_keymaterial(additional_seed),
Expand Down Expand Up @@ -126,7 +126,7 @@ impl RNG for RNGFactory {
}
}

fn fill_keymaterial_out(&mut self, out: &mut impl KeyMaterialTrait) -> Result<usize, RNGError> {
fn fill_keymaterial_out(&mut self, out: &mut dyn KeyMaterialTrait) -> Result<usize, RNGError> {
match self {
Self::HashDRBG_SHA256(rng) => rng.fill_keymaterial_out(out),
Self::HashDRBG_SHA512(rng) => rng.fill_keymaterial_out(out),
Expand Down
2 changes: 1 addition & 1 deletion crypto/mldsa-lowmemory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
//! ## Generating Keys
//!
//! ```rust
//! use bouncycastle_mldsa_lowmemory::MLDSA65;
//! use bouncycastle_mldsa_lowmemory::{MLDSA65, MLDSATrait};
//!
//! let (pk, sk) = MLDSA65::keygen().unwrap();
//! ```
Expand Down
Loading
Loading