feat: add Signature and KEM factory enums - #85
Conversation
Implement SignatureFactory and KEMFactory in bouncycastle-factory as enums that encapsulate all supported ML-DSA / ML-KEM parameter sets, following the existing Hash/MAC/RNG factory pattern. - SignatureFactory / KEMFactory implement AlgorithmFactory (defaults, 128/256-bit defaults, construction by algorithm name) - Key enums wrap public/private keys with encode/from_bytes pass-through - SignatureSigner / SignatureVerifierEngine wrap streaming engines - Inherent methods mirror Signer/SignatureVerifier/KEMEncapsulator/ KEMDecapsulator and dispatch to the underlying types Const-generic sizes on the core traits prevent a single enum from implementing those traits directly; the factory APIs pass through with type-erased keys and Vec encodings instead. Fixes bcgit#68 Signed-off-by: Vedant Madane <6527493+VedantMadane@users.noreply.github.com>
|
Follow-up: reopen was blocked after the force-push (GitHub 422), so the complete implementation is in #85 on the same branch |
|
Thank you for the contribution. The core idea of the factories is that they are an enum that impl's the same traits as the types that it's encapsulating so that you can pass the factory enum itself as a As an example: /// Wrapper object for all algorithms that impl [`KDF`].
pub enum KDFFactory {
///
#[allow(non_camel_case_types)]
HKDF_SHA256(hkdf::HKDF_SHA256),
...
impl KDF for KDFFactory {
fn derive_key(
self,
key: &impl KeyMaterialTrait,
...
}You have, as an example: /// Wrapper for all supported KEM public (encapsulation) keys.
pub enum KEMPublicKey {
/// ML-KEM-512 public key.
MLKEM512(mlkem::MLKEM512PublicKey),
...
}
impl KEMPublicKey {
/// Encode the public key to its standard byte encoding.
pub fn encode(&self) -> Vec<u8> {
....
}
}That should instead be: use bouncycastle-core::traits::KEMPublicKey;
/// Wrapper for all supported KEM public (encapsulation) keys that impl [`KEMPublicKey`]
pub enum KEMPublicKeyFactory {
/// ML-KEM-512 public key.
MLKEM512(mlkem::MLKEM512PublicKey),
...
}
impl KEMPublicKey for KEMPublicKeyFactory {
....
}Now that I'm taking a closer look at this, there are generic params on the KEMPublicKey trait which might make this approach more complicated, and this may end up being a bit of a research task that requires a bit of a redesign of how we're doing factories. If you want to do some playing around with how to get the various Signature and KEM traits in |
Summary
Implements Signature and KEM factories in
bouncycastle-factory, addressing maintainer feedback on closed PR #84 / issue #68.The previous PR only added empty stub structs at the workspace root. This replaces that with full enum factories that follow the existing
HashFactory/MACFactory/RNGFactorypattern.Design
Core
Signer/SignatureVerifier/KEMEncapsulator/KEMDecapsulatortraits are parameterized by const-generic key and ciphertext/signature sizes. A single enum wrapping ML-DSA-44/65/87 (or ML-KEM-512/768/1024) cannot implement those traits with one fixed size set.So this PR:
SignatureFactory/KEMFactoryenums — algorithm selectors implementingAlgorithmFactory(Default / Default128Bit / Default256Bit /new(name)).SignaturePublicKey,SignaturePrivateKey,KEMPublicKey,KEMPrivateKey) that encapsulate all supported key objects withencode/from_bytespass-through.SignatureSigner,SignatureVerifierEngine) that encapsulate the underlying ML-DSA state machines aftersign_init/verify_init.Defaults
default()default_128_bit()default_256_bit()Tests
crypto/factory/tests/signature_kem_factory_tests.rscovers defaults, name lookup, full sign/verify and encaps/decaps round-trips for every parameter set, streaming sign/verify, and algorithm/key mismatch errors.Fixes #68
Supersedes #84