summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/mlkem/mlkem.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/mlkem/mlkem.h')
-rw-r--r--src/lib/libcrypto/mlkem/mlkem.h168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.h b/src/lib/libcrypto/mlkem/mlkem.h
new file mode 100644
index 0000000000..8040f4844b
--- /dev/null
+++ b/src/lib/libcrypto/mlkem/mlkem.h
@@ -0,0 +1,168 @@
1/* Copyright (c) 2024, Google Inc.
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_MLKEM_H
16#define OPENSSL_HEADER_MLKEM_H
17
18#include <sys/types.h>
19#include <stdint.h>
20
21#ifdef LIBRESSL_HAS_MLKEM
22/* This needs to become public */
23#include <openssl/bytestring.h>
24#else
25/* Hack for now */
26struct cbs_st;
27struct cbb_st;
28#endif
29
30#if defined(__cplusplus)
31extern "C" {
32#endif
33
34/*
35 * ML-KEM-768
36 *
37 * This implements the Module-Lattice-Based Key-Encapsulation Mechanism from
38 * https://csrc.nist.gov/pubs/fips/204/final
39 */
40
41/*
42 * MLKEM768_public_key contains a ML-KEM-768 public key. The contents of this
43 * object should never leave the address space since the format is unstable.
44 */
45struct MLKEM768_public_key {
46 union {
47 uint8_t bytes[512 * (3 + 9) + 32 + 32];
48 uint16_t alignment;
49 } opaque;
50};
51
52/*
53 * MLKEM768_private_key contains a ML-KEM-768 private key. The contents of this
54 * object should never leave the address space since the format is unstable.
55 */
56struct MLKEM768_private_key {
57 union {
58 uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
59 uint16_t alignment;
60 } opaque;
61};
62
63/*
64 * MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM768 public
65 * key.
66 */
67#define MLKEM768_PUBLIC_KEY_BYTES 1184
68
69/* MLKEM_SEED_BYTES is the number of bytes in an ML-KEM seed. */
70#define MLKEM_SEED_BYTES 64
71
72/*
73 * MLKEM_SHARED_SECRET_BYTES is the number of bytes in the ML-KEM768 shared
74 * secret. Although the round-3 specification has a variable-length output, the
75 * final ML-KEM construction is expected to use a fixed 32-byte output. To
76 * simplify the future transition, we apply the same restriction.
77 */
78#define MLKEM_SHARED_SECRET_BYTES 32
79
80/*
81 * MLKEM_generate_key generates a random public/private key pair, writes the
82 * encoded public key to |out_encoded_public_key| and sets |out_private_key| to
83 * the private key. If |optional_out_seed| us not NULL then te seed used to
84 * generate te private key is written to it.
85 */
86void MLKEM768_generate_key(
87 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
88 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
89 struct MLKEM768_private_key *out_private_key);
90
91/*
92 * MLKEM768_private_key_from_seed derives a private key from a seed that was
93 * generated by |MLKEM768_generate_key|. It fails and returns 0 if |seed_len| is
94 * incorrect, otherwise it writes |*out_private_key| and returns 1.
95 */
96int MLKEM768_private_key_from_seed(struct MLKEM768_private_key *out_private_key,
97 const uint8_t *seed, size_t seed_len);
98
99/*
100 * MLKEM_public_from_private sets |*out_public_key| to the public key that
101 * corresponds to |private_key|. (This is faster than parsing the output of
102 * |MLKEM_generate_key| if, for some reason, you need to encapsulate to a key
103 * that was just generated.)
104 */
105void MLKEM768_public_from_private(struct MLKEM768_public_key *out_public_key,
106 const struct MLKEM768_private_key *private_key);
107
108/* MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM768 ciphertext. */
109#define MLKEM768_CIPHERTEXT_BYTES 1088
110
111/*
112 * MLKEM768_encap encrypts a random shared secret for |public_key|, writes the
113 * ciphertext to |out_ciphertext|, and writes the random shared secret to
114 * |out_shared_secret|.
115 */
116void MLKEM768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
117 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
118 const struct MLKEM768_public_key *public_key);
119
120/*
121 * MLKEM768_decap decrypts a shared secret from |ciphertext| using |private_key|
122 * and writes it to |out_shared_secret|. If |ciphertext_len| is incorrect it
123 * returns 0, otherwise it rreturns 1. If |ciphertext| is invalid,
124 * |out_shared_secret| is filled with a key that will always be the same for the
125 * same |ciphertext| and |private_key|, but which appears to be random unless
126 * one has access to |private_key|. These alternatives occur in constant time.
127 * Any subsequent symmetric encryption using |out_shared_secret| must use an
128 * authenticated encryption scheme in order to discover the decapsulation
129 * failure.
130 */
131int MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
132 const uint8_t *ciphertext, size_t ciphertext_len,
133 const struct MLKEM768_private_key *private_key);
134
135/* Serialisation of keys. */
136
137/*
138 * MLKEM768_marshal_public_key serializes |public_key| to |out| in the standard
139 * format for ML-KEM public keys. It returns one on success or zero on allocation
140 * error.
141 */
142int MLKEM768_marshal_public_key(struct cbb_st *out,
143 const struct MLKEM768_public_key *public_key);
144
145/*
146 * MLKEM768_parse_public_key parses a public key, in the format generated by
147 * |MLKEM_marshal_public_key|, from |in| and writes the result to
148 * |out_public_key|. It returns one on success or zero on parse error or if
149 * there are trailing bytes in |in|.
150 */
151int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key,
152 struct cbs_st *in);
153
154/*
155 * MLKEM_parse_private_key parses a private key, in the format generated by
156 * |MLKEM_marshal_private_key|, from |in| and writes the result to
157 * |out_private_key|. It returns one on success or zero on parse error or if
158 * there are trailing bytes in |in|. This formate is verbose and should be avoided.
159 * Private keys should be stored as seeds and parsed using |MLKEM768_private_key_from_seed|.
160 */
161int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key,
162 struct cbs_st *in);
163
164#if defined(__cplusplus)
165}
166#endif
167
168#endif /* OPENSSL_HEADER_MLKEM_H */