pub mod ecdsa_k256_keccak {
extern crate alloc;
use alloc::vec::Vec;
use miden_core::{Felt, Word};
use miden_crypto::{
SequentialCommit,
dsa::ecdsa_k256_keccak::{PublicKey, Signature, SigningKey},
};
pub fn sign(sk: &SigningKey, msg: Word) -> Vec<Felt> {
let pk = sk.public_key();
let sig = sk.sign(msg);
encode_signature(&pk, &sig)
}
pub fn encode_signature(pk: &PublicKey, sig: &Signature) -> Vec<Felt> {
let pk_elements = pk.to_elements();
assert_eq!(
pk_elements.len(),
16,
"ECDSA public key elements must be QX[8] || QY[8] native limbs",
);
let mut out = Vec::with_capacity(32);
out.extend(pk_elements);
out.extend_from_slice(&signature_felts(sig));
out
}
pub fn public_key_commitment(pk: &PublicKey) -> Word {
pk.to_commitment()
}
fn signature_felts(signature: &Signature) -> [Felt; 16] {
let mut felts = [Felt::from_u32(0); 16];
felts[..8].copy_from_slice(&limbs_to_felts(be_bytes_to_le_limbs(signature.r())));
felts[8..].copy_from_slice(&limbs_to_felts(be_bytes_to_le_limbs(signature.s())));
felts
}
fn be_bytes_to_le_limbs(bytes: &[u8; 32]) -> [u32; 8] {
core::array::from_fn(|i| {
let offset = bytes.len() - (i + 1) * 4;
u32::from_be_bytes(bytes[offset..offset + 4].try_into().expect("u32 limb"))
})
}
fn limbs_to_felts<const N: usize>(limbs: [u32; N]) -> [Felt; N] {
limbs.map(Felt::from_u32)
}
}
pub mod falcon512_poseidon2 {
extern crate alloc;
use alloc::vec::Vec;
pub use miden_core::crypto::dsa::falcon512_poseidon2::{PublicKey, SecretKey, Signature};
use miden_core::{
Felt, Word,
crypto::{dsa::falcon512_poseidon2::Polynomial, hash::Poseidon2},
};
pub fn sign(sk: &SecretKey, msg: Word) -> Option<Vec<Felt>> {
let sig = sk.sign(msg);
Some(encode_signature(sig.public_key(), &sig))
}
pub fn encode_signature(pk: &PublicKey, sig: &Signature) -> Vec<Felt> {
use alloc::vec;
let nonce = sig.nonce();
let s2 = sig.sig_poly();
let pi = Polynomial::mul_modulo_p(pk, s2);
let mut polynomials = pk.to_elements();
polynomials.extend(s2.to_elements());
polynomials.extend(pi.iter().map(|a| Felt::new_unchecked(*a)));
let digest_polynomials = Poseidon2::hash_elements(&polynomials);
let challenge = (digest_polynomials[0], digest_polynomials[1]);
let mut result: Vec<Felt> = vec![challenge.1, challenge.0];
result.extend_from_slice(&polynomials);
result.extend_from_slice(&nonce.to_elements());
result
}
}