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