• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2024 The BoringSSL Authors
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #ifndef OPENSSL_HEADER_MLDSA_H_
16 #define OPENSSL_HEADER_MLDSA_H_
17 
18 #include <openssl/base.h>
19 
20 #if defined(__cplusplus)
21 extern "C" {
22 #endif
23 
24 
25 // ML-DSA.
26 //
27 // This implements the Module-Lattice-Based Digital Signature Standard from
28 // https://csrc.nist.gov/pubs/fips/204/final
29 
30 
31 // MLDSA_SEED_BYTES is the number of bytes in an ML-DSA seed value.
32 #define MLDSA_SEED_BYTES 32
33 
34 
35 // ML-DSA-65.
36 
37 // MLDSA65_private_key contains an ML-DSA-65 private key. The contents of this
38 // object should never leave the address space since the format is unstable.
39 struct MLDSA65_private_key {
40   union {
41     uint8_t bytes[32 + 32 + 64 + 256 * 4 * (5 + 6 + 6)];
42     uint32_t alignment;
43   } opaque;
44 };
45 
46 // MLDSA65_public_key contains an ML-DSA-65 public key. The contents of this
47 // object should never leave the address space since the format is unstable.
48 struct MLDSA65_public_key {
49   union {
50     uint8_t bytes[32 + 64 + 256 * 4 * 6];
51     uint32_t alignment;
52   } opaque;
53 };
54 
55 // MLDSA65_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-65
56 // private key.
57 #define MLDSA65_PRIVATE_KEY_BYTES 4032
58 
59 // MLDSA65_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-65
60 // public key.
61 #define MLDSA65_PUBLIC_KEY_BYTES 1952
62 
63 // MLDSA65_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-65
64 // signature.
65 #define MLDSA65_SIGNATURE_BYTES 3309
66 
67 // MLDSA65_generate_key generates a random public/private key pair, writes the
68 // encoded public key to |out_encoded_public_key|, writes the seed to
69 // |out_seed|, and sets |out_private_key| to the private key. Returns 1 on
70 // success and 0 on allocation failure.
71 OPENSSL_EXPORT int MLDSA65_generate_key(
72     uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES],
73     uint8_t out_seed[MLDSA_SEED_BYTES],
74     struct MLDSA65_private_key *out_private_key);
75 
76 // MLDSA65_private_key_from_seed regenerates a private key from a seed value
77 // that was generated by |MLDSA65_generate_key|. Returns 1 on success and 0 on
78 // allocation failure or if |seed_len| is incorrect.
79 OPENSSL_EXPORT int MLDSA65_private_key_from_seed(
80     struct MLDSA65_private_key *out_private_key, const uint8_t *seed,
81     size_t seed_len);
82 
83 // MLDSA65_public_from_private sets |*out_public_key| to the public key that
84 // corresponds to |private_key|. Returns 1 on success and 0 on failure.
85 OPENSSL_EXPORT int MLDSA65_public_from_private(
86     struct MLDSA65_public_key *out_public_key,
87     const struct MLDSA65_private_key *private_key);
88 
89 // MLDSA65_sign generates a signature for the message |msg| of length
90 // |msg_len| using |private_key| (following the randomized algorithm), and
91 // writes the encoded signature to |out_encoded_signature|. The |context|
92 // argument is also signed over and can be used to include implicit contextual
93 // information that isn't included in |msg|. The same value of |context| must be
94 // presented to |MLDSA65_verify| in order for the generated signature to be
95 // considered valid. |context| and |context_len| may be |NULL| and 0 to use an
96 // empty context (this is common). Returns 1 on success and 0 on failure.
97 OPENSSL_EXPORT int MLDSA65_sign(
98     uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES],
99     const struct MLDSA65_private_key *private_key, const uint8_t *msg,
100     size_t msg_len, const uint8_t *context, size_t context_len);
101 
102 // MLDSA65_verify verifies that |signature| constitutes a valid
103 // signature for the message |msg| of length |msg_len| using |public_key|. The
104 // value of |context| must equal the value that was passed to |MLDSA65_sign|
105 // when the signature was generated. Returns 1 on success or 0 on error.
106 OPENSSL_EXPORT int MLDSA65_verify(const struct MLDSA65_public_key *public_key,
107                                   const uint8_t *signature,
108                                   size_t signature_len, const uint8_t *msg,
109                                   size_t msg_len, const uint8_t *context,
110                                   size_t context_len);
111 
112 // MLDSA65_marshal_public_key serializes |public_key| to |out| in the standard
113 // format for ML-DSA-65 public keys. It returns 1 on success or 0 on
114 // allocation error.
115 OPENSSL_EXPORT int MLDSA65_marshal_public_key(
116     CBB *out, const struct MLDSA65_public_key *public_key);
117 
118 // MLDSA65_parse_public_key parses a public key, in the format generated by
119 // |MLDSA65_marshal_public_key|, from |in| and writes the result to
120 // |out_public_key|. It returns 1 on success or 0 on parse error or if
121 // there are trailing bytes in |in|.
122 OPENSSL_EXPORT int MLDSA65_parse_public_key(
123     struct MLDSA65_public_key *public_key, CBS *in);
124 
125 
126 #if defined(__cplusplus)
127 }  // extern C
128 #endif
129 
130 #endif  // OPENSSL_HEADER_MLDSA_H_
131