x25519_test.cc
Go to the documentation of this file.
1 /* Copyright (c) 2015, 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 <stdint.h>
16 #include <stdio.h>
17 #include <string.h>
18 
19 #include <gtest/gtest.h>
20 
21 #include <openssl/curve25519.h>
22 
23 #include "../internal.h"
24 #include "../test/file_test.h"
25 #include "../test/test_util.h"
26 #include "../test/wycheproof_util.h"
27 
28 
29 TEST(X25519Test, TestVector) {
30  // Taken from https://tools.ietf.org/html/rfc7748#section-5.2
31  static const uint8_t kScalar1[32] = {
32  0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
33  0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
34  0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4,
35  };
36  static const uint8_t kPoint1[32] = {
37  0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1,
38  0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3,
39  0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c,
40  };
41 
42  uint8_t out[32];
43  EXPECT_TRUE(X25519(out, kScalar1, kPoint1));
44 
45  static const uint8_t kExpected1[32] = {
46  0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea,
47  0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c,
48  0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52,
49  };
50  EXPECT_EQ(Bytes(kExpected1), Bytes(out));
51 
52  static const uint8_t kScalar2[32] = {
53  0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26,
54  0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea,
55  0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d,
56  };
57  static const uint8_t kPoint2[32] = {
58  0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95,
59  0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0,
60  0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93,
61  };
62 
63  EXPECT_TRUE(X25519(out, kScalar2, kPoint2));
64 
65  static const uint8_t kExpected2[32] = {
66  0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4,
67  0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f,
68  0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57,
69  };
70  EXPECT_EQ(Bytes(kExpected2), Bytes(out));
71 }
72 
73 TEST(X25519Test, SmallOrder) {
74  static const uint8_t kSmallOrderPoint[32] = {
75  0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
76  0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
77  0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8,
78  };
79 
80  uint8_t out[32], private_key[32];
81  OPENSSL_memset(private_key, 0x11, sizeof(private_key));
82 
83  OPENSSL_memset(out, 0xff, sizeof(out));
84  EXPECT_FALSE(X25519(out, private_key, kSmallOrderPoint))
85  << "X25519 returned success with a small-order input.";
86 
87  // For callers which don't check, |out| should still be filled with zeros.
88  static const uint8_t kZeros[32] = {0};
89  EXPECT_EQ(Bytes(kZeros), Bytes(out));
90 }
91 
92 TEST(X25519Test, Iterated) {
93  // Taken from https://tools.ietf.org/html/rfc7748#section-5.2.
94  uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
95 
96  for (unsigned i = 0; i < 1000; i++) {
98  OPENSSL_memcpy(point, scalar, sizeof(point));
99  OPENSSL_memcpy(scalar, out, sizeof(scalar));
100  }
101 
102  static const uint8_t kExpected[32] = {
103  0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, 0x28, 0x00, 0xef,
104  0x56, 0x6f, 0x2f, 0x4d, 0x3c, 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60,
105  0xe3, 0x87, 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51,
106  };
107 
108  EXPECT_EQ(Bytes(kExpected), Bytes(scalar));
109 }
110 
111 TEST(X25519Test, DISABLED_IteratedLarge) {
112  // Taken from https://tools.ietf.org/html/rfc7748#section-5.2.
113  uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
114 
115  for (unsigned i = 0; i < 1000000; i++) {
117  OPENSSL_memcpy(point, scalar, sizeof(point));
118  OPENSSL_memcpy(scalar, out, sizeof(scalar));
119  }
120 
121  static const uint8_t kExpected[32] = {
122  0x7c, 0x39, 0x11, 0xe0, 0xab, 0x25, 0x86, 0xfd, 0x86, 0x44, 0x97,
123  0x29, 0x7e, 0x57, 0x5e, 0x6f, 0x3b, 0xc6, 0x01, 0xc0, 0x88, 0x3c,
124  0x30, 0xdf, 0x5f, 0x4d, 0xd2, 0xd2, 0x4f, 0x66, 0x54, 0x24,
125  };
126 
127  EXPECT_EQ(Bytes(kExpected), Bytes(scalar));
128 }
129 
130 TEST(X25519Test, Wycheproof) {
131  FileTestGTest("third_party/wycheproof_testvectors/x25519_test.txt",
132  [](FileTest *t) {
133  t->IgnoreInstruction("curve");
134  t->IgnoreAttribute("curve");
135 
138  std::vector<uint8_t> priv, pub, shared;
139  ASSERT_TRUE(t->GetBytes(&priv, "private"));
140  ASSERT_TRUE(t->GetBytes(&pub, "public"));
141  ASSERT_TRUE(t->GetBytes(&shared, "shared"));
142  ASSERT_EQ(32u, priv.size());
143  ASSERT_EQ(32u, pub.size());
144  uint8_t secret[32];
145  int ret = X25519(secret, priv.data(), pub.data());
146  EXPECT_EQ(ret, result.IsValid({"NonCanonicalPublic", "Twist"}) ? 1 : 0);
147  EXPECT_EQ(Bytes(secret), Bytes(shared));
148  });
149 }
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
Bytes
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:38
WycheproofResult
Definition: wycheproof_util.h:34
scalar
Definition: spake25519.c:317
string.h
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
FileTestGTest
void FileTestGTest(const char *path, std::function< void(FileTest *)> run_test)
Definition: file_test_gtest.cc:68
TEST
TEST(X25519Test, TestVector)
Definition: x25519_test.cc:29
FileTest
Definition: file_test.h:90
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
GetWycheproofResult
bool GetWycheproofResult(FileTest *t, WycheproofResult *out)
Definition: wycheproof_util.cc:49
stdint.h
point
Definition: bloaty/third_party/zlib/examples/zran.c:67
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
private_key
Definition: hrss.c:1885
curve25519.h
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056
X25519
#define X25519
Definition: boringssl_prefix_symbols.h:2209


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:55