From ae4298ce6bc0324748e5fba20190a0957beaa66b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meusel?= Date: Tue, 25 Jun 2024 18:38:05 +0200 Subject: [PATCH] Cache the result of ntt(t1 << D) in the verification op t1 is part of the public key and thus independent of any other verification input. Precomputing it saves about 20% of verification runtime when performing more than a single verification with the same Botan::PK_Verifier. Co-Authored-By: Fabian Albert --- src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp b/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp index 51caeb62260..d64d644ea00 100644 --- a/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp +++ b/src/lib/pubkey/dilithium/dilithium_common/dilithium.cpp @@ -278,6 +278,7 @@ class Dilithium_Verification_Operation final : public PK_Ops::Verification { Dilithium_Verification_Operation(std::shared_ptr pubkey) : m_pub_key(std::move(pubkey)), m_A(dilithium_expand_A(m_pub_key->rho(), m_pub_key->mode())), + m_t1_ntt_shifted(ntt(m_pub_key->t1() << DilithiumConstants::D)), m_h(m_pub_key->mode().symmetric_primitives().get_message_hash(m_pub_key->tr())) {} void update(const uint8_t msg[], size_t msg_len) override { m_h.update({msg, msg_len}); } @@ -315,7 +316,7 @@ class Dilithium_Verification_Operation final : public PK_Ops::Verification { const auto c_hat = ntt(dilithium_sample_in_ball(c1, mode)); auto w_approx = m_A * ntt(std::move(z)); - w_approx -= c_hat * ntt(m_pub_key->t1() << DilithiumConstants::D); + w_approx -= c_hat * m_t1_ntt_shifted; w_approx.reduce(); auto w1 = inverse_ntt(std::move(w_approx)); w1.conditional_add_q(); @@ -332,6 +333,7 @@ class Dilithium_Verification_Operation final : public PK_Ops::Verification { private: std::shared_ptr m_pub_key; DilithiumPolyMatNTT m_A; + DilithiumPolyVecNTT m_t1_ntt_shifted; DilithiumMessageHash m_h; };