Skip to content

Commit 9fbb4bb

Browse files
committed
add API generating Dilithium pubkey from privkey
1 parent 27df554 commit 9fbb4bb

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
@@ -7980,6 +7980,145 @@ static int dilithium_make_key_from_seed(dilithium_key* key, const byte* seed)
79807980
#endif
79817981
}
79827982

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

1009810237
return ret;
1009910238
}
10239+
10240+
int wc_dilithium_pub_from_priv(dilithium_key* key)
10241+
{
10242+
int ret = 0;
10243+
10244+
if (key == NULL) {
10245+
ret = BAD_FUNC_ARG;
10246+
}
10247+
10248+
if (ret == 0) {
10249+
#ifdef WOLFSSL_WC_DILITHIUM
10250+
ret = dilithium_pub_from_priv(key);
10251+
#elif defined(HAVE_LIBOQS)
10252+
ret = NOT_COMPILED_IN;
10253+
#endif
10254+
}
10255+
10256+
return ret;
10257+
}
1010010258
#endif
1010110259

1010210260
#ifndef WOLFSSL_DILITHIUM_NO_SIGN

wolfssl/wolfcrypt/dilithium.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,8 @@ WOLFSSL_API
806806
int wc_dilithium_make_key(dilithium_key* key, WC_RNG* rng);
807807
WOLFSSL_API
808808
int wc_dilithium_make_key_from_seed(dilithium_key* key, const byte* seed);
809+
WOLFSSL_API
810+
int wc_dilithium_pub_from_priv(dilithium_key* key);
809811

810812
WOLFSSL_API
811813
int wc_dilithium_sign_msg(const byte* msg, word32 msgLen, byte* sig,

0 commit comments

Comments
 (0)