Skip to content

Commit

Permalink
Add some tests for pre-hashed variants
Browse files Browse the repository at this point in the history
  • Loading branch information
jschneider-bensch committed Oct 1, 2024
1 parent c1a03d3 commit 26a2231
Show file tree
Hide file tree
Showing 9 changed files with 3,118 additions and 609 deletions.
14 changes: 14 additions & 0 deletions libcrux-ml-dsa/tests/kats/dilithium.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,13 @@ def keygen(self):
sk = self._pack_sk(rho, K, tr, s1, s2, t0)
return pk, sk

def sign_pre_hashed(self, sk_bytes, m, ctx=b"", rnd=None):
shake128_oid = b'\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0B'
m_hashed = Shake128.digest(m, 256)
m_prime = b'\x01' + len(ctx).to_bytes(1, "little") + ctx + shake128_oid + m_hashed

return self.sign_internal(sk_bytes, m_prime, rnd)

def sign(self, sk_bytes, m, ctx=b"", rnd=None):
m_prime = b'\x00' + len(ctx).to_bytes(1, "little") + ctx + m
return self.sign_internal(sk_bytes, m_prime, rnd)
Expand Down Expand Up @@ -529,6 +536,13 @@ def sign_internal(self, sk_bytes, m, rnd):

return self._pack_sig(c_tilde, z, h)

def verify_pre_hashed(self, pk_bytes, m, sig_bytes, ctx=b""):
shake128_oid = b'\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x0B'
m_hashed = Shake128.digest(m, 256)
m_prime = b'\x01' + len(ctx).to_bytes(1, "little") + ctx + shake128_oid + m_hashed

return self.verify_internal(sk_bytes, m_prime, rnd)

def verify(self, pk_bytes, m, sig_bytes, ctx=b""):
m_prime = b'\x00' + len(ctx).to_bytes(1, "little") + ctx + m
return self.verify_internal(sk_bytes, m_prime, rnd)
Expand Down
32 changes: 30 additions & 2 deletions libcrux-ml-dsa/tests/kats/generate_kats.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

def generate_nistkats(algorithm):
kats_formatted = []
pre_hashed_kats_formatted = []

entropy_input = bytes([i for i in range(48)])
rng = AES256_CTR_DRBG(entropy_input)
Expand Down Expand Up @@ -43,9 +44,36 @@ def generate_nistkats(algorithm):
}
)

with open("nistkats-{}{}.json".format(algorithm.k, algorithm.l), "w") as f:
json.dump(kats_formatted, f, ensure_ascii=False, indent=4)
for i in range(100):
seed = rng.random_bytes(48)

algorithm.set_drbg_seed(seed)

vk, sk = algorithm.keygen()

msg_len = 33 * (i + 1)
msg = rng.random_bytes(msg_len)
sig_pre_hashed = algorithm.sign_pre_hashed(sk, msg)

pre_hashed_kats_formatted.append(
{
"key_generation_seed": bytes(algorithm.keygen_seed).hex(),
"sha3_256_hash_of_verification_key": bytes(
hashlib.sha3_256(vk).digest()
).hex(),
"sha3_256_hash_of_signing_key": bytes(
hashlib.sha3_256(sk).digest()
).hex(),
"message": bytes(msg).hex(),
"signing_randomness": bytes(algorithm.signing_randomness).hex(),
"sha3_256_hash_of_signature": bytes(
hashlib.sha3_256(sig_pre_hashed).digest()
).hex(),
}
)

with open("nistkats_pre_hashed-{}{}.json".format(algorithm.k, algorithm.l), "w") as f:
json.dump(pre_hashed_kats_formatted, f, ensure_ascii=False, indent=4)

generate_nistkats(Dilithium2)
generate_nistkats(Dilithium3)
Expand Down
400 changes: 200 additions & 200 deletions libcrux-ml-dsa/tests/kats/nistkats-44.json

Large diffs are not rendered by default.

400 changes: 200 additions & 200 deletions libcrux-ml-dsa/tests/kats/nistkats-65.json

Large diffs are not rendered by default.

400 changes: 200 additions & 200 deletions libcrux-ml-dsa/tests/kats/nistkats-87.json

Large diffs are not rendered by default.

802 changes: 802 additions & 0 deletions libcrux-ml-dsa/tests/kats/nistkats_pre_hashed-44.json

Large diffs are not rendered by default.

802 changes: 802 additions & 0 deletions libcrux-ml-dsa/tests/kats/nistkats_pre_hashed-65.json

Large diffs are not rendered by default.

802 changes: 802 additions & 0 deletions libcrux-ml-dsa/tests/kats/nistkats_pre_hashed-87.json

Large diffs are not rendered by default.

75 changes: 68 additions & 7 deletions libcrux-ml-dsa/tests/nistkats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct MlDsaNISTKAT {
}

