Serenity Operating System
1/*
2 * Copyright (c) 2022, stelar7 <dudedbz@gmail.com>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/ByteBuffer.h>
8#include <LibCrypto/Curves/Ed25519.h>
9#include <LibTest/TestCase.h>
10
11// https://datatracker.ietf.org/doc/html/rfc8032#section-7.1
12TEST_CASE(TEST_1)
13{
14 u8 private_bytes[32] = {
15 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60,
16 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4,
17 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19,
18 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60
19 };
20
21 u8 public_bytes[32] = {
22 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7,
23 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a,
24 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25,
25 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a
26 };
27
28 u8 message_bytes[0] = {};
29
30 u8 signature_bytes[64] = {
31 0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72,
32 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a,
33 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74,
34 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55,
35 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac,
36 0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b,
37 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24,
38 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b
39 };
40
41 ReadonlyBytes private_key { private_bytes, 32 };
42 ReadonlyBytes public_key { public_bytes, 32 };
43 ReadonlyBytes message { message_bytes, 0 };
44 ReadonlyBytes expected_signature { signature_bytes, 64 };
45
46 Crypto::Curves::Ed25519 curve;
47
48 auto generated_signature = MUST(curve.sign(public_key, private_key, message));
49 EXPECT_EQ(generated_signature, expected_signature);
50 EXPECT_EQ(true, curve.verify(public_key, expected_signature, message));
51}
52
53TEST_CASE(TEST_2)
54{
55 u8 private_bytes[32] = {
56 0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda,
57 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f,
58 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24,
59 0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb
60 };
61
62 u8 public_bytes[32] = {
63 0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a,
64 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc,
65 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c,
66 0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c
67 };
68
69 u8 message_bytes[1] = { 0x72 };
70
71 u8 signature_bytes[64] = {
72 0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8,
73 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40,
74 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f,
75 0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda,
76 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e,
77 0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c,
78 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee,
79 0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00
80 };
81
82 ReadonlyBytes private_key { private_bytes, 32 };
83 ReadonlyBytes public_key { public_bytes, 32 };
84 ReadonlyBytes message { message_bytes, 1 };
85 ReadonlyBytes expected_signature { signature_bytes, 64 };
86
87 Crypto::Curves::Ed25519 curve;
88
89 auto generated_signature = MUST(curve.sign(public_key, private_key, message));
90 EXPECT_EQ(generated_signature, expected_signature);
91 EXPECT_EQ(true, curve.verify(public_key, expected_signature, message));
92}
93
94TEST_CASE(TEST_3)
95{
96 // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1
97 u8 private_bytes[32] = {
98 0xc5, 0xaa, 0x8d, 0xf4, 0x3f, 0x9f, 0x83, 0x7b,
99 0xed, 0xb7, 0x44, 0x2f, 0x31, 0xdc, 0xb7, 0xb1,
100 0x66, 0xd3, 0x85, 0x35, 0x07, 0x6f, 0x09, 0x4b,
101 0x85, 0xce, 0x3a, 0x2e, 0x0b, 0x44, 0x58, 0xf7
102 };
103
104 u8 public_bytes[32] = {
105 0xfc, 0x51, 0xcd, 0x8e, 0x62, 0x18, 0xa1, 0xa3,
106 0x8d, 0xa4, 0x7e, 0xd0, 0x02, 0x30, 0xf0, 0x58,
107 0x08, 0x16, 0xed, 0x13, 0xba, 0x33, 0x03, 0xac,
108 0x5d, 0xeb, 0x91, 0x15, 0x48, 0x90, 0x80, 0x25
109 };
110
111 u8 message_bytes[2] = { 0xaf, 0x82 };
112
113 u8 signature_bytes[64] = {
114 0x62, 0x91, 0xd6, 0x57, 0xde, 0xec, 0x24, 0x02,
115 0x48, 0x27, 0xe6, 0x9c, 0x3a, 0xbe, 0x01, 0xa3,
116 0x0c, 0xe5, 0x48, 0xa2, 0x84, 0x74, 0x3a, 0x44,
117 0x5e, 0x36, 0x80, 0xd7, 0xdb, 0x5a, 0xc3, 0xac,
118 0x18, 0xff, 0x9b, 0x53, 0x8d, 0x16, 0xf2, 0x90,
119 0xae, 0x67, 0xf7, 0x60, 0x98, 0x4d, 0xc6, 0x59,
120 0x4a, 0x7c, 0x15, 0xe9, 0x71, 0x6e, 0xd2, 0x8d,
121 0xc0, 0x27, 0xbe, 0xce, 0xea, 0x1e, 0xc4, 0x0a
122 };
123
124 ReadonlyBytes private_key { private_bytes, 32 };
125 ReadonlyBytes public_key { public_bytes, 32 };
126 ReadonlyBytes message { message_bytes, 2 };
127 ReadonlyBytes expected_signature { signature_bytes, 64 };
128
129 Crypto::Curves::Ed25519 curve;
130
131 auto generated_signature = MUST(curve.sign(public_key, private_key, message));
132 EXPECT_EQ(generated_signature, expected_signature);
133 EXPECT_EQ(true, curve.verify(public_key, expected_signature, message));
134}
135
136TEST_CASE(TEST_SHA_ABC)
137{
138 // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1
139 u8 private_bytes[32] = {
140 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
141 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
142 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
143 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
144 };
145
146 u8 public_bytes[32] = {
147 0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
148 0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
149 0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
150 0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
151 };
152
153 u8 message_bytes[64] = {
154 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
155 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
156 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
157 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
158 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
159 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
160 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
161 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f
162 };
163
164 u8 signature_bytes[64] = {
165 0xdc, 0x2a, 0x44, 0x59, 0xe7, 0x36, 0x96, 0x33,
166 0xa5, 0x2b, 0x1b, 0xf2, 0x77, 0x83, 0x9a, 0x00,
167 0x20, 0x10, 0x09, 0xa3, 0xef, 0xbf, 0x3e, 0xcb,
168 0x69, 0xbe, 0xa2, 0x18, 0x6c, 0x26, 0xb5, 0x89,
169 0x09, 0x35, 0x1f, 0xc9, 0xac, 0x90, 0xb3, 0xec,
170 0xfd, 0xfb, 0xc7, 0xc6, 0x64, 0x31, 0xe0, 0x30,
171 0x3d, 0xca, 0x17, 0x9c, 0x13, 0x8a, 0xc1, 0x7a,
172 0xd9, 0xbe, 0xf1, 0x17, 0x73, 0x31, 0xa7, 0x04
173 };
174
175 ReadonlyBytes private_key { private_bytes, 32 };
176 ReadonlyBytes public_key { public_bytes, 32 };
177 ReadonlyBytes message { message_bytes, 64 };
178 ReadonlyBytes expected_signature { signature_bytes, 64 };
179
180 Crypto::Curves::Ed25519 curve;
181
182 auto generated_signature = MUST(curve.sign(public_key, private_key, message));
183 EXPECT_EQ(generated_signature, expected_signature);
184 EXPECT_EQ(true, curve.verify(public_key, expected_signature, message));
185}