1use ml_dsa::MlDsa65;
5use mldsa_core::KeyPair as CoreKeyPair;
6
7#[cfg(all(
8 not(target_feature = "atomics"),
9 target_family = "wasm",
10 feature = "talc"
11))]
12#[global_allocator]
13static TALC: talc::wasm::WasmDynamicTalc = talc::wasm::new_wasm_dynamic_allocator();
14
15pub const SEED_SIZE: usize = 32;
16pub const SIGNING_KEY_SIZE: usize = 4032;
17pub const VERIFYING_KEY_SIZE: usize = 1952;
18pub const SIGNATURE_SIZE: usize = 3309;
19
20pub type KeyPair = CoreKeyPair<VERIFYING_KEY_SIZE>;
21
22pub fn generate_keypair() -> KeyPair {
23 mldsa_core::generate_keypair::<MlDsa65, VERIFYING_KEY_SIZE>()
24}
25
26pub fn sign(
27 seed: &[u8; SEED_SIZE],
28 message: &[u8],
29 context: Option<&[u8]>,
30) -> [u8; SIGNATURE_SIZE] {
31 mldsa_core::sign::<MlDsa65, SIGNATURE_SIZE>(seed, message, context)
32}
33
34pub fn verify(
35 vk: &[u8; VERIFYING_KEY_SIZE],
36 message: &[u8],
37 sig: &[u8; SIGNATURE_SIZE],
38 context: Option<&[u8]>,
39) -> bool {
40 mldsa_core::verify::<MlDsa65, VERIFYING_KEY_SIZE, SIGNATURE_SIZE>(vk, message, sig, context)
41}
42
43#[cfg(feature = "wasm")]
44mod wasm {
45 use super::*;
46 use mldsa_core::wasm::{GenerateKeypairResult, decode_fixed, encode};
47 use wasm_bindgen::prelude::*;
48
49 #[wasm_bindgen(js_name = "generateKeypair")]
50 pub fn generate_keypair_wasm() -> GenerateKeypairResult {
51 let kp = super::generate_keypair();
52
53 GenerateKeypairResult {
54 seed: encode(&kp.seed),
55 verifying_key: encode(&kp.verifying_key),
56 }
57 }
58
59 #[wasm_bindgen]
60 pub fn sign(seed: &str, message: &[u8], context: Option<Vec<u8>>) -> Result<String, JsError> {
61 let seed_bytes = decode_fixed::<SEED_SIZE>(seed, "seed")?;
62 let ctx = context.as_deref();
63
64 Ok(encode(&super::sign(&seed_bytes, message, ctx)))
65 }
66
67 #[wasm_bindgen]
68 pub fn verify(
69 vk: &str,
70 message: &[u8],
71 signature: &str,
72 context: Option<Vec<u8>>,
73 ) -> Result<bool, JsError> {
74 let vk_bytes = decode_fixed::<VERIFYING_KEY_SIZE>(vk, "verifyingKey")?;
75 let sig_bytes = decode_fixed::<SIGNATURE_SIZE>(signature, "signature")?;
76 let ctx = context.as_deref();
77
78 Ok(super::verify(&vk_bytes, message, &sig_bytes, ctx))
79 }
80}
81
82#[cfg(feature = "wasm")]
83pub use wasm::*;
84
85mldsa_core::test_mldsa!();