Home | History | Annotate | Download | only in curve25519
      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