Ejemplo n.º 1
0
RCP<const Integer> carmichael(const RCP<const Integer> &n)
{
    if (n->is_zero())
        return integer(1);

    map_integer_uint prime_mul;
    integer_class lambda, t, p;
    unsigned multiplicity;

    prime_factor_multiplicities(prime_mul, *n);
    lambda = 1;
    for (const auto it : prime_mul) {
        p = it.first->as_integer_class();
        multiplicity = it.second;
        if (p == 2
            and multiplicity
                    > 2) { // For powers of 2 greater than 4 divide by 2.
            multiplicity--;
        }
        t = p - 1;
        mp_lcm(lambda, lambda, t);
        mp_pow_ui(t, p, multiplicity - 1);
        // lambda and p are relatively prime.
        lambda = lambda * t;
    }
    return integer(std::move(lambda));
}
Ejemplo n.º 2
0
/* lcm */
static int lcm(void *a, void *b, void *c)
{
   LTC_ARGCHK(a != NULL);
   LTC_ARGCHK(b != NULL);
   LTC_ARGCHK(c != NULL);
   return mpi_to_ltc_error(mp_lcm(a, b, c));
}
Ejemplo n.º 3
0
/* mostly taken from libtomcrypt's rsa key generation routine */
dropbear_rsa_key * gen_rsa_priv_key(unsigned int size) {

	dropbear_rsa_key * key;
	DEF_MP_INT(pminus);
	DEF_MP_INT(qminus);
	DEF_MP_INT(lcm);

	if (size < 512 || size > 4096 || (size % 8 != 0)) {
		dropbear_exit("Bits must satisfy 512 <= bits <= 4096, and be a"
			" multiple of 8");
	}

	key = m_malloc(sizeof(*key));
	m_mp_alloc_init_multi(&key->e, &key->n, &key->d, &key->p, &key->q, NULL);
	m_mp_init_multi(&pminus, &lcm, &qminus, NULL);

	if (mp_set_int(key->e, RSA_E) != MP_OKAY) {
		fprintf(stderr, "RSA generation failed\n");
		exit(1);
	}

	while (1) {
		getrsaprime(key->p, &pminus, key->e, size/16);
		getrsaprime(key->q, &qminus, key->e, size/16);

		if (mp_mul(key->p, key->q, key->n) != MP_OKAY) {
			fprintf(stderr, "RSA generation failed\n");
			exit(1);
		}

		if ((unsigned int)mp_count_bits(key->n) == size) {
			break;
		}
	}

	/* lcm(p-1, q-1) */
	if (mp_lcm(&pminus, &qminus, &lcm) != MP_OKAY) {
		fprintf(stderr, "RSA generation failed\n");
		exit(1);
	}

	/* de = 1 mod lcm(p-1,q-1) */
	/* therefore d = (e^-1) mod lcm(p-1,q-1) */
	if (mp_invmod(key->e, &lcm, key->d) != MP_OKAY) {
		fprintf(stderr, "RSA generation failed\n");
		exit(1);
	}

	mp_clear_multi(&pminus, &qminus, &lcm, NULL);

	return key;
}	
Ejemplo n.º 4
0
/* Make an RSA key for size bits, with e specified, 65537 is a good e */
int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng)
{
    mp_int p, q, tmp1, tmp2, tmp3;
    int    err;

    if (key == NULL || rng == NULL)
        return BAD_FUNC_ARG;

    if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
        return BAD_FUNC_ARG;

    if (e < 3 || (e & 1) == 0)
        return BAD_FUNC_ARG;

    if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
        return err;

    err = mp_set_int(&tmp3, e);

    /* make p */
    if (err == MP_OKAY) {
        do {
            err = rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */

            if (err == MP_OKAY)
                err = mp_sub_d(&p, 1, &tmp1);  /* tmp1 = p-1 */

            if (err == MP_OKAY)
                err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(p-1, e) */
        } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divdes p-1 */
    }

    /* make q */
    if (err == MP_OKAY) {
        do {
            err = rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */

            if (err == MP_OKAY)
                err = mp_sub_d(&q, 1, &tmp1);  /* tmp1 = q-1 */

            if (err == MP_OKAY)
                err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(q-1, e) */
        } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divdes q-1 */
    }

    if (err == MP_OKAY)
        err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);

    if (err == MP_OKAY)
        err = mp_init_multi(&key->dP, &key->dP, &key->u, NULL, NULL, NULL);

    if (err == MP_OKAY)
        err = mp_sub_d(&p, 1, &tmp2);  /* tmp2 = p-1 */

    if (err == MP_OKAY)
        err = mp_lcm(&tmp1, &tmp2, &tmp1);  /* tmp1 = lcm(p-1, q-1),last loop */

    /* make key */
    if (err == MP_OKAY)
        err = mp_set_int(&key->e, e);  /* key->e = e */

    if (err == MP_OKAY)                /* key->d = 1/e mod lcm(p-1, q-1) */
        err = mp_invmod(&key->e, &tmp1, &key->d);

    if (err == MP_OKAY)
        err = mp_mul(&p, &q, &key->n);  /* key->n = pq */

    if (err == MP_OKAY)
        err = mp_sub_d(&p, 1, &tmp1);

    if (err == MP_OKAY)
        err = mp_sub_d(&q, 1, &tmp2);

    if (err == MP_OKAY)
        err = mp_mod(&key->d, &tmp1, &key->dP);

    if (err == MP_OKAY)
        err = mp_mod(&key->d, &tmp2, &key->dQ);

    if (err == MP_OKAY)
        err = mp_invmod(&q, &p, &key->u);

    if (err == MP_OKAY)
        err = mp_copy(&p, &key->p);

    if (err == MP_OKAY)
        err = mp_copy(&q, &key->q);

    if (err == MP_OKAY)
        key->type = RSA_PRIVATE; 

    mp_clear(&tmp3); 
    mp_clear(&tmp2); 
    mp_clear(&tmp1); 
    mp_clear(&q); 
    mp_clear(&p);

    if (err != MP_OKAY) {
        FreeRsaKey(key);        
        return err;
    }

    return 0;
}
Ejemplo n.º 5
0
RCP<const Integer> lcm(const Integer &a, const Integer &b)
{
    integer_class c;
    mp_lcm(c, a.as_integer_class(), b.as_integer_class());
    return integer(std::move(c));
}
Ejemplo n.º 6
0
Archivo: mtest.c Proyecto: mkj/dropbear
int main(int argc, char *argv[])
{
   int n, tmp;
   long long max;
   mp_int a, b, c, d, e;
#ifdef MTEST_NO_FULLSPEED
   clock_t t1;
#endif
   char buf[4096];

   mp_init(&a);
   mp_init(&b);
   mp_init(&c);
   mp_init(&d);
   mp_init(&e);

   if (argc > 1) {
       max = strtol(argv[1], NULL, 0);
       if (max < 0) {
           if (max > -64) {
               max = (1 << -(max)) + 1;
           } else {
               max = 1;
           }
       } else if (max == 0) {
           max = 1;
       }
   }
   else {
       max = 0;
   }


   /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */
/*
   mp_set(&a, 1);
   for (n = 1; n < 8192; n++) {
       mp_mul(&a, &a, &c);
       printf("mul\n");
       mp_to64(&a, buf);
       printf("%s\n%s\n", buf, buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);

       mp_add_d(&a, 1, &a);
       mp_mul_2(&a, &a);
       mp_sub_d(&a, 1, &a);
   }
*/

#ifdef LTM_MTEST_REAL_RAND
   rng = fopen("/dev/urandom", "rb");
   if (rng == NULL) {
      rng = fopen("/dev/random", "rb");
      if (rng == NULL) {
         fprintf(stderr, "\nWarning:  stdin used as random source\n\n");
         rng = stdin;
      }
   }
#else
   srand(23);
#endif

#ifdef MTEST_NO_FULLSPEED
   t1 = clock();
#endif
   for (;;) {
#ifdef MTEST_NO_FULLSPEED
      if (clock() - t1 > CLOCKS_PER_SEC) {
         sleep(2);
         t1 = clock();
      }
#endif
       n = getRandChar() % 15;

       if (max != 0) {
           --max;
           if (max == 0)
             n = 255;
       }

   if (n == 0) {
       /* add tests */
       rand_num(&a);
       rand_num(&b);
       mp_add(&a, &b, &c);
       printf("add\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
   } else if (n == 1) {
      /* sub tests */
       rand_num(&a);
       rand_num(&b);
       mp_sub(&a, &b, &c);
       printf("sub\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
   } else if (n == 2) {
       /* mul tests */
       rand_num(&a);
       rand_num(&b);
       mp_mul(&a, &b, &c);
       printf("mul\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
   } else if (n == 3) {
      /* div tests */
       rand_num(&a);
       rand_num(&b);
       mp_div(&a, &b, &c, &d);
       printf("div\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
       mp_to64(&d, buf);
       printf("%s\n", buf);
   } else if (n == 4) {
      /* sqr tests */
       rand_num(&a);
       mp_sqr(&a, &b);
       printf("sqr\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
   } else if (n == 5) {
      /* mul_2d test */
      rand_num(&a);
      mp_copy(&a, &b);
      n = getRandChar() & 63;
      mp_mul_2d(&b, n, &b);
      mp_to64(&a, buf);
      printf("mul2d\n");
      printf("%s\n", buf);
      printf("%d\n", n);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 6) {
      /* div_2d test */
      rand_num(&a);
      mp_copy(&a, &b);
      n = getRandChar() & 63;
      mp_div_2d(&b, n, &b, NULL);
      mp_to64(&a, buf);
      printf("div2d\n");
      printf("%s\n", buf);
      printf("%d\n", n);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 7) {
      /* gcd test */
      rand_num(&a);
      rand_num(&b);
      a.sign = MP_ZPOS;
      b.sign = MP_ZPOS;
      mp_gcd(&a, &b, &c);
      printf("gcd\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
   } else if (n == 8) {
      /* lcm test */
      rand_num(&a);
      rand_num(&b);
      a.sign = MP_ZPOS;
      b.sign = MP_ZPOS;
      mp_lcm(&a, &b, &c);
      printf("lcm\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
   } else if (n == 9) {
      /* exptmod test */
      rand_num2(&a);
      rand_num2(&b);
      rand_num2(&c);
//      if (c.dp[0]&1) mp_add_d(&c, 1, &c);
      a.sign = b.sign = c.sign = 0;
      mp_exptmod(&a, &b, &c, &d);
      printf("expt\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
      mp_to64(&d, buf);
      printf("%s\n", buf);
   } else if (n == 10) {
      /* invmod test */
      do {
      rand_num2(&a);
      rand_num2(&b);
      b.sign = MP_ZPOS;
      a.sign = MP_ZPOS;
      mp_gcd(&a, &b, &c);
      } while (mp_cmp_d(&c, 1) != 0 || mp_cmp_d(&b, 1) == 0);
      mp_invmod(&a, &b, &c);
      printf("invmod\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
   } else if (n == 11) {
      rand_num(&a);
      mp_mul_2(&a, &a);
      mp_div_2(&a, &b);
      printf("div2\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 12) {
      rand_num2(&a);
      mp_mul_2(&a, &b);
      printf("mul2\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 13) {
      rand_num2(&a);
      tmp = abs(rand()) & THE_MASK;
      mp_add_d(&a, tmp, &b);
      printf("add_d\n");
      mp_to64(&a, buf);
      printf("%s\n%d\n", buf, tmp);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 14) {
      rand_num2(&a);
      tmp = abs(rand()) & THE_MASK;
      mp_sub_d(&a, tmp, &b);
      printf("sub_d\n");
      mp_to64(&a, buf);
      printf("%s\n%d\n", buf, tmp);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 255) {
      printf("exit\n");
      break;
   }

   }
#ifdef LTM_MTEST_REAL_RAND
   fclose(rng);
#endif
   return 0;
}
Ejemplo n.º 7
0
int main(void)
{
   mp_int a, b, c, d, e, f;
   unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n,
      gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t;
   unsigned rr;
   int i, n, err, cnt, ix, old_kara_m, old_kara_s;
   mp_digit mp;


   mp_init(&a);
   mp_init(&b);
   mp_init(&c);
   mp_init(&d);
   mp_init(&e);
   mp_init(&f);

   srand(time(NULL));

#if 0
   // test montgomery
   printf("Testing montgomery...\n");
   for (i = 1; i < 10; i++) {
      printf("Testing digit size: %d\n", i);
      for (n = 0; n < 1000; n++) {
         mp_rand(&a, i);
         a.dp[0] |= 1;

         // let's see if R is right
         mp_montgomery_calc_normalization(&b, &a);
         mp_montgomery_setup(&a, &mp);

         // now test a random reduction
         for (ix = 0; ix < 100; ix++) {
             mp_rand(&c, 1 + abs(rand()) % (2*i));
             mp_copy(&c, &d);
             mp_copy(&c, &e);

             mp_mod(&d, &a, &d);
             mp_montgomery_reduce(&c, &a, mp);
             mp_mulmod(&c, &b, &a, &c);

             if (mp_cmp(&c, &d) != MP_EQ) {
printf("d = e mod a, c = e MOD a\n");
mp_todecimal(&a, buf); printf("a = %s\n", buf);
mp_todecimal(&e, buf); printf("e = %s\n", buf);
mp_todecimal(&d, buf); printf("d = %s\n", buf);
mp_todecimal(&c, buf); printf("c = %s\n", buf);
printf("compare no compare!\n"); exit(EXIT_FAILURE); }
         }
      }
   }
   printf("done\n");

   // test mp_get_int
   printf("Testing: mp_get_int\n");
   for (i = 0; i < 1000; ++i) {
      t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF;
      mp_set_int(&a, t);
      if (t != mp_get_int(&a)) {
	 printf("mp_get_int() bad result!\n");
	 return 1;
      }
   }
   mp_set_int(&a, 0);
   if (mp_get_int(&a) != 0) {
      printf("mp_get_int() bad result!\n");
      return 1;
   }
   mp_set_int(&a, 0xffffffff);
   if (mp_get_int(&a) != 0xffffffff) {
      printf("mp_get_int() bad result!\n");
      return 1;
   }
   // test mp_sqrt
   printf("Testing: mp_sqrt\n");
   for (i = 0; i < 1000; ++i) {
      printf("%6d\r", i);
      fflush(stdout);
      n = (rand() & 15) + 1;
      mp_rand(&a, n);
      if (mp_sqrt(&a, &b) != MP_OKAY) {
	 printf("mp_sqrt() error!\n");
	 return 1;
      }
      mp_n_root(&a, 2, &a);
      if (mp_cmp_mag(&b, &a) != MP_EQ) {
	 printf("mp_sqrt() bad result!\n");
	 return 1;
      }
   }

   printf("\nTesting: mp_is_square\n");
   for (i = 0; i < 1000; ++i) {
      printf("%6d\r", i);
      fflush(stdout);

      /* test mp_is_square false negatives */
      n = (rand() & 7) + 1;
      mp_rand(&a, n);
      mp_sqr(&a, &a);
      if (mp_is_square(&a, &n) != MP_OKAY) {
	 printf("fn:mp_is_square() error!\n");
	 return 1;
      }
      if (n == 0) {
	 printf("fn:mp_is_square() bad result!\n");
	 return 1;
      }

      /* test for false positives */
      mp_add_d(&a, 1, &a);
      if (mp_is_square(&a, &n) != MP_OKAY) {
	 printf("fp:mp_is_square() error!\n");
	 return 1;
      }
      if (n == 1) {
	 printf("fp:mp_is_square() bad result!\n");
	 return 1;
      }

   }
   printf("\n\n");

   /* test for size */
   for (ix = 10; ix < 128; ix++) {
      printf("Testing (not safe-prime): %9d bits    \r", ix);
      fflush(stdout);
      err =
	 mp_prime_random_ex(&a, 8, ix,
			    (rand() & 1) ? LTM_PRIME_2MSB_OFF :
			    LTM_PRIME_2MSB_ON, myrng, NULL);
      if (err != MP_OKAY) {
	 printf("failed with err code %d\n", err);
	 return EXIT_FAILURE;
      }
      if (mp_count_bits(&a) != ix) {
	 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix);
	 return EXIT_FAILURE;
      }
   }

   for (ix = 16; ix < 128; ix++) {
      printf("Testing (   safe-prime): %9d bits    \r", ix);
      fflush(stdout);
      err =
	 mp_prime_random_ex(&a, 8, ix,
			    ((rand() & 1) ? LTM_PRIME_2MSB_OFF :
			     LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng,
			    NULL);
      if (err != MP_OKAY) {
	 printf("failed with err code %d\n", err);
	 return EXIT_FAILURE;
      }
      if (mp_count_bits(&a) != ix) {
	 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix);
	 return EXIT_FAILURE;
      }
      /* let's see if it's really a safe prime */
      mp_sub_d(&a, 1, &a);
      mp_div_2(&a, &a);
      mp_prime_is_prime(&a, 8, &cnt);
      if (cnt != MP_YES) {
	 printf("sub is not prime!\n");
	 return EXIT_FAILURE;
      }
   }

   printf("\n\n");

   mp_read_radix(&a, "123456", 10);
   mp_toradix_n(&a, buf, 10, 3);
   printf("a == %s\n", buf);
   mp_toradix_n(&a, buf, 10, 4);
   printf("a == %s\n", buf);
   mp_toradix_n(&a, buf, 10, 30);
   printf("a == %s\n", buf);


#if 0
   for (;;) {
      fgets(buf, sizeof(buf), stdin);
      mp_read_radix(&a, buf, 10);
      mp_prime_next_prime(&a, 5, 1);
      mp_toradix(&a, buf, 10);
      printf("%s, %lu\n", buf, a.dp[0] & 3);
   }
#endif

   /* test mp_cnt_lsb */
   printf("testing mp_cnt_lsb...\n");
   mp_set(&a, 1);
   for (ix = 0; ix < 1024; ix++) {
      if (mp_cnt_lsb(&a) != ix) {
	 printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a));
	 return 0;
      }
      mp_mul_2(&a, &a);
   }

/* test mp_reduce_2k */
   printf("Testing mp_reduce_2k...\n");
   for (cnt = 3; cnt <= 128; ++cnt) {
      mp_digit tmp;

      mp_2expt(&a, cnt);
      mp_sub_d(&a, 2, &a);	/* a = 2**cnt - 2 */


      printf("\nTesting %4d bits", cnt);
      printf("(%d)", mp_reduce_is_2k(&a));
      mp_reduce_2k_setup(&a, &tmp);
      printf("(%d)", tmp);
      for (ix = 0; ix < 1000; ix++) {
	 if (!(ix & 127)) {
	    printf(".");
	    fflush(stdout);
	 }
	 mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2);
	 mp_copy(&c, &b);
	 mp_mod(&c, &a, &c);
	 mp_reduce_2k(&b, &a, 2);
	 if (mp_cmp(&c, &b)) {
	    printf("FAILED\n");
	    exit(0);
	 }
      }
   }

/* test mp_div_3  */
   printf("Testing mp_div_3...\n");
   mp_set(&d, 3);
   for (cnt = 0; cnt < 10000;) {
      mp_digit r1, r2;

      if (!(++cnt & 127))
	 printf("%9d\r", cnt);
      mp_rand(&a, abs(rand()) % 128 + 1);
      mp_div(&a, &d, &b, &e);
      mp_div_3(&a, &c, &r2);

      if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) {
	 printf("\n\nmp_div_3 => Failure\n");
      }
   }
   printf("\n\nPassed div_3 testing\n");

/* test the DR reduction */
   printf("testing mp_dr_reduce...\n");
   for (cnt = 2; cnt < 32; cnt++) {
      printf("%d digit modulus\n", cnt);
      mp_grow(&a, cnt);
      mp_zero(&a);
      for (ix = 1; ix < cnt; ix++) {
	 a.dp[ix] = MP_MASK;
      }
      a.used = cnt;
      a.dp[0] = 3;

      mp_rand(&b, cnt - 1);
      mp_copy(&b, &c);

      rr = 0;
      do {
	 if (!(rr & 127)) {
	    printf("%9lu\r", rr);
	    fflush(stdout);
	 }
	 mp_sqr(&b, &b);
	 mp_add_d(&b, 1, &b);
	 mp_copy(&b, &c);

	 mp_mod(&b, &a, &b);
	 mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]);

	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("Failed on trial %lu\n", rr);
	    exit(-1);

	 }
      } while (++rr < 500);
      printf("Passed DR test for %d digits\n", cnt);
   }

#endif

/* test the mp_reduce_2k_l code */
#if 0
#if 0
/* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */
   mp_2expt(&a, 1024);
   mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16);
   mp_sub(&a, &b, &a);
#elif 1
/*  p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F  */
   mp_2expt(&a, 2048);
   mp_read_radix(&b,
		 "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F",
		 16);
   mp_sub(&a, &b, &a);
#endif

   mp_todecimal(&a, buf);
   printf("p==%s\n", buf);
/* now mp_reduce_is_2k_l() should return */
   if (mp_reduce_is_2k_l(&a) != 1) {
      printf("mp_reduce_is_2k_l() return 0, should be 1\n");
      return EXIT_FAILURE;
   }
   mp_reduce_2k_setup_l(&a, &d);
   /* now do a million square+1 to see if it varies */
   mp_rand(&b, 64);
   mp_mod(&b, &a, &b);
   mp_copy(&b, &c);
   printf("testing mp_reduce_2k_l...");
   fflush(stdout);
   for (cnt = 0; cnt < (1UL << 20); cnt++) {
      mp_sqr(&b, &b);
      mp_add_d(&b, 1, &b);
      mp_reduce_2k_l(&b, &a, &d);
      mp_sqr(&c, &c);
      mp_add_d(&c, 1, &c);
      mp_mod(&c, &a, &c);
      if (mp_cmp(&b, &c) != MP_EQ) {
	 printf("mp_reduce_2k_l() failed at step %lu\n", cnt);
	 mp_tohex(&b, buf);
	 printf("b == %s\n", buf);
	 mp_tohex(&c, buf);
	 printf("c == %s\n", buf);
	 return EXIT_FAILURE;
      }
   }
   printf("...Passed\n");
#endif

   div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =
      sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n =
      sub_d_n = 0;

   /* force KARA and TOOM to enable despite cutoffs */
   KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8;
   TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16;

   for (;;) {
      /* randomly clear and re-init one variable, this has the affect of triming the alloc space */
      switch (abs(rand()) % 7) {
      case 0:
	 mp_clear(&a);
	 mp_init(&a);
	 break;
      case 1:
	 mp_clear(&b);
	 mp_init(&b);
	 break;
      case 2:
	 mp_clear(&c);
	 mp_init(&c);
	 break;
      case 3:
	 mp_clear(&d);
	 mp_init(&d);
	 break;
      case 4:
	 mp_clear(&e);
	 mp_init(&e);
	 break;
      case 5:
	 mp_clear(&f);
	 mp_init(&f);
	 break;
      case 6:
	 break;			/* don't clear any */
      }


      printf
	 ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ",
	  add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n,
	  expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n);
      fgets(cmd, 4095, stdin);
      cmd[strlen(cmd) - 1] = 0;
      printf("%s  ]\r", cmd);
      fflush(stdout);
      if (!strcmp(cmd, "mul2d")) {
	 ++mul2d_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 sscanf(buf, "%d", &rr);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);

	 mp_mul_2d(&a, rr, &a);
	 a.sign = b.sign;
	 if (mp_cmp(&a, &b) != MP_EQ) {
	    printf("mul2d failed, rr == %d\n", rr);
	    draw(&a);
	    draw(&b);
	    return 0;
	 }
      } else if (!strcmp(cmd, "div2d")) {
	 ++div2d_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 sscanf(buf, "%d", &rr);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);

	 mp_div_2d(&a, rr, &a, &e);
	 a.sign = b.sign;
	 if (a.used == b.used && a.used == 0) {
	    a.sign = b.sign = MP_ZPOS;
	 }
	 if (mp_cmp(&a, &b) != MP_EQ) {
	    printf("div2d failed, rr == %d\n", rr);
	    draw(&a);
	    draw(&b);
	    return 0;
	 }
      } else if (!strcmp(cmd, "add")) {
	 ++add_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_add(&d, &b, &d);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("add %lu failure!\n", add_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return 0;
	 }

	 /* test the sign/unsigned storage functions */

	 rr = mp_signed_bin_size(&c);
	 mp_to_signed_bin(&c, (unsigned char *) cmd);
	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
	 mp_read_signed_bin(&d, (unsigned char *) cmd, rr);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("mp_signed_bin failure!\n");
	    draw(&c);
	    draw(&d);
	    return 0;
	 }


	 rr = mp_unsigned_bin_size(&c);
	 mp_to_unsigned_bin(&c, (unsigned char *) cmd);
	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
	 mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr);
	 if (mp_cmp_mag(&c, &d) != MP_EQ) {
	    printf("mp_unsigned_bin failure!\n");
	    draw(&c);
	    draw(&d);
	    return 0;
	 }

      } else if (!strcmp(cmd, "sub")) {
	 ++sub_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_sub(&d, &b, &d);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("sub %lu failure!\n", sub_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return 0;
	 }
      } else if (!strcmp(cmd, "mul")) {
	 ++mul_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_mul(&d, &b, &d);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("mul %lu failure!\n", mul_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return 0;
	 }
      } else if (!strcmp(cmd, "div")) {
	 ++div_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&d, buf, 64);

	 mp_div(&a, &b, &e, &f);
	 if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) {
	    printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e),
		   mp_cmp(&d, &f));
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    draw(&e);
	    draw(&f);
	    return 0;
	 }

      } else if (!strcmp(cmd, "sqr")) {
	 ++sqr_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 mp_copy(&a, &c);
	 mp_sqr(&c, &c);
	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("sqr %lu failure!\n", sqr_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    return 0;
	 }
      } else if (!strcmp(cmd, "gcd")) {
	 ++gcd_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_gcd(&d, &b, &d);
	 d.sign = c.sign;
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("gcd %lu failure!\n", gcd_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return 0;
	 }
      } else if (!strcmp(cmd, "lcm")) {
	 ++lcm_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_lcm(&d, &b, &d);
	 d.sign = c.sign;
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("lcm %lu failure!\n", lcm_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return 0;
	 }
      } else if (!strcmp(cmd, "expt")) {
	 ++expt_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&d, buf, 64);
	 mp_copy(&a, &e);
	 mp_exptmod(&e, &b, &c, &e);
	 if (mp_cmp(&d, &e) != MP_EQ) {
	    printf("expt %lu failure!\n", expt_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    draw(&e);
	    return 0;
	 }
      } else if (!strcmp(cmd, "invmod")) {
	 ++inv_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&c, buf, 64);
	 mp_invmod(&a, &b, &d);
	 mp_mulmod(&d, &a, &b, &e);
	 if (mp_cmp_d(&e, 1) != MP_EQ) {
	    printf("inv [wrong value from MPI?!] failure\n");
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    mp_gcd(&a, &b, &e);
	    draw(&e);
	    return 0;
	 }

      } else if (!strcmp(cmd, "div2")) {
	 ++div2_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 mp_div_2(&a, &c);
	 if (mp_cmp(&c, &b) != MP_EQ) {
	    printf("div_2 %lu failure\n", div2_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    return 0;
	 }
      } else if (!strcmp(cmd, "mul2")) {
	 ++mul2_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 mp_mul_2(&a, &c);
	 if (mp_cmp(&c, &b) != MP_EQ) {
	    printf("mul_2 %lu failure\n", mul2_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    return 0;
	 }
      } else if (!strcmp(cmd, "add_d")) {
	 ++add_d_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 sscanf(buf, "%d", &ix);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 mp_add_d(&a, ix, &c);
	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("add_d %lu failure\n", add_d_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    printf("d == %d\n", ix);
	    return 0;
	 }
      } else if (!strcmp(cmd, "sub_d")) {
	 ++sub_d_n;
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&a, buf, 64);
	 fgets(buf, 4095, stdin);
	 sscanf(buf, "%d", &ix);
	 fgets(buf, 4095, stdin);
	 mp_read_radix(&b, buf, 64);
	 mp_sub_d(&a, ix, &c);
	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("sub_d %lu failure\n", sub_d_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    printf("d == %d\n", ix);
	    return 0;
	 }
      }
   }
   return 0;
}
Ejemplo n.º 8
0
/** 
   Create a Katja key
   @param prng     An active PRNG state
   @param wprng    The index of the PRNG desired
   @param size     The size of the modulus (key size) desired (octets)
   @param key      [out] Destination of a newly created private key pair
   @return CRYPT_OK if successful, upon error all allocated ram is freed
*/
int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key)
{
   void *p, *q, *tmp1, *tmp2;
   int    err;
  
   LTC_ARGCHK(key != NULL);
   LTC_ARGCHK(ltc_mp.name != NULL);

   if ((size < (MIN_KAT_SIZE/8)) || (size > (MAX_KAT_SIZE/8))) {
      return CRYPT_INVALID_KEYSIZE;
   }

   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }

   if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, NULL)) != CRYPT_OK) {
      return err;
   }

   /* divide size by three  */
   size   = (((size << 3) / 3) + 7) >> 3;

   /* make prime "q" (we negate size to make q == 3 mod 4) */
   if ((err = rand_prime(q, -size, prng, wprng)) != CRYPT_OK)      { goto done; }
   if ((err = mp_sub_d(q, 1, tmp1)) != CRYPT_OK)                   { goto done; }

   /* make prime "p" */
   do {
      if ((err = rand_prime(p, size+1, prng, wprng)) != CRYPT_OK)  { goto done; }
      if ((err = mp_gcd(p, tmp1, tmp2)) != CRYPT_OK)               { goto done; }
   } while (mp_cmp_d(tmp2, 1) != LTC_MP_EQ);

   /* make key */
   if ((err = mp_init_multi(&key->d, &key->N, &key->dQ, &key->dP,
                     &key->qP, &key->p, &key->q, &key->pq, NULL)) != CRYPT_OK) {
      goto error;
   }

   /* n=p^2q and 1/n mod pq */
   if ((err = mp_copy( p,  key->p)) != CRYPT_OK)                       { goto error2; }
   if ((err = mp_copy( q,  key->q)) != CRYPT_OK)                       { goto error2; }
   if ((err = mp_mul(key->p, key->q, key->pq)) != CRYPT_OK)            { goto error2; } /* tmp1 = pq  */
   if ((err = mp_mul(key->pq, key->p, key->N)) != CRYPT_OK)            { goto error2; } /* N = p^2q   */  
   if ((err = mp_sub_d( p, 1,  tmp1)) != CRYPT_OK)                     { goto error2; } /* tmp1 = q-1 */
   if ((err = mp_sub_d( q, 1,  tmp2)) != CRYPT_OK)                     { goto error2; } /* tmp2 = p-1 */
   if ((err = mp_lcm(tmp1, tmp2, key->d)) != CRYPT_OK)                 { goto error2; } /* tmp1 = lcd(p-1,q-1) */
   if ((err = mp_invmod( key->N,  key->d,  key->d)) != CRYPT_OK)       { goto error2; } /* key->d = 1/N mod pq */

   /* optimize for CRT now */
   /* find d mod q-1 and d mod p-1 */
   if ((err = mp_mod( key->d,  tmp1,  key->dP)) != CRYPT_OK)           { goto error2; } /* dP = d mod p-1 */
   if ((err = mp_mod( key->d,  tmp2,  key->dQ)) != CRYPT_OK)           { goto error2; } /* dQ = d mod q-1 */
   if ((err = mp_invmod( q,  p,  key->qP)) != CRYPT_OK)                { goto error2; } /* qP = 1/q mod p */

   /* set key type (in this case it's CRT optimized) */
   key->type = PK_PRIVATE;

   /* return ok and free temps */
   err       = CRYPT_OK;
   goto done;
