From 0639c4d5a2afc7437b9c46ade26105618770c12e Mon Sep 17 00:00:00 2001 From: mraksoll4 <32709596+mraksoll4@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:22:09 +0200 Subject: [PATCH] add suport public key generation from private key dilithium2 - 5 add suport public key generation from private key dilithium2 - 5 --- .../oldpqclean_dilithium2_aarch64/api.h | 2 + .../oldpqclean_dilithium2_aarch64/sign.c | 55 +++++++++++- .../oldpqclean_dilithium2_aarch64/sign.h | 3 + .../oldpqclean_dilithium3_aarch64/api.h | 2 + .../oldpqclean_dilithium3_aarch64/sign.c | 55 +++++++++++- .../oldpqclean_dilithium3_aarch64/sign.h | 3 + .../oldpqclean_dilithium5_aarch64/api.h | 2 + .../oldpqclean_dilithium5_aarch64/sign.c | 56 +++++++++++- .../oldpqclean_dilithium5_aarch64/sign.h | 3 + .../api.h | 12 +++ .../sign.c | 85 ++++++++++++++++++- .../sign.h | 3 + .../pqcrystals-dilithium_dilithium2_ref/api.h | 12 +++ .../sign.c | 56 +++++++++++- .../sign.h | 3 + .../api.h | 12 +++ .../sign.c | 85 ++++++++++++++++++- .../sign.h | 3 + .../pqcrystals-dilithium_dilithium3_ref/api.h | 12 +++ .../sign.c | 56 +++++++++++- .../sign.h | 3 + .../api.h | 11 +++ .../sign.c | 85 ++++++++++++++++++- .../sign.h | 3 + .../pqcrystals-dilithium_dilithium5_ref/api.h | 12 +++ .../sign.c | 56 +++++++++++- .../sign.h | 3 + src/sig/dilithium/sig_dilithium.h | 3 + src/sig/dilithium/sig_dilithium_2.c | 30 +++++++ src/sig/dilithium/sig_dilithium_3.c | 30 +++++++ src/sig/dilithium/sig_dilithium_5.c | 29 +++++++ 31 files changed, 767 insertions(+), 18 deletions(-) diff --git a/src/sig/dilithium/oldpqclean_dilithium2_aarch64/api.h b/src/sig/dilithium/oldpqclean_dilithium2_aarch64/api.h index 084f20e57..b9700497e 100644 --- a/src/sig/dilithium/oldpqclean_dilithium2_aarch64/api.h +++ b/src/sig/dilithium/oldpqclean_dilithium2_aarch64/api.h @@ -21,6 +21,8 @@ int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_signature( uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.c b/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.c index 876001e10..537f5a5b1 100644 --- a/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.c +++ b/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.c @@ -97,14 +97,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -151,6 +157,51 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from exist private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to the input private key (points +* to a read-only array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; + polyvecl s1, s1hat; + polyveck s2, t0, t1; + polyvecl mat[K]; + + /* unpack privat key */ + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + /* Expand matrix */ + polyvec_matrix_expand(mat, rho); + + /* Matrix-vector multiplication */ + s1hat = s1; + polyvecl_ntt(&s1hat); + polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat); + polyveck_reduce(&t1); + polyveck_invntt_tomont(&t1); + + /* Add error vector s2 */ + polyveck_add(&t1, &t1, &s2); + + /* Extract t1 */ + polyveck_caddq(&t1); + polyveck_power2round(&t1, &t0, &t1); + + /* Pack public key */ + pack_pk(pk, rho, &t1); + + return 0; +} /************************************************* * Name: crypto_sign_signature diff --git a/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.h b/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.h index 2e5686ca9..23886457f 100644 --- a/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.h +++ b/src/sig/dilithium/oldpqclean_dilithium2_aarch64/sign.h @@ -24,6 +24,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(crypto_sign_signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/oldpqclean_dilithium3_aarch64/api.h b/src/sig/dilithium/oldpqclean_dilithium3_aarch64/api.h index 6a18eecb2..3752bc631 100644 --- a/src/sig/dilithium/oldpqclean_dilithium3_aarch64/api.h +++ b/src/sig/dilithium/oldpqclean_dilithium3_aarch64/api.h @@ -21,6 +21,8 @@ int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_signature( uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.c b/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.c index 876001e10..537f5a5b1 100644 --- a/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.c +++ b/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.c @@ -97,14 +97,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -151,6 +157,51 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from exist private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to the input private key (points +* to a read-only array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; + polyvecl s1, s1hat; + polyveck s2, t0, t1; + polyvecl mat[K]; + + /* unpack privat key */ + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + /* Expand matrix */ + polyvec_matrix_expand(mat, rho); + + /* Matrix-vector multiplication */ + s1hat = s1; + polyvecl_ntt(&s1hat); + polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat); + polyveck_reduce(&t1); + polyveck_invntt_tomont(&t1); + + /* Add error vector s2 */ + polyveck_add(&t1, &t1, &s2); + + /* Extract t1 */ + polyveck_caddq(&t1); + polyveck_power2round(&t1, &t0, &t1); + + /* Pack public key */ + pack_pk(pk, rho, &t1); + + return 0; +} /************************************************* * Name: crypto_sign_signature diff --git a/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.h b/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.h index 2e5686ca9..23886457f 100644 --- a/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.h +++ b/src/sig/dilithium/oldpqclean_dilithium3_aarch64/sign.h @@ -24,6 +24,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(crypto_sign_signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/oldpqclean_dilithium5_aarch64/api.h b/src/sig/dilithium/oldpqclean_dilithium5_aarch64/api.h index 668e332eb..69c1ccc48 100644 --- a/src/sig/dilithium/oldpqclean_dilithium5_aarch64/api.h +++ b/src/sig/dilithium/oldpqclean_dilithium5_aarch64/api.h @@ -22,6 +22,8 @@ int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_signature( uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.c b/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.c index 665e9367b..537f5a5b1 100644 --- a/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.c +++ b/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.c @@ -97,14 +97,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -151,6 +157,52 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from exist private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to the input private key (points +* to a read-only array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; + polyvecl s1, s1hat; + polyveck s2, t0, t1; + polyvecl mat[K]; + + /* unpack privat key */ + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + /* Expand matrix */ + polyvec_matrix_expand(mat, rho); + + /* Matrix-vector multiplication */ + s1hat = s1; + polyvecl_ntt(&s1hat); + polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat); + polyveck_reduce(&t1); + polyveck_invntt_tomont(&t1); + + /* Add error vector s2 */ + polyveck_add(&t1, &t1, &s2); + + /* Extract t1 */ + polyveck_caddq(&t1); + polyveck_power2round(&t1, &t0, &t1); + + /* Pack public key */ + pack_pk(pk, rho, &t1); + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.h b/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.h index 2e5686ca9..23886457f 100644 --- a/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.h +++ b/src/sig/dilithium/oldpqclean_dilithium5_aarch64/sign.h @@ -24,6 +24,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(crypto_sign_signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/api.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/api.h index 0b51d68ad..ffa492020 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/api.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/api.h @@ -16,6 +16,8 @@ int pqcrystals_dilithium2_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -40,6 +42,8 @@ int pqcrystals_dilithium2aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -68,6 +72,8 @@ int pqcrystals_dilithium3_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -92,6 +98,8 @@ int pqcrystals_dilithium3aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -120,6 +128,8 @@ int pqcrystals_dilithium5_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -144,6 +154,8 @@ int pqcrystals_dilithium5aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.c b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.c index e70154090..72306d29a 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.c +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.c @@ -176,14 +176,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -293,6 +299,81 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from existing private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to input private key (points +* to array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + unsigned int i; + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; +#ifdef DILITHIUM_USE_AES + uint64_t nonce; + aes256ctr_ctx aesctx; + polyvecl rowbuf[1]; +#else + polyvecl rowbuf[2]; +#endif + polyvecl s1, *row = rowbuf; + polyveck s2; + poly t1, t0; + + // Unpack private key + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + // Store rho in public key + memcpy(pk, rho, SEEDBYTES); + + // Transform s1 + polyvecl_ntt(&s1); + +#ifdef DILITHIUM_USE_AES + aes256ctr_init_u64(&aesctx, rho, 0); +#endif + + // Process each row + for(i = 0; i < K; i++) { + /* Expand matrix row */ +#ifdef DILITHIUM_USE_AES + for(unsigned int j = 0; j < L; j++) { + nonce = (i << 8) + j; + aes256ctr_init_iv_u64(&aesctx, nonce); + poly_uniform_preinit(&row->vec[j], &aesctx); + poly_nttunpack(&row->vec[j]); + } +#else + polyvec_matrix_expand_row(&row, rowbuf, rho, i); +#endif + + /* Compute inner-product */ + polyvecl_pointwise_acc_montgomery(&t1, row, &s1); + poly_invntt_tomont(&t1); + + /* Add error polynomial */ + poly_add(&t1, &t1, &s2.vec[i]); + + /* Round t and pack t1 */ + poly_caddq(&t1); + poly_power2round(&t1, &t0, &t1); + polyt1_pack(pk + SEEDBYTES + i*POLYT1_PACKEDBYTES, &t1); + } + +#ifdef DILITHIUM_USE_AES + aes256_ctx_release(&aesctx); +#endif + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.h index cd978b507..a89a709d3 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_avx2/sign.h @@ -16,6 +16,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/api.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/api.h index 44e02e55c..4616372a5 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/api.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/api.h @@ -16,6 +16,8 @@ int pqcrystals_dilithium2_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -40,6 +42,8 @@ int pqcrystals_dilithium2aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -68,6 +72,8 @@ int pqcrystals_dilithium3_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -92,6 +98,8 @@ int pqcrystals_dilithium3aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -120,6 +128,8 @@ int pqcrystals_dilithium5_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -144,6 +154,8 @@ int pqcrystals_dilithium5aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.c b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.c index 49a66937a..6ac94524c 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.c +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.c @@ -65,14 +65,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -119,6 +125,52 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from exist private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to the input private key (points +* to a read-only array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; + polyvecl s1, s1hat; + polyveck s2, t0, t1; + polyvecl mat[K]; + + /* unpack privat key */ + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + /* Expand matrix */ + polyvec_matrix_expand(mat, rho); + + /* Matrix-vector multiplication */ + s1hat = s1; + polyvecl_ntt(&s1hat); + polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat); + polyveck_reduce(&t1); + polyveck_invntt_tomont(&t1); + + /* Add error vector s2 */ + polyveck_add(&t1, &t1, &s2); + + /* Extract t1 */ + polyveck_caddq(&t1); + polyveck_power2round(&t1, &t0, &t1); + + /* Pack public key */ + pack_pk(pk, rho, &t1); + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.h index cd978b507..a89a709d3 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium2_ref/sign.h @@ -16,6 +16,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/api.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/api.h index 0b51d68ad..ffa492020 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/api.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/api.h @@ -16,6 +16,8 @@ int pqcrystals_dilithium2_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -40,6 +42,8 @@ int pqcrystals_dilithium2aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -68,6 +72,8 @@ int pqcrystals_dilithium3_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -92,6 +98,8 @@ int pqcrystals_dilithium3aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -120,6 +128,8 @@ int pqcrystals_dilithium5_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -144,6 +154,8 @@ int pqcrystals_dilithium5aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.c b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.c index e70154090..72306d29a 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.c +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.c @@ -176,14 +176,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -293,6 +299,81 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from existing private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to input private key (points +* to array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + unsigned int i; + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; +#ifdef DILITHIUM_USE_AES + uint64_t nonce; + aes256ctr_ctx aesctx; + polyvecl rowbuf[1]; +#else + polyvecl rowbuf[2]; +#endif + polyvecl s1, *row = rowbuf; + polyveck s2; + poly t1, t0; + + // Unpack private key + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + // Store rho in public key + memcpy(pk, rho, SEEDBYTES); + + // Transform s1 + polyvecl_ntt(&s1); + +#ifdef DILITHIUM_USE_AES + aes256ctr_init_u64(&aesctx, rho, 0); +#endif + + // Process each row + for(i = 0; i < K; i++) { + /* Expand matrix row */ +#ifdef DILITHIUM_USE_AES + for(unsigned int j = 0; j < L; j++) { + nonce = (i << 8) + j; + aes256ctr_init_iv_u64(&aesctx, nonce); + poly_uniform_preinit(&row->vec[j], &aesctx); + poly_nttunpack(&row->vec[j]); + } +#else + polyvec_matrix_expand_row(&row, rowbuf, rho, i); +#endif + + /* Compute inner-product */ + polyvecl_pointwise_acc_montgomery(&t1, row, &s1); + poly_invntt_tomont(&t1); + + /* Add error polynomial */ + poly_add(&t1, &t1, &s2.vec[i]); + + /* Round t and pack t1 */ + poly_caddq(&t1); + poly_power2round(&t1, &t0, &t1); + polyt1_pack(pk + SEEDBYTES + i*POLYT1_PACKEDBYTES, &t1); + } + +#ifdef DILITHIUM_USE_AES + aes256_ctx_release(&aesctx); +#endif + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.h index cd978b507..a89a709d3 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_avx2/sign.h @@ -16,6 +16,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/api.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/api.h index 44e02e55c..4616372a5 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/api.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/api.h @@ -16,6 +16,8 @@ int pqcrystals_dilithium2_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -40,6 +42,8 @@ int pqcrystals_dilithium2aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -68,6 +72,8 @@ int pqcrystals_dilithium3_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -92,6 +98,8 @@ int pqcrystals_dilithium3aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -120,6 +128,8 @@ int pqcrystals_dilithium5_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -144,6 +154,8 @@ int pqcrystals_dilithium5aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.c b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.c index 49a66937a..6ac94524c 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.c +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.c @@ -65,14 +65,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -119,6 +125,52 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from exist private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to the input private key (points +* to a read-only array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; + polyvecl s1, s1hat; + polyveck s2, t0, t1; + polyvecl mat[K]; + + /* unpack privat key */ + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + /* Expand matrix */ + polyvec_matrix_expand(mat, rho); + + /* Matrix-vector multiplication */ + s1hat = s1; + polyvecl_ntt(&s1hat); + polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat); + polyveck_reduce(&t1); + polyveck_invntt_tomont(&t1); + + /* Add error vector s2 */ + polyveck_add(&t1, &t1, &s2); + + /* Extract t1 */ + polyveck_caddq(&t1); + polyveck_power2round(&t1, &t0, &t1); + + /* Pack public key */ + pack_pk(pk, rho, &t1); + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.h index cd978b507..a89a709d3 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium3_ref/sign.h @@ -16,6 +16,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/api.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/api.h index c8df40133..ffa492020 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/api.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/api.h @@ -16,6 +16,8 @@ int pqcrystals_dilithium2_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -40,6 +42,7 @@ int pqcrystals_dilithium2aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); int pqcrystals_dilithium2aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, @@ -69,6 +72,8 @@ int pqcrystals_dilithium3_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -93,6 +98,8 @@ int pqcrystals_dilithium3aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -121,6 +128,8 @@ int pqcrystals_dilithium5_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -145,6 +154,8 @@ int pqcrystals_dilithium5aes_avx2_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5aes_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5aes_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5aes_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.c b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.c index e70154090..72306d29a 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.c +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.c @@ -176,14 +176,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -293,6 +299,81 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from existing private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to input private key (points +* to array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + unsigned int i; + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; +#ifdef DILITHIUM_USE_AES + uint64_t nonce; + aes256ctr_ctx aesctx; + polyvecl rowbuf[1]; +#else + polyvecl rowbuf[2]; +#endif + polyvecl s1, *row = rowbuf; + polyveck s2; + poly t1, t0; + + // Unpack private key + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + // Store rho in public key + memcpy(pk, rho, SEEDBYTES); + + // Transform s1 + polyvecl_ntt(&s1); + +#ifdef DILITHIUM_USE_AES + aes256ctr_init_u64(&aesctx, rho, 0); +#endif + + // Process each row + for(i = 0; i < K; i++) { + /* Expand matrix row */ +#ifdef DILITHIUM_USE_AES + for(unsigned int j = 0; j < L; j++) { + nonce = (i << 8) + j; + aes256ctr_init_iv_u64(&aesctx, nonce); + poly_uniform_preinit(&row->vec[j], &aesctx); + poly_nttunpack(&row->vec[j]); + } +#else + polyvec_matrix_expand_row(&row, rowbuf, rho, i); +#endif + + /* Compute inner-product */ + polyvecl_pointwise_acc_montgomery(&t1, row, &s1); + poly_invntt_tomont(&t1); + + /* Add error polynomial */ + poly_add(&t1, &t1, &s2.vec[i]); + + /* Round t and pack t1 */ + poly_caddq(&t1); + poly_power2round(&t1, &t0, &t1); + polyt1_pack(pk + SEEDBYTES + i*POLYT1_PACKEDBYTES, &t1); + } + +#ifdef DILITHIUM_USE_AES + aes256_ctx_release(&aesctx); +#endif + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.h index cd978b507..a89a709d3 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_avx2/sign.h @@ -16,6 +16,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/api.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/api.h index 44e02e55c..4616372a5 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/api.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/api.h @@ -16,6 +16,8 @@ int pqcrystals_dilithium2_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -40,6 +42,8 @@ int pqcrystals_dilithium2aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium2aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium2aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium2aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -68,6 +72,8 @@ int pqcrystals_dilithium3_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -92,6 +98,8 @@ int pqcrystals_dilithium3aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium3aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium3aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium3aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -120,6 +128,8 @@ int pqcrystals_dilithium5_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); @@ -144,6 +154,8 @@ int pqcrystals_dilithium5aes_ref_keypair(uint8_t *pk, uint8_t *sk); int pqcrystals_dilithium5aes_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +int pqcrystals_dilithium5aes_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + int pqcrystals_dilithium5aes_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.c b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.c index 49a66937a..6ac94524c 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.c +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.c @@ -65,14 +65,20 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_keypair from fixed seed. +* Name: crypto_sign_keypair_from_fseed * -* Description: Generates public and private key. +* Description: Generates public and private key from fixed seed. * * Arguments: - uint8_t *pk: pointer to output public key (allocated * array of CRYPTO_PUBLICKEYBYTES bytes) * - uint8_t *sk: pointer to output private key (allocated * array of CRYPTO_SECRETKEYBYTES bytes) +* - const uint8_t *seed: Pointer to the input fixed seed. +* Must point to an array of SEEDBYTES bytes. +* The seed provides deterministic randomness +* for key generation and must be unique and +* securely generated for each keypair to +* ensure security. * * Returns 0 (success) **************************************************/ @@ -119,6 +125,52 @@ int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed return 0; } +/************************************************* +* Name: crypto_sign_pubkey_from_privkey +* +* Description: Generates public key from exist private key. +* +* Arguments: - uint8_t *pk: pointer to output public key (allocated +* array of CRYPTO_PUBLICKEYBYTES bytes) +* - const uint8_t *sk: pointer to the input private key (points +* to a read-only array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk) { + uint8_t rho[SEEDBYTES]; + uint8_t tr[SEEDBYTES]; + uint8_t key[SEEDBYTES]; + polyvecl s1, s1hat; + polyveck s2, t0, t1; + polyvecl mat[K]; + + /* unpack privat key */ + unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); + + /* Expand matrix */ + polyvec_matrix_expand(mat, rho); + + /* Matrix-vector multiplication */ + s1hat = s1; + polyvecl_ntt(&s1hat); + polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat); + polyveck_reduce(&t1); + polyveck_invntt_tomont(&t1); + + /* Add error vector s2 */ + polyveck_add(&t1, &t1, &s2); + + /* Extract t1 */ + polyveck_caddq(&t1); + polyveck_power2round(&t1, &t0, &t1); + + /* Pack public key */ + pack_pk(pk, rho, &t1); + + return 0; +} + /************************************************* * Name: crypto_sign_signature * diff --git a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.h b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.h index cd978b507..a89a709d3 100644 --- a/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.h +++ b/src/sig/dilithium/pqcrystals-dilithium_dilithium5_ref/sign.h @@ -16,6 +16,9 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); #define crypto_sign_keypair_from_fseed DILITHIUM_NAMESPACE(keypair_from_fseed) int crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +#define crypto_sign_pubkey_from_privkey DILITHIUM_NAMESPACE(pubkey_from_privkey) +int crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, diff --git a/src/sig/dilithium/sig_dilithium.h b/src/sig/dilithium/sig_dilithium.h index 3f035e661..4776881e1 100644 --- a/src/sig/dilithium/sig_dilithium.h +++ b/src/sig/dilithium/sig_dilithium.h @@ -13,6 +13,7 @@ OQS_SIG *OQS_SIG_dilithium_2_new(void); OQS_API OQS_STATUS OQS_SIG_dilithium_2_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_2_keypair_from_fseed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed); +OQS_API OQS_STATUS OQS_SIG_dilithium_2_pubkey_from_privkey(uint8_t *public_key, const uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); OQS_API OQS_STATUS OQS_SIG_dilithium_2_sign_with_ctx_str(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *ctx, size_t ctxlen, const uint8_t *secret_key); @@ -27,6 +28,7 @@ OQS_API OQS_STATUS OQS_SIG_dilithium_2_verify_with_ctx_str(const uint8_t *messag OQS_SIG *OQS_SIG_dilithium_3_new(void); OQS_API OQS_STATUS OQS_SIG_dilithium_3_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_3_keypair_from_fseed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed); +OQS_API OQS_STATUS OQS_SIG_dilithium_3_pubkey_from_privkey(uint8_t *public_key, const uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); OQS_API OQS_STATUS OQS_SIG_dilithium_3_sign_with_ctx_str(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *ctx, size_t ctxlen, const uint8_t *secret_key); @@ -41,6 +43,7 @@ OQS_API OQS_STATUS OQS_SIG_dilithium_3_verify_with_ctx_str(const uint8_t *messag OQS_SIG *OQS_SIG_dilithium_5_new(void); OQS_API OQS_STATUS OQS_SIG_dilithium_5_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_5_keypair_from_fseed(uint8_t *public_key, uint8_t *secret_key, const uint8_t *seed); +OQS_API OQS_STATUS OQS_SIG_dilithium_5_pubkey_from_privkey(uint8_t *public_key, const uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_5_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_dilithium_5_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); OQS_API OQS_STATUS OQS_SIG_dilithium_5_sign_with_ctx_str(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *ctx, size_t ctxlen, const uint8_t *secret_key); diff --git a/src/sig/dilithium/sig_dilithium_2.c b/src/sig/dilithium/sig_dilithium_2.c index 1484a3a7e..9ec7cdf91 100644 --- a/src/sig/dilithium/sig_dilithium_2.c +++ b/src/sig/dilithium/sig_dilithium_2.c @@ -24,6 +24,7 @@ OQS_SIG *OQS_SIG_dilithium_2_new(void) { sig->keypair = OQS_SIG_dilithium_2_keypair; sig->keypair_from_fseed = OQS_SIG_dilithium_2_keypair_from_fseed; + sig->pubkey_from_privkey = OQS_SIG_dilithium_2_pubkey_from_privkey; sig->sign = OQS_SIG_dilithium_2_sign; sig->verify = OQS_SIG_dilithium_2_verify; sig->sign_with_ctx_str = OQS_SIG_dilithium_2_sign_with_ctx_str; @@ -34,12 +35,14 @@ OQS_SIG *OQS_SIG_dilithium_2_new(void) { extern int pqcrystals_dilithium2_ref_keypair(uint8_t *pk, uint8_t *sk); extern int pqcrystals_dilithium2_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int pqcrystals_dilithium2_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int pqcrystals_dilithium2_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int pqcrystals_dilithium2_ref_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #if defined(OQS_ENABLE_SIG_dilithium_2_avx2) extern int pqcrystals_dilithium2_avx2_keypair(uint8_t *pk, uint8_t *sk); extern int pqcrystals_dilithium2_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int pqcrystals_dilithium2_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int pqcrystals_dilithium2_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int pqcrystals_dilithium2_avx2_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #endif @@ -47,6 +50,7 @@ extern int pqcrystals_dilithium2_avx2_verify(const uint8_t *sig, size_t siglen, #if defined(OQS_ENABLE_SIG_dilithium_2_aarch64) extern int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); extern int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #endif @@ -103,6 +107,32 @@ OQS_API OQS_STATUS OQS_SIG_dilithium_2_keypair_from_fseed(uint8_t *public_key, u #endif } +OQS_API OQS_STATUS OQS_SIG_dilithium_2_pubkey_from_privkey(uint8_t *public_key, const uint8_t *secret_key) { +#if defined(OQS_ENABLE_SIG_dilithium_2_avx2) +#if defined(OQS_DIST_BUILD) + if (OQS_CPU_has_extension(OQS_CPU_EXT_AVX2) && OQS_CPU_has_extension(OQS_CPU_EXT_POPCNT)) { +#endif /* OQS_DIST_BUILD */ + return (OQS_STATUS) pqcrystals_dilithium2_avx2_pubkey_from_privkey(public_key, secret_key); +#if defined(OQS_DIST_BUILD) + } else { + return (OQS_STATUS) pqcrystals_dilithium2_ref_pubkey_from_privkey(public_key, secret_key); + } +#endif /* OQS_DIST_BUILD */ +#elif defined(OQS_ENABLE_SIG_dilithium_2_aarch64) +#if defined(OQS_DIST_BUILD) + if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_NEON)) { +#endif /* OQS_DIST_BUILD */ + return (OQS_STATUS) PQCLEAN_DILITHIUM2_AARCH64_crypto_sign_pubkey_from_privkey(public_key, secret_key); +#if defined(OQS_DIST_BUILD) + } else { + return (OQS_STATUS) pqcrystals_dilithium2_ref_pubkey_from_privkey(public_key, secret_key); + } +#endif /* OQS_DIST_BUILD */ +#else + return (OQS_STATUS) pqcrystals_dilithium2_ref_pubkey_from_privkey(public_key, secret_key); +#endif +} + OQS_API OQS_STATUS OQS_SIG_dilithium_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key) { #if defined(OQS_ENABLE_SIG_dilithium_2_avx2) #if defined(OQS_DIST_BUILD) diff --git a/src/sig/dilithium/sig_dilithium_3.c b/src/sig/dilithium/sig_dilithium_3.c index d90992a6f..c919f5c53 100644 --- a/src/sig/dilithium/sig_dilithium_3.c +++ b/src/sig/dilithium/sig_dilithium_3.c @@ -24,6 +24,7 @@ OQS_SIG *OQS_SIG_dilithium_3_new(void) { sig->keypair = OQS_SIG_dilithium_3_keypair; sig->keypair_from_fseed = OQS_SIG_dilithium_3_keypair_from_fseed; + sig->pubkey_from_privkey = OQS_SIG_dilithium_3_pubkey_from_privkey; sig->sign = OQS_SIG_dilithium_3_sign; sig->verify = OQS_SIG_dilithium_3_verify; sig->sign_with_ctx_str = OQS_SIG_dilithium_3_sign_with_ctx_str; @@ -34,12 +35,14 @@ OQS_SIG *OQS_SIG_dilithium_3_new(void) { extern int pqcrystals_dilithium3_ref_keypair(uint8_t *pk, uint8_t *sk); extern int pqcrystals_dilithium3_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int pqcrystals_dilithium3_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int pqcrystals_dilithium3_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int pqcrystals_dilithium3_ref_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #if defined(OQS_ENABLE_SIG_dilithium_3_avx2) extern int pqcrystals_dilithium3_avx2_keypair(uint8_t *pk, uint8_t *sk); extern int pqcrystals_dilithium3_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int pqcrystals_dilithium3_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int pqcrystals_dilithium3_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int pqcrystals_dilithium3_avx2_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #endif @@ -47,6 +50,7 @@ extern int pqcrystals_dilithium3_avx2_verify(const uint8_t *sig, size_t siglen, #if defined(OQS_ENABLE_SIG_dilithium_3_aarch64) extern int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); extern int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #endif @@ -103,6 +107,32 @@ OQS_API OQS_STATUS OQS_SIG_dilithium_3_keypair_from_fseed(uint8_t *public_key, u #endif } +OQS_API OQS_STATUS OQS_SIG_dilithium_3_pubkey_from_privkey(uint8_t *public_key, const uint8_t *secret_key) { +#if defined(OQS_ENABLE_SIG_dilithium_3_avx2) +#if defined(OQS_DIST_BUILD) + if (OQS_CPU_has_extension(OQS_CPU_EXT_AVX2) && OQS_CPU_has_extension(OQS_CPU_EXT_POPCNT)) { +#endif /* OQS_DIST_BUILD */ + return (OQS_STATUS) pqcrystals_dilithium3_avx2_pubkey_from_privkey(public_key, secret_key); +#if defined(OQS_DIST_BUILD) + } else { + return (OQS_STATUS) pqcrystals_dilithium3_ref_pubkey_from_privkey(public_key, secret_key); + } +#endif /* OQS_DIST_BUILD */ +#elif defined(OQS_ENABLE_SIG_dilithium_3_aarch64) +#if defined(OQS_DIST_BUILD) + if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_NEON)) { +#endif /* OQS_DIST_BUILD */ + return (OQS_STATUS) PQCLEAN_DILITHIUM3_AARCH64_crypto_sign_pubkey_from_privkey(public_key, secret_key); +#if defined(OQS_DIST_BUILD) + } else { + return (OQS_STATUS) pqcrystals_dilithium3_ref_pubkey_from_privkey(public_key, secret_key); + } +#endif /* OQS_DIST_BUILD */ +#else + return (OQS_STATUS) pqcrystals_dilithium3_ref_pubkey_from_privkey(public_key, secret_key); +#endif +} + OQS_API OQS_STATUS OQS_SIG_dilithium_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key) { #if defined(OQS_ENABLE_SIG_dilithium_3_avx2) #if defined(OQS_DIST_BUILD) diff --git a/src/sig/dilithium/sig_dilithium_5.c b/src/sig/dilithium/sig_dilithium_5.c index 7b676408d..f1d3c9238 100644 --- a/src/sig/dilithium/sig_dilithium_5.c +++ b/src/sig/dilithium/sig_dilithium_5.c @@ -24,6 +24,7 @@ OQS_SIG *OQS_SIG_dilithium_5_new(void) { sig->keypair = OQS_SIG_dilithium_5_keypair; sig->keypair_from_fseed = OQS_SIG_dilithium_5_keypair_from_fseed; + sig->pubkey_from_privkey = OQS_SIG_dilithium_5_pubkey_from_privkey; sig->sign = OQS_SIG_dilithium_5_sign; sig->verify = OQS_SIG_dilithium_5_verify; sig->sign_with_ctx_str = OQS_SIG_dilithium_5_sign_with_ctx_str; @@ -34,12 +35,14 @@ OQS_SIG *OQS_SIG_dilithium_5_new(void) { extern int pqcrystals_dilithium5_ref_keypair(uint8_t *pk, uint8_t *sk); extern int pqcrystals_dilithium5_ref_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int pqcrystals_dilithium5_ref_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int pqcrystals_dilithium5_ref_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int pqcrystals_dilithium5_ref_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #if defined(OQS_ENABLE_SIG_dilithium_5_avx2) extern int pqcrystals_dilithium5_avx2_keypair(uint8_t *pk, uint8_t *sk); extern int pqcrystals_dilithium5_avx2_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int pqcrystals_dilithium5_avx2_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int pqcrystals_dilithium5_avx2_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int pqcrystals_dilithium5_avx2_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #endif @@ -47,6 +50,7 @@ extern int pqcrystals_dilithium5_avx2_verify(const uint8_t *sig, size_t siglen, #if defined(OQS_ENABLE_SIG_dilithium_5_aarch64) extern int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); extern int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_keypair_from_fseed(uint8_t *pk, uint8_t *sk, const uint8_t *seed); +extern int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_pubkey_from_privkey(uint8_t *pk, const uint8_t *sk); extern int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); extern int PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); #endif @@ -103,6 +107,31 @@ OQS_API OQS_STATUS OQS_SIG_dilithium_5_keypair_from_fseed(uint8_t *public_key, u #endif } +OQS_API OQS_STATUS OQS_SIG_dilithium_5_pubkey_from_privkey(uint8_t *public_key, const uint8_t *secret_key) { +#if defined(OQS_ENABLE_SIG_dilithium_5_avx2) +#if defined(OQS_DIST_BUILD) + if (OQS_CPU_has_extension(OQS_CPU_EXT_AVX2) && OQS_CPU_has_extension(OQS_CPU_EXT_POPCNT)) { +#endif /* OQS_DIST_BUILD */ + return (OQS_STATUS) pqcrystals_dilithium5_avx2_pubkey_from_privkey(public_key, secret_key); +#if defined(OQS_DIST_BUILD) + } else { + return (OQS_STATUS) pqcrystals_dilithium5_ref_pubkey_from_privkey(public_key, secret_key); + } +#endif /* OQS_DIST_BUILD */ +#elif defined(OQS_ENABLE_SIG_dilithium_5_aarch64) +#if defined(OQS_DIST_BUILD) + if (OQS_CPU_has_extension(OQS_CPU_EXT_ARM_NEON)) { +#endif /* OQS_DIST_BUILD */ + return (OQS_STATUS) PQCLEAN_DILITHIUM5_AARCH64_crypto_sign_pubkey_from_privkey(public_key, secret_key); +#if defined(OQS_DIST_BUILD) + } else { + return (OQS_STATUS) pqcrystals_dilithium5_ref_pubkey_from_privkey(public_key, secret_key); + } +#endif /* OQS_DIST_BUILD */ +#else + return (OQS_STATUS) pqcrystals_dilithium5_ref_pubkey_from_privkey(public_key, secret_key); +#endif +} OQS_API OQS_STATUS OQS_SIG_dilithium_5_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key) { #if defined(OQS_ENABLE_SIG_dilithium_5_avx2)