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 <stdio.h> 17 #include <string.h> 18 19 #include <openssl/curve25519.h> 20 21 22 static bool TestX25519() { 23 /* Taken from 24 * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */ 25 static const uint8_t kScalar1[32] = { 26 0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15, 27 0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc, 28 0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4, 29 }; 30 static const uint8_t kPoint1[32] = { 31 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1, 32 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3, 33 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c, 34 }; 35 36 uint8_t out[32]; 37 X25519(out, kScalar1, kPoint1); 38 39 static const uint8_t kExpected1[32] = { 40 0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea, 41 0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c, 42 0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52, 43 }; 44 if (memcmp(kExpected1, out, sizeof(out)) != 0) { 45 fprintf(stderr, "X25519 test one failed.\n"); 46 return false; 47 } 48 49 static const uint8_t kScalar2[32] = { 50 0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26, 51 0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea, 52 0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d, 53 }; 54 static const uint8_t kPoint2[32] = { 55 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95, 56 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0, 57 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93, 58 }; 59 60 X25519(out, kScalar2, kPoint2); 61 62 static const uint8_t kExpected2[32] = { 63 0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4, 64 0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f, 65 0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57, 66 }; 67 if (memcmp(kExpected2, out, sizeof(out)) != 0) { 68 fprintf(stderr, "X25519 test two failed.\n"); 69 return false; 70 } 71 72 return true; 73 } 74 75 static bool TestX25519SmallOrder() { 76 static const uint8_t kSmallOrderPoint[32] = { 77 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 78 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 79 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 80 }; 81 82 uint8_t out[32], private_key[32]; 83 memset(private_key, 0x11, sizeof(private_key)); 84 85 if (X25519(out, private_key, kSmallOrderPoint)) { 86 fprintf(stderr, "X25519 returned success with a small-order input.\n"); 87 return false; 88 } 89 90 return true; 91 } 92 93 static bool TestX25519Iterated() { 94 /* Taken from 95 * https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */ 96 uint8_t scalar[32] = {9}, point[32] = {9}, out[32]; 97 98 unsigned i; 99 for (i = 0; i < 1000; i++) { 100 X25519(out, scalar, point); 101 memcpy(point, scalar, sizeof(point)); 102 memcpy(scalar, out, sizeof(scalar)); 103 } 104 105 static const uint8_t kExpected[32] = { 106 0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, 0x28, 0x00, 0xef, 107 0x56, 0x6f, 0x2f, 0x4d, 0x3c, 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, 108 0xe3, 0x87, 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51, 109 }; 110 111 if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) { 112 fprintf(stderr, "Iterated X25519 test failed\n"); 113 return false; 114 } 115 116 return true; 117 } 118 119 int main(int argc, char **argv) { 120 if (!TestX25519() || 121 !TestX25519Iterated() || 122 !TestX25519SmallOrder()) { 123 return 1; 124 } 125 126 printf("PASS\n"); 127 return 0; 128 } 129