error2:
   mp_clear_multi( key->d,  key->N,  key->dQ,  key->dP,  key->qP,  key->p,  key->q, key->pq, NULL);
error:
done:
   mp_clear_multi( tmp2,  tmp1,  p,  q, NULL);
   return err;
}
Ejemplo n.º 9
0
/** 
   Create an RSA key
   @param size     The size of the modulus (key size) desired (octets)
   @param e        The "e" value (public key).  e==65537 is a good choice
   @param key      [out] Destination of a newly created private key pair
   @return CRYPT_OK if successful, upon error all allocated ram is freed
*/
int rsa_make_key(int size, long e, rsa_key * key)
{
	mp_int p, q, tmp1, tmp2, tmp3;
	int err;

	LTC_ARGCHK(key != NULL);

	if ((size < (MIN_RSA_SIZE / 8)) || (size > (MAX_RSA_SIZE / 8))) {
		return CRYPT_INVALID_KEYSIZE;
	}

	if ((e < 3) || ((e & 1) == 0)) {
		return CRYPT_INVALID_ARG;
	}

	if ((err =
	     mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) {
		return err;
	}

	/* make primes p and q (optimization provided by Wayne Scott) */
	if ((err = mp_set_int(&tmp3, e)) != CRYPT_OK) {
		goto cleanup;
	}

	/* tmp3 = e */
	/* make prime "p" */
	do {
		if ((err = rand_prime(&p, size / 2)) != CRYPT_OK) {
			goto cleanup;
		}
		if ((err = mp_sub_d(&p, 1, &tmp1)) != CRYPT_OK) {
			goto cleanup;
		}		/* tmp1 = p-1 */
		if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != CRYPT_OK) {
			goto cleanup;
		}		/* tmp2 = gcd(p-1, e) */
	} while (mp_cmp_d(&tmp2, 1) != 0);	/* while e divides p-1 */

	/* make prime "q" */
	do {
		if ((err = rand_prime(&q, size / 2)) != CRYPT_OK) {
			goto cleanup;
		}
		if ((err = mp_sub_d(&q, 1, &tmp1)) != CRYPT_OK) {
			goto cleanup;
		}		/* tmp1 = q-1 */
		if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != CRYPT_OK) {
			goto cleanup;
		}		/* tmp2 = gcd(q-1, e) */
	} while (mp_cmp_d(&tmp2, 1) != 0);	/* while e divides q-1 */

	/* tmp1 = lcm(p-1, q-1) */
	if ((err = mp_sub_d(&p, 1, &tmp2)) != CRYPT_OK) {
		goto cleanup;
	}
	/* tmp2 = p-1 */
	/* tmp1 = q-1 (previous do/while loop) */
	if ((err = mp_lcm(&tmp1, &tmp2, &tmp1)) != CRYPT_OK) {
		goto cleanup;
	}

	/* tmp1 = lcm(p-1, q-1) */
	/* make key */
	if ((err =
	     mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
			   &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) {
		goto cleanup;
	}

	if ((err = mp_set_int(&key->e, e)) != CRYPT_OK) {
		goto errkey;
	}			/* key->e =  e */
	if ((err = mp_invmod(&key->e, &tmp1, &key->d)) != CRYPT_OK) {
		goto errkey;
	}			/* key->d = 1/e mod lcm(p-1,q-1) */
	if ((err = mp_mul(&p, &q, &key->N)) != CRYPT_OK) {
		goto errkey;
	}

	/* key->N = pq */
	/* optimize for CRT now */
	/* find d mod q-1 and d mod p-1 */
	if ((err = mp_sub_d(&p, 1, &tmp1)) != CRYPT_OK) {
		goto errkey;
	}			/* tmp1 = q-1 */
	if ((err = mp_sub_d(&q, 1, &tmp2)) != CRYPT_OK) {
		goto errkey;
	}			/* tmp2 = p-1 */
	if ((err = mp_mod(&key->d, &tmp1, &key->dP)) != CRYPT_OK) {
		goto errkey;
	}			/* dP = d mod p-1 */
	if ((err = mp_mod(&key->d, &tmp2, &key->dQ)) != CRYPT_OK) {
		goto errkey;
	}			/* dQ = d mod q-1 */
	if ((err = mp_invmod(&q, &p, &key->qP)) != CRYPT_OK) {
		goto errkey;
	}
	/* qP = 1/q mod p */
	if ((err = mp_copy(&p, &key->p)) != CRYPT_OK) {
		goto errkey;
	}
	if ((err = mp_copy(&q, &key->q)) != CRYPT_OK) {
		goto errkey;
	}

	/* set key type (in this case it's CRT optimized) */
	key->type = PK_PRIVATE;

	/* return ok and free temps */
	err = CRYPT_OK;
	goto cleanup;
errkey:
	mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP, &key->qP,
		       &key->p, &key->q, NULL);
