/src/openssl/crypto/ml_dsa/ml_dsa_local.h
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /*  | 
2  |  |  * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.  | 
3  |  |  *  | 
4  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use  | 
5  |  |  * this file except in compliance with the License.  You can obtain a copy  | 
6  |  |  * in the file LICENSE in the source distribution or at  | 
7  |  |  * https://www.openssl.org/source/license.html  | 
8  |  |  */  | 
9  |  |  | 
10  |  | #ifndef OSSL_CRYPTO_ML_DSA_LOCAL_H  | 
11  |  | # define OSSL_CRYPTO_ML_DSA_LOCAL_H  | 
12  |  |  | 
13  |  | # include "crypto/ml_dsa.h"  | 
14  |  | # include "internal/constant_time.h"  | 
15  |  | # include "internal/packet.h"  | 
16  |  |  | 
17  |  | /* The following constants are shared by ML-DSA-44, ML-DSA-65 & ML-DSA-87 */  | 
18  | 0  | # define ML_DSA_Q 8380417   /* The modulus is 23 bits (2^23 - 2^13 + 1) */  | 
19  | 0  | # define ML_DSA_Q_MINUS1_DIV2 ((ML_DSA_Q - 1) / 2)  | 
20  |  |  | 
21  |  | # define ML_DSA_Q_BITS 23  | 
22  |  | # define ML_DSA_Q_INV 58728449  /* q^-1 satisfies: q^-1 * q = 1 mod 2^32 */  | 
23  | 0  | # define ML_DSA_Q_NEG_INV 4236238847 /* Inverse of -q modulo 2^32 */  | 
24  |  | # define ML_DSA_DEGREE_INV_MONTGOMERY 41978 /* Inverse of 256 mod q, in Montgomery form. */  | 
25  |  |  | 
26  | 0  | # define ML_DSA_D_BITS 13   /* The number of bits dropped from the public vector t */  | 
27  |  | # define ML_DSA_NUM_POLY_COEFFICIENTS 256  /* The number of coefficients in the polynomials */  | 
28  | 0  | # define ML_DSA_RHO_BYTES 32   /* p = Public Random Seed */  | 
29  | 0  | # define ML_DSA_PRIV_SEED_BYTES 64 /* p' = Private random seed */  | 
30  |  | # define ML_DSA_K_BYTES 32 /* K = Private random seed for signing */  | 
31  |  | # define ML_DSA_TR_BYTES 64 /* Size of the Hash of the public key used for signing */  | 
32  | 0  | # define ML_DSA_RHO_PRIME_BYTES 64 /* private random seed size */  | 
33  |  |  | 
34  |  | /*  | 
35  |  |  * There is special case code related to encoding/decoding that tests the  | 
36  |  |  * for the following values.  | 
37  |  |  */  | 
38  |  | /*  | 
39  |  |  * The possible value for eta - If a new value is added, then all code  | 
40  |  |  * that accesses ML_DSA_ETA_4 would need to be modified.  | 
41  |  |  */  | 
42  | 0  | # define ML_DSA_ETA_4 4  | 
43  |  | # define ML_DSA_ETA_2 2  | 
44  |  | /*  | 
45  |  |  * The possible values of gamma1 - If a new value is added, then all code  | 
46  |  |  * that accesses ML_DSA_GAMMA1_TWO_POWER_19 would need to be modified.  | 
47  |  |  */  | 
48  | 0  | # define ML_DSA_GAMMA1_TWO_POWER_19 (1 << 19)  | 
49  |  | # define ML_DSA_GAMMA1_TWO_POWER_17 (1 << 17)  | 
50  |  | /*  | 
51  |  |  * The possible values for gamma2 - If a new value is added, then all code  | 
52  |  |  * that accesses ML_DSA_GAMMA2_Q_MINUS1_DIV32 would need to be modified.  | 
53  |  |  */  | 
54  | 0  | # define ML_DSA_GAMMA2_Q_MINUS1_DIV32 ((ML_DSA_Q - 1) / 32)  | 
55  | 0  | # define ML_DSA_GAMMA2_Q_MINUS1_DIV88 ((ML_DSA_Q - 1) / 88)  | 
56  |  |  | 
57  |  | typedef struct poly_st POLY;  | 
58  |  | typedef struct vector_st VECTOR;  | 
59  |  | typedef struct matrix_st MATRIX;  | 
60  |  | typedef struct ml_dsa_sig_st ML_DSA_SIG;  | 
61  |  |  | 
62  |  | int ossl_ml_dsa_matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md,  | 
63  |  |                                 const uint8_t *rho, MATRIX *out);  | 
64  |  | int ossl_ml_dsa_vector_expand_S(EVP_MD_CTX *h_ctx, const EVP_MD *md, int eta,  | 
65  |  |                                 const uint8_t *seed, VECTOR *s1, VECTOR *s2);  | 
66  |  | void ossl_ml_dsa_matrix_mult_vector(const MATRIX *matrix_kl, const VECTOR *vl,  | 
67  |  |                                     VECTOR *vk);  | 
68  |  | int ossl_ml_dsa_poly_expand_mask(POLY *out, const uint8_t *seed, size_t seed_len,  | 
69  |  |                                  uint32_t gamma1,  | 
70  |  |                                  EVP_MD_CTX *h_ctx, const EVP_MD *md);  | 
71  |  | int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_len,  | 
72  |  |                                     EVP_MD_CTX *h_ctx, const EVP_MD *md,  | 
73  |  |                                     uint32_t tau);  | 
74  |  |  | 
75  |  | void ossl_ml_dsa_poly_ntt(POLY *s);  | 
76  |  | void ossl_ml_dsa_poly_ntt_inverse(POLY *s);  | 
77  |  | void ossl_ml_dsa_poly_ntt_mult(const POLY *lhs, const POLY *rhs, POLY *out);  | 
78  |  |  | 
79  |  | void ossl_ml_dsa_key_compress_power2_round(uint32_t r, uint32_t *r1, uint32_t *r0);  | 
80  |  | uint32_t ossl_ml_dsa_key_compress_high_bits(uint32_t r, uint32_t gamma2);  | 
81  |  | void ossl_ml_dsa_key_compress_decompose(uint32_t r, uint32_t gamma2,  | 
82  |  |                                         uint32_t *r1, int32_t *r0);  | 
83  |  | void ossl_ml_dsa_key_compress_decompose(uint32_t r, uint32_t gamma2,  | 
84  |  |                                         uint32_t *r1, int32_t *r0);  | 
85  |  | int32_t ossl_ml_dsa_key_compress_low_bits(uint32_t r, uint32_t gamma2);  | 
86  |  | int32_t ossl_ml_dsa_key_compress_make_hint(uint32_t ct0, uint32_t cs2,  | 
87  |  |                                            uint32_t gamma2, uint32_t w);  | 
88  |  | uint32_t ossl_ml_dsa_key_compress_use_hint(uint32_t hint, uint32_t r,  | 
89  |  |                                            uint32_t gamma2);  | 
90  |  |  | 
91  |  | int ossl_ml_dsa_pk_encode(ML_DSA_KEY *key);  | 
92  |  | int ossl_ml_dsa_sk_encode(ML_DSA_KEY *key);  | 
93  |  |  | 
94  |  | int ossl_ml_dsa_sig_encode(const ML_DSA_SIG *sig, const ML_DSA_PARAMS *params,  | 
95  |  |                            uint8_t *out);  | 
96  |  | int ossl_ml_dsa_sig_decode(ML_DSA_SIG *sig, const uint8_t *in, size_t in_len,  | 
97  |  |                            const ML_DSA_PARAMS *params);  | 
98  |  | int ossl_ml_dsa_w1_encode(const VECTOR *w1, uint32_t gamma2,  | 
99  |  |                           uint8_t *out, size_t out_len);  | 
100  |  | int ossl_ml_dsa_poly_decode_expand_mask(POLY *out,  | 
101  |  |                                         const uint8_t *in, size_t in_len,  | 
102  |  |                                         uint32_t gamma1);  | 
103  |  |  | 
104  |  | /*  | 
105  |  |  * @brief Reduces x mod q in constant time  | 
106  |  |  * i.e. return x < q ? x : x - q;  | 
107  |  |  *  | 
108  |  |  * @param x Where x is assumed to be in the range 0 <= x < 2*q  | 
109  |  |  * @returns the difference in the range 0..q-1  | 
110  |  |  */  | 
111  |  | static ossl_inline ossl_unused uint32_t reduce_once(uint32_t x)  | 
112  | 0  | { | 
113  | 0  |     return constant_time_select_32(constant_time_lt_32(x, ML_DSA_Q), x, x - ML_DSA_Q);  | 
114  | 0  | } Unexecuted instantiation: ml_dsa_encoders.c:reduce_once Unexecuted instantiation: ml_dsa_key.c:reduce_once Unexecuted instantiation: ml_dsa_key_compress.c:reduce_once Unexecuted instantiation: ml_dsa_matrix.c:reduce_once Unexecuted instantiation: ml_dsa_ntt.c:reduce_once Unexecuted instantiation: ml_dsa_params.c:reduce_once Unexecuted instantiation: ml_dsa_sample.c:reduce_once Unexecuted instantiation: ml_dsa_sign.c:reduce_once  | 
115  |  |  | 
116  |  | /*  | 
117  |  |  * @brief Calculate The positive value of (a-b) mod q in constant time.  | 
118  |  |  *  | 
119  |  |  * a - b mod q gives a value in the range -(q-1)..(q-1)  | 
120  |  |  * By adding q we get a range of 1..(2q-1).  | 
121  |  |  * Reducing this once then gives the range 0..q-1  | 
122  |  |  *  | 
123  |  |  * @param a The minuend assumed to be in the range 0..q-1  | 
124  |  |  * @param b The subtracthend assumed to be in the range 0..q-1.  | 
125  |  |  * @returns The value (q + a - b) mod q  | 
126  |  |  */  | 
127  |  | static ossl_inline ossl_unused uint32_t mod_sub(uint32_t a, uint32_t b)  | 
128  | 0  | { | 
129  | 0  |     return reduce_once(ML_DSA_Q + a - b);  | 
130  | 0  | } Unexecuted instantiation: ml_dsa_encoders.c:mod_sub Unexecuted instantiation: ml_dsa_key.c:mod_sub Unexecuted instantiation: ml_dsa_key_compress.c:mod_sub Unexecuted instantiation: ml_dsa_matrix.c:mod_sub Unexecuted instantiation: ml_dsa_ntt.c:mod_sub Unexecuted instantiation: ml_dsa_params.c:mod_sub Unexecuted instantiation: ml_dsa_sample.c:mod_sub Unexecuted instantiation: ml_dsa_sign.c:mod_sub  | 
131  |  |  | 
132  |  | /*  | 
133  |  |  * @brief Returns the absolute value in constant time.  | 
134  |  |  * i.e. return is_positive(x) ? x : -x;  | 
135  |  |  */  | 
136  |  | static ossl_inline ossl_unused uint32_t abs_signed(uint32_t x)  | 
137  | 0  | { | 
138  | 0  |     return constant_time_select_32(constant_time_lt_32(x, 0x80000000), x, 0u - x);  | 
139  | 0  | } Unexecuted instantiation: ml_dsa_encoders.c:abs_signed Unexecuted instantiation: ml_dsa_key.c:abs_signed Unexecuted instantiation: ml_dsa_key_compress.c:abs_signed Unexecuted instantiation: ml_dsa_matrix.c:abs_signed Unexecuted instantiation: ml_dsa_ntt.c:abs_signed Unexecuted instantiation: ml_dsa_params.c:abs_signed Unexecuted instantiation: ml_dsa_sample.c:abs_signed Unexecuted instantiation: ml_dsa_sign.c:abs_signed  | 
140  |  |  | 
141  |  | /*  | 
142  |  |  * @brief Returns the absolute value modulo q in constant time  | 
143  |  |  * i.e return x > (q - 1) / 2 ? q - x : x;  | 
144  |  |  */  | 
145  |  | static ossl_inline ossl_unused uint32_t abs_mod_prime(uint32_t x)  | 
146  | 0  | { | 
147  | 0  |     return constant_time_select_32(constant_time_lt_32(ML_DSA_Q_MINUS1_DIV2, x),  | 
148  | 0  |                                                        ML_DSA_Q - x, x);  | 
149  | 0  | } Unexecuted instantiation: ml_dsa_encoders.c:abs_mod_prime Unexecuted instantiation: ml_dsa_key.c:abs_mod_prime Unexecuted instantiation: ml_dsa_key_compress.c:abs_mod_prime Unexecuted instantiation: ml_dsa_matrix.c:abs_mod_prime Unexecuted instantiation: ml_dsa_ntt.c:abs_mod_prime Unexecuted instantiation: ml_dsa_params.c:abs_mod_prime Unexecuted instantiation: ml_dsa_sample.c:abs_mod_prime Unexecuted instantiation: ml_dsa_sign.c:abs_mod_prime  | 
150  |  |  | 
151  |  | /*  | 
152  |  |  * @brief Returns the maximum of two values in constant time.  | 
153  |  |  * i.e return x < y ? y : x;  | 
154  |  |  */  | 
155  |  | static ossl_inline ossl_unused uint32_t maximum(uint32_t x, uint32_t y)  | 
156  | 0  | { | 
157  | 0  |     return constant_time_select_int(constant_time_lt(x, y), y, x);  | 
158  | 0  | } Unexecuted instantiation: ml_dsa_encoders.c:maximum Unexecuted instantiation: ml_dsa_key.c:maximum Unexecuted instantiation: ml_dsa_key_compress.c:maximum Unexecuted instantiation: ml_dsa_matrix.c:maximum Unexecuted instantiation: ml_dsa_ntt.c:maximum Unexecuted instantiation: ml_dsa_params.c:maximum Unexecuted instantiation: ml_dsa_sample.c:maximum Unexecuted instantiation: ml_dsa_sign.c:maximum  | 
159  |  |  | 
160  |  | #endif /* OSSL_CRYPTO_ML_DSA_LOCAL_H */  |