Skip to content

Commit 80025ea

Browse files
committed
add API generating Dilithium pubkey from privkey
1 parent 0792c67 commit 80025ea

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
@@ -7998,6 +7998,145 @@ static int dilithium_make_key_from_seed(dilithium_key* key, const byte* seed)
79987998
#endif
79997999
}
80008000

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

1016210301
return ret;
1016310302
}
10303+
10304+
int wc_dilithium_pub_from_priv(dilithium_key* key)
10305+
{
10306+
int ret = 0;
10307+
10308+
if (key == NULL) {
10309+
ret = BAD_FUNC_ARG;
10310+
}
10311+
10312+
if (ret == 0) {
10313+
#ifdef WOLFSSL_WC_DILITHIUM
10314+
ret = dilithium_pub_from_priv(key);
10315+
#elif defined(HAVE_LIBOQS)
10316+
ret = NOT_COMPILED_IN;
10317+
#endif
10318+
}
10319+
10320+
return ret;
10321+
}
1016410322
#endif
1016510323

1016610324
#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)