xref: /aosp_15_r20/external/boringssl/src/crypto/curve25519/ed25519_test.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
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 <string.h>
17 
18 #include <gtest/gtest.h>
19 
20 #include <openssl/curve25519.h>
21 
22 #include "../internal.h"
23 #include "../test/file_test.h"
24 #include "../test/test_util.h"
25 
26 
TEST(Ed25519Test,TestVectors)27 TEST(Ed25519Test, TestVectors) {
28   FileTestGTest("crypto/curve25519/ed25519_tests.txt", [](FileTest *t) {
29     std::vector<uint8_t> private_key, public_key, message, expected_signature;
30     ASSERT_TRUE(t->GetBytes(&private_key, "PRIV"));
31     ASSERT_EQ(64u, private_key.size());
32     ASSERT_TRUE(t->GetBytes(&public_key, "PUB"));
33     ASSERT_EQ(32u, public_key.size());
34     ASSERT_TRUE(t->GetBytes(&message, "MESSAGE"));
35     ASSERT_TRUE(t->GetBytes(&expected_signature, "SIG"));
36     ASSERT_EQ(64u, expected_signature.size());
37 
38     // Signing should not leak the private key or the message.
39     CONSTTIME_SECRET(private_key.data(), private_key.size());
40     CONSTTIME_SECRET(message.data(), message.size());
41     uint8_t signature[64];
42     ASSERT_TRUE(ED25519_sign(signature, message.data(), message.size(),
43                              private_key.data()));
44     CONSTTIME_DECLASSIFY(signature, sizeof(signature));
45     CONSTTIME_DECLASSIFY(message.data(), message.size());
46 
47     EXPECT_EQ(Bytes(expected_signature), Bytes(signature));
48     EXPECT_TRUE(ED25519_verify(message.data(), message.size(), signature,
49                                public_key.data()));
50   });
51 }
52 
TEST(Ed25519Test,Malleability)53 TEST(Ed25519Test, Malleability) {
54   // https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
55   // that s be in [0, order). This prevents someone from adding a multiple of
56   // order to s and obtaining a second valid signature for the same message.
57   static const uint8_t kMsg[] = {0x54, 0x65, 0x73, 0x74};
58   static const uint8_t kSig[] = {
59       0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a,
60       0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b,
61       0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67,
62       0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d,
63       0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33,
64       0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d,
65   };
66   static const uint8_t kPub[] = {
67       0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5,
68       0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34,
69       0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa,
70   };
71 
72   EXPECT_FALSE(ED25519_verify(kMsg, sizeof(kMsg), kSig, kPub));
73 
74   // The following inputs try to exercise the boundaries of the order check,
75   // where s is near the order above and below. EdDSA hashes the public key with
76   // the message, which frustrates constructing actual boundary cases. Instead,
77   // these inputs were found by randomly generating signatures. kSigValid had
78   // the highest s value. kSigInvalid had the lowest s value, and then the order
79   // was added.
80   //
81   // This isn't ideal, but it is sensitive to the most significant 32 bits.
82   //
83   // The private key seed for kPub2 is
84   // a59a4130fcfd293c9737db8f14177ce034305cf34bdc4346f24b4d262e07b5c2.
85   static const uint8_t kPub2[] = {
86       0x10, 0x0f, 0xdf, 0x47, 0xfb, 0x94, 0xf1, 0x53, 0x6a, 0x4f, 0x7c,
87       0x3f, 0xda, 0x27, 0x38, 0x3f, 0xa0, 0x33, 0x75, 0xa8, 0xf5, 0x27,
88       0xc5, 0x37, 0xe6, 0xf1, 0x70, 0x3c, 0x47, 0xf9, 0x4f, 0x86};
89   static const uint8_t kMsgValid[] = {
90       0x12, 0x4e, 0x58, 0x3f, 0x8b, 0x8e, 0xca, 0x58, 0xbb, 0x29, 0xc2,
91       0x71, 0xb4, 0x1d, 0x36, 0x98, 0x6b, 0xbc, 0x45, 0x54, 0x1f, 0x8e,
92       0x51, 0xf9, 0xcb, 0x01, 0x33, 0xec, 0xa4, 0x47, 0x60, 0x1e};
93   static const uint8_t kSigValid[] = {
94       0xda, 0xc1, 0x19, 0xd6, 0xca, 0x87, 0xfc, 0x59, 0xae, 0x61, 0x1c,
95       0x15, 0x70, 0x48, 0xf4, 0xd4, 0xfc, 0x93, 0x2a, 0x14, 0x9d, 0xbe,
96       0x20, 0xec, 0x6e, 0xff, 0xd1, 0x43, 0x6a, 0xbf, 0x83, 0xea, 0x05,
97       0xc7, 0xdf, 0x0f, 0xef, 0x06, 0x14, 0x72, 0x41, 0x25, 0x91, 0x13,
98       0x90, 0x9b, 0xc7, 0x1b, 0xd3, 0xc5, 0x3b, 0xa4, 0x46, 0x4f, 0xfc,
99       0xad, 0x3c, 0x09, 0x68, 0xf2, 0xff, 0xff, 0xff, 0x0f};
100   static const uint8_t kMsgInvalid[] = {
101       0x6a, 0x0b, 0xc2, 0xb0, 0x05, 0x7c, 0xed, 0xfc, 0x0f, 0xa2, 0xe3,
102       0xf7, 0xf7, 0xd3, 0x92, 0x79, 0xb3, 0x0f, 0x45, 0x4a, 0x69, 0xdf,
103       0xd1, 0x11, 0x7c, 0x75, 0x8d, 0x86, 0xb1, 0x9d, 0x85, 0xe0};
104   static const uint8_t kSigInvalid[] = {
105       0x09, 0x71, 0xf8, 0x6d, 0x2c, 0x9c, 0x78, 0x58, 0x25, 0x24, 0xa1,
106       0x03, 0xcb, 0x9c, 0xf9, 0x49, 0x52, 0x2a, 0xe5, 0x28, 0xf8, 0x05,
107       0x4d, 0xc2, 0x01, 0x07, 0xd9, 0x99, 0xbe, 0x67, 0x3f, 0xf4, 0xe2,
108       0x5e, 0xbf, 0x2f, 0x29, 0x28, 0x76, 0x6b, 0x12, 0x48, 0xbe, 0xc6,
109       0xe9, 0x16, 0x97, 0x77, 0x5f, 0x84, 0x46, 0x63, 0x9e, 0xde, 0x46,
110       0xad, 0x4d, 0xf4, 0x05, 0x30, 0x00, 0x00, 0x00, 0x10};
111 
112   EXPECT_TRUE(ED25519_verify(kMsgValid, sizeof(kMsgValid), kSigValid, kPub2));
113   EXPECT_FALSE(
114       ED25519_verify(kMsgInvalid, sizeof(kMsgInvalid), kSigInvalid, kPub2));
115 }
116 
TEST(Ed25519Test,KeypairFromSeed)117 TEST(Ed25519Test, KeypairFromSeed) {
118   uint8_t public_key1[32], private_key1[64];
119   ED25519_keypair(public_key1, private_key1);
120 
121   uint8_t seed[32];
122   OPENSSL_memcpy(seed, private_key1, sizeof(seed));
123   CONSTTIME_SECRET(seed, sizeof(seed));
124 
125   uint8_t public_key2[32], private_key2[64];
126   ED25519_keypair_from_seed(public_key2, private_key2, seed);
127   CONSTTIME_DECLASSIFY(public_key2, sizeof(public_key2));
128   CONSTTIME_DECLASSIFY(private_key2, sizeof(private_key2));
129 
130   EXPECT_EQ(Bytes(public_key1), Bytes(public_key2));
131   EXPECT_EQ(Bytes(private_key1), Bytes(private_key2));
132 }
133