253 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			253 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <tomcrypt_test.h>
 | 
						|
 | 
						|
#ifdef LTC_MECC
 | 
						|
 | 
						|
static int sizes[] = {
 | 
						|
#ifdef ECC112
 | 
						|
14,
 | 
						|
#endif
 | 
						|
#ifdef ECC128
 | 
						|
16,
 | 
						|
#endif
 | 
						|
#ifdef ECC160
 | 
						|
20,
 | 
						|
#endif
 | 
						|
#ifdef ECC192
 | 
						|
24,
 | 
						|
#endif
 | 
						|
#ifdef ECC224
 | 
						|
28,
 | 
						|
#endif
 | 
						|
#ifdef ECC256
 | 
						|
32,
 | 
						|
#endif
 | 
						|
#ifdef ECC384
 | 
						|
48,
 | 
						|
#endif
 | 
						|
#ifdef ECC521
 | 
						|
65
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
#ifdef LTC_ECC_SHAMIR
 | 
						|
int ecc_test_shamir(void)
 | 
						|
{
 | 
						|
   void *modulus, *mp, *kA, *kB, *rA, *rB;
 | 
						|
   ecc_point *G, *A, *B, *C1, *C2;
 | 
						|
   int x, y, z;
 | 
						|
   unsigned char buf[ECC_BUF_SIZE];
 | 
						|
 | 
						|
   DO(mp_init_multi(&kA, &kB, &rA, &rB, &modulus, NULL));
 | 
						|
   LTC_ARGCHK((G  = ltc_ecc_new_point()) != NULL);
 | 
						|
   LTC_ARGCHK((A  = ltc_ecc_new_point()) != NULL);
 | 
						|
   LTC_ARGCHK((B  = ltc_ecc_new_point()) != NULL);
 | 
						|
   LTC_ARGCHK((C1 = ltc_ecc_new_point()) != NULL);
 | 
						|
   LTC_ARGCHK((C2 = ltc_ecc_new_point()) != NULL);
 | 
						|
 | 
						|
   for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) {
 | 
						|
       /* get the base point */
 | 
						|
       for (z = 0; ltc_ecc_sets[z].name; z++) {
 | 
						|
           if (sizes[z] < ltc_ecc_sets[z].size) break;
 | 
						|
       }
 | 
						|
       LTC_ARGCHK(ltc_ecc_sets[z].name != NULL);
 | 
						|
 | 
						|
       /* load it */
 | 
						|
       DO(mp_read_radix(G->x, ltc_ecc_sets[z].Gx, 16));
 | 
						|
       DO(mp_read_radix(G->y, ltc_ecc_sets[z].Gy, 16));
 | 
						|
       DO(mp_set(G->z, 1));
 | 
						|
       DO(mp_read_radix(modulus, ltc_ecc_sets[z].prime, 16));
 | 
						|
       DO(mp_montgomery_setup(modulus, &mp));
 | 
						|
 | 
						|
       /* do 100 random tests */
 | 
						|
       for (y = 0; y < 100; y++) {
 | 
						|
          /* pick a random r1, r2 */
 | 
						|
          LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
 | 
						|
          DO(mp_read_unsigned_bin(rA, buf, sizes[x]));
 | 
						|
          LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
 | 
						|
          DO(mp_read_unsigned_bin(rB, buf, sizes[x]));
 | 
						|
 | 
						|
          /* compute rA * G = A */
 | 
						|
          DO(ltc_mp.ecc_ptmul(rA, G, A, modulus, 1));
 | 
						|
       
 | 
						|
          /* compute rB * G = B */
 | 
						|
          DO(ltc_mp.ecc_ptmul(rB, G, B, modulus, 1));
 | 
						|
 | 
						|
          /* pick a random kA, kB */
 | 
						|
          LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
 | 
						|
          DO(mp_read_unsigned_bin(kA, buf, sizes[x]));
 | 
						|
          LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]);
 | 
						|
          DO(mp_read_unsigned_bin(kB, buf, sizes[x]));
 | 
						|
 | 
						|
          /* now, compute kA*A + kB*B = C1 using the older method */
 | 
						|
          DO(ltc_mp.ecc_ptmul(kA, A, C1, modulus, 0));
 | 
						|
          DO(ltc_mp.ecc_ptmul(kB, B, C2, modulus, 0));
 | 
						|
          DO(ltc_mp.ecc_ptadd(C1, C2, C1, modulus, mp));
 | 
						|
          DO(ltc_mp.ecc_map(C1, modulus, mp));
 | 
						|
 | 
						|
          /* now compute using mul2add */
 | 
						|
          DO(ltc_mp.ecc_mul2add(A, kA, B, kB, C2, modulus));
 | 
						|
 | 
						|
          /* is they the sames?  */
 | 
						|
          if ((mp_cmp(C1->x, C2->x) != LTC_MP_EQ) || (mp_cmp(C1->y, C2->y) != LTC_MP_EQ) || (mp_cmp(C1->z, C2->z) != LTC_MP_EQ)) {
 | 
						|
             fprintf(stderr, "ECC failed shamir test: size=%d, testno=%d\n", sizes[x], y);
 | 
						|
             return 1;
 | 
						|
          }
 | 
						|
      }
 | 
						|
      mp_montgomery_free(mp);
 | 
						|
  }
 | 
						|
  ltc_ecc_del_point(C2);
 | 
						|
  ltc_ecc_del_point(C1);
 | 
						|
  ltc_ecc_del_point(B);
 | 
						|
  ltc_ecc_del_point(A);
 | 
						|
  ltc_ecc_del_point(G);
 | 
						|
  mp_clear_multi(kA, kB, rA, rB, modulus, NULL);
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
int ecc_tests (void)
 | 
						|
{
 | 
						|
  unsigned char buf[4][4096];
 | 
						|
  unsigned long x, y, z, s;
 | 
						|
  int           stat, stat2;
 | 
						|
  ecc_key usera, userb, pubKey, privKey;
 | 
						|
	
 | 
						|
  DO(ecc_test ());
 | 
						|
  DO(ecc_test ());
 | 
						|
  DO(ecc_test ());
 | 
						|
  DO(ecc_test ());
 | 
						|
  DO(ecc_test ());
 | 
						|
 | 
						|
  for (s = 0; s < (sizeof(sizes)/sizeof(sizes[0])); s++) {
 | 
						|
     /* make up two keys */
 | 
						|
     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
 | 
						|
     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb));
 | 
						|
 | 
						|
     /* make the shared secret */
 | 
						|
     x = sizeof(buf[0]);
 | 
						|
     DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
 | 
						|
 | 
						|
     y = sizeof(buf[1]);
 | 
						|
     DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
 | 
						|
 | 
						|
     if (y != x) {
 | 
						|
       fprintf(stderr, "ecc Shared keys are not same size.");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
 | 
						|
     if (memcmp (buf[0], buf[1], x)) {
 | 
						|
       fprintf(stderr, "ecc Shared keys not same contents.");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
 | 
						|
     /* now export userb */
 | 
						|
     y = sizeof(buf[0]);
 | 
						|
     DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
 | 
						|
     ecc_free (&userb);
 | 
						|
 | 
						|
     /* import and make the shared secret again */
 | 
						|
     DO(ecc_import (buf[1], y, &userb));
 | 
						|
 | 
						|
     z = sizeof(buf[0]);
 | 
						|
     DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
 | 
						|
 | 
						|
     if (z != x) {
 | 
						|
       fprintf(stderr, "failed.  Size don't match?");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
     if (memcmp (buf[0], buf[2], x)) {
 | 
						|
       fprintf(stderr, "Failed.  Contents didn't match.");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
 | 
						|
     /* export with ANSI X9.63 */
 | 
						|
     y = sizeof(buf[1]);
 | 
						|
     DO(ecc_ansi_x963_export(&userb, buf[1], &y));
 | 
						|
     ecc_free (&userb);
 | 
						|
 | 
						|
     /* now import the ANSI key */
 | 
						|
     DO(ecc_ansi_x963_import(buf[1], y, &userb));
 | 
						|
 | 
						|
     /* shared secret */
 | 
						|
     z = sizeof(buf[0]);
 | 
						|
     DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
 | 
						|
 | 
						|
     if (z != x) {
 | 
						|
       fprintf(stderr, "failed.  Size don't match?");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
     if (memcmp (buf[0], buf[2], x)) {
 | 
						|
       fprintf(stderr, "Failed.  Contents didn't match.");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
 | 
						|
     ecc_free (&usera);
 | 
						|
     ecc_free (&userb);
 | 
						|
 | 
						|
     /* test encrypt_key */
 | 
						|
     DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera));
 | 
						|
 | 
						|
     /* export key */
 | 
						|
     x = sizeof(buf[0]);
 | 
						|
     DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera));
 | 
						|
     DO(ecc_import(buf[0], x, &pubKey));
 | 
						|
     x = sizeof(buf[0]);
 | 
						|
     DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera));
 | 
						|
     DO(ecc_import(buf[0], x, &privKey));
 | 
						|
 | 
						|
     for (x = 0; x < 32; x++) {
 | 
						|
        buf[0][x] = x;
 | 
						|
     }
 | 
						|
     y = sizeof (buf[1]);
 | 
						|
     DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey));
 | 
						|
     zeromem (buf[0], sizeof (buf[0]));
 | 
						|
     x = sizeof (buf[0]);
 | 
						|
     DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey));
 | 
						|
     if (x != 32) {
 | 
						|
       fprintf(stderr, "Failed (length)");
 | 
						|
       return 1;
 | 
						|
     }
 | 
						|
     for (x = 0; x < 32; x++) {
 | 
						|
        if (buf[0][x] != x) {
 | 
						|
           fprintf(stderr, "Failed (contents)");
 | 
						|
           return 1;
 | 
						|
        }
 | 
						|
     }
 | 
						|
     /* test sign_hash */
 | 
						|
     for (x = 0; x < 16; x++) {
 | 
						|
        buf[0][x] = x;
 | 
						|
     }
 | 
						|
     x = sizeof (buf[1]);
 | 
						|
     DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey));
 | 
						|
     DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey));
 | 
						|
     buf[0][0] ^= 1;
 | 
						|
     DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey));
 | 
						|
     if (!(stat == 1 && stat2 == 0)) { 
 | 
						|
        fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2);
 | 
						|
        return 1;
 | 
						|
     }
 | 
						|
     ecc_free (&usera); 
 | 
						|
     ecc_free (&pubKey);
 | 
						|
     ecc_free (&privKey);
 | 
						|
  }
 | 
						|
#ifdef LTC_ECC_SHAMIR
 | 
						|
  return ecc_test_shamir();
 | 
						|
#else
 | 
						|
  return 0;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
int ecc_tests(void)
 | 
						|
{
 | 
						|
   fprintf(stderr, "NOP");
 | 
						|
   return 0;
 | 
						|
}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
/* $Source$ */
 | 
						|
/* $Revision$ */
 | 
						|
/* $Date$ */
 |