Skip to content

Commit a1f73bc

Browse files
authored
[ML-KEM] Import ml-kem-ipd source code from Crystals repo (#1514)
This commit only imports the ML-KEM source files from https://github.com/pq-crystals/kyber/tree/standard. We will add them to the build in subsequent PRs.
1 parent 14b1cf8 commit a1f73bc

26 files changed

+2836
-2
lines changed

LICENSE

+2-2
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ are met:
206206
written permission.
207207

208208

209-
The code in crypto/kyber/pqcrystals-kyber_kyber512_ref carries the
210-
Public Domain license:
209+
The code in crypto/kyber/pqcrystals-kyber_kyber512_ref and
210+
crypto/ml_kem/ml_kem_ipd_ref_common carries the Public Domain license:
211211

212212
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/)
213213

crypto/ml_kem/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# AWS-LC ML-KEM readme file
2+
3+
The source code in this folder implements ML-KEM-ipd as defined in FIPS 203 (Initial Public Draft) Module-Lattice-Based Key-Encapsulation Mechanism Standard ([link](https://csrc.nist.gov/pubs/fips/203/ipd)).
4+
5+
NOTE: THIS IS AN IMPLEMENTATION OF THE DRAFT VERSION OF FIPS 203, NOT THE FINAL STANDARD. WE WILL CHANGE THIS IMPLEMENTATION TO CONFORM WITH THE STANDARD WHEN IT BECOMES OFFICIAL AND PUBLIC.
6+
7+
**Source code origin and modifications.** The source code was imported from a branch of the official repository of the Crystals-Kyber team that follows the standard draft: https://github.com/pq-crystals/kyber/tree/standard. The code was taken at [commit](https://github.com/pq-crystals/kyber/commit/11d00ff1f20cfca1f72d819e5a45165c1e0a2816) as of 03/26/2024. At the moment, only the reference C implementation is imported.
8+
+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#ifndef API_H
2+
#define API_H
3+
4+
#include <stdint.h>
5+
6+
#define pqcrystals_kyber512_SECRETKEYBYTES 1632
7+
#define pqcrystals_kyber512_PUBLICKEYBYTES 800
8+
#define pqcrystals_kyber512_CIPHERTEXTBYTES 768
9+
#define pqcrystals_kyber512_KEYPAIRCOINBYTES 64
10+
#define pqcrystals_kyber512_ENCCOINBYTES 32
11+
#define pqcrystals_kyber512_BYTES 32
12+
13+
#define pqcrystals_kyber512_ref_SECRETKEYBYTES pqcrystals_kyber512_SECRETKEYBYTES
14+
#define pqcrystals_kyber512_ref_PUBLICKEYBYTES pqcrystals_kyber512_PUBLICKEYBYTES
15+
#define pqcrystals_kyber512_ref_CIPHERTEXTBYTES pqcrystals_kyber512_CIPHERTEXTBYTES
16+
#define pqcrystals_kyber512_ref_KEYPAIRCOINBYTES pqcrystals_kyber512_KEYPAIRCOINBYTES
17+
#define pqcrystals_kyber512_ref_ENCCOINBYTES pqcrystals_kyber512_ENCCOINBYTES
18+
#define pqcrystals_kyber512_ref_BYTES pqcrystals_kyber512_BYTES
19+
20+
int pqcrystals_kyber512_ref_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t *coins);
21+
int pqcrystals_kyber512_ref_keypair(uint8_t *pk, uint8_t *sk);
22+
int pqcrystals_kyber512_ref_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t *coins);
23+
int pqcrystals_kyber512_ref_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk);
24+
int pqcrystals_kyber512_ref_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk);
25+
26+
#define pqcrystals_kyber768_SECRETKEYBYTES 2400
27+
#define pqcrystals_kyber768_PUBLICKEYBYTES 1184
28+
#define pqcrystals_kyber768_CIPHERTEXTBYTES 1088
29+
#define pqcrystals_kyber768_KEYPAIRCOINBYTES 64
30+
#define pqcrystals_kyber768_ENCCOINBYTES 32
31+
#define pqcrystals_kyber768_BYTES 32
32+
33+
#define pqcrystals_kyber768_ref_SECRETKEYBYTES pqcrystals_kyber768_SECRETKEYBYTES
34+
#define pqcrystals_kyber768_ref_PUBLICKEYBYTES pqcrystals_kyber768_PUBLICKEYBYTES
35+
#define pqcrystals_kyber768_ref_CIPHERTEXTBYTES pqcrystals_kyber768_CIPHERTEXTBYTES
36+
#define pqcrystals_kyber768_ref_KEYPAIRCOINBYTES pqcrystals_kyber768_KEYPAIRCOINBYTES
37+
#define pqcrystals_kyber768_ref_ENCCOINBYTES pqcrystals_kyber768_ENCCOINBYTES
38+
#define pqcrystals_kyber768_ref_BYTES pqcrystals_kyber768_BYTES
39+
40+
int pqcrystals_kyber768_ref_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t *coins);
41+
int pqcrystals_kyber768_ref_keypair(uint8_t *pk, uint8_t *sk);
42+
int pqcrystals_kyber768_ref_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t *coins);
43+
int pqcrystals_kyber768_ref_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk);
44+
int pqcrystals_kyber768_ref_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk);
45+
46+
#define pqcrystals_kyber1024_SECRETKEYBYTES 3168
47+
#define pqcrystals_kyber1024_PUBLICKEYBYTES 1568
48+
#define pqcrystals_kyber1024_CIPHERTEXTBYTES 1568
49+
#define pqcrystals_kyber1024_KEYPAIRCOINBYTES 64
50+
#define pqcrystals_kyber1024_ENCCOINBYTES 32
51+
#define pqcrystals_kyber1024_BYTES 32
52+
53+
#define pqcrystals_kyber1024_ref_SECRETKEYBYTES pqcrystals_kyber1024_SECRETKEYBYTES
54+
#define pqcrystals_kyber1024_ref_PUBLICKEYBYTES pqcrystals_kyber1024_PUBLICKEYBYTES
55+
#define pqcrystals_kyber1024_ref_CIPHERTEXTBYTES pqcrystals_kyber1024_CIPHERTEXTBYTES
56+
#define pqcrystals_kyber1024_ref_KEYPAIRCOINBYTES pqcrystals_kyber1024_KEYPAIRCOINBYTES
57+
#define pqcrystals_kyber1024_ref_ENCCOINBYTES pqcrystals_kyber1024_ENCCOINBYTES
58+
#define pqcrystals_kyber1024_ref_BYTES pqcrystals_kyber1024_BYTES
59+
60+
int pqcrystals_kyber1024_ref_keypair_derand(uint8_t *pk, uint8_t *sk, const uint8_t *coins);
61+
int pqcrystals_kyber1024_ref_keypair(uint8_t *pk, uint8_t *sk);
62+
int pqcrystals_kyber1024_ref_enc_derand(uint8_t *ct, uint8_t *ss, const uint8_t *pk, const uint8_t *coins);
63+
int pqcrystals_kyber1024_ref_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk);
64+
int pqcrystals_kyber1024_ref_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk);
65+
66+
#endif
+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#include <stdint.h>
2+
#include "params.h"
3+
#include "cbd.h"
4+
5+
/*************************************************
6+
* Name: load32_littleendian
7+
*
8+
* Description: load 4 bytes into a 32-bit integer
9+
* in little-endian order
10+
*
11+
* Arguments: - const uint8_t *x: pointer to input byte array
12+
*
13+
* Returns 32-bit unsigned integer loaded from x
14+
**************************************************/
15+
static uint32_t load32_littleendian(const uint8_t x[4])
16+
{
17+
uint32_t r;
18+
r = (uint32_t)x[0];
19+
r |= (uint32_t)x[1] << 8;
20+
r |= (uint32_t)x[2] << 16;
21+
r |= (uint32_t)x[3] << 24;
22+
return r;
23+
}
24+
25+
/*************************************************
26+
* Name: load24_littleendian
27+
*
28+
* Description: load 3 bytes into a 32-bit integer
29+
* in little-endian order.
30+
* This function is only needed for Kyber-512
31+
*
32+
* Arguments: - const uint8_t *x: pointer to input byte array
33+
*
34+
* Returns 32-bit unsigned integer loaded from x (most significant byte is zero)
35+
**************************************************/
36+
#if KYBER_ETA1 == 3
37+
static uint32_t load24_littleendian(const uint8_t x[3])
38+
{
39+
uint32_t r;
40+
r = (uint32_t)x[0];
41+
r |= (uint32_t)x[1] << 8;
42+
r |= (uint32_t)x[2] << 16;
43+
return r;
44+
}
45+
#endif
46+
47+
48+
/*************************************************
49+
* Name: cbd2
50+
*
51+
* Description: Given an array of uniformly random bytes, compute
52+
* polynomial with coefficients distributed according to
53+
* a centered binomial distribution with parameter eta=2
54+
*
55+
* Arguments: - poly *r: pointer to output polynomial
56+
* - const uint8_t *buf: pointer to input byte array
57+
**************************************************/
58+
static void cbd2(poly *r, const uint8_t buf[2*KYBER_N/4])
59+
{
60+
unsigned int i,j;
61+
uint32_t t,d;
62+
int16_t a,b;
63+
64+
for(i=0;i<KYBER_N/8;i++) {
65+
t = load32_littleendian(buf+4*i);
66+
d = t & 0x55555555;
67+
d += (t>>1) & 0x55555555;
68+
69+
for(j=0;j<8;j++) {
70+
a = (d >> (4*j+0)) & 0x3;
71+
b = (d >> (4*j+2)) & 0x3;
72+
r->coeffs[8*i+j] = a - b;
73+
}
74+
}
75+
}
76+
77+
/*************************************************
78+
* Name: cbd3
79+
*
80+
* Description: Given an array of uniformly random bytes, compute
81+
* polynomial with coefficients distributed according to
82+
* a centered binomial distribution with parameter eta=3.
83+
* This function is only needed for Kyber-512
84+
*
85+
* Arguments: - poly *r: pointer to output polynomial
86+
* - const uint8_t *buf: pointer to input byte array
87+
**************************************************/
88+
#if KYBER_ETA1 == 3
89+
static void cbd3(poly *r, const uint8_t buf[3*KYBER_N/4])
90+
{
91+
unsigned int i,j;
92+
uint32_t t,d;
93+
int16_t a,b;
94+
95+
for(i=0;i<KYBER_N/4;i++) {
96+
t = load24_littleendian(buf+3*i);
97+
d = t & 0x00249249;
98+
d += (t>>1) & 0x00249249;
99+
d += (t>>2) & 0x00249249;
100+
101+
for(j=0;j<4;j++) {
102+
a = (d >> (6*j+0)) & 0x7;
103+
b = (d >> (6*j+3)) & 0x7;
104+
r->coeffs[4*i+j] = a - b;
105+
}
106+
}
107+
}
108+
#endif
109+
110+
void poly_cbd_eta1(poly *r, const uint8_t buf[KYBER_ETA1*KYBER_N/4])
111+
{
112+
#if KYBER_ETA1 == 2
113+
cbd2(r, buf);
114+
#elif KYBER_ETA1 == 3
115+
cbd3(r, buf);
116+
#else
117+
#error "This implementation requires eta1 in {2,3}"
118+
#endif
119+
}
120+
121+
void poly_cbd_eta2(poly *r, const uint8_t buf[KYBER_ETA2*KYBER_N/4])
122+
{
123+
#if KYBER_ETA2 == 2
124+
cbd2(r, buf);
125+
#else
126+
#error "This implementation requires eta2 = 2"
127+
#endif
128+
}
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef CBD_H
2+
#define CBD_H
3+
4+
#include <stdint.h>
5+
#include "params.h"
6+
#include "poly.h"
7+
8+
#define poly_cbd_eta1 KYBER_NAMESPACE(poly_cbd_eta1)
9+
void poly_cbd_eta1(poly *r, const uint8_t buf[KYBER_ETA1*KYBER_N/4]);
10+
11+
#define poly_cbd_eta2 KYBER_NAMESPACE(poly_cbd_eta2)
12+
void poly_cbd_eta2(poly *r, const uint8_t buf[KYBER_ETA2*KYBER_N/4]);
13+
14+
#endif

0 commit comments

Comments
 (0)