• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2023, 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 #include <vector>
16 
17 #include <string.h>
18 
19 #include <gtest/gtest.h>
20 
21 #include <openssl/bytestring.h>
22 #include <openssl/ctrdrbg.h>
23 #include <openssl/kyber.h>
24 
25 #include "../test/file_test.h"
26 #include "../test/test_util.h"
27 #include "../keccak/internal.h"
28 #include "./internal.h"
29 
30 
31 template <typename T>
Marshal(int (* marshal_func)(CBB *,const T *),const T * t)32 static std::vector<uint8_t> Marshal(int (*marshal_func)(CBB *, const T *),
33                                     const T *t) {
34   bssl::ScopedCBB cbb;
35   uint8_t *encoded;
36   size_t encoded_len;
37   if (!CBB_init(cbb.get(), 1) ||      //
38       !marshal_func(cbb.get(), t) ||  //
39       !CBB_finish(cbb.get(), &encoded, &encoded_len)) {
40     abort();
41   }
42 
43   std::vector<uint8_t> ret(encoded, encoded + encoded_len);
44   OPENSSL_free(encoded);
45   return ret;
46 }
47 
TEST(KyberTest,Basic)48 TEST(KyberTest, Basic) {
49   uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES];
50   KYBER_private_key priv;
51   KYBER_generate_key(encoded_public_key, &priv);
52 
53   uint8_t first_two_bytes[2];
54   OPENSSL_memcpy(first_two_bytes, encoded_public_key, sizeof(first_two_bytes));
55   OPENSSL_memset(encoded_public_key, 0xff, sizeof(first_two_bytes));
56   CBS encoded_public_key_cbs;
57   CBS_init(&encoded_public_key_cbs, encoded_public_key,
58            sizeof(encoded_public_key));
59   KYBER_public_key pub;
60   // Parsing should fail because the first coefficient is >= kPrime;
61   ASSERT_FALSE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs));
62 
63   OPENSSL_memcpy(encoded_public_key, first_two_bytes, sizeof(first_two_bytes));
64   CBS_init(&encoded_public_key_cbs, encoded_public_key,
65            sizeof(encoded_public_key));
66   ASSERT_TRUE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs));
67   EXPECT_EQ(CBS_len(&encoded_public_key_cbs), 0u);
68 
69   EXPECT_EQ(Bytes(encoded_public_key),
70             Bytes(Marshal(KYBER_marshal_public_key, &pub)));
71 
72   KYBER_public_key pub2;
73   KYBER_public_from_private(&pub2, &priv);
74   EXPECT_EQ(Bytes(encoded_public_key),
75             Bytes(Marshal(KYBER_marshal_public_key, &pub2)));
76 
77   std::vector<uint8_t> encoded_private_key(
78       Marshal(KYBER_marshal_private_key, &priv));
79   EXPECT_EQ(encoded_private_key.size(), size_t{KYBER_PRIVATE_KEY_BYTES});
80 
81   OPENSSL_memcpy(first_two_bytes, encoded_private_key.data(),
82                  sizeof(first_two_bytes));
83   OPENSSL_memset(encoded_private_key.data(), 0xff, sizeof(first_two_bytes));
84   CBS cbs;
85   CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size());
86   KYBER_private_key priv2;
87   // Parsing should fail because the first coefficient is >= kPrime.
88   ASSERT_FALSE(KYBER_parse_private_key(&priv2, &cbs));
89 
90   OPENSSL_memcpy(encoded_private_key.data(), first_two_bytes,
91                  sizeof(first_two_bytes));
92   CBS_init(&cbs, encoded_private_key.data(), encoded_private_key.size());
93   ASSERT_TRUE(KYBER_parse_private_key(&priv2, &cbs));
94   EXPECT_EQ(Bytes(encoded_private_key),
95             Bytes(Marshal(KYBER_marshal_private_key, &priv2)));
96 
97   uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
98   uint8_t shared_secret1[64];
99   uint8_t shared_secret2[sizeof(shared_secret1)];
100   KYBER_encap(ciphertext, shared_secret1, sizeof(shared_secret1), &pub);
101   KYBER_decap(shared_secret2, sizeof(shared_secret2), ciphertext, &priv);
102   EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2));
103   KYBER_decap(shared_secret2, sizeof(shared_secret2), ciphertext, &priv2);
104   EXPECT_EQ(Bytes(shared_secret1), Bytes(shared_secret2));
105 }
106 
KyberFileTest(FileTest * t)107 static void KyberFileTest(FileTest *t) {
108   std::vector<uint8_t> seed, public_key_expected, private_key_expected,
109       ciphertext_expected, shared_secret_expected, given_generate_entropy,
110       given_encap_entropy_pre_hash;
111   t->IgnoreAttribute("count");
112   ASSERT_TRUE(t->GetBytes(&seed, "seed"));
113   ASSERT_TRUE(t->GetBytes(&public_key_expected, "pk"));
114   ASSERT_TRUE(t->GetBytes(&private_key_expected, "sk"));
115   ASSERT_TRUE(t->GetBytes(&ciphertext_expected, "ct"));
116   ASSERT_TRUE(t->GetBytes(&shared_secret_expected, "ss"));
117   ASSERT_TRUE(t->GetBytes(&given_generate_entropy, "generateEntropy"));
118   ASSERT_TRUE(
119       t->GetBytes(&given_encap_entropy_pre_hash, "encapEntropyPreHash"));
120 
121   KYBER_private_key priv;
122   uint8_t encoded_private_key[KYBER_PRIVATE_KEY_BYTES];
123   KYBER_public_key pub;
124   uint8_t encoded_public_key[KYBER_PUBLIC_KEY_BYTES];
125   uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES];
126   uint8_t gen_key_entropy[KYBER_GENERATE_KEY_ENTROPY];
127   uint8_t encap_entropy[KYBER_ENCAP_ENTROPY];
128   uint8_t encapsulated_key[32];
129   uint8_t decapsulated_key[32];
130   // The test vectors provide a CTR-DRBG seed which is used to generate the
131   // input entropy.
132   ASSERT_EQ(seed.size(), size_t{CTR_DRBG_ENTROPY_LEN});
133   {
134     bssl::UniquePtr<CTR_DRBG_STATE> state(
135         CTR_DRBG_new(seed.data(), nullptr, 0));
136     ASSERT_TRUE(state);
137     ASSERT_TRUE(
138         CTR_DRBG_generate(state.get(), gen_key_entropy, 32, nullptr, 0));
139     ASSERT_TRUE(
140         CTR_DRBG_generate(state.get(), gen_key_entropy + 32, 32, nullptr, 0));
141     ASSERT_TRUE(CTR_DRBG_generate(state.get(), encap_entropy,
142                                   KYBER_ENCAP_ENTROPY, nullptr, 0));
143   }
144 
145   EXPECT_EQ(Bytes(gen_key_entropy), Bytes(given_generate_entropy));
146   EXPECT_EQ(Bytes(encap_entropy), Bytes(given_encap_entropy_pre_hash));
147 
148   BORINGSSL_keccak(encap_entropy, sizeof(encap_entropy), encap_entropy,
149                    sizeof(encap_entropy), boringssl_sha3_256);
150 
151   KYBER_generate_key_external_entropy(encoded_public_key, &priv,
152                                       gen_key_entropy);
153   CBB cbb;
154   CBB_init_fixed(&cbb, encoded_private_key, sizeof(encoded_private_key));
155   ASSERT_TRUE(KYBER_marshal_private_key(&cbb, &priv));
156   CBS encoded_public_key_cbs;
157   CBS_init(&encoded_public_key_cbs, encoded_public_key,
158            sizeof(encoded_public_key));
159   ASSERT_TRUE(KYBER_parse_public_key(&pub, &encoded_public_key_cbs));
160   KYBER_encap_external_entropy(ciphertext, encapsulated_key,
161                                sizeof(encapsulated_key), &pub, encap_entropy);
162   KYBER_decap(decapsulated_key, sizeof(decapsulated_key), ciphertext, &priv);
163 
164   EXPECT_EQ(Bytes(encapsulated_key), Bytes(decapsulated_key));
165   EXPECT_EQ(Bytes(private_key_expected), Bytes(encoded_private_key));
166   EXPECT_EQ(Bytes(public_key_expected), Bytes(encoded_public_key));
167   EXPECT_EQ(Bytes(ciphertext_expected), Bytes(ciphertext));
168   EXPECT_EQ(Bytes(shared_secret_expected), Bytes(encapsulated_key));
169 
170   uint8_t corrupted_ciphertext[KYBER_CIPHERTEXT_BYTES];
171   OPENSSL_memcpy(corrupted_ciphertext, ciphertext, KYBER_CIPHERTEXT_BYTES);
172   corrupted_ciphertext[3] ^= 0x40;
173   uint8_t corrupted_decapsulated_key[32];
174   KYBER_decap(corrupted_decapsulated_key, sizeof(corrupted_decapsulated_key),
175               corrupted_ciphertext, &priv);
176   // It would be nice to have actual test vectors for the failure case, but the
177   // NIST submission currently does not include those, so we are just testing
178   // for inequality.
179   EXPECT_NE(Bytes(encapsulated_key), Bytes(corrupted_decapsulated_key));
180 }
181 
TEST(KyberTest,TestVectors)182 TEST(KyberTest, TestVectors) {
183   FileTestGTest("crypto/kyber/kyber_tests.txt", KyberFileTest);
184 }
185