58 lines
2.4 KiB
Rust
58 lines
2.4 KiB
Rust
//! KAT (Known-Answer Test) — байт-точный референс. iOS/Android/Web реализации
|
||
//! должны выдавать идентичные значения на той же мнемонике.
|
||
|
||
use mt_codec::domain;
|
||
use mt_crypto::{keypair_from_seed, sign as mldsa_sign, verify as mldsa_verify};
|
||
use mt_mnemonic::{entropy_to_mnemonic, mldsa_seed_for_role, mnemonic_to_master_seed};
|
||
use mt_state::derive_account_id;
|
||
|
||
const MT_SUITE_MLDSA65: u16 = 0x0001;
|
||
const ENTROPY_ZERO: [u8; 32] = [0u8; 32];
|
||
|
||
#[test]
|
||
fn kat_entropy_zero_to_account_id() {
|
||
let mnemonic = entropy_to_mnemonic(&ENTROPY_ZERO);
|
||
assert_eq!(mnemonic.split_whitespace().count(), 24);
|
||
|
||
let master = mnemonic_to_master_seed(&mnemonic).expect("master seed");
|
||
let acc_seed = mldsa_seed_for_role(&master, domain::ACCOUNT_KEY);
|
||
let (pk, _sk) = keypair_from_seed(&acc_seed).expect("keypair");
|
||
let account_id = derive_account_id(MT_SUITE_MLDSA65, pk.as_bytes());
|
||
|
||
eprintln!("=== KAT vector #1 (entropy = 32×0x00) ===");
|
||
eprintln!("mnemonic : {mnemonic}");
|
||
eprintln!("master[..8] : {}", hex::encode(&master[..8]));
|
||
eprintln!("acc_seed : {}", hex::encode(acc_seed));
|
||
eprintln!("pubkey[..16]: {}", hex::encode(&pk.as_bytes()[..16]));
|
||
eprintln!("account_id : {}", hex::encode(account_id));
|
||
}
|
||
|
||
#[test]
|
||
fn determinism() {
|
||
let mnemonic = entropy_to_mnemonic(&ENTROPY_ZERO);
|
||
let master1 = mnemonic_to_master_seed(&mnemonic).unwrap();
|
||
let master2 = mnemonic_to_master_seed(&mnemonic).unwrap();
|
||
assert_eq!(master1, master2);
|
||
let s1 = mldsa_seed_for_role(&master1, domain::ACCOUNT_KEY);
|
||
let s2 = mldsa_seed_for_role(&master2, domain::ACCOUNT_KEY);
|
||
assert_eq!(s1, s2);
|
||
let (pk1, _) = keypair_from_seed(&s1).unwrap();
|
||
let (pk2, _) = keypair_from_seed(&s2).unwrap();
|
||
assert_eq!(pk1.as_bytes(), pk2.as_bytes());
|
||
let id1 = derive_account_id(MT_SUITE_MLDSA65, pk1.as_bytes());
|
||
let id2 = derive_account_id(MT_SUITE_MLDSA65, pk2.as_bytes());
|
||
assert_eq!(id1, id2);
|
||
}
|
||
|
||
#[test]
|
||
fn sign_verify_roundtrip() {
|
||
let mnemonic = entropy_to_mnemonic(&ENTROPY_ZERO);
|
||
let master = mnemonic_to_master_seed(&mnemonic).unwrap();
|
||
let s = mldsa_seed_for_role(&master, domain::ACCOUNT_KEY);
|
||
let (pk, sk) = keypair_from_seed(&s).unwrap();
|
||
let msg = b"montana mainnet test";
|
||
let sig = mldsa_sign(&sk, msg).unwrap();
|
||
assert!(mldsa_verify(&pk, msg, &sig));
|
||
assert!(!mldsa_verify(&pk, b"tampered", &sig));
|
||
}
|