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