cleanup:
	mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL);
	return err;
}
Ejemplo n.º 10
0
int main(void)
{
   int n, tmp;
   mp_int a, b, c, d, e;
   clock_t t1;
   char buf[4096];

   mp_init(&a);
   mp_init(&b);
   mp_init(&c);
   mp_init(&d);
   mp_init(&e);


   /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */
/*
   mp_set(&a, 1);
   for (n = 1; n < 8192; n++) {
       mp_mul(&a, &a, &c);
       printf("mul\n");
       mp_to64(&a, buf);
       printf("%s\n%s\n", buf, buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);

       mp_add_d(&a, 1, &a);
       mp_mul_2(&a, &a);
       mp_sub_d(&a, 1, &a);
   }
*/

   rng = fopen("/dev/urandom", "rb");
   if (rng == NULL) {
      rng = fopen("/dev/random", "rb");
      if (rng == NULL) {
         fprintf(stderr, "\nWarning:  stdin used as random source\n\n");
         rng = stdin;
      }
   }

   t1 = clock();
   for (;;) {
#if 0
      if (clock() - t1 > CLOCKS_PER_SEC) {
         sleep(2);
         t1 = clock();
      }
#endif
       n = fgetc(rng) % 15;

   if (n == 0) {
       /* add tests */
       rand_num(&a);
       rand_num(&b);
       mp_add(&a, &b, &c);
       printf("add\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
   } else if (n == 1) {
      /* sub tests */
       rand_num(&a);
       rand_num(&b);
       mp_sub(&a, &b, &c);
       printf("sub\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
   } else if (n == 2) {
       /* mul tests */
       rand_num(&a);
       rand_num(&b);
       mp_mul(&a, &b, &c);
       printf("mul\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
   } else if (n == 3) {
      /* div tests */
       rand_num(&a);
       rand_num(&b);
       mp_div(&a, &b, &c, &d);
       printf("div\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
       mp_to64(&c, buf);
       printf("%s\n", buf);
       mp_to64(&d, buf);
       printf("%s\n", buf);
   } else if (n == 4) {
      /* sqr tests */
       rand_num(&a);
       mp_sqr(&a, &b);
       printf("sqr\n");
       mp_to64(&a, buf);
       printf("%s\n", buf);
       mp_to64(&b, buf);
       printf("%s\n", buf);
   } else if (n == 5) {
      /* mul_2d test */
      rand_num(&a);
      mp_copy(&a, &b);
      n = fgetc(rng) & 63;
      mp_mul_2d(&b, n, &b);
      mp_to64(&a, buf);
      printf("mul2d\n");
      printf("%s\n", buf);
      printf("%d\n", n);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 6) {
      /* div_2d test */
      rand_num(&a);
      mp_copy(&a, &b);
      n = fgetc(rng) & 63;
      mp_div_2d(&b, n, &b, NULL);
      mp_to64(&a, buf);
      printf("div2d\n");
      printf("%s\n", buf);
      printf("%d\n", n);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 7) {
      /* gcd test */
      rand_num(&a);
      rand_num(&b);
      a.sign = MP_ZPOS;
      b.sign = MP_ZPOS;
      mp_gcd(&a, &b, &c);
      printf("gcd\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
   } else if (n == 8) {
      /* lcm test */
      rand_num(&a);
      rand_num(&b);
      a.sign = MP_ZPOS;
      b.sign = MP_ZPOS;
      mp_lcm(&a, &b, &c);
      printf("lcm\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
   } else if (n == 9) {
      /* exptmod test */
      rand_num2(&a);
      rand_num2(&b);
      rand_num2(&c);
//      if (c.dp[0]&1) mp_add_d(&c, 1, &c);
      a.sign = b.sign = c.sign = 0;
      mp_exptmod(&a, &b, &c, &d);
      printf("expt\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
      mp_to64(&d, buf);
      printf("%s\n", buf);
   } else if (n == 10) {
      /* invmod test */
      rand_num2(&a);
      rand_num2(&b);
      b.sign = MP_ZPOS;
      a.sign = MP_ZPOS;
      mp_gcd(&a, &b, &c);
      if (mp_cmp_d(&c, 1) != 0) continue;
      if (mp_cmp_d(&b, 1) == 0) continue;
      mp_invmod(&a, &b, &c);
      printf("invmod\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
      mp_to64(&c, buf);
      printf("%s\n", buf);
   } else if (n == 11) {
      rand_num(&a);
      mp_mul_2(&a, &a);
      mp_div_2(&a, &b);
      printf("div2\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 12) {
      rand_num2(&a);
      mp_mul_2(&a, &b);
      printf("mul2\n");
      mp_to64(&a, buf);
      printf("%s\n", buf);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 13) {
      rand_num2(&a);
      tmp = abs(rand()) & THE_MASK;
      mp_add_d(&a, tmp, &b);
      printf("add_d\n");
      mp_to64(&a, buf);
      printf("%s\n%d\n", buf, tmp);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   } else if (n == 14) {
      rand_num2(&a);
      tmp = abs(rand()) & THE_MASK;
      mp_sub_d(&a, tmp, &b);
      printf("sub_d\n");
      mp_to64(&a, buf);
      printf("%s\n%d\n", buf, tmp);
      mp_to64(&b, buf);
      printf("%s\n", buf);
   }
   }
   fclose(rng);
   return 0;
}
Ejemplo n.º 11
0
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
{
   mp_int p, q, tmp1, tmp2, tmp3;
   int res, err;

   _ARGCHK(key != NULL);

   if ((size < (1024/8)) || (size > (4096/8))) {
      return CRYPT_INVALID_KEYSIZE;
   }

   if ((e < 3) || ((e & 1) == 0)) {
      return CRYPT_INVALID_ARG;
   }

   if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
      return err;
   }

   if (mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL) != MP_OKAY) {
      return CRYPT_MEM;
   }

   /* make primes p and q (optimization provided by Wayne Scott) */
   if (mp_set_int(&tmp3, e) != MP_OKAY) { goto error; }            /* tmp3 = e */

   /* make prime "p" */
   do {
       if (rand_prime(&p, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
       if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY)              { goto error; }  /* tmp1 = p-1 */
       if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; }  /* tmp2 = gcd(p-1, e) */
   } while (mp_cmp_d(&tmp2, 1) != 0);                                       /* while e divides p-1 */

   /* make prime "q" */
   do {
       if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
       if (mp_sub_d(&q, 1, &tmp1) != MP_OKAY)              { goto error; } /* tmp1 = q-1 */
       if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; } /* tmp2 = gcd(q-1, e) */
   } while (mp_cmp_d(&tmp2, 1) != 0);                                      /* while e divides q-1 */

   /* tmp1 = lcm(p-1, q-1) */
   if (mp_sub_d(&p, 1, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = p-1 */
                                                                           /* tmp1 = q-1 (previous do/while loop) */
   if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY)             { goto error; } /* tmp1 = lcm(p-1, q-1) */

   /* make key */
   if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
                     &key->qP, &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
      goto error;
   }

   if (mp_set_int(&key->e, e) != MP_OKAY)                  { goto error2; } /* key->e =  e */
   if (mp_invmod(&key->e, &tmp1, &key->d) != MP_OKAY)      { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */
   if (mp_mul(&p, &q, &key->N) != MP_OKAY)                 { goto error2; } /* key->N = pq */

/* optimize for CRT now */
   /* find d mod q-1 and d mod p-1 */
   if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY)                  { goto error2; } /* tmp1 = q-1 */
   if (mp_sub_d(&q, 1, &tmp2) != MP_OKAY)                  { goto error2; } /* tmp2 = p-1 */

   if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY)        { goto error2; } /* dP = d mod p-1 */
   if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY)        { goto error2; } /* dQ = d mod q-1 */

   if (mp_invmod(&q, &p, &key->qP) != MP_OKAY)             { goto error2; } /* qP = 1/q mod p */
   if (mp_mulmod(&key->qP, &q, &key->N, &key->qP))         { goto error2; } /* qP = q * (1/q mod p) mod N */

   if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY)             { goto error2; } /* pQ = 1/p mod q */
   if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ))         { goto error2; } /* pQ = p * (1/p mod q) mod N */

   if (mp_copy(&p, &key->p) != MP_OKAY)                    { goto error2; }
   if (mp_copy(&q, &key->q) != MP_OKAY)                    { goto error2; }

   /* shrink ram required  */
   if (mp_shrink(&key->e) != MP_OKAY)                      { goto error2; }
   if (mp_shrink(&key->d) != MP_OKAY)                      { goto error2; }
   if (mp_shrink(&key->N) != MP_OKAY)                      { goto error2; }
   if (mp_shrink(&key->dQ) != MP_OKAY)                     { goto error2; }
   if (mp_shrink(&key->dP) != MP_OKAY)                     { goto error2; }
   if (mp_shrink(&key->qP) != MP_OKAY)                     { goto error2; }
   if (mp_shrink(&key->pQ) != MP_OKAY)                     { goto error2; }
   if (mp_shrink(&key->p) != MP_OKAY)                      { goto error2; }
   if (mp_shrink(&key->q) != MP_OKAY)                      { goto error2; }

   res = CRYPT_OK;
   key->type = PK_PRIVATE_OPTIMIZED;
   goto done;
error2:
   mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
                  &key->qP, &key->pQ, &key->p, &key->q, NULL);
error:
   res = CRYPT_MEM;
done:
   mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL);
   return res;
}
Ejemplo n.º 12
0
BigNum BigNum::Lcm(const BigNum &other) const {
    BigNum result;
    mp_lcm(*this, other, result);
    return result;
}
Ejemplo n.º 13
0
Archivo: demo.c Proyecto: mkj/dropbear
int main(void)
{
   unsigned rr;
   int cnt, ix;
#if LTM_DEMO_TEST_VS_MTEST
   unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n,
      gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n;
   char* ret;
#else
   unsigned long s, t;
   unsigned long long q, r;
   mp_digit mp;
   int i, n, err, should;
#endif

   if (mp_init_multi(&a, &b, &c, &d, &e, &f, NULL)!= MP_OKAY)
     return EXIT_FAILURE;

   atexit(_cleanup);

#if defined(LTM_DEMO_REAL_RAND)
   if (!fd_urandom) {
      fd_urandom = fopen("/dev/urandom", "r");
      if (!fd_urandom) {
#if !defined(_WIN32)
         fprintf(stderr, "\ncould not open /dev/urandom\n");
#endif
      }
   }
#endif
   srand(LTM_DEMO_RAND_SEED);

#ifdef MP_8BIT
   printf("Digit size 8 Bit \n");
#endif
#ifdef MP_16BIT
   printf("Digit size 16 Bit \n");
#endif
#ifdef MP_32BIT
   printf("Digit size 32 Bit \n");
#endif
#ifdef MP_64BIT
   printf("Digit size 64 Bit \n");
#endif
   printf("Size of mp_digit: %u\n", (unsigned int)sizeof(mp_digit));
   printf("Size of mp_word: %u\n", (unsigned int)sizeof(mp_word));
   printf("DIGIT_BIT: %d\n", DIGIT_BIT);
   printf("MP_PREC: %d\n", MP_PREC);

#if LTM_DEMO_TEST_VS_MTEST == 0
   // trivial stuff
   // a: 0->5
   mp_set_int(&a, 5);
   // a: 5-> b: -5
   mp_neg(&a, &b);
   if (mp_cmp(&a, &b) != MP_GT) {
      return EXIT_FAILURE;
   }
   if (mp_cmp(&b, &a) != MP_LT) {
      return EXIT_FAILURE;
   }
   // a: 5-> a: -5
   mp_neg(&a, &a);
   if (mp_cmp(&b, &a) != MP_EQ) {
      return EXIT_FAILURE;
   }
   // a: -5-> b: 5
   mp_abs(&a, &b);
   if (mp_isneg(&b) != MP_NO) {
      return EXIT_FAILURE;
   }
   // a: -5-> b: -4
   mp_add_d(&a, 1, &b);
   if (mp_isneg(&b) != MP_YES) {
      return EXIT_FAILURE;
   }
   if (mp_get_int(&b) != 4) {
      return EXIT_FAILURE;
   }
   // a: -5-> b: 1
   mp_add_d(&a, 6, &b);
   if (mp_get_int(&b) != 1) {
      return EXIT_FAILURE;
   }
   // a: -5-> a: 1
   mp_add_d(&a, 6, &a);
   if (mp_get_int(&a) != 1) {
      return EXIT_FAILURE;
   }
   mp_zero(&a);
   // a: 0-> a: 6
   mp_add_d(&a, 6, &a);
   if (mp_get_int(&a) != 6) {
      return EXIT_FAILURE;
   }


   mp_set_int(&a, 0);
   mp_set_int(&b, 1);
   if ((err = mp_jacobi(&a, &b, &i)) != MP_OKAY) {
      printf("Failed executing mp_jacobi(0 | 1) %s.\n", mp_error_to_string(err));
      return EXIT_FAILURE;
   }
   if (i != 1) {
      printf("Failed trivial mp_jacobi(0 | 1) %d != 1\n", i);
      return EXIT_FAILURE;
   }
   for (cnt = 0; cnt < (int)(sizeof(jacobi)/sizeof(jacobi[0])); ++cnt) {
      mp_set_int(&b, jacobi[cnt].n);
      /* only test positive values of a */
      for (n = -5; n <= 10; ++n) {
         mp_set_int(&a, abs(n));
         should = MP_OKAY;
         if (n < 0) {
            mp_neg(&a, &a);
            /* Until #44 is fixed the negative a's must fail */
            should = MP_VAL;
         }
         if ((err = mp_jacobi(&a, &b, &i)) != should) {
            printf("Failed executing mp_jacobi(%d | %lu) %s.\n", n, jacobi[cnt].n, mp_error_to_string(err));
            return EXIT_FAILURE;
         }
         if (err == MP_OKAY && i != jacobi[cnt].c[n + 5]) {
            printf("Failed trivial mp_jacobi(%d | %lu) %d != %d\n", n, jacobi[cnt].n, i, jacobi[cnt].c[n + 5]);
            return EXIT_FAILURE;
         }
      }
   }

   // test mp_get_int
   printf("\n\nTesting: mp_get_int");
   for (i = 0; i < 1000; ++i) {
      t = ((unsigned long) rand () * rand () + 1) & 0xFFFFFFFF;
      mp_set_int (&a, t);
      if (t != mp_get_int (&a)) {
         printf ("\nmp_get_int() bad result!");
         return EXIT_FAILURE;
      }
   }
   mp_set_int(&a, 0);
   if (mp_get_int(&a) != 0) {
      printf("\nmp_get_int() bad result!");
      return EXIT_FAILURE;
   }
   mp_set_int(&a, 0xffffffff);
   if (mp_get_int(&a) != 0xffffffff) {
      printf("\nmp_get_int() bad result!");
      return EXIT_FAILURE;
   }

   printf("\n\nTesting: mp_get_long\n");
   for (i = 0; i < (int)(sizeof(unsigned long)*CHAR_BIT) - 1; ++i) {
      t = (1ULL << (i+1)) - 1;
      if (!t)
         t = -1;
      printf(" t = 0x%lx i = %d\r", t, i);
      do {
         if (mp_set_long(&a, t) != MP_OKAY) {
            printf("\nmp_set_long() error!");
            return EXIT_FAILURE;
         }
         s = mp_get_long(&a);
         if (s != t) {
            printf("\nmp_get_long() bad result! 0x%lx != 0x%lx", s, t);
            return EXIT_FAILURE;
         }
         t <<= 1;
      } while(t);
   }

   printf("\n\nTesting: mp_get_long_long\n");
   for (i = 0; i < (int)(sizeof(unsigned long long)*CHAR_BIT) - 1; ++i) {
      r = (1ULL << (i+1)) - 1;
      if (!r)
         r = -1;
      printf(" r = 0x%llx i = %d\r", r, i);
      do {
         if (mp_set_long_long(&a, r) != MP_OKAY) {
            printf("\nmp_set_long_long() error!");
            return EXIT_FAILURE;
         }
         q = mp_get_long_long(&a);
         if (q != r) {
            printf("\nmp_get_long_long() bad result! 0x%llx != 0x%llx", q, r);
            return EXIT_FAILURE;
         }
         r <<= 1;
      } while(r);
   }

   // test mp_sqrt
   printf("\n\nTesting: mp_sqrt\n");
   for (i = 0; i < 1000; ++i) {
      printf ("%6d\r", i);
      fflush (stdout);
      n = (rand () & 15) + 1;
      mp_rand (&a, n);
      if (mp_sqrt (&a, &b) != MP_OKAY) {
         printf ("\nmp_sqrt() error!");
         return EXIT_FAILURE;
      }
      mp_n_root_ex (&a, 2, &c, 0);
      mp_n_root_ex (&a, 2, &d, 1);
      if (mp_cmp_mag (&c, &d) != MP_EQ) {
         printf ("\nmp_n_root_ex() bad result!");
         return EXIT_FAILURE;
      }
      if (mp_cmp_mag (&b, &c) != MP_EQ) {
         printf ("mp_sqrt() bad result!\n");
         return EXIT_FAILURE;
      }
   }

   printf("\n\nTesting: mp_is_square\n");
   for (i = 0; i < 1000; ++i) {
      printf ("%6d\r", i);
      fflush (stdout);

      /* test mp_is_square false negatives */
      n = (rand () & 7) + 1;
      mp_rand (&a, n);
      mp_sqr (&a, &a);
      if (mp_is_square (&a, &n) != MP_OKAY) {
         printf ("\nfn:mp_is_square() error!");
         return EXIT_FAILURE;
      }
      if (n == 0) {
         printf ("\nfn:mp_is_square() bad result!");
         return EXIT_FAILURE;
      }

      /* test for false positives */
      mp_add_d (&a, 1, &a);
      if (mp_is_square (&a, &n) != MP_OKAY) {
         printf ("\nfp:mp_is_square() error!");
         return EXIT_FAILURE;
      }
      if (n == 1) {
         printf ("\nfp:mp_is_square() bad result!");
         return EXIT_FAILURE;
      }

   }
   printf("\n\n");

   // r^2 = n (mod p)
   for (i = 0; i < (int)(sizeof(sqrtmod_prime)/sizeof(sqrtmod_prime[0])); ++i) {
      mp_set_int(&a, sqrtmod_prime[i].p);
      mp_set_int(&b, sqrtmod_prime[i].n);
      if (mp_sqrtmod_prime(&b, &a, &c) != MP_OKAY) {
         printf("Failed executing %d. mp_sqrtmod_prime\n", (i+1));
         return EXIT_FAILURE;
      }
      if (mp_cmp_d(&c, sqrtmod_prime[i].r) != MP_EQ) {
         printf("Failed %d. trivial mp_sqrtmod_prime\n", (i+1));
         ndraw(&c, "r");
         return EXIT_FAILURE;
      }
   }

   /* test for size */
   for (ix = 10; ix < 128; ix++) {
      printf ("Testing (not safe-prime): %9d bits    \r", ix);
      fflush (stdout);
      err = mp_prime_random_ex (&a, 8, ix,
                                (rand () & 1) ? 0 : LTM_PRIME_2MSB_ON, myrng,
                                NULL);
      if (err != MP_OKAY) {
         printf ("failed with err code %d\n", err);
         return EXIT_FAILURE;
      }
      if (mp_count_bits (&a) != ix) {
         printf ("Prime is %d not %d bits!!!\n", mp_count_bits (&a), ix);
         return EXIT_FAILURE;
      }
   }
   printf("\n");

   for (ix = 16; ix < 128; ix++) {
      printf ("Testing (    safe-prime): %9d bits    \r", ix);
      fflush (stdout);
      err = mp_prime_random_ex (
            &a, 8, ix, ((rand () & 1) ? 0 : LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE,
            myrng, NULL);
      if (err != MP_OKAY) {
         printf ("failed with err code %d\n", err);
         return EXIT_FAILURE;
      }
      if (mp_count_bits (&a) != ix) {
         printf ("Prime is %d not %d bits!!!\n", mp_count_bits (&a), ix);
         return EXIT_FAILURE;
      }
      /* let's see if it's really a safe prime */
      mp_sub_d (&a, 1, &a);
      mp_div_2 (&a, &a);
      mp_prime_is_prime (&a, 8, &cnt);
      if (cnt != MP_YES) {
         printf ("sub is not prime!\n");
         return EXIT_FAILURE;
      }
   }

   printf("\n\n");

   // test montgomery
   printf("Testing: montgomery...\n");
   for (i = 1; i <= 10; i++) {
      if (i == 10)
         i = 1000;
      printf(" digit size: %2d\r", i);
      fflush(stdout);
      for (n = 0; n < 1000; n++) {
         mp_rand(&a, i);
         a.dp[0] |= 1;

         // let's see if R is right
         mp_montgomery_calc_normalization(&b, &a);
         mp_montgomery_setup(&a, &mp);

         // now test a random reduction
         for (ix = 0; ix < 100; ix++) {
             mp_rand(&c, 1 + abs(rand()) % (2*i));
             mp_copy(&c, &d);
             mp_copy(&c, &e);

             mp_mod(&d, &a, &d);
             mp_montgomery_reduce(&c, &a, mp);
             mp_mulmod(&c, &b, &a, &c);

             if (mp_cmp(&c, &d) != MP_EQ) {
printf("d = e mod a, c = e MOD a\n");
mp_todecimal(&a, buf); printf("a = %s\n", buf);
mp_todecimal(&e, buf); printf("e = %s\n", buf);
mp_todecimal(&d, buf); printf("d = %s\n", buf);
mp_todecimal(&c, buf); printf("c = %s\n", buf);
printf("compare no compare!\n"); return EXIT_FAILURE; }
             /* only one big montgomery reduction */
             if (i > 10)
             {
                n = 1000;
                ix = 100;
             }
         }
      }
   }

   printf("\n\n");

   mp_read_radix(&a, "123456", 10);
   mp_toradix_n(&a, buf, 10, 3);
   printf("a == %s\n", buf);
   mp_toradix_n(&a, buf, 10, 4);
   printf("a == %s\n", buf);
   mp_toradix_n(&a, buf, 10, 30);
   printf("a == %s\n", buf);


#if 0
   for (;;) {
      fgets(buf, sizeof(buf), stdin);
      mp_read_radix(&a, buf, 10);
      mp_prime_next_prime(&a, 5, 1);
      mp_toradix(&a, buf, 10);
      printf("%s, %lu\n", buf, a.dp[0] & 3);
   }
#endif

   /* test mp_cnt_lsb */
   printf("\n\nTesting: mp_cnt_lsb");
   mp_set(&a, 1);
   for (ix = 0; ix < 1024; ix++) {
      if (mp_cnt_lsb (&a) != ix) {
         printf ("Failed at %d, %d\n", ix, mp_cnt_lsb (&a));
         return EXIT_FAILURE;
      }
      mp_mul_2 (&a, &a);
   }

/* test mp_reduce_2k */
   printf("\n\nTesting: mp_reduce_2k\n");
   for (cnt = 3; cnt <= 128; ++cnt) {
      mp_digit tmp;

      mp_2expt (&a, cnt);
      mp_sub_d (&a, 2, &a); /* a = 2**cnt - 2 */

      printf ("\r %4d bits", cnt);
      printf ("(%d)", mp_reduce_is_2k (&a));
      mp_reduce_2k_setup (&a, &tmp);
      printf ("(%lu)", (unsigned long) tmp);
      for (ix = 0; ix < 1000; ix++) {
         if (!(ix & 127)) {
            printf (".");
            fflush (stdout);
         }
         mp_rand (&b, (cnt / DIGIT_BIT + 1) * 2);
         mp_copy (&c, &b);
         mp_mod (&c, &a, &c);
         mp_reduce_2k (&b, &a, 2);
         if (mp_cmp (&c, &b)) {
            printf ("FAILED\n");
            return EXIT_FAILURE;
         }
      }
   }

/* test mp_div_3  */
   printf("\n\nTesting: mp_div_3...\n");
   mp_set(&d, 3);
   for (cnt = 0; cnt < 10000;) {
      mp_digit r2;

      if (!(++cnt & 127))
      {
        printf("%9d\r", cnt);
        fflush(stdout);
      }
      mp_rand(&a, abs(rand()) % 128 + 1);
      mp_div(&a, &d, &b, &e);
      mp_div_3(&a, &c, &r2);

      if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) {
	 printf("\nmp_div_3 => Failure\n");
      }
   }
   printf("\nPassed div_3 testing");

/* test the DR reduction */
   printf("\n\nTesting: mp_dr_reduce...\n");
   for (cnt = 2; cnt < 32; cnt++) {
      printf ("\r%d digit modulus", cnt);
      mp_grow (&a, cnt);
      mp_zero (&a);
      for (ix = 1; ix < cnt; ix++) {
         a.dp[ix] = MP_MASK;
      }
      a.used = cnt;
      a.dp[0] = 3;

      mp_rand (&b, cnt - 1);
      mp_copy (&b, &c);

      rr = 0;
      do {
         if (!(rr & 127)) {
            printf (".");
            fflush (stdout);
         }
         mp_sqr (&b, &b);
         mp_add_d (&b, 1, &b);
         mp_copy (&b, &c);

         mp_mod (&b, &a, &b);
         mp_dr_setup(&a, &mp),
         mp_dr_reduce (&c, &a, mp);

         if (mp_cmp (&b, &c) != MP_EQ) {
            printf ("Failed on trial %u\n", rr);
            return EXIT_FAILURE;
         }
      } while (++rr < 500);
      printf (" passed");
      fflush (stdout);
   }

#if LTM_DEMO_TEST_REDUCE_2K_L
/* test the mp_reduce_2k_l code */
#if LTM_DEMO_TEST_REDUCE_2K_L == 1
/* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */
   mp_2expt(&a, 1024);
   mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16);
   mp_sub(&a, &b, &a);
