Skip to content

Commit 2830f35

Browse files
committed
add API generating Dilithium pubkey from privkey
1 parent 9e5d03b commit 2830f35

2 files changed

Lines changed: 160 additions & 0 deletions

File tree

wolfcrypt/src/dilithium.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7981,6 +7981,145 @@ static int dilithium_make_key_from_seed(dilithium_key* key, const byte* seed)
79817981
#endif
79827982
}
79837983

7984+
static int dilithium_pub_from_priv(dilithium_key* key)
7985+
{
7986+
int ret = 0;
7987+
const wc_dilithium_params* params = key->params;
7988+
const byte* pub_seed = key->k;
7989+
const byte* s1p = pub_seed + DILITHIUM_PUB_SEED_SZ + DILITHIUM_K_SZ + DILITHIUM_TR_SZ;
7990+
const byte* s2p = s1p + params->s1EncSz;
7991+
sword32* a = NULL;
7992+
sword32* s1 = NULL;
7993+
sword32* s2 = NULL;
7994+
sword32* t = NULL;
7995+
byte* t0 = NULL;
7996+
byte* t1 = key->p + DILITHIUM_PUB_SEED_SZ;
7997+
7998+
/* Allocate and create cached values. */
7999+
#ifndef WC_DILITHIUM_CACHE_MATRIX_A
8000+
a = (sword32*)XMALLOC(params->aSz, key->heap,
8001+
DYNAMIC_TYPE_DILITHIUM);
8002+
if (a == NULL) {
8003+
ret = MEMORY_E;
8004+
}
8005+
else {
8006+
XMEMSET(a, 0, params->aSz);
8007+
}
8008+
8009+
if (ret == 0) {
8010+
ret = dilithium_expand_a(&key->shake, pub_seed, params->k, params->l,
8011+
a, key->heap);
8012+
}
8013+
#else
8014+
if (ret == 0) {
8015+
if (key->a == NULL) {
8016+
ret = BAD_STATE_E;
8017+
}
8018+
else {
8019+
a = key->a;
8020+
}
8021+
}
8022+
#endif
8023+
#ifndef WC_DILITHIUM_CACHE_PRIV_VECTORS
8024+
if (ret == 0) {
8025+
s1 = (sword32*)XMALLOC(params->s1Sz + params->s2Sz, key->heap,
8026+
DYNAMIC_TYPE_DILITHIUM);
8027+
if (s1 == NULL) {
8028+
ret = MEMORY_E;
8029+
}
8030+
else {
8031+
s2 = s1 + params->s1Sz / sizeof(*s1);
8032+
8033+
dilithium_vec_decode_eta_bits(s1p, params->eta, s1, params->l);
8034+
dilithium_vec_decode_eta_bits(s2p, params->eta, s2, params->k);
8035+
8036+
dilithium_vec_ntt_small(s1, params->l);
8037+
}
8038+
}
8039+
#else
8040+
if (ret == 0) {
8041+
if (key->s1 == NULL || key->s2 == NULL) {
8042+
ret = BAD_STATE_E;
8043+
}
8044+
else {
8045+
s1 = key->s1;
8046+
s2 = key->s2;
8047+
}
8048+
}
8049+
#endif
8050+
8051+
if (ret == 0) {
8052+
t0 = (byte*)XMALLOC(params->s2Sz, key->heap, DYNAMIC_TYPE_DILITHIUM);
8053+
if (t0 == NULL) {
8054+
ret = MEMORY_E;
8055+
}
8056+
}
8057+
8058+
if (ret == 0) {
8059+
t = (sword32*)XMALLOC(params->s2Sz, key->heap, DYNAMIC_TYPE_DILITHIUM);
8060+
if (t == NULL) {
8061+
ret = MEMORY_E;
8062+
}
8063+
}
8064+
8065+
/* cal t and get t0, t1 */
8066+
if (ret == 0) {
8067+
/* Copy public seed into public key. */
8068+
XMEMCPY(key->p, pub_seed, DILITHIUM_PUB_SEED_SZ);
8069+
8070+
/* t <- NTT-1(A_circum o NTT(s1)) + s2 */
8071+
dilithium_matrix_mul(t, a, s1, params->k, params->l);
8072+
dilithium_vec_invntt_full(t, params->k);
8073+
dilithium_vec_add(t, s2, params->k);
8074+
/* NTT s2 */
8075+
dilithium_vec_ntt_small(s2, params->k);
8076+
8077+
/* Make positive for decomposing. */
8078+
dilithium_vec_make_pos(t, params->k);
8079+
/* Decompose t in t0 and t1 and encode into public and private key. */
8080+
dilithium_vec_encode_t0_t1(t, params->k, t0, t1);
8081+
}
8082+
8083+
#ifndef WC_DILITHIUM_CACHE_MATRIX_A
8084+
XMEMSET(a, 0, params->aSz);
8085+
XFREE(a, key->heap, DYNAMIC_TYPE_DILITHIUM);
8086+
#endif
8087+
#ifndef WC_DILITHIUM_CACHE_PRIV_VECTORS
8088+
XMEMSET(s1, 0, params->s1Sz + params->s2Sz);
8089+
XFREE(s1, key->heap, DYNAMIC_TYPE_DILITHIUM);
8090+
#endif
8091+
XMEMSET(t0, 0, params->s2Sz);
8092+
XMEMSET(t, 0, params->s2Sz);
8093+
XFREE(t0, key->heap, DYNAMIC_TYPE_DILITHIUM);
8094+
XFREE(t, key->heap, DYNAMIC_TYPE_DILITHIUM);
8095+
8096+
if (ret == 0) {
8097+
#ifdef WC_DILITHIUM_CACHE_PUB_VECTORS
8098+
#ifndef WC_DILITHIUM_FIXED_ARRAY
8099+
/* Allocate t1 if required. */
8100+
if (key->t1 == NULL) {
8101+
key->t1 = (sword32*)XMALLOC(params->s2Sz, key->heap,
8102+
DYNAMIC_TYPE_DILITHIUM);
8103+
if (key->t1 == NULL) {
8104+
ret = MEMORY_E;
8105+
}
8106+
else {
8107+
XMEMSET(key->t1, 0, key->params->s2Sz);
8108+
}
8109+
}
8110+
#endif
8111+
}
8112+
if (ret == 0) {
8113+
/* Compute t1 from public key data. */
8114+
dilithium_make_pub_vec(key, key->t1);
8115+
#endif
8116+
/* Public key is set. */
8117+
key->pubKeySet = 1;
8118+
}
8119+
8120+
return ret;
8121+
}
8122+
79848123
/* Make a key from a random seed.
79858124
*
79868125
* FIPS 204. 5.1: Algorithm 1 ML-DSA.KeyGen()
@@ -10105,6 +10244,25 @@ int wc_dilithium_make_key_from_seed(dilithium_key* key, const byte* seed)
1010510244

1010610245
return ret;
1010710246
}
10247+
10248+
int wc_dilithium_pub_from_priv(dilithium_key* key)
10249+
{
10250+
int ret = 0;
10251+
10252+
if (key == NULL) {
10253+
ret = BAD_FUNC_ARG;
10254+
}
10255+
10256+
if (ret == 0) {
10257+
#ifdef WOLFSSL_WC_DILITHIUM
10258+
ret = dilithium_pub_from_priv(key);
10259+
#elif defined(HAVE_LIBOQS)
10260+
ret = NOT_COMPILED_IN;
10261+
#endif
10262+
}
10263+
10264+
return ret;
10265+
}
1010810266
#endif
1010910267

1011010268
#ifndef WOLFSSL_DILITHIUM_NO_SIGN

wolfssl/wolfcrypt/dilithium.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,8 @@ WOLFSSL_API
810810
int wc_dilithium_make_key(dilithium_key* key, WC_RNG* rng);
811811
WOLFSSL_API
812812
int wc_dilithium_make_key_from_seed(dilithium_key* key, const byte* seed);
813+
WOLFSSL_API
814+
int wc_dilithium_pub_from_priv(dilithium_key* key);
813815

814816
WOLFSSL_API
815817
int wc_dilithium_sign_msg(const byte* msg, word32 msgLen, byte* sig,

0 commit comments

Comments
 (0)