1*d20a2f80Stb /* $OpenBSD: x25519test.c,v 1.3 2022/12/01 13:55:22 tb Exp $ */
28ef0e975Sjsing /*
38ef0e975Sjsing * Copyright (c) 2015, Google Inc.
48ef0e975Sjsing *
58ef0e975Sjsing * Permission to use, copy, modify, and/or distribute this software for any
68ef0e975Sjsing * purpose with or without fee is hereby granted, provided that the above
78ef0e975Sjsing * copyright notice and this permission notice appear in all copies.
88ef0e975Sjsing *
98ef0e975Sjsing * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
108ef0e975Sjsing * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
118ef0e975Sjsing * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
128ef0e975Sjsing * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
138ef0e975Sjsing * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
148ef0e975Sjsing * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
158ef0e975Sjsing * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
168ef0e975Sjsing */
178ef0e975Sjsing
188ef0e975Sjsing #include <stdint.h>
198ef0e975Sjsing #include <stdio.h>
208ef0e975Sjsing #include <string.h>
218ef0e975Sjsing
228ef0e975Sjsing #include <openssl/curve25519.h>
238ef0e975Sjsing
248ef0e975Sjsing static int
x25519_test(void)258ef0e975Sjsing x25519_test(void)
268ef0e975Sjsing {
278ef0e975Sjsing /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */
288ef0e975Sjsing static const uint8_t kScalar1[32] = {
298ef0e975Sjsing 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d,
308ef0e975Sjsing 0x3b, 0x16, 0x15, 0x4b, 0x82, 0x46, 0x5e, 0xdd,
318ef0e975Sjsing 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, 0x5a, 0x18,
328ef0e975Sjsing 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4,
338ef0e975Sjsing };
348ef0e975Sjsing static const uint8_t kPoint1[32] = {
358ef0e975Sjsing 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb,
368ef0e975Sjsing 0x35, 0x94, 0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c,
378ef0e975Sjsing 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 0x35, 0x3b,
388ef0e975Sjsing 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c,
398ef0e975Sjsing };
408ef0e975Sjsing static const uint8_t kExpected1[32] = {
418ef0e975Sjsing 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90,
428ef0e975Sjsing 0x8e, 0x94, 0xea, 0x4d, 0xf2, 0x8d, 0x08, 0x4f,
438ef0e975Sjsing 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c, 0x71, 0xf7,
448ef0e975Sjsing 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52,
458ef0e975Sjsing };
468ef0e975Sjsing static const uint8_t kScalar2[32] = {
478ef0e975Sjsing 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c,
488ef0e975Sjsing 0x5a, 0xd2, 0x26, 0x91, 0x95, 0x7d, 0x6a, 0xf5,
498ef0e975Sjsing 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea, 0x01, 0xd4,
508ef0e975Sjsing 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d,
518ef0e975Sjsing };
528ef0e975Sjsing static const uint8_t kPoint2[32] = {
538ef0e975Sjsing 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3,
548ef0e975Sjsing 0xf4, 0xb7, 0x95, 0x9d, 0x05, 0x38, 0xae, 0x2c,
558ef0e975Sjsing 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, 0x3c, 0x3e,
568ef0e975Sjsing 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93,
578ef0e975Sjsing };
588ef0e975Sjsing static const uint8_t kExpected2[32] = {
598ef0e975Sjsing 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d,
608ef0e975Sjsing 0x7a, 0xad, 0xe4, 0x5c, 0xb4, 0xb8, 0x73, 0xf8,
618ef0e975Sjsing 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f, 0xa1, 0x52,
628ef0e975Sjsing 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57,
638ef0e975Sjsing };
648ef0e975Sjsing
658ef0e975Sjsing uint8_t out[32];
668ef0e975Sjsing
678ef0e975Sjsing X25519(out, kScalar1, kPoint1);
688ef0e975Sjsing if (memcmp(kExpected1, out, sizeof(out)) != 0) {
698ef0e975Sjsing fprintf(stderr, "X25519 test one failed.\n");
70*d20a2f80Stb return 1;
718ef0e975Sjsing }
728ef0e975Sjsing
738ef0e975Sjsing X25519(out, kScalar2, kPoint2);
748ef0e975Sjsing if (memcmp(kExpected2, out, sizeof(out)) != 0) {
758ef0e975Sjsing fprintf(stderr, "X25519 test two failed.\n");
76*d20a2f80Stb return 1;
778ef0e975Sjsing }
788ef0e975Sjsing
79*d20a2f80Stb return 0;
808ef0e975Sjsing }
818ef0e975Sjsing
828ef0e975Sjsing static int
x25519_iterated_test(void)838ef0e975Sjsing x25519_iterated_test(void)
848ef0e975Sjsing {
858ef0e975Sjsing /* Taken from https://tools.ietf.org/html/rfc7748#section-5.2 */
868ef0e975Sjsing static const uint8_t kExpected[32] = {
878ef0e975Sjsing 0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55,
888ef0e975Sjsing 0x28, 0x00, 0xef, 0x56, 0x6f, 0x2f, 0x4d, 0x3c,
898ef0e975Sjsing 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, 0xe3, 0x87,
908ef0e975Sjsing 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51,
918ef0e975Sjsing };
928ef0e975Sjsing
938ef0e975Sjsing uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
948ef0e975Sjsing unsigned i;
958ef0e975Sjsing
968ef0e975Sjsing for (i = 0; i < 1000; i++) {
978ef0e975Sjsing X25519(out, scalar, point);
988ef0e975Sjsing memcpy(point, scalar, sizeof(point));
998ef0e975Sjsing memcpy(scalar, out, sizeof(scalar));
1008ef0e975Sjsing }
1018ef0e975Sjsing
1028ef0e975Sjsing if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) {
1038ef0e975Sjsing fprintf(stderr, "Iterated X25519 test failed\n");
104*d20a2f80Stb return 1;
1058ef0e975Sjsing }
1068ef0e975Sjsing
107*d20a2f80Stb return 0;
1088ef0e975Sjsing }
1098ef0e975Sjsing
1108ef0e975Sjsing static int
x25519_small_order_test(void)1118ef0e975Sjsing x25519_small_order_test(void)
1128ef0e975Sjsing {
1138ef0e975Sjsing static const uint8_t kSmallOrderPoint[32] = {
1148ef0e975Sjsing 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae,
1158ef0e975Sjsing 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
1168ef0e975Sjsing 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd,
1178ef0e975Sjsing 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00,
1188ef0e975Sjsing };
1198ef0e975Sjsing
1208ef0e975Sjsing uint8_t out[32], private_key[32];
1218ef0e975Sjsing
1228ef0e975Sjsing memset(private_key, 0x11, sizeof(private_key));
1238ef0e975Sjsing if (X25519(out, private_key, kSmallOrderPoint)) {
1248ef0e975Sjsing fprintf(stderr, "X25519 returned success with a small-order input.\n");
125*d20a2f80Stb return 1;
1268ef0e975Sjsing }
1278ef0e975Sjsing
128*d20a2f80Stb return 0;
1298ef0e975Sjsing }
1308ef0e975Sjsing
1318ef0e975Sjsing int
main(int argc,char ** argv)132*d20a2f80Stb main(int argc, char **argv)
133*d20a2f80Stb {
134*d20a2f80Stb int failed = 0;
1358ef0e975Sjsing
136*d20a2f80Stb failed |= x25519_test();
137*d20a2f80Stb failed |= x25519_iterated_test();
138*d20a2f80Stb failed |= x25519_small_order_test();
139*d20a2f80Stb
140*d20a2f80Stb return failed;
1418ef0e975Sjsing }
142