macro_rules! impl_nist_known_answer_tests {
($name:ident, $parameter_set:literal, $key_gen:expr, $sign:expr, $verify:expr) => {
($name:ident, $name_pre_hashed:ident, $parameter_set:literal, $key_gen:expr, $sign:expr, $verify:expr, $sign_pre_hashed:expr, $verify_pre_hashed:expr) => {
#[test]
fn $name() {
let katfile_path = Path::new("tests")
Expand Down Expand Up @@ -70,61 +70,122 @@ macro_rules! impl_nist_known_answer_tests {
.expect("Verification should pass since the signature was honestly generated");
}
}

#[test]
fn $name_pre_hashed() {
let katfile_path = Path::new("tests")
.join("kats")
.join(format!("nistkats_pre_hashed-{}.json", $parameter_set));
let katfile = File::open(katfile_path).expect("Could not open KAT file.");
let reader = BufReader::new(katfile);

let nist_kats: Vec<MlDsaNISTKAT> =
serde_json::from_reader(reader).expect("Could not deserialize KAT file.");

for kat in nist_kats {
let key_pair = $key_gen(kat.key_generation_seed);

let verification_key_hash = libcrux_sha3::sha256(&key_pair.verification_key.0);
assert_eq!(
verification_key_hash, kat.sha3_256_hash_of_verification_key,
"verification_key_hash != kat.sha3_256_hash_of_verification_key"
);

let signing_key_hash = libcrux_sha3::sha256(&key_pair.signing_key.0);
assert_eq!(
signing_key_hash, kat.sha3_256_hash_of_signing_key,
"signing_key_hash != kat.sha3_256_hash_of_signing_key"
);

let message = hex::decode(kat.message).expect("Hex-decoding the message failed.");

let signature =
$sign_pre_hashed(&key_pair.signing_key, &message, b"", kat.signing_randomness)
.expect("Rejection sampling failure probability is < 2⁻¹²⁸");

let signature_hash = libcrux_sha3::sha256(&signature.0);
assert_eq!(
signature_hash, kat.sha3_256_hash_of_signature,
"signature_hash != kat.sha3_256_hash_of_signature"
);

$verify_pre_hashed(&key_pair.verification_key, &message, b"", &signature)
.expect("Verification should pass since the signature was honestly generated");
}
}
};
}

// 44

impl_nist_known_answer_tests!(
nist_known_answer_tests_44,
nist_known_answer_tests_pre_hashed_44,
44,
libcrux_ml_dsa::ml_dsa_44::generate_key_pair,
libcrux_ml_dsa::ml_dsa_44::sign,
libcrux_ml_dsa::ml_dsa_44::verify
libcrux_ml_dsa::ml_dsa_44::verify,
libcrux_ml_dsa::ml_dsa_44::sign_pre_hashed,
libcrux_ml_dsa::ml_dsa_44::verify_pre_hashed
);

impl_nist_known_answer_tests!(
nist_known_answer_tests_44_portable,
nist_known_answer_tests_pre_hashed_44_portable,
44,
libcrux_ml_dsa::ml_dsa_44::portable::generate_key_pair,
libcrux_ml_dsa::ml_dsa_44::portable::sign,
libcrux_ml_dsa::ml_dsa_44::portable::verify
libcrux_ml_dsa::ml_dsa_44::portable::verify,
libcrux_ml_dsa::ml_dsa_44::sign_pre_hashed,
libcrux_ml_dsa::ml_dsa_44::verify_pre_hashed
);

#[cfg(feature = "simd128")]
impl_nist_known_answer_tests!(
nist_known_answer_tests_44_simd128,
nist_known_answer_tests_pre_hashed_44_simd128,
44,
libcrux_ml_dsa::ml_dsa_44::neon::generate_key_pair,
libcrux_ml_dsa::ml_dsa_44::neon::sign,
libcrux_ml_dsa::ml_dsa_44::neon::verify
libcrux_ml_dsa::ml_dsa_44::neon::verify,
libcrux_ml_dsa::ml_dsa_44::sign_pre_hashed,
libcrux_ml_dsa::ml_dsa_44::verify_pre_hashed
);

#[cfg(feature = "simd256")]
impl_nist_known_answer_tests!(
nist_known_answer_tests_44_simd256,
nist_known_answer_tests_pre_hashed_44_simd256,
44,
libcrux_ml_dsa::ml_dsa_44::avx2::generate_key_pair,
libcrux_ml_dsa::ml_dsa_44::avx2::sign,
libcrux_ml_dsa::ml_dsa_44::avx2::verify
libcrux_ml_dsa::ml_dsa_44::avx2::verify,
libcrux_ml_dsa::ml_dsa_44::sign_pre_hashed,
libcrux_ml_dsa::ml_dsa_44::verify_pre_hashed
);

// 65

impl_nist_known_answer_tests!(
nist_known_answer_tests_65,
nist_known_answer_tests_pre_hashed_65,
65,
libcrux_ml_dsa::ml_dsa_65::generate_key_pair,
libcrux_ml_dsa::ml_dsa_65::sign,
libcrux_ml_dsa::ml_dsa_65::verify
libcrux_ml_dsa::ml_dsa_65::verify,
libcrux_ml_dsa::ml_dsa_65::sign_pre_hashed,
libcrux_ml_dsa::ml_dsa_65::verify_pre_hashed
);

// 87

impl_nist_known_answer_tests!(
nist_known_answer_tests_87,
nist_known_answer_tests_pre_hashed_87,
87,
libcrux_ml_dsa::ml_dsa_87::generate_key_pair,
libcrux_ml_dsa::ml_dsa_87::sign,
libcrux_ml_dsa::ml_dsa_87::verify
libcrux_ml_dsa::ml_dsa_87::verify,
libcrux_ml_dsa::ml_dsa_87::sign_pre_hashed,
libcrux_ml_dsa::ml_dsa_87::verify_pre_hashed
);

0 comments on commit 26a2231

Please sign in to comment.