feat: add generate_ml_kem_768, pending implement ML-KEM later

This commit is contained in:
2025-09-27 00:49:37 +08:00
parent 1d23dba248
commit 3d29fe6a6d
4 changed files with 97 additions and 0 deletions

52
Cargo.lock generated
View File

@@ -614,6 +614,7 @@ dependencies = [
"external-command-rs", "external-command-rs",
"hex", "hex",
"jwt", "jwt",
"ml-kem",
"openpgp-card 0.3.7", "openpgp-card 0.3.7",
"openpgp-card-pcsc", "openpgp-card-pcsc",
"openpgp-card-sequoia", "openpgp-card-sequoia",
@@ -1750,6 +1751,15 @@ version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "hybrid-array"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9"
dependencies = [
"typenum",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "1.6.0" version = "1.6.0"
@@ -2071,6 +2081,25 @@ dependencies = [
"sha2 0.10.9", "sha2 0.10.9",
] ]
[[package]]
name = "keccak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
dependencies = [
"cpufeatures",
]
[[package]]
name = "kem"
version = "0.3.0-pre.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b8645470337db67b01a7f966decf7d0bafedbae74147d33e641c67a91df239f"
dependencies = [
"rand_core 0.6.4",
"zeroize",
]
[[package]] [[package]]
name = "kernel32-sys" name = "kernel32-sys"
version = "0.2.2" version = "0.2.2"
@@ -2356,6 +2385,19 @@ dependencies = [
"ws2_32-sys", "ws2_32-sys",
] ]
[[package]]
name = "ml-kem"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97befee0c869cb56f3118f49d0f9bb68c9e3f380dec23c1100aedc4ec3ba239a"
dependencies = [
"hybrid-array",
"kem",
"rand_core 0.6.4",
"sha3",
"zeroize",
]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.14" version = "0.2.14"
@@ -3892,6 +3934,16 @@ dependencies = [
"digest 0.10.7", "digest 0.10.7",
] ]
[[package]]
name = "sha3"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
dependencies = [
"digest 0.10.7",
"keccak",
]
[[package]] [[package]]
name = "shlex" name = "shlex"
version = "1.3.0" version = "1.3.0"

View File

@@ -67,5 +67,9 @@ ssh-key = { version = "0.6", features = ["ecdsa", "alloc"] }
tokio = "1.45.1" tokio = "1.45.1"
ssh-encoding = { version = "0.2.0", features = ["alloc"] } ssh-encoding = { version = "0.2.0", features = ["alloc"] }
zeroize = "1.8" zeroize = "1.8"
ml-kem = { version = "0.2.1", features = ["zeroize"] }
#lazy_static = "1.4.0" #lazy_static = "1.4.0"
#ctap-hid-fido2 = "2.1.3" #ctap-hid-fido2 = "2.1.3"
#[patch.crates-io]
#ml-kem = { path = "externals/ml-kem" }

View File

@@ -84,6 +84,7 @@ mod sshutil;
mod util; mod util;
mod yubikeyutil; mod yubikeyutil;
mod cmd_yubikey; mod cmd_yubikey;
mod mlkemutil;
pub struct DefaultCommandImpl; pub struct DefaultCommandImpl;

40
src/mlkemutil.rs Normal file
View File

@@ -0,0 +1,40 @@
use crate::util::base64_encode;
use ml_kem::kem::{Decapsulate, Encapsulate};
use ml_kem::{EncodedSizeUser, KemCore, MlKem768};
use rust_util::XResult;
use std::convert::TryInto;
// #[test]
pub fn generate_ml_kem_768() -> XResult<()> {
let mut rng = rand::thread_rng();
let (dk, ek) = <MlKem768 as KemCore>::generate(&mut rng);
println!("dk: {}", base64_encode(&dk.as_bytes().0.to_vec()));
println!("ek: {}", base64_encode(ek.as_bytes().0.to_vec()));
let ek_bytes = dk.as_bytes().0.to_vec();
let dk = <MlKem768 as KemCore>::DecapsulationKey::from_bytes(&opt_result!(
ek_bytes.as_slice().try_into(),
"Parse decapsulation key failed: {}"
));
let (encoded_ciphertext, shared_key) = opt_result!(
ek.encapsulate(&mut rng),
"Encapsulation key encapsulate failed: {:?}"
);
println!(
"encoded_ciphertext: {}",
base64_encode(&encoded_ciphertext.0.to_vec())
);
println!("shared_key: {}", base64_encode(&shared_key.0.to_vec()));
let k_bytes = encoded_ciphertext.0.to_vec();
let shared_key_2 = opt_result!(
dk.decapsulate(opt_result!(
&k_bytes.as_slice().try_into(),
"Parse encoded ciphertext failed: {}"
)),
"Decapsulation key decapsulate failed: {:?}"
);
println!("shared_key2: {}", base64_encode(&shared_key_2.0.to_vec()));
Ok(())
}