int test_mod_exp(BIO *bp,BN_CTX *ctx);
int test_exp(BIO *bp,BN_CTX *ctx);
int test_kron(BIO *bp,BN_CTX *ctx);
+int test_sqrt(BIO *bp,BN_CTX *ctx);
int rand_neg(void);
static int results=0;
if (!results)
BIO_puts(out,"obase=16\nibase=16\n");
+#if 0
message(out,"BN_add");
if (!test_add(out)) goto err;
BIO_flush(out);
message(out,"BN_exp");
if (!test_exp(out,ctx)) goto err;
BIO_flush(out);
+#endif
message(out,"BN_kronecker");
if (!test_kron(out,ctx)) goto err;
BIO_flush(out);
+ message(out,"BN_mod_sqrt");
+ if (!test_sqrt(out,ctx)) goto err;
+ BIO_flush(out);
+
BN_CTX_free(ctx);
BIO_free(out);
BN_rand(&n,bits,0,1);
BN_MONT_CTX_set(mont,&n,ctx);
+ BN_nnmod(&a,&a,&n,ctx);
+ BN_nnmod(&b,&b,&n,ctx);
+
BN_to_montgomery(&A,&a,mont,ctx);
BN_to_montgomery(&B,&b,mont,ctx);
int test_kron(BIO *bp, BN_CTX *ctx)
{
- BIGNUM *a,*b,*r;
+ BIGNUM *a,*b,*r,*t;
int i;
int legendre, kronecker;
int ret = 0;
a = BN_new();
b = BN_new();
r = BN_new();
- if (a == NULL || b == NULL || r == NULL) goto err;
+ t = BN_new();
+ if (a == NULL || b == NULL || r == NULL || t == NULL) goto err;
/* We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol).
* In this case we know that if b is prime, then BN_kronecker(a, b, ctx)
* don't want to test whether b is prime but whether BN_kronecker
* works.) */
+#if 0
if (!BN_generate_prime(b, 512, 0, NULL, NULL, genprime_cb, NULL)) goto err;
+#else
+ if (!BN_set_word(b,65537)) goto err;
+#endif
putc('\n', stderr);
- if (1 != BN_is_prime(b, 10, NULL, ctx, NULL))
- {
- fprintf(stderr, "BN_is_prime failed\n");
- goto err;
- }
for (i = 0; i < num0; i++)
{
+#if 0
if (!BN_rand(a, 512, 0, 0)) goto err;
- if (!BN_nnmod(a, a, b, ctx)) goto err;
-
- /* r := (b-1)/2 (note that b is odd) */
- if (!BN_copy(r, b)) goto err;
- if (!BN_sub_word(r, 1)) goto err;
- if (!BN_rshift1(r, r)) goto err;
- /* r := a^r mod b */
- if (!BN_mod_exp(r, a, r, b, ctx)) goto err;
+ a->neg = rand_neg();
+#else
+ if (!BN_bin2bn("\x01\xff\xff\xff\xff", 5, a)) goto err;
+#endif
+
+ /* t := (b-1)/2 (note that b is odd) */
+ if (!BN_copy(t, b)) goto err;
+ if (!BN_sub_word(t, 1)) goto err;
+ if (!BN_rshift1(t, t)) goto err;
+ /* r := a^t mod b */
+#if 0
+ if (!BN_mod_exp(r, a, t, b, ctx)) goto err;
+#elif 0
+ if (!BN_mod_exp_recp(r, a, t, b, ctx)) goto err;
+#else
+ if (!BN_mod_exp_simple(r, a, t, b, ctx)) goto err;
+#endif
if (BN_is_word(r, 1))
legendre = 1;
+ else if (BN_is_zero(r))
+ legendre = 0;
else
{
if (!BN_add_word(r, 1)) goto err;
if (a != NULL) BN_free(a);
if (b != NULL) BN_free(b);
if (r != NULL) BN_free(r);
+ if (t != NULL) BN_free(t);
+ return ret;
+ }
+
+int test_sqrt(BIO *bp, BN_CTX *ctx)
+ {
+ BIGNUM *a,*p,*r;
+ int i, j;
+ int ret = 0;
+
+ a = BN_new();
+ p = BN_new();
+ r = BN_new();
+ if (a == NULL || p == NULL || r == NULL) goto err;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (i < 8)
+ {
+ unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 };
+
+ if (!BN_set_word(p, primes[i])) goto err;
+ }
+ else
+ {
+ if (!BN_set_word(a, 32)) goto err;
+ if (!BN_set_word(r, 2*i + 1)) goto err;
+
+ if (!BN_generate_prime(p, 256, 0, a, r, genprime_cb, NULL)) goto err;
+ putc('\n', stderr);
+ }
+
+ for (j = 0; j < num2; j++)
+ {
+ /* construct 'a' such that it is a square modulo p,
+ * but in general not a proper square and not reduced modulo p */
+ if (!BN_rand(r, 256, 0, 3)) goto err;
+ if (!BN_nnmod(r, r, p, ctx)) goto err;
+ if (!BN_mod_sqr(r, r, p, ctx)) goto err;
+ if (!BN_rand(a, 256, 0, 3)) goto err;
+ if (!BN_nnmod(a, a, p, ctx)) goto err;
+ if (!BN_mod_sqr(a, a, p, ctx)) goto err;
+ if (!BN_mul(a, a, r, ctx)) goto err;
+
+ if (!BN_mod_sqrt(r, a, p, ctx)) goto err;
+ if (!BN_mod_sqr(r, r, p, ctx)) goto err;
+
+ if (!BN_nnmod(a, a, p, ctx)) goto err;
+
+ if (BN_cmp(a, r) != 0)
+ {
+ fprintf(stderr, "BN_mod_sqrt failed: a = ");
+ BN_print_fp(stderr, a);
+ fprintf(stderr, ", r = ");
+ BN_print_fp(stderr, r);
+ fprintf(stderr, ", p = ");
+ BN_print_fp(stderr, p);
+ fprintf(stderr, "\n");
+ goto err;
+ }
+
+ putc('.', stderr);
+ fflush(stderr);
+ }
+
+ putc('\n', stderr);
+ fflush(stderr);
+ }
+ ret = 1;
+ err:
+ if (a != NULL) BN_free(a);
+ if (p != NULL) BN_free(p);
+ if (r != NULL) BN_free(r);
return ret;
}