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