xref: /openbsd-src/regress/lib/libcrypto/curve25519/x25519test.c (revision d20a2f80d6c4d0bcee8d4e0093faa01ff0fddfed)
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