use data::{
DETERMINISTIC_SIGNATURE, EXPECTED_SIG, EXPECTED_SIG_POLYS, NUM_TEST_VECTORS, SK_POLYS,
SYNC_DATA_FOR_TEST_VECTOR,
};
use prng::Shake256Testing;
use rand::{RngCore, SeedableRng};
use rand_chacha::ChaCha20Rng;
use super::{Serializable, math::Polynomial};
use crate::dsa::falcon512_poseidon2::{
PREVERSIONED_NONCE, PREVERSIONED_NONCE_LEN, SIG_NONCE_LEN, SIG_POLY_BYTE_LEN, SecretKey,
};
mod data;
mod prng;
pub(crate) use prng::ChaCha;
#[test]
fn test_signature_gen_reference_impl() {
let message = b"data1";
let seed = b"external";
let mut rng_shake = Shake256Testing::new(seed.to_vec());
rng_shake.sync_rng();
for i in 0..NUM_TEST_VECTORS {
let [f, g, big_f, big_g] = SK_POLYS[i];
let f = Polynomial::new(f.to_vec());
let g = Polynomial::new(g.to_vec());
let big_f = Polynomial::new(big_f.to_vec());
let big_g = Polynomial::new(big_g.to_vec());
let sk = SecretKey::from_short_lattice_basis([g, f, big_g, big_f]);
let skip_bytes = SYNC_DATA_FOR_TEST_VECTOR[i].0 * 8;
let mut dummy = vec![0_u8; skip_bytes];
rng_shake.fill_bytes(&mut dummy);
let signature = sk.sign_with_rng_testing(message, &mut rng_shake);
let sig_coef = signature.sig_poly().to_balanced_values();
assert_eq!(sig_coef, EXPECTED_SIG_POLYS[i]);
let sig_bytes = &signature.to_bytes();
let expected_sig_bytes = EXPECTED_SIG[i];
let hex_expected_sig_bytes = hex::decode(expected_sig_bytes).unwrap();
let nonce = signature.nonce();
assert_eq!(hex_expected_sig_bytes[1..1 + SIG_NONCE_LEN], nonce.as_bytes());
assert_eq!(
&hex_expected_sig_bytes[1 + SIG_NONCE_LEN..],
&sig_bytes[2..2 + SIG_POLY_BYTE_LEN]
);
}
}
#[test]
fn test_secret_key_debug_redaction() {
let seed = [1_u8; 32];
let mut rng = ChaCha20Rng::from_seed(seed);
let sk = SecretKey::with_rng(&mut rng);
let debug_output = format!("{sk:?}");
assert_eq!(debug_output, "<elided secret for SecretKey>");
let display_output = format!("{sk}");
assert_eq!(display_output, "<elided secret for SecretKey>");
}
#[test]
fn test_signature_determinism() {
let seed = [0_u8; 32];
let mut rng = ChaCha20Rng::from_seed(seed);
let sk = SecretKey::with_rng(&mut rng);
let message = b"data";
let signature = sk.sign(message.into());
let serialized_signature = signature.to_bytes();
assert_eq!(serialized_signature, DETERMINISTIC_SIGNATURE);
}
#[test]
fn check_preversioned_fixed_nonce() {
assert_eq!(build_preversioned_fixed_nonce(), PREVERSIONED_NONCE)
}
fn build_preversioned_fixed_nonce() -> [u8; PREVERSIONED_NONCE_LEN] {
use crate::dsa::falcon512_poseidon2::LOG_N;
let mut result = [0_u8; 39];
result[0] = LOG_N;
let domain_separator = "FALCON-POSEIDON2-DET".as_bytes();
result
.iter_mut()
.skip(1)
.zip(domain_separator.iter())
.for_each(|(dst, src)| *dst = *src);
result
}