mirror of
https://github.com/hanzoai/crypto.git
synced 2026-09-30 21:37:30 +00:00
give the crate a workspace root, and the pqc callers the api that exists
cargo could not read the manifest at all:
error inheriting `aes-gcm` from workspace root manifest's
workspace.dependencies.aes-gcm: failed to find a workspace root
All 25 dependencies are declared `workspace = true`, which resolves only
against a [workspace.dependencies] table, and the crate was extracted from a
monorepo without one. The versions here are the ones Cargo.lock had already
resolved, so this records what the crate was building against and chooses
nothing new — `cargo build --locked` leaves Cargo.lock untouched.
That got the manifest parsed and the library building, which exposed three
callers written against an ml-kem/ml-dsa that predates the pinned versions:
Encapsulate and Decapsulate are private at ml_kem's root and public at
ml_kem::kem, and MlKem768::generate needs KemCore in scope.
ml-dsa has no Ml_Dsa65, no VerificationKey and no SigningKey::generate.
Key generation is the KeyGen trait (MlDsa65::key_gen), the pair hands out
signing_key()/verifying_key(), and signing goes through signature::Signer
and Verifier.
ml-dsa is on rand_core 0.9 while ml-kem is on 0.6, so one thread_rng cannot
serve both. The ml-dsa side takes OsRng from ml-dsa's own re-export, via
unwrap_err, because OsRng is fallible in 0.9 and key_gen wants an
infallible CryptoRng. No new dependency.
integration_test's message list mixed [u8; 9], [u8; 27], [u8; 0] and
[u8; 1000] in one untyped array, which has no single element type. Typed
as [&[u8]; 4].
Both examples RUN, not merely compile: ML-KEM encapsulation round-trips,
ML-DSA signatures verify, HQC round-trips. 12 tests pass.
Worth knowing separately: src/ml_kem.rs, src/ml_dsa.rs, src/hqc.rs, src/pqc/
and src/hybrid/ are in no build target — lib.rs declares only symmetric, hash,
error and prelude. Those wrappers are dead files and would not compile as they
stand (src/ml_dsa.rs imports the same Ml_Dsa65 and VerificationKey that do not
exist). Post-quantum is reachable today only as the re-exported upstream
crates, without this crate's SecurityLevel/zeroizing layer over it.
This commit is contained in:
+39
-1
@@ -60,4 +60,42 @@ no-std = []
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
# This crate is its own workspace root. Every dependency below is declared
|
||||
# `workspace = true`, which only resolves against a [workspace.dependencies]
|
||||
# table — and there was none, so cargo could not read the manifest at all:
|
||||
#
|
||||
# error inheriting `aes-gcm` from workspace root manifest's
|
||||
# workspace.dependencies.aes-gcm: failed to find a workspace root
|
||||
#
|
||||
# The versions are the ones Cargo.lock already resolved, so this records what
|
||||
# the crate was building against rather than choosing anything new.
|
||||
[workspace]
|
||||
|
||||
[workspace.dependencies]
|
||||
ml-kem = "0.3.0-pre"
|
||||
ml-dsa = "0.1.0-rc.0"
|
||||
pqcrypto-hqc = "0.2.2"
|
||||
pqcrypto-traits = "0.3.5"
|
||||
blake3 = "1.8.2"
|
||||
chacha20poly1305 = "0.10.1"
|
||||
aes-gcm = "0.10.3"
|
||||
sha3 = "0.10.8"
|
||||
x25519-dalek = "2.0.1"
|
||||
ed25519-dalek = "2.2.0"
|
||||
argon2 = "0.5.3"
|
||||
rand = "0.8.5"
|
||||
rand_core = "0.6.4"
|
||||
zeroize = "1.8.1"
|
||||
subtle = "2.6.1"
|
||||
hex = "0.4.3"
|
||||
base64 = "0.22.1"
|
||||
serde = "1.0.226"
|
||||
serde_json = "1.0.145"
|
||||
bincode = "1.3.3"
|
||||
thiserror = "1.0.69"
|
||||
anyhow = "1.0.100"
|
||||
criterion = "0.5.1"
|
||||
proptest = "1.8.0"
|
||||
quickcheck = "1.0.3"
|
||||
|
||||
+14
-7
@@ -9,7 +9,8 @@ fn main() -> Result<()> {
|
||||
// ML-KEM (NIST FIPS 203) - Post-quantum key encapsulation
|
||||
println!("1. ML-KEM-768 (formerly Kyber):");
|
||||
{
|
||||
use ml_kem::{MlKem768, Encapsulate, Decapsulate};
|
||||
use ml_kem::kem::{Decapsulate, Encapsulate};
|
||||
use ml_kem::{KemCore, MlKem768};
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let (dk, ek) = MlKem768::generate(&mut rng);
|
||||
@@ -24,16 +25,20 @@ fn main() -> Result<()> {
|
||||
// ML-DSA (NIST FIPS 204) - Post-quantum signatures
|
||||
println!("\n2. ML-DSA-65 (formerly Dilithium):");
|
||||
{
|
||||
use ml_dsa::{Ml_Dsa65, SigningKey, VerificationKey};
|
||||
// ml-dsa is on rand_core 0.9 while ml-kem above is on 0.6, so the two
|
||||
// blocks cannot share one RNG. OsRng is fallible there; unwrap_err gives
|
||||
// the infallible CryptoRng key_gen asks for.
|
||||
use ml_dsa::signature::rand_core::{OsRng, TryRngCore};
|
||||
use ml_dsa::signature::{Signer, Verifier};
|
||||
use ml_dsa::{KeyGen, MlDsa65};
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let signing_key = SigningKey::generate(&mut rng).unwrap();
|
||||
let verification_key = signing_key.verification_key();
|
||||
let mut rng = OsRng.unwrap_err();
|
||||
let keypair = MlDsa65::key_gen(&mut rng);
|
||||
|
||||
let message = b"Hello, post-quantum world!";
|
||||
let signature = signing_key.try_sign_with_rng(&mut rng, message).unwrap();
|
||||
let signature = keypair.signing_key().sign(message);
|
||||
|
||||
verification_key.verify(message, &signature).unwrap();
|
||||
keypair.verifying_key().verify(message, &signature).unwrap();
|
||||
println!(" ✓ Signature verification successful");
|
||||
}
|
||||
|
||||
@@ -90,6 +95,8 @@ fn main() -> Result<()> {
|
||||
println!("\n6. HQC-192:");
|
||||
{
|
||||
use hanzo_crypto::hqc::hqc192::*;
|
||||
// as_bytes on a shared secret comes from this trait, not the type.
|
||||
use pqcrypto_traits::kem::SharedSecret;
|
||||
|
||||
let (pk, sk) = keypair();
|
||||
let (ss1, ct) = encapsulate(&pk);
|
||||
|
||||
+14
-7
@@ -6,7 +6,8 @@ fn main() {
|
||||
// Test ML-KEM (Pure Rust - no AVX2 issues!)
|
||||
println!("✓ ML-KEM-768 (FIPS 203):");
|
||||
{
|
||||
use ml_kem::{MlKem768, KemCore};
|
||||
use ml_kem::kem::{Decapsulate, Encapsulate};
|
||||
use ml_kem::{KemCore, MlKem768};
|
||||
use rand::thread_rng;
|
||||
|
||||
let mut rng = thread_rng();
|
||||
@@ -20,14 +21,20 @@ fn main() {
|
||||
// Test ML-DSA (Pure Rust)
|
||||
println!("\n✓ ML-DSA-65 (FIPS 204):");
|
||||
{
|
||||
use ml_dsa::MlDsa65;
|
||||
use rand::thread_rng;
|
||||
// ml-dsa is on rand_core 0.9 while ml-kem above is on 0.6, so the two
|
||||
// blocks cannot share one RNG. Take ml-dsa's own re-export rather than
|
||||
// add a second rand to the manifest.
|
||||
use ml_dsa::signature::rand_core::{OsRng, TryRngCore};
|
||||
use ml_dsa::signature::{Signer, Verifier};
|
||||
use ml_dsa::{KeyGen, MlDsa65};
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let (sk, vk) = MlDsa65::generate(&mut rng).unwrap();
|
||||
// OsRng is fallible in rand_core 0.9; unwrap_err gives the infallible
|
||||
// CryptoRng that key_gen asks for.
|
||||
let mut rng = OsRng.unwrap_err();
|
||||
let keypair = MlDsa65::key_gen(&mut rng);
|
||||
let message = b"Quantum-resistant on ARM!";
|
||||
let signature = sk.try_sign(&message[..]).unwrap();
|
||||
vk.verify(&message[..], &signature).unwrap();
|
||||
let signature = keypair.signing_key().sign(&message[..]);
|
||||
keypair.verifying_key().verify(&message[..], &signature).unwrap();
|
||||
println!(" ✅ Digital signatures work!");
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ use rand::thread_rng;
|
||||
|
||||
#[test]
|
||||
fn test_ml_kem_integration() {
|
||||
use ml_kem::{MlKem768, Encapsulate, Decapsulate};
|
||||
use ml_kem::kem::{Decapsulate, Encapsulate};
|
||||
use ml_kem::{KemCore, MlKem768};
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let (dk, ek) = MlKem768::generate(&mut rng);
|
||||
@@ -21,14 +22,22 @@ fn test_ml_kem_integration() {
|
||||
|
||||
#[test]
|
||||
fn test_ml_dsa_integration() {
|
||||
use ml_dsa::{Ml_Dsa65, SigningKey};
|
||||
// ml-dsa is on rand_core 0.9 where ml-kem above is on 0.6, so this test
|
||||
// takes its RNG from ml-dsa's own re-export. OsRng is fallible there;
|
||||
// unwrap_err gives the infallible CryptoRng key_gen asks for.
|
||||
use ml_dsa::signature::rand_core::{OsRng, TryRngCore};
|
||||
use ml_dsa::signature::{Signer, Verifier};
|
||||
use ml_dsa::{KeyGen, MlDsa65};
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let signing_key = SigningKey::generate(&mut rng).unwrap();
|
||||
let verification_key = signing_key.verification_key();
|
||||
let mut rng = OsRng.unwrap_err();
|
||||
let keypair = MlDsa65::key_gen(&mut rng);
|
||||
let signing_key = keypair.signing_key();
|
||||
let verification_key = keypair.verifying_key();
|
||||
|
||||
// Test multiple messages
|
||||
let messages = [
|
||||
// Typed as slices: each literal is its own [u8; N], so an untyped array of
|
||||
// them has no single element type and never compiled.
|
||||
let messages: [&[u8]; 4] = [
|
||||
b"Message 1",
|
||||
b"Message 2 with more content",
|
||||
b"",
|
||||
@@ -36,7 +45,7 @@ fn test_ml_dsa_integration() {
|
||||
];
|
||||
|
||||
for msg in &messages {
|
||||
let signature = signing_key.try_sign_with_rng(&mut rng, *msg).unwrap();
|
||||
let signature = signing_key.sign(*msg);
|
||||
verification_key.verify(*msg, &signature).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user