#elif LTM_DEMO_TEST_REDUCE_2K_L == 2
/*  p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F  */
   mp_2expt(&a, 2048);
   mp_read_radix(&b,
		 "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F",
		 16);
   mp_sub(&a, &b, &a);
#else
#error oops
#endif

   mp_todecimal(&a, buf);
   printf("\n\np==%s\n", buf);
/* now mp_reduce_is_2k_l() should return */
   if (mp_reduce_is_2k_l(&a) != 1) {
      printf("mp_reduce_is_2k_l() return 0, should be 1\n");
      return EXIT_FAILURE;
   }
   mp_reduce_2k_setup_l(&a, &d);
   /* now do a million square+1 to see if it varies */
   mp_rand(&b, 64);
   mp_mod(&b, &a, &b);
   mp_copy(&b, &c);
   printf("Testing: mp_reduce_2k_l...");
   fflush(stdout);
   for (cnt = 0; cnt < (int)(1UL << 20); cnt++) {
      mp_sqr(&b, &b);
      mp_add_d(&b, 1, &b);
      mp_reduce_2k_l(&b, &a, &d);
      mp_sqr(&c, &c);
      mp_add_d(&c, 1, &c);
      mp_mod(&c, &a, &c);
      if (mp_cmp(&b, &c) != MP_EQ) {
	 printf("mp_reduce_2k_l() failed at step %d\n", cnt);
	 mp_tohex(&b, buf);
	 printf("b == %s\n", buf);
	 mp_tohex(&c, buf);
	 printf("c == %s\n", buf);
	 return EXIT_FAILURE;
      }
   }
   printf("...Passed\n");
