#[doc(inline)]
pub use crate::xwing_internal::{
ciphertext_from_bytes, ciphertext_to_bytes, decaps, encaps, generate_keypair,
sharedsecret_to_bytes, xwingencapskey_from_bytes, xwingencapskey_to_bytes, SHAREDSECRET,
XWINGCIPHERTEXT, XWINGDECAPSKEY, XWINGENCAPSKEY,
};
#[cfg(test)]
#[cfg(feature = "rfctest")]
mod tests {
use core::fmt;
use core::fmt::Debug;
use hybrid_array::{
sizes::{U1088, U1120, U1184, U1216, U32, U6, U64, U96},
Array, ArrayN,
};
use serde::Deserialize;
use x25519_dalek::{PublicKey, SharedSecret, StaticSecret};
use super::*;
use crate::xwing_internal::{
encaps_derand, generate_keypair_derand, xwingdecapskey_from_bytes, xwingdecapskey_to_bytes,
CIPHERTEXT_SIZE, DECAPSULATION_KEY_SIZE, ENCAPSULATION_KEY_SIZE,
ENCAPSULATION_RANDOMNESS_SIZE,
};
use rkyber::randombytes::randombytes;
#[derive(Deserialize)]
struct TestVector {
#[serde(deserialize_with = "hex::serde::deserialize")]
seed: Vec<u8>,
#[serde(deserialize_with = "hex::serde::deserialize")]
eseed: Vec<u8>,
#[serde(deserialize_with = "hex::serde::deserialize")]
ss: [u8; 32],
#[serde(deserialize_with = "hex::serde::deserialize")]
sk: [u8; 32],
#[serde(deserialize_with = "hex::serde::deserialize")]
pk: Vec<u8>,
#[serde(deserialize_with = "hex::serde::deserialize")]
ct: Vec<u8>, }
#[test]
#[cfg(feature = "rfctest")]
fn rfc_test_vectors() {
let test_vectors =
serde_json::from_str::<Vec<TestVector>>(include_str!("test-vectors.json")).unwrap();
for test_vector in test_vectors {
run_test(test_vector);
}
}
#[cfg(feature = "rfctest")]
fn run_test(test_vector: TestVector) {
let seed = ArrayN::<u8, 32>::try_from(test_vector.seed.as_slice()).unwrap();
let mut sk: XWINGDECAPSKEY = Default::default();
let mut pk: XWINGENCAPSKEY = Default::default();
generate_keypair_derand(&mut pk, &mut sk, (&seed).into());
let mut dk_bytes: [u8; DECAPSULATION_KEY_SIZE] = [42; DECAPSULATION_KEY_SIZE];
xwingdecapskey_to_bytes(&mut dk_bytes, &sk);
assert_eq!(dk_bytes, test_vector.sk);
let mut ek_bytes: [u8; ENCAPSULATION_KEY_SIZE] = [42; ENCAPSULATION_KEY_SIZE];
xwingencapskey_to_bytes((&mut ek_bytes).into(), &pk);
assert_eq!(ek_bytes, test_vector.pk.as_slice());
let eseed =
ArrayN::<u8, ENCAPSULATION_RANDOMNESS_SIZE>::try_from(test_vector.eseed.as_slice())
.unwrap();
let mut ct: XWINGCIPHERTEXT = Default::default();
let mut ss: SHAREDSECRET = Default::default();
encaps_derand(&mut ss, &mut ct, &pk, &eseed);
assert_eq!(ss.ss_hat.as_slice(), test_vector.ss);
let mut bytes: [u8; CIPHERTEXT_SIZE] = [42; CIPHERTEXT_SIZE];
ciphertext_to_bytes((&mut bytes).into(), &ct);
assert_eq!(bytes, *test_vector.ct.as_slice());
decaps(&mut ss, &ct, &sk);
assert_eq!(ss.ss_hat.as_slice(), test_vector.ss);
}
#[test]
#[cfg(feature = "rfctest")]
fn ciphertext_serialize() {
let mut ct_a: XWINGCIPHERTEXT = Default::default();
let mut bytes: [u8; 32] = [42; 32];
randombytes(&mut ct_a.ct_m, 1088);
randombytes(&mut bytes, 32);
ct_a.ct_x = PublicKey::from(bytes);
let mut bytes: [u8; CIPHERTEXT_SIZE] = [42; CIPHERTEXT_SIZE];
ciphertext_to_bytes((&mut bytes).into(), &ct_a);
let mut ct_b: XWINGCIPHERTEXT = Default::default();
ciphertext_from_bytes(&mut ct_b, (&bytes).into());
assert_eq!(ct_a, ct_b);
}
#[test]
#[cfg(feature = "rfctest")]
fn key_serialize() {
let mut sk: XWINGDECAPSKEY = Default::default();
let mut pk: XWINGENCAPSKEY = Default::default();
generate_keypair(&mut pk, &mut sk);
let mut sk_bytes: [u8; DECAPSULATION_KEY_SIZE] = [42; DECAPSULATION_KEY_SIZE];
xwingdecapskey_to_bytes(&mut sk_bytes, &sk);
let mut pk_bytes: Array<u8, U1216> = Default::default();
xwingencapskey_to_bytes(&mut pk_bytes, &pk);
let mut sk_b: XWINGDECAPSKEY = Default::default();
xwingdecapskey_from_bytes(&mut sk_b, &sk_bytes);
let mut pk_b: XWINGENCAPSKEY = Default::default();
xwingencapskey_from_bytes(&mut pk_b, &pk_bytes);
assert_eq!(sk, sk_b);
assert_eq!(pk, pk_b);
}
}