@@ -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
0 commit comments