#endif /* LTM_DEMO_TEST_REDUCE_2K_L */

#else

   div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =
      sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n =
      sub_d_n = 0;

   /* force KARA and TOOM to enable despite cutoffs */
   KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8;
   TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16;

   for (;;) {
      /* randomly clear and re-init one variable, this has the affect of triming the alloc space */
      switch (abs(rand()) % 7) {
      case 0:
	 mp_clear(&a);
	 mp_init(&a);
	 break;
      case 1:
	 mp_clear(&b);
	 mp_init(&b);
	 break;
      case 2:
	 mp_clear(&c);
	 mp_init(&c);
	 break;
      case 3:
	 mp_clear(&d);
	 mp_init(&d);
	 break;
      case 4:
	 mp_clear(&e);
	 mp_init(&e);
	 break;
      case 5:
	 mp_clear(&f);
	 mp_init(&f);
	 break;
      case 6:
	 break;			/* don't clear any */
      }


      printf
	 ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ",
	  add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n,
	  expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n);
      ret=fgets(cmd, 4095, stdin); if(!ret){_panic(__LINE__);}
      cmd[strlen(cmd) - 1] = 0;
      printf("%-6s ]\r", cmd);
      fflush(stdout);
      if (!strcmp(cmd, "mul2d")) {
	 ++mul2d_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 sscanf(buf, "%d", &rr);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);

	 mp_mul_2d(&a, rr, &a);
	 a.sign = b.sign;
	 if (mp_cmp(&a, &b) != MP_EQ) {
	    printf("mul2d failed, rr == %d\n", rr);
	    draw(&a);
	    draw(&b);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "div2d")) {
	 ++div2d_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 sscanf(buf, "%d", &rr);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);

	 mp_div_2d(&a, rr, &a, &e);
	 a.sign = b.sign;
	 if (a.used == b.used && a.used == 0) {
	    a.sign = b.sign = MP_ZPOS;
	 }
	 if (mp_cmp(&a, &b) != MP_EQ) {
	    printf("div2d failed, rr == %d\n", rr);
	    draw(&a);
	    draw(&b);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "add")) {
	 ++add_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_add(&d, &b, &d);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("add %lu failure!\n", add_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }

	 /* test the sign/unsigned storage functions */

	 rr = mp_signed_bin_size(&c);
	 mp_to_signed_bin(&c, (unsigned char *) cmd);
	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
	 mp_read_signed_bin(&d, (unsigned char *) cmd, rr);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("mp_signed_bin failure!\n");
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }


	 rr = mp_unsigned_bin_size(&c);
	 mp_to_unsigned_bin(&c, (unsigned char *) cmd);
	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
	 mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr);
	 if (mp_cmp_mag(&c, &d) != MP_EQ) {
	    printf("mp_unsigned_bin failure!\n");
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }

      } else if (!strcmp(cmd, "sub")) {
	 ++sub_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_sub(&d, &b, &d);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("sub %lu failure!\n", sub_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "mul")) {
	 ++mul_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_mul(&d, &b, &d);
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("mul %lu failure!\n", mul_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "div")) {
	 ++div_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&d, buf, 64);

	 mp_div(&a, &b, &e, &f);
	 if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) {
	    printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e),
		   mp_cmp(&d, &f));
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    draw(&e);
	    draw(&f);
	    return EXIT_FAILURE;
	 }

      } else if (!strcmp(cmd, "sqr")) {
	 ++sqr_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 mp_copy(&a, &c);
	 mp_sqr(&c, &c);
	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("sqr %lu failure!\n", sqr_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "gcd")) {
	 ++gcd_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_gcd(&d, &b, &d);
	 d.sign = c.sign;
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("gcd %lu failure!\n", gcd_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "lcm")) {
	 ++lcm_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 mp_copy(&a, &d);
	 mp_lcm(&d, &b, &d);
	 d.sign = c.sign;
	 if (mp_cmp(&c, &d) != MP_EQ) {
	    printf("lcm %lu failure!\n", lcm_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "expt")) {
	 ++expt_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&d, buf, 64);
	 mp_copy(&a, &e);
	 mp_exptmod(&e, &b, &c, &e);
	 if (mp_cmp(&d, &e) != MP_EQ) {
	    printf("expt %lu failure!\n", expt_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    draw(&e);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "invmod")) {
	 ++inv_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&c, buf, 64);
	 mp_invmod(&a, &b, &d);
	 mp_mulmod(&d, &a, &b, &e);
	 if (mp_cmp_d(&e, 1) != MP_EQ) {
	    printf("inv [wrong value from MPI?!] failure\n");
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    draw(&d);
	    draw(&e);
	    mp_gcd(&a, &b, &e);
	    draw(&e);
	    return EXIT_FAILURE;
	 }

      } else if (!strcmp(cmd, "div2")) {
	 ++div2_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 mp_div_2(&a, &c);
	 if (mp_cmp(&c, &b) != MP_EQ) {
	    printf("div_2 %lu failure\n", div2_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "mul2")) {
	 ++mul2_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 mp_mul_2(&a, &c);
	 if (mp_cmp(&c, &b) != MP_EQ) {
	    printf("mul_2 %lu failure\n", mul2_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "add_d")) {
	 ++add_d_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 sscanf(buf, "%d", &ix);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 mp_add_d(&a, ix, &c);
	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("add_d %lu failure\n", add_d_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    printf("d == %d\n", ix);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "sub_d")) {
	 ++sub_d_n;
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&a, buf, 64);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 sscanf(buf, "%d", &ix);
	 ret=fgets(buf, 4095, stdin); if(!ret){_panic(__LINE__);}
	 mp_read_radix(&b, buf, 64);
	 mp_sub_d(&a, ix, &c);
	 if (mp_cmp(&b, &c) != MP_EQ) {
	    printf("sub_d %lu failure\n", sub_d_n);
	    draw(&a);
	    draw(&b);
	    draw(&c);
	    printf("d == %d\n", ix);
	    return EXIT_FAILURE;
	 }
      } else if (!strcmp(cmd, "exit")) {
         printf("\nokay, exiting now\n");
         break;
      }
   }
#endif
   return 0;
}