Beispiel #1
0
/*
 * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success.
 */
static int test_exp_mod_zero()
{
    BIGNUM a, p, m;
    BIGNUM r;
    BN_CTX *ctx = BN_CTX_new();
    int ret = 1;

    BN_init(&m);
    BN_one(&m);

    BN_init(&a);
    BN_one(&a);

    BN_init(&p);
    BN_zero(&p);

    BN_init(&r);
    BN_mod_exp(&r, &a, &p, &m, ctx);
    BN_CTX_free(ctx);

    if (BN_is_zero(&r))
        ret = 0;
    else {
        printf("1**0 mod 1 = ");
        BN_print_fp(stdout, &r);
        printf(", should be 0\n");
    }

    BN_free(&r);
    BN_free(&a);
    BN_free(&p);
    BN_free(&m);

    return ret;
}
Beispiel #2
0
BIGNUM * Polynomial::GetLagIntCoe(vector<int> *allParties,int index)
{
   	BN_CTX *ctx = BN_CTX_new();
   	BIGNUM *up = BN_new();
   	BN_one(up);
   	BIGNUM *down = BN_new();
   	BN_one(down);
   	vector<int>::iterator iter;  
   	for (iter=allParties->begin();iter!= allParties->end();iter++)  
   	{
    	if(*iter == index)
        	continue;    
     	BIGNUM *j   = BN_int2bn(-(*iter));
     	BIGNUM *i_j = BN_int2bn(index-(*iter));
    	BN_mul(up,up,j,ctx);
     	BN_mul(down,down,i_j,ctx);
   	}

   	BIGNUM * result = BN_new();
   	BN_mod_inverse(result,down,p,ctx);
   	BN_mod_mul(result,result,up,p,ctx);
   
   	BN_free(up);
  	BN_free(down);
   	BN_CTX_free(ctx);

   	return result;
}
void compute_y(BIGNUM *bn_y, BIGNUM *bn_a, BIGNUM *bn_r, BIGNUM *bn_n, BN_CTX *bn_ctx){
	BIGNUM *bn_i = NULL;
	BIGNUM *bn_1 = NULL;
	int num_bits = 0;
	int i = 0;
	BIGNUM **bn_array = NULL;
	
	num_bits = BN_num_bits(bn_r);
	bn_array = (BIGNUM **)malloc(sizeof(BIGNUM*) * num_bits);
	computeBNArray(bn_array, bn_a, bn_n, bn_ctx, num_bits);
	
	bn_1 = BN_new();
	bn_i = BN_new();
	BN_one(bn_1);
	BN_zero(bn_i);
	BN_one(bn_y);
	
	for(i = 0; i < num_bits; i++){
		if(BN_is_bit_set(bn_r, i) == 1){
			BN_mod_mul(bn_y, bn_y, bn_array[i], bn_n, bn_ctx);
		}
	}
	BN_free(bn_1);
	BN_free(bn_i);
}
Beispiel #4
0
// Extended Euclidean algorithm, Knuth's Algorithm X
int bnem_xgcd (BIGNUM *rx, BIGNUM *ry, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
	int result = 0;	// default return value is failure
	BIGNUM x, y, lastx, lasty, q, r, t1, t2, wa, wb;
	BN_init (&x);
	BN_init (&y);
	BN_init (&lastx);
	BN_init (&lasty);
	BN_init (&q);
	BN_init (&r);
	BN_init (&t1);
	BN_init (&t2);
	BN_init (&wa);
	BN_init (&wb);
	if ( ! BN_copy (&wa, a)) goto err;
	if ( ! BN_copy (&wb, b)) goto err;
	/*
	x, lastx = 0, 1
	y, lasty = 1, 0
	while b:
		q, r = divmod (a, b)
		a, b = b, r
		x, lastx = (lastx - q*x), x
		y, lasty = (lasty - q*y), y
	return lastx, lasty
	*/
	BN_one (&lastx);
	BN_one (&y);
	while ( ! BN_is_zero (&wb)) {
		if ( ! BN_div (&q, &r, &wa, &wb, ctx)) goto err;
		if ( ! BN_copy (&wa, &wb)) goto err;
		if ( ! BN_copy (&wb, &r)) goto err;
		
		if ( ! BN_copy (&t1, &x)) goto err;
		if ( ! BN_mul (&t2, &q, &x, ctx)) goto err;
		if ( ! BN_sub (&x, &lastx, &t2)) goto err;
		if ( ! BN_copy (&lastx, &t1)) goto err;
		
		if ( ! BN_copy (&t1, &y)) goto err;
		if ( ! BN_mul (&t2, &q, &y, ctx)) goto err;
		if ( ! BN_sub (&y, &lasty, &t2)) goto err;
		if ( ! BN_copy (&lasty, &t1)) goto err;
	}
	if (rx) { if ( ! BN_copy (rx, &lastx)) goto err; }
	if (ry) { if ( ! BN_copy (ry, &lasty)) goto err; }
	result = 1;	// result is success
err:
	BN_clear_free (&x);
	BN_clear_free (&y);
	BN_clear_free (&lastx);
	BN_clear_free (&lasty);
	BN_clear_free (&q);
	BN_clear_free (&r);
	BN_clear_free (&t1);
	BN_clear_free (&t2);
	BN_clear_free (&wa);
	BN_clear_free (&wb);
	return result;
} // bnem_xgcd
Beispiel #5
0
int test_exp(BIO *bp, BN_CTX *ctx)
	{
	BIGNUM *a,*b,*d,*e,*one;
	int i;

	a=BN_new();
	b=BN_new();
	d=BN_new();
	e=BN_new();
	one=BN_new();
	BN_one(one);

	for (i=0; i<num2; i++)
		{
		BN_bntest_rand(a,20+i*5,0,0); /**/
		BN_bntest_rand(b,2+i,0,0); /**/

		if (!BN_exp(d,a,b,ctx))
			return(00);

		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," ^ ");
				BN_print(bp,b);
				BIO_puts(bp," - ");
				}
			BN_print(bp,d);
			BIO_puts(bp,"\n");
			}
		BN_one(e);
		for( ; !BN_is_zero(b) ; BN_sub(b,b,one))
		    BN_mul(e,e,a,ctx);
		BN_sub(e,e,d);
		if(!BN_is_zero(e))
		    {
		    fprintf(stderr,"Exponentiation test failed!\n");
		    return 0;
		    }
		}
	BN_free(a);
	BN_free(b);
	BN_free(d);
	BN_free(e);
	BN_free(one);
	return(1);
	}
Beispiel #6
0
/* Forces the given EC_POINT to internally use affine coordinates. */
int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
	{
	BN_CTX *new_ctx = NULL;
	BIGNUM *x, *y;
	int ret = 0;

	if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
		return 1;
	
	if (ctx == NULL)
		{
		ctx = new_ctx = BN_CTX_new();
		if (ctx == NULL)
			return 0;
		}

	BN_CTX_start(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	if (y == NULL) goto err;
	
	if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err;
	if (!BN_copy(&point->X, x)) goto err;
	if (!BN_copy(&point->Y, y)) goto err;
	if (!BN_one(&point->Z)) goto err;
	
	ret = 1;		

  err:
	if (ctx) BN_CTX_end(ctx);
	if (new_ctx) BN_CTX_free(new_ctx);
	return ret;
	}
data_chunk deterministic_wallet::generate_public_key(
    size_t n, bool for_change) const
{
    hash_digest sequence = get_sequence(n, for_change);

    ssl_bignum x, y, z;
    BN_bin2bn(sequence.data(), sequence.size(), z);
    BN_bin2bn(master_public_key_.data(), 32, x);
    BN_bin2bn(master_public_key_.data() + 32, 32, y);

    // Create a point.
    ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
    ec_point mpk(EC_POINT_new(group));
    bn_ctx ctx(BN_CTX_new());
    EC_POINT_set_affine_coordinates_GFp(group, mpk, x, y, ctx);
    ec_point result(EC_POINT_new(group));

    // result pubkey_point = mpk_pubkey_point + z*curve.generator
    ssl_bignum one;
    BN_one(one);
    EC_POINT_mul(group, result, z, mpk, one, ctx);

    // Create the actual public key.
    EC_POINT_get_affine_coordinates_GFp(group, result, x, y, ctx);
    // 04 + x + y
    data_chunk raw_pubkey{0x04};
    extend_data(raw_pubkey, bignum_data(x));
    extend_data(raw_pubkey, bignum_data(y));
    return raw_pubkey;
}
Beispiel #8
0
CHECK_RETVAL_BOOL \
static BOOLEAN selfTestGeneralOps1( void )
	{
	BIGNUM a;

	/* Simple tests that don't need the support of higher-level routines 
	   like importBignum() */
	BN_init( &a );
	if( !BN_zero( &a ) )
		return( FALSE );
	if( !BN_is_zero( &a ) || BN_is_one( &a ) )
		return( FALSE );
	if( !BN_is_word( &a, 0 ) || BN_is_word( &a, 1 ) )
		return( FALSE );
	if( BN_is_odd( &a ) )
		return( FALSE );
	if( BN_get_word( &a ) != 0 )
		return( FALSE );
	if( !BN_one( &a ) )
		return( FALSE );
	if( BN_is_zero( &a ) || !BN_is_one( &a ) )
		return( FALSE );
	if( BN_is_word( &a, 0 ) || !BN_is_word( &a, 1 ) )
		return( FALSE );
	if( !BN_is_odd( &a ) )
		return( FALSE );
	if( BN_num_bytes( &a ) != 1 )
		return( FALSE );
	if( BN_get_word( &a ) != 1 )
		return( FALSE );
	BN_clear( &a );

	return( TRUE );
	}
Beispiel #9
0
int BN_solinas2bn(const BN_SOLINAS *solinas, BIGNUM *bn)
{
	int ret = 0;
	BIGNUM *tmp = NULL;

	if (!solinas || !bn) {
		BNerr(BN_F_BN_SOLINAS2BN, ERR_R_MALLOC_FAILURE);
		return 0;
	}

	if (solinas->b <= 0 || solinas->a <= solinas->b
		|| (solinas->s != 1 && solinas->s != -1)
		|| (solinas->c != 1 && solinas->c != -1)) {
		BNerr(BN_F_BN_SOLINAS2BN, BN_R_INVALID_SOLINAS_PARAMETERS);
		return 0;
	}

	if (!(tmp = BN_new())) {
		BNerr(BN_F_BN_SOLINAS2BN, ERR_R_MALLOC_FAILURE);
		goto end;
	}

	BN_one(tmp);

	if (!BN_lshift(bn, tmp, solinas->a)) {
		BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
		goto end;
	}

	if (!BN_lshift(tmp, tmp, solinas->b)) {
		BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
		goto end;
	}

	if (!BN_add_word(tmp, solinas->c)) {
		BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
		goto end;
	}

	if (solinas->s > 0) {
		if (!BN_add(bn, bn, tmp)) {
			BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
			goto end;
		}
	} else {
		if (!BN_sub(bn, bn, tmp)) {
			BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
			goto end;
		}
	}

	/* check if it is a prime */

	ret = 1;
end:
	BN_free(tmp);
	return ret;
}
Beispiel #10
0
/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) 
 * using Montgomery point multiplication algorithm Mxy() in appendix of 
 *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
 *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
 * Returns:
 *     0 on error
 *     1 if return value should be the point at infinity
 *     2 otherwise
 */
static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIGNUM *x1, 
	BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, BN_CTX *ctx)
	{
	BIGNUM *t3, *t4, *t5;
	int ret = 0;
	
	if (BN_is_zero(z1))
		{
		BN_zero(x2);
		BN_zero(z2);
		return 1;
		}
	
	if (BN_is_zero(z2))
		{
		if (!BN_copy(x2, x)) return 0;
		if (!BN_GF2m_add(z2, x, y)) return 0;
		return 2;
		}
		
	/* Since Mxy is static we can guarantee that ctx != NULL. */
	BN_CTX_start(ctx);
	t3 = BN_CTX_get(ctx);
	t4 = BN_CTX_get(ctx);
	t5 = BN_CTX_get(ctx);
	if (t5 == NULL) goto err;

	if (!BN_one(t5)) goto err;

	if (!group->meth->field_mul(group, t3, z1, z2, ctx)) goto err;

	if (!group->meth->field_mul(group, z1, z1, x, ctx)) goto err;
	if (!BN_GF2m_add(z1, z1, x1)) goto err;
	if (!group->meth->field_mul(group, z2, z2, x, ctx)) goto err;
	if (!group->meth->field_mul(group, x1, z2, x1, ctx)) goto err;
	if (!BN_GF2m_add(z2, z2, x2)) goto err;

	if (!group->meth->field_mul(group, z2, z2, z1, ctx)) goto err;
	if (!group->meth->field_sqr(group, t4, x, ctx)) goto err;
	if (!BN_GF2m_add(t4, t4, y)) goto err;
	if (!group->meth->field_mul(group, t4, t4, t3, ctx)) goto err;
	if (!BN_GF2m_add(t4, t4, z2)) goto err;

	if (!group->meth->field_mul(group, t3, t3, x, ctx)) goto err;
	if (!group->meth->field_div(group, t3, t5, t3, ctx)) goto err;
	if (!group->meth->field_mul(group, t4, t3, t4, ctx)) goto err;
	if (!group->meth->field_mul(group, x2, x1, t3, ctx)) goto err;
	if (!BN_GF2m_add(z2, x2, x)) goto err;

	if (!group->meth->field_mul(group, z2, z2, t4, ctx)) goto err;
	if (!BN_GF2m_add(z2, z2, y)) goto err;

	ret = 2;

 err:
	BN_CTX_end(ctx);
	return ret;
	}
Beispiel #11
0
int test_lshift(BIO *bp,BN_CTX *ctx,BIGNUM *a_)
	{
	BIGNUM *a,*b,*c,*d;
	int i;

	b=BN_new();
	c=BN_new();
	d=BN_new();
	BN_one(c);

	if(a_)
	    a=a_;
	else
	    {
	    a=BN_new();
	    BN_bntest_rand(a,200,0,0); /**/
	    a->neg=rand_neg();
	    }
	for (i=0; i<num0; i++)
		{
		BN_lshift(b,a,i+1);
		BN_add(c,c,c);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," * ");
				BN_print(bp,c);
				BIO_puts(bp," - ");
				}
			BN_print(bp,b);
			BIO_puts(bp,"\n");
			}
		BN_mul(d,a,c,ctx);
		BN_sub(d,d,b);
		if(!BN_is_zero(d))
		    {
		    fprintf(stderr,"Left shift test failed!\n");
		    fprintf(stderr,"a=");
		    BN_print_fp(stderr,a);
		    fprintf(stderr,"\nb=");
		    BN_print_fp(stderr,b);
		    fprintf(stderr,"\nc=");
		    BN_print_fp(stderr,c);
		    fprintf(stderr,"\nd=");
		    BN_print_fp(stderr,d);
		    fprintf(stderr,"\n");
		    return 0;
		    }
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	return(1);
	}
Beispiel #12
0
int gost_do_verify (const unsigned char *dgst, int dgst_len, DSA_SIG * sig, DSA * dsa)
{
    BIGNUM *md, *tmp = NULL;

    BIGNUM *q2 = NULL;

    BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;

    BIGNUM *tmp2 = NULL, *tmp3 = NULL;

    int ok;

    BN_CTX *ctx = BN_CTX_new ();

    BN_CTX_start (ctx);
    if (BN_cmp (sig->s, dsa->q) >= 1 || BN_cmp (sig->r, dsa->q) >= 1)
    {
        GOSTerr (GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
        return 0;
    }
    md = hashsum2bn (dgst);

    tmp = BN_CTX_get (ctx);
    v = BN_CTX_get (ctx);
    q2 = BN_CTX_get (ctx);
    z1 = BN_CTX_get (ctx);
    z2 = BN_CTX_get (ctx);
    tmp2 = BN_CTX_get (ctx);
    tmp3 = BN_CTX_get (ctx);
    u = BN_CTX_get (ctx);

    BN_mod (tmp, md, dsa->q, ctx);
    if (BN_is_zero (tmp))
    {
        BN_one (md);
    }
    BN_copy (q2, dsa->q);
    BN_sub_word (q2, 2);
    BN_mod_exp (v, md, q2, dsa->q, ctx);
    BN_mod_mul (z1, sig->s, v, dsa->q, ctx);
    BN_sub (tmp, dsa->q, sig->r);
    BN_mod_mul (z2, tmp, v, dsa->p, ctx);
    BN_mod_exp (tmp, dsa->g, z1, dsa->p, ctx);
    BN_mod_exp (tmp2, dsa->pub_key, z2, dsa->p, ctx);
    BN_mod_mul (tmp3, tmp, tmp2, dsa->p, ctx);
    BN_mod (u, tmp3, dsa->q, ctx);
    ok = BN_cmp (u, sig->r);

    BN_free (md);
    BN_CTX_end (ctx);
    BN_CTX_free (ctx);
    if (ok != 0)
    {
        GOSTerr (GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
    }
    return (ok == 0);
}
Beispiel #13
0
int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
  int i, bits, ret = 0;
  BIGNUM *v, *rr;

  if ((p->flags & BN_FLG_CONSTTIME) != 0) {
    /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
    OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  BN_CTX_start(ctx);
  if (r == a || r == p) {
    rr = BN_CTX_get(ctx);
  } else {
    rr = r;
  }

  v = BN_CTX_get(ctx);
  if (rr == NULL || v == NULL) {
    goto err;
  }

  if (BN_copy(v, a) == NULL) {
    goto err;
  }
  bits = BN_num_bits(p);

  if (BN_is_odd(p)) {
    if (BN_copy(rr, a) == NULL) {
      goto err;
    }
  } else {
    if (!BN_one(rr)) {
      goto err;
    }
  }

  for (i = 1; i < bits; i++) {
    if (!BN_sqr(v, v, ctx)) {
      goto err;
    }
    if (BN_is_bit_set(p, i)) {
      if (!BN_mul(rr, rr, v, ctx)) {
        goto err;
      }
    }
  }

  if (r != rr && !BN_copy(r, rr)) {
    goto err;
  }
  ret = 1;

err:
  BN_CTX_end(ctx);
  return ret;
}
Beispiel #14
0
/*
 * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success.
 */
static int test_exp_mod_zero()
{
    BIGNUM *a = NULL, *p = NULL, *m = NULL;
    BIGNUM *r = NULL;
    BN_CTX *ctx = BN_CTX_new();
    int ret = 1;

    m = BN_new();
    if (!m)
        goto err;
    BN_one(m);

    a = BN_new();
    if (!a)
        goto err;
    BN_one(a);

    p = BN_new();
    if (!p)
        goto err;
    BN_zero(p);

    r = BN_new();
    if (!r)
        goto err;
    BN_mod_exp(r, a, p, m, ctx);
    BN_CTX_free(ctx);

    if (BN_is_zero(r))
        ret = 0;
    else {
        printf("1**0 mod 1 = ");
        BN_print_fp(stdout, r);
        printf(", should be 0\n");
    }

 err:
    BN_free(r);
    BN_free(a);
    BN_free(p);
    BN_free(m);

    return ret;
}
Beispiel #15
0
/**
  https://core.telegram.org/api/end-to-end says:
  "Both clients in a secret chat creation are to check that g, g_a and g_b are greater than one and smaller than p-1.
  Recommented checking that g_a and g_b are between 2^{2048-64} and p - 2^{2048-64} as well."
*/
qint32 CryptoUtils::checkCalculatedParams(const BIGNUM *gAOrB, const BIGNUM *g, const BIGNUM *p) {
    ASSERT(gAOrB);
    ASSERT(g);
    ASSERT(p);

    // 1) gAOrB and g greater than one and smaller than p-1
    BIGNUM one;
    BN_init(&one);
    Utils::ensure(BN_one(&one));

    BIGNUM *pMinusOne = BN_dup(p);
    Utils::ensure(BN_sub_word(pMinusOne, 1));

    // check params greater than one
    if (BN_cmp(gAOrB, &one) <= 0) return -1;
    if (BN_cmp(g, &one) <= 0) return -1;

    // check params <= p-1
    if (BN_cmp(gAOrB, pMinusOne) >= 0) return -1;
    if (BN_cmp(g, pMinusOne) >= 0) return -1;

    // 2) gAOrB between 2^{2048-64} and p - 2^{2048-64}
    quint64 expWord = 2048 - 64;
    BIGNUM exp;
    BN_init(&exp);
    Utils::ensure(BN_set_word(&exp, expWord));

    BIGNUM base;
    BN_init(&base);
    Utils::ensure(BN_set_word(&base, 2));

    // lowLimit = base ^ exp
    BIGNUM lowLimit;
    BN_init(&lowLimit);
    Utils::ensure(BN_exp(&lowLimit, &base, &exp, BN_ctx));

    // highLimit = p - lowLimit
    BIGNUM highLimit;
    BN_init(&highLimit);
    BN_sub(&highLimit, p, &lowLimit);

    if (BN_cmp(gAOrB, &lowLimit) < 0) return -1;
    if (BN_cmp(gAOrB, &highLimit) > 0) return -1;

    BN_free(&one);
    BN_free(pMinusOne);
    BN_free(&exp);
    BN_free(&lowLimit);
    BN_free(&highLimit);
    delete g;
    delete gAOrB;
    delete p;

    return 0;
}
Beispiel #16
0
static RSA *
fermat_question_ask(const RSA *rsa)
{
  BIGNUM
    *a = BN_new(),
    *b = BN_new(),
    *a2 = BN_new(),
    *b2 = BN_new();
  BIGNUM *n = rsa->n;
  BIGNUM
    *tmp = BN_new(),
    *rem = BN_new(),
    *dssdelta = BN_new();
  BN_CTX *ctx = BN_CTX_new();
  RSA *ret = NULL;

  BN_sqrtmod(tmp, rem, n, ctx);
  /* Δ = |p - q| = |a + b - a + b| = |2b| > √N  2⁻¹⁰⁰ */
  /* BN_rshift(dssdelta, tmp, 101); */
  BN_one(dssdelta);
  BN_lshift(dssdelta, dssdelta, BN_num_bits(n) / 4 + 10);

  BN_copy(a, tmp);
  BN_sqr(a2, a, ctx);

  do {
    /* a² += 2a + 1 */
    BN_lshift1(tmp, a);
    BN_uiadd1(tmp);
    BN_add(a2, a2, tmp);
    /* a += 1 */
    BN_uiadd1(a);
    /* b² = a² - N */
    BN_usub(b2, a2, n);
    /* b */
    BN_sqrtmod(b, rem, b2, ctx);
  } while (!BN_is_zero(rem) && BN_cmp(b, dssdelta) < 1);

  if (BN_is_zero(rem)) {
    BN_uadd(a, a, b);
    ret = qa_RSA_recover(rsa, a, ctx);
  }

  BN_CTX_free(ctx);
  BN_free(a);
  BN_free(b);
  BN_free(a2);
  BN_free(b2);
  BN_free(dssdelta);
  BN_free(tmp);
  BN_free(rem);
  return ret;
}
Beispiel #17
0
/*
 * Computes signature and returns it as DSA_SIG structure
 */
DSA_SIG *gost_do_sign (const unsigned char *dgst, int dlen, DSA * dsa)
{
    BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL;

    DSA_SIG *newsig = DSA_SIG_new ();

    BIGNUM *md = hashsum2bn (dgst);

    /* check if H(M) mod q is zero */
    BN_CTX *ctx = BN_CTX_new ();

    BN_CTX_start (ctx);
    if (!newsig)
    {
        GOSTerr (GOST_F_GOST_DO_SIGN, GOST_R_NO_MEMORY);
        goto err;
    }
    tmp = BN_CTX_get (ctx);
    k = BN_CTX_get (ctx);
    tmp2 = BN_CTX_get (ctx);
    BN_mod (tmp, md, dsa->q, ctx);
    if (BN_is_zero (tmp))
    {
        BN_one (md);
    }
    do
    {
        do
        {
            /*Generate random number k less than q */
            BN_rand_range (k, dsa->q);
            /* generate r = (a^x mod p) mod q */
            BN_mod_exp (tmp, dsa->g, k, dsa->p, ctx);
            if (!(newsig->r))
                newsig->r = BN_new ();
            BN_mod (newsig->r, tmp, dsa->q, ctx);
        }
        while (BN_is_zero (newsig->r));
        /* generate s = (xr + k(Hm)) mod q */
        BN_mod_mul (tmp, dsa->priv_key, newsig->r, dsa->q, ctx);
        BN_mod_mul (tmp2, k, md, dsa->q, ctx);
        if (!newsig->s)
            newsig->s = BN_new ();
        BN_mod_add (newsig->s, tmp, tmp2, dsa->q, ctx);
    }
    while (BN_is_zero (newsig->s));
  err:
    BN_free (md);
    BN_CTX_end (ctx);
    BN_CTX_free (ctx);
    return newsig;
}
Beispiel #18
0
int test_rshift(BIO *bp,BN_CTX *ctx)
	{
	BIGNUM *a,*b,*c,*d,*e;
	int i;

	a=BN_new();
	b=BN_new();
	c=BN_new();
	d=BN_new();
	e=BN_new();
	BN_one(c);

	BN_bntest_rand(a,200,0,0); /**/
	a->neg=rand_neg();
	for (i=0; i<num0; i++)
		{
		BN_rshift(b,a,i+1);
		BN_add(c,c,c);
		if (bp != NULL)
			{
			if (!results)
				{
				BN_print(bp,a);
				BIO_puts(bp," / ");
				BN_print(bp,c);
				BIO_puts(bp," - ");
				}
			BN_print(bp,b);
			BIO_puts(bp,"\n");
			}
		BN_div(d,e,a,c,ctx);
		BN_sub(d,d,b);
		if(!BN_is_zero(d))
		    {
		    fprintf(stderr,"Right shift test failed!\n");
		    return 0;
		    }
		}
	BN_free(a);
	BN_free(b);
	BN_free(c);
	BN_free(d);
	BN_free(e);
	return(1);
	}
Beispiel #19
0
void setup()
{
    mod = BN_bin2bn( mod_buffer, /*len*/192, NULL );
    
    // modOrder = ( mod - 1 ) / 2
    BIGNUM* postSubtract = BN_new();
    BIGNUM* oneBN = BN_new();
    int ret = BN_one( oneBN );
    if ( ret != 1 )
    {
        printf( "setup: BN_one failed: %d", ret );
    }

    ret = BN_sub( postSubtract, mod, oneBN );  // r = a - b
    if ( ret != 1 )
    {
        printf( "setup: BN_sub failed: %d", ret );
    }
    BN_clear_free( oneBN );
    
    modOrder = BN_new();
    ret = BN_rshift1( modOrder, postSubtract ); // r = a Ö 2
    if ( ret != 1 )
    {
        printf( "setup: BN_rshift1 failed: %d", ret );
    }
    BN_clear_free( postSubtract );
    
    g2 = BN_new();
    g3 = BN_new();
    c1 = BN_new();
    c2 = BN_new();
    d1 = BN_new();
    d2 = BN_new();
    g3a = BN_new();
    
    // exponent used in step 1
    gen = BN_new();
    ret = BN_set_word( gen, 2 );
    
    match = 0;
}
Beispiel #20
0
/*	
 *	prime_totient(p,q,totient)
 *	Euler totient function of n, under the assumption
 *	that n = pq and p and q are prime
 *	inputs: BIGNUM* p
 *		BIGNUM* q
 *	output: BIGNUM* totient
 *
 *	return value: 	0 if failure
 *			1 if success
 */
int prime_totient(BIGNUM* p, BIGNUM* q, BIGNUM* totient){
	BIGNUM one;
	BN_init(&one);
	BN_one(&one);

	BIGNUM* temp_p = BN_dup(p);
	BIGNUM* temp_q = BN_dup(q);

	BN_sub_word(temp_p, 1);
	BN_sub_word(temp_q, 1);

	BN_CTX* ctx = BN_CTX_new();

	BN_mul(totient, temp_p, temp_q, ctx);

	BN_free(temp_p);
	BN_free(temp_q);
	BN_CTX_free(ctx);

	return 1;
}
Beispiel #21
0
BIGNUM * Polynomial::GetFunctionValue(BIGNUM *x)
{
    BN_CTX *ctx = BN_CTX_new();

    BIGNUM * value = BN_new() ;

    BN_copy(value,*(coefficients->begin())); 

    BIGNUM * tmp  = BN_new();
    BIGNUM * tmpx = BN_new();
    BN_one(tmpx);
    vector<BIGNUM *>::iterator iter; 
    for (iter=coefficients->begin()+1;iter!= coefficients->end();iter++)  
    {
         BN_mod_mul(tmpx,tmpx,x,p,ctx);
         BN_mod_mul(tmp,tmpx,*iter,p,ctx);	
         BN_mod_add(value,tmp,value,p,ctx);
    }
    BN_free(tmp);
    BN_free(tmpx);
    BN_CTX_free(ctx);
    return value;
}  
Beispiel #22
0
bool CECKey::TweakPublic(const unsigned char vchTweak[32]) {
    bool ret = true;
    BN_CTX *ctx = BN_CTX_new();
    BN_CTX_start(ctx);
    BIGNUM *bnTweak = BN_CTX_get(ctx);
    BIGNUM *bnOrder = BN_CTX_get(ctx);
    BIGNUM *bnOne = BN_CTX_get(ctx);
    const EC_GROUP *group = EC_KEY_get0_group(pkey);
    EC_GROUP_get_order(group, bnOrder, ctx); // what a grossly inefficient way to get the (constant) group order...
    BN_bin2bn(vchTweak, 32, bnTweak);
    if (BN_cmp(bnTweak, bnOrder) >= 0)
        ret = false; // extremely unlikely
    EC_POINT *point = EC_POINT_dup(EC_KEY_get0_public_key(pkey), group);
    BN_one(bnOne);
    EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx);
    if (EC_POINT_is_at_infinity(group, point))
        ret = false; // ridiculously unlikely
    EC_KEY_set_public_key(pkey, point);
    EC_POINT_free(point);
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    return ret;
}
Beispiel #23
0
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse. 
 * It does not contain branches that may leak sensitive information.
 */
static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
	{
	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
	BIGNUM local_A, local_B;
	BIGNUM *pA, *pB;
	BIGNUM *ret=NULL;
	int sign;

	bn_check_top(a);
	bn_check_top(n);

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	B = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	D = BN_CTX_get(ctx);
	M = BN_CTX_get(ctx);
	Y = BN_CTX_get(ctx);
	T = BN_CTX_get(ctx);
	if (T == NULL) goto err;

	if (in == NULL)
		R=BN_new();
	else
		R=in;
	if (R == NULL) goto err;

	BN_one(X);
	BN_zero(Y);
	if (BN_copy(B,a) == NULL) goto err;
	if (BN_copy(A,n) == NULL) goto err;
	A->neg = 0;

	if (B->neg || (BN_ucmp(B, A) >= 0))
		{
		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
	 	 * BN_div_no_branch will be called eventually.
	 	 */
		pB = &local_B;
		BN_with_flags(pB, B, BN_FLG_CONSTTIME);	
		if (!BN_nnmod(B, pB, A, ctx)) goto err;
		}
	sign = -1;
	/* From  B = a mod |n|,  A = |n|  it follows that
	 *
	 *      0 <= B < A,
	 *     -sign*X*a  ==  B   (mod |n|),
	 *      sign*Y*a  ==  A   (mod |n|).
	 */

	while (!BN_is_zero(B))
		{
		BIGNUM *tmp;
		
		/*
		 *      0 < B < A,
		 * (*) -sign*X*a  ==  B   (mod |n|),
		 *      sign*Y*a  ==  A   (mod |n|)
		 */

		/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
	 	 * BN_div_no_branch will be called eventually.
	 	 */
		pA = &local_A;
		BN_with_flags(pA, A, BN_FLG_CONSTTIME);	
		
		/* (D, M) := (A/B, A%B) ... */		
		if (!BN_div(D,M,pA,B,ctx)) goto err;
		
		/* Now
		 *      A = D*B + M;
		 * thus we have
		 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
		 */
		
		tmp=A; /* keep the BIGNUM object, the value does not matter */
		
		/* (A, B) := (B, A mod B) ... */
		A=B;
		B=M;
		/* ... so we have  0 <= B < A  again */
		
		/* Since the former  M  is now  B  and the former  B  is now  A,
		 * (**) translates into
		 *       sign*Y*a  ==  D*A + B    (mod |n|),
		 * i.e.
		 *       sign*Y*a - D*A  ==  B    (mod |n|).
		 * Similarly, (*) translates into
		 *      -sign*X*a  ==  A          (mod |n|).
		 *
		 * Thus,
		 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
		 * i.e.
		 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
		 *
		 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
		 *      -sign*X*a  ==  B   (mod |n|),
		 *       sign*Y*a  ==  A   (mod |n|).
		 * Note that  X  and  Y  stay non-negative all the time.
		 */
			
		if (!BN_mul(tmp,D,X,ctx)) goto err;
		if (!BN_add(tmp,tmp,Y)) goto err;

		M=Y; /* keep the BIGNUM object, the value does not matter */
		Y=X;
		X=tmp;
		sign = -sign;
		}
		
	/*
	 * The while loop (Euclid's algorithm) ends when
	 *      A == gcd(a,n);
	 * we have
	 *       sign*Y*a  ==  A  (mod |n|),
	 * where  Y  is non-negative.
	 */

	if (sign < 0)
		{
		if (!BN_sub(Y,n,Y)) goto err;
		}
	/* Now  Y*a  ==  A  (mod |n|).  */

	if (BN_is_one(A))
		{
		/* Y*a == 1  (mod |n|) */
		if (!Y->neg && BN_ucmp(Y,n) < 0)
			{
			if (!BN_copy(R,Y)) goto err;
			}
		else
			{
			if (!BN_nnmod(R,Y,n,ctx)) goto err;
			}
		}
	else
		{
		BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH,BN_R_NO_INVERSE);
		goto err;
		}
	ret=R;
err:
	if ((ret == NULL) && (in == NULL)) BN_free(R);
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return(ret);
	}
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) 
/* Returns 'ret' such that
 *      ret^2 == a (mod p),
 * using the Tonelli/Shanks algorithm (cf. Henri Cohen, "A Course
 * in Algebraic Computational Number Theory", algorithm 1.5.1).
 * 'p' must be prime!
 */
	{
	BIGNUM *ret = in;
	int err = 1;
	int r;
	BIGNUM *A, *b, *q, *t, *x, *y;
	int e, i, j;
	
	if (!BN_is_odd(p) || BN_abs_is_word(p, 1))
		{
		if (BN_abs_is_word(p, 2))
			{
			if (ret == NULL)
				ret = BN_new();
			if (ret == NULL)
				goto end;
			if (!BN_set_word(ret, BN_is_bit_set(a, 0)))
				{
				if (ret != in)
					BN_free(ret);
				return NULL;
				}
			bn_check_top(ret);
			return ret;
			}

		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
		return(NULL);
		}

	if (BN_is_zero(a) || BN_is_one(a))
		{
		if (ret == NULL)
			ret = BN_new();
		if (ret == NULL)
			goto end;
		if (!BN_set_word(ret, BN_is_one(a)))
			{
			if (ret != in)
				BN_free(ret);
			return NULL;
			}
		bn_check_top(ret);
		return ret;
		}

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	b = BN_CTX_get(ctx);
	q = BN_CTX_get(ctx);
	t = BN_CTX_get(ctx);
	x = BN_CTX_get(ctx);
	y = BN_CTX_get(ctx);
	if (y == NULL) goto end;
	
	if (ret == NULL)
		ret = BN_new();
	if (ret == NULL) goto end;

	/* A = a mod p */
	if (!BN_nnmod(A, a, p, ctx)) goto end;

	/* now write  |p| - 1  as  2^e*q  where  q  is odd */
	e = 1;
	while (!BN_is_bit_set(p, e))
		e++;
	/* we'll set  q  later (if needed) */

	if (e == 1)
		{
		/* The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
		 * modulo  (|p|-1)/2,  and square roots can be computed
		 * directly by modular exponentiation.
		 * We have
		 *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
		 * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
		 */
		if (!BN_rshift(q, p, 2)) goto end;
		q->neg = 0;
		if (!BN_add_word(q, 1)) goto end;
		if (!BN_mod_exp(ret, A, q, p, ctx)) goto end;
		err = 0;
		goto vrfy;
		}
	
	if (e == 2)
		{
		/* |p| == 5  (mod 8)
		 *
		 * In this case  2  is always a non-square since
		 * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
		 * So if  a  really is a square, then  2*a  is a non-square.
		 * Thus for
		 *      b := (2*a)^((|p|-5)/8),
		 *      i := (2*a)*b^2
		 * we have
		 *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
		 *         = (2*a)^((p-1)/2)
		 *         = -1;
		 * so if we set
		 *      x := a*b*(i-1),
		 * then
		 *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
		 *         = a^2 * b^2 * (-2*i)
		 *         = a*(-i)*(2*a*b^2)
		 *         = a*(-i)*i
		 *         = a.
		 *
		 * (This is due to A.O.L. Atkin, 
		 * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
		 * November 1992.)
		 */

		/* t := 2*a */
		if (!BN_mod_lshift1_quick(t, A, p)) goto end;

		/* b := (2*a)^((|p|-5)/8) */
		if (!BN_rshift(q, p, 3)) goto end;
		q->neg = 0;
		if (!BN_mod_exp(b, t, q, p, ctx)) goto end;

		/* y := b^2 */
		if (!BN_mod_sqr(y, b, p, ctx)) goto end;

		/* t := (2*a)*b^2 - 1*/
		if (!BN_mod_mul(t, t, y, p, ctx)) goto end;
		if (!BN_sub_word(t, 1)) goto end;

		/* x = a*b*t */
		if (!BN_mod_mul(x, A, b, p, ctx)) goto end;
		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;

		if (!BN_copy(ret, x)) goto end;
		err = 0;
		goto vrfy;
		}
	
	/* e > 2, so we really have to use the Tonelli/Shanks algorithm.
	 * First, find some  y  that is not a square. */
	if (!BN_copy(q, p)) goto end; /* use 'q' as temp */
	q->neg = 0;
	i = 2;
	do
		{
		/* For efficiency, try small numbers first;
		 * if this fails, try random numbers.
		 */
		if (i < 22)
			{
			if (!BN_set_word(y, i)) goto end;
			}
		else
			{
			if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) goto end;
			if (BN_ucmp(y, p) >= 0)
				{
				if (!(p->neg ? BN_add : BN_sub)(y, y, p)) goto end;
				}
			/* now 0 <= y < |p| */
			if (BN_is_zero(y))
				if (!BN_set_word(y, i)) goto end;
			}
		
		r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
		if (r < -1) goto end;
		if (r == 0)
			{
			/* m divides p */
			BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
			goto end;
			}
		}
	while (r == 1 && ++i < 82);
	
	if (r != -1)
		{
		/* Many rounds and still no non-square -- this is more likely
		 * a bug than just bad luck.
		 * Even if  p  is not prime, we should have found some  y
		 * such that r == -1.
		 */
		BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
		goto end;
		}

	/* Here's our actual 'q': */
	if (!BN_rshift(q, q, e)) goto end;

	/* Now that we have some non-square, we can find an element
	 * of order  2^e  by computing its q'th power. */
	if (!BN_mod_exp(y, y, q, p, ctx)) goto end;
	if (BN_is_one(y))
		{
		BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
		goto end;
		}

	/* Now we know that (if  p  is indeed prime) there is an integer
	 * k,  0 <= k < 2^e,  such that
	 *
	 *      a^q * y^k == 1   (mod p).
	 *
	 * As  a^q  is a square and  y  is not,  k  must be even.
	 * q+1  is even, too, so there is an element
	 *
	 *     X := a^((q+1)/2) * y^(k/2),
	 *
	 * and it satisfies
	 *
	 *     X^2 = a^q * a     * y^k
	 *         = a,
	 *
	 * so it is the square root that we are looking for.
	 */
	
	/* t := (q-1)/2  (note that  q  is odd) */
	if (!BN_rshift1(t, q)) goto end;
	
	/* x := a^((q-1)/2) */
	if (BN_is_zero(t)) /* special case: p = 2^e + 1 */
		{
		if (!BN_nnmod(t, A, p, ctx)) goto end;
		if (BN_is_zero(t))
			{
			/* special case: a == 0  (mod p) */
			BN_zero(ret);
			err = 0;
			goto end;
			}
		else
			if (!BN_one(x)) goto end;
		}
	else
		{
		if (!BN_mod_exp(x, A, t, p, ctx)) goto end;
		if (BN_is_zero(x))
			{
			/* special case: a == 0  (mod p) */
			BN_zero(ret);
			err = 0;
			goto end;
			}
		}

	/* b := a*x^2  (= a^q) */
	if (!BN_mod_sqr(b, x, p, ctx)) goto end;
	if (!BN_mod_mul(b, b, A, p, ctx)) goto end;
	
	/* x := a*x    (= a^((q+1)/2)) */
	if (!BN_mod_mul(x, x, A, p, ctx)) goto end;

	while (1)
		{
		/* Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
		 * where  E  refers to the original value of  e,  which we
		 * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
		 *
		 * We have  a*b = x^2,
		 *    y^2^(e-1) = -1,
		 *    b^2^(e-1) = 1.
		 */

		if (BN_is_one(b))
			{
			if (!BN_copy(ret, x)) goto end;
			err = 0;
			goto vrfy;
			}


		/* find smallest  i  such that  b^(2^i) = 1 */
		i = 1;
		if (!BN_mod_sqr(t, b, p, ctx)) goto end;
		while (!BN_is_one(t))
			{
			i++;
			if (i == e)
				{
				BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
				goto end;
				}
			if (!BN_mod_mul(t, t, t, p, ctx)) goto end;
			}
		

		/* t := y^2^(e - i - 1) */
		if (!BN_copy(t, y)) goto end;
		for (j = e - i - 1; j > 0; j--)
			{
			if (!BN_mod_sqr(t, t, p, ctx)) goto end;
			}
		if (!BN_mod_mul(y, t, t, p, ctx)) goto end;
		if (!BN_mod_mul(x, x, t, p, ctx)) goto end;
		if (!BN_mod_mul(b, b, y, p, ctx)) goto end;
		e = i;
		}

 vrfy:
	if (!err)
		{
		/* verify the result -- the input might have been not a square
		 * (test added in 0.9.8) */
		
		if (!BN_mod_sqr(x, ret, p, ctx))
			err = 1;
		
		if (!err && 0 != BN_cmp(x, A))
			{
			BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
			err = 1;
			}
		}

 end:
	if (err)
		{
		if (ret != NULL && ret != in)
			{
			BN_clear_free(ret);
			}
		ret = NULL;
		}
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return ret;
	}
Beispiel #25
0
BIGNUM *BN_mod_inverse(BIGNUM *in,
	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
	{
	BIGNUM *A,*B,*X,*Y,*M,*D,*T,*R=NULL;
	BIGNUM *ret=NULL;
	int sign;

	if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0))
		{
		return BN_mod_inverse_no_branch(in, a, n, ctx);
		}

	bn_check_top(a);
	bn_check_top(n);

	BN_CTX_start(ctx);
	A = BN_CTX_get(ctx);
	B = BN_CTX_get(ctx);
	X = BN_CTX_get(ctx);
	D = BN_CTX_get(ctx);
	M = BN_CTX_get(ctx);
	Y = BN_CTX_get(ctx);
	T = BN_CTX_get(ctx);
	if (T == NULL) goto err;

	if (in == NULL)
		R=BN_new();
	else
		R=in;
	if (R == NULL) goto err;

	BN_one(X);
	BN_zero(Y);
	if (BN_copy(B,a) == NULL) goto err;
	if (BN_copy(A,n) == NULL) goto err;
	A->neg = 0;
	if (B->neg || (BN_ucmp(B, A) >= 0))
		{
		if (!BN_nnmod(B, B, A, ctx)) goto err;
		}
	sign = -1;
	/* From  B = a mod |n|,  A = |n|  it follows that
	 *
	 *      0 <= B < A,
	 *     -sign*X*a  ==  B   (mod |n|),
	 *      sign*Y*a  ==  A   (mod |n|).
	 */

	if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048)))
		{
		/* Binary inversion algorithm; requires odd modulus.
		 * This is faster than the general algorithm if the modulus
		 * is sufficiently small (about 400 .. 500 bits on 32-bit
		 * sytems, but much more on 64-bit systems) */
		int shift;
		
		while (!BN_is_zero(B))
			{
			/*
			 *      0 < B < |n|,
			 *      0 < A <= |n|,
			 * (1) -sign*X*a  ==  B   (mod |n|),
			 * (2)  sign*Y*a  ==  A   (mod |n|)
			 */

			/* Now divide  B  by the maximum possible power of two in the integers,
			 * and divide  X  by the same value mod |n|.
			 * When we're done, (1) still holds. */
			shift = 0;
			while (!BN_is_bit_set(B, shift)) /* note that 0 < B */
				{
				shift++;
				
				if (BN_is_odd(X))
					{
					if (!BN_uadd(X, X, n)) goto err;
					}
				/* now X is even, so we can easily divide it by two */
				if (!BN_rshift1(X, X)) goto err;
				}
			if (shift > 0)
				{
				if (!BN_rshift(B, B, shift)) goto err;
				}


			/* Same for  A  and  Y.  Afterwards, (2) still holds. */
			shift = 0;
			while (!BN_is_bit_set(A, shift)) /* note that 0 < A */
				{
				shift++;
				
				if (BN_is_odd(Y))
					{
					if (!BN_uadd(Y, Y, n)) goto err;
					}
				/* now Y is even */
				if (!BN_rshift1(Y, Y)) goto err;
				}
			if (shift > 0)
				{
				if (!BN_rshift(A, A, shift)) goto err;
				}

			
			/* We still have (1) and (2).
			 * Both  A  and  B  are odd.
			 * The following computations ensure that
			 *
			 *     0 <= B < |n|,
			 *      0 < A < |n|,
			 * (1) -sign*X*a  ==  B   (mod |n|),
			 * (2)  sign*Y*a  ==  A   (mod |n|),
			 *
			 * and that either  A  or  B  is even in the next iteration.
			 */
			if (BN_ucmp(B, A) >= 0)
				{
				/* -sign*(X + Y)*a == B - A  (mod |n|) */
				if (!BN_uadd(X, X, Y)) goto err;
				/* NB: we could use BN_mod_add_quick(X, X, Y, n), but that
				 * actually makes the algorithm slower */
				if (!BN_usub(B, B, A)) goto err;
				}
			else
				{
				/*  sign*(X + Y)*a == A - B  (mod |n|) */
				if (!BN_uadd(Y, Y, X)) goto err;
				/* as above, BN_mod_add_quick(Y, Y, X, n) would slow things down */
				if (!BN_usub(A, A, B)) goto err;
				}
			}
		}
	else
		{
		/* general inversion algorithm */

		while (!BN_is_zero(B))
			{
			BIGNUM *tmp;
			
			/*
			 *      0 < B < A,
			 * (*) -sign*X*a  ==  B   (mod |n|),
			 *      sign*Y*a  ==  A   (mod |n|)
			 */
			
			/* (D, M) := (A/B, A%B) ... */
			if (BN_num_bits(A) == BN_num_bits(B))
				{
				if (!BN_one(D)) goto err;
				if (!BN_sub(M,A,B)) goto err;
				}
			else if (BN_num_bits(A) == BN_num_bits(B) + 1)
				{
				/* A/B is 1, 2, or 3 */
				if (!BN_lshift1(T,B)) goto err;
				if (BN_ucmp(A,T) < 0)
					{
					/* A < 2*B, so D=1 */
					if (!BN_one(D)) goto err;
					if (!BN_sub(M,A,B)) goto err;
					}
				else
					{
					/* A >= 2*B, so D=2 or D=3 */
					if (!BN_sub(M,A,T)) goto err;
					if (!BN_add(D,T,B)) goto err; /* use D (:= 3*B) as temp */
					if (BN_ucmp(A,D) < 0)
						{
						/* A < 3*B, so D=2 */
						if (!BN_set_word(D,2)) goto err;
						/* M (= A - 2*B) already has the correct value */
						}
					else
						{
						/* only D=3 remains */
						if (!BN_set_word(D,3)) goto err;
						/* currently  M = A - 2*B,  but we need  M = A - 3*B */
						if (!BN_sub(M,M,B)) goto err;
						}
					}
				}
			else
				{
				if (!BN_div(D,M,A,B,ctx)) goto err;
				}
			
			/* Now
			 *      A = D*B + M;
			 * thus we have
			 * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
			 */
			
			tmp=A; /* keep the BIGNUM object, the value does not matter */
			
			/* (A, B) := (B, A mod B) ... */
			A=B;
			B=M;
			/* ... so we have  0 <= B < A  again */
			
			/* Since the former  M  is now  B  and the former  B  is now  A,
			 * (**) translates into
			 *       sign*Y*a  ==  D*A + B    (mod |n|),
			 * i.e.
			 *       sign*Y*a - D*A  ==  B    (mod |n|).
			 * Similarly, (*) translates into
			 *      -sign*X*a  ==  A          (mod |n|).
			 *
			 * Thus,
			 *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
			 * i.e.
			 *        sign*(Y + D*X)*a  ==  B  (mod |n|).
			 *
			 * So if we set  (X, Y, sign) := (Y + D*X, X, -sign),  we arrive back at
			 *      -sign*X*a  ==  B   (mod |n|),
			 *       sign*Y*a  ==  A   (mod |n|).
			 * Note that  X  and  Y  stay non-negative all the time.
			 */
			
			/* most of the time D is very small, so we can optimize tmp := D*X+Y */
			if (BN_is_one(D))
				{
				if (!BN_add(tmp,X,Y)) goto err;
				}
			else
				{
				if (BN_is_word(D,2))
					{
					if (!BN_lshift1(tmp,X)) goto err;
					}
				else if (BN_is_word(D,4))
					{
					if (!BN_lshift(tmp,X,2)) goto err;
					}
				else if (D->top == 1)
					{
					if (!BN_copy(tmp,X)) goto err;
					if (!BN_mul_word(tmp,D->d[0])) goto err;
					}
				else
					{
					if (!BN_mul(tmp,D,X,ctx)) goto err;
					}
				if (!BN_add(tmp,tmp,Y)) goto err;
				}
			
			M=Y; /* keep the BIGNUM object, the value does not matter */
			Y=X;
			X=tmp;
			sign = -sign;
			}
		}
		
	/*
	 * The while loop (Euclid's algorithm) ends when
	 *      A == gcd(a,n);
	 * we have
	 *       sign*Y*a  ==  A  (mod |n|),
	 * where  Y  is non-negative.
	 */

	if (sign < 0)
		{
		if (!BN_sub(Y,n,Y)) goto err;
		}
	/* Now  Y*a  ==  A  (mod |n|).  */
	

	if (BN_is_one(A))
		{
		/* Y*a == 1  (mod |n|) */
		if (!Y->neg && BN_ucmp(Y,n) < 0)
			{
			if (!BN_copy(R,Y)) goto err;
			}
		else
			{
			if (!BN_nnmod(R,Y,n,ctx)) goto err;
			}
		}
	else
		{
		BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE);
		goto err;
		}
	ret=R;
err:
	if ((ret == NULL) && (in == NULL)) BN_free(R);
	BN_CTX_end(ctx);
	bn_check_top(ret);
	return(ret);
	}
int millerrabin(BIGNUM *bn_n, int maxitr, FILE *primesfile, int num_idnt){
	int s = 0;
	BIGNUM *bn_r = NULL;
	BIGNUM *bn_n_1 = NULL;
	BN_CTX *bn_ctx = NULL;
	BIGNUM *bn_a = NULL;
	BIGNUM *bn_y = NULL;
	BIGNUM *bn_1 = NULL;
	int i = 0;
	int j = 0;

	bn_a = BN_new();
	bn_y = BN_new();
	bn_r = BN_new();
	bn_1 = BN_new();
	BN_one(bn_1);
	bn_ctx = BN_CTX_new();
	bn_n_1 = BN_new();
	BN_CTX_init(bn_ctx);
	fseek(primesfile, 0 ,SEEK_SET);
	s = compute_sr(bn_n, bn_r, bn_n_1, bn_ctx);
	if(s == -1){
		return -1;
	}
	
	if(num_idnt == 0){
		fprintf(stdout, "n = %s\n", BN_bn2dec(bn_n));
	}
	printIndents(num_idnt);
	fprintf(stdout, "  n-1 = %s\n", BN_bn2dec(bn_n_1));
	printIndents(num_idnt);
	fprintf(stdout, "  s = %d\n", s);
	printIndents(num_idnt);
	fprintf(stdout, "  r = %s\n", BN_bn2dec(bn_r));
	
	for(i = 1; i <= maxitr; i++){
		printIndents(num_idnt);
		fprintf(stdout, "  Itr %d of %d, ", i, maxitr);
		
		ithPrime(i, primesfile, bn_a);
		if(BN_cmp(bn_a, bn_n_1) == 1){
			return -1;
		}
		
		compute_y(bn_y, bn_a, bn_r, bn_n, bn_ctx);
		
		
		if(BN_cmp(bn_y, bn_1) != 0 && BN_cmp(bn_y, bn_n_1) != 0){
			fprintf(stdout, "a = %s, y = %s\n", BN_bn2dec(bn_a), BN_bn2dec(bn_y));
			for(j = 1; j <= s - 1; j++){
				BN_mod_mul(bn_y, bn_y, bn_y, bn_n, bn_ctx);
				printIndents(num_idnt);
				fprintf(stdout, "    j = %d of %d, y = %s", j, s - 1, BN_bn2dec(bn_y));
				if(BN_cmp(bn_y, bn_n_1) == 0){
					fprintf(stdout, " (which is n-1)\n");
					break;
				}
				putchar('\n');
				
				if(BN_cmp(bn_y, bn_1) == 0){
					return 0;
				}
			}
			
			if(BN_cmp(bn_y, bn_n_1) != 0){
				printIndents(num_idnt);
				fprintf(stdout, "Miller-Rabin found a strong witness %s\n", BN_bn2dec(bn_a));
				return 0;
			}
		}
		else{
			if(BN_cmp(bn_y, bn_n_1) == 0){
				fprintf(stdout, "a = %s, y = %s (which is n-1)\n", BN_bn2dec(bn_a), BN_bn2dec(bn_y));
			}
			else{
				fprintf(stdout, "a = %s, y = %s\n", BN_bn2dec(bn_a), BN_bn2dec(bn_y));
			}
		}
		
		
	}
	printIndents(num_idnt);
	fprintf(stdout, "Miller-Rabin declares n to be a prime number\n");	
	return 1;
	
	BN_free(bn_1);
	BN_free(bn_a);
	BN_free(bn_y);
	BN_free(bn_r);
	BN_CTX_free(bn_ctx);
}
Beispiel #27
0
/* ------------------------------------------------------------------ */
int eg_decode (char *s, char *private_key, char **result)
{
    // there is no any padding processing in the decoding routine
    //  (see comment in rsa_encode)

    BIGNUM         message, *gamma, *delta, k, temp1, temp2, one;
    BIGNUM         *p=NULL, *g=NULL, *key=NULL;
    int            i, nl, nc, rc1, rc2, rc3, length, index;
    unsigned char  *buf = NULL;
    BN_CTX         *ctx = NULL;
    char           *p1, *p2, *p3;

    // setup key (p, g, key)
    p1 = strdup (private_key);
    p2 = strchr (p1, ':');
    if (p2 == NULL) {free (p1); return -1;}
    *p2 = '\0';
    p3 = strchr (p1, ',');
    if (p3 == NULL)
    {
        index = atoi (p1);
        if (index > sizeof(precomp)/sizeof(precomp[0])-1) return -1;
        p = NULL;
        rc1 = BN_hex2bn (&p, precomp[index].prime);
        if (rc1 == 0) return -1;
        g = BN_new ();
        if (g == NULL) return -1;
        BN_set_word (g, precomp[index].generator);
    }
    else
    {
        rc1 = BN_hex2bn (&p, p1);
        rc2 = BN_hex2bn (&g, p3+1);
        if (rc1 == 0 || rc2 == 0) return -1;
    }
    rc3 = BN_hex2bn (&key, p2+1);
    free (p1);
    if (rc3 == 0) return -1;

    // initialize temp variables
    BN_init (&message);
    BN_init (&k);
    BN_init (&temp1);
    BN_init (&temp2);
    BN_init (&one);
    BN_one (&one);
    gamma = BN_new ();
    if (gamma == NULL) return -1;
    delta = BN_new ();
    if (delta == NULL) return -1;
    ctx = BN_CTX_new ();
    if (ctx == NULL) return -1;

    // number of bytes in the modulus. this is the amount of bytes
    // we can convert in one gulp and should expect to be in one
    // group
    nl = BN_num_bytes (p);
    buf = malloc (nl);
    if (buf == NULL) return -1;

    // find the number of pieces in the encrypted message (the last
    // piece is not terminated with space)
    nc = str_numchars (s, ' ') + 1;
    
    // preallocate output buffer
    length = nc * nl;
    *result = malloc (length);
    if (*result == NULL) return -1;

    // cycle by pieces of input, each piece is 'nl' bytes long
    // (except the last one)
    p1 = s;
    for (i=0; i<nc; i++)
    {
        // extract next piece
        p2 = strchr (p1, ' ');
        if (p2 == NULL)
        {
            if (i != nc-1) return -1;
        }
        else
        {
            *p2 = '\0';
        }
        p3 = strchr (p1, ',');
        if (p3 == NULL) return -1;
        *p3++ = '\0';
        // convert to bignum
        rc1 = BN_hex2bn (&gamma, p1);
        if (rc1 == 0) return -1;
        rc1 = BN_hex2bn (&delta, p3);
        if (rc1 == 0) return -1;
        // ElGamal
        BN_sub (&temp1, p, &one);
        BN_sub (&temp2, &temp1, key);
        BN_mod_exp (&temp1, gamma, &temp2, p, ctx);
        BN_mod_mul (&message, &temp1, delta, p, ctx);
        // convert into binary output
        BN_bn2bin (&message, (unsigned char *)(*result+i*nl));
        // advance pointer to prepare search for next piece
        p1 = p2 + 1;
    }
    
    BN_CTX_free (ctx);
    memset (buf, 0, nl);
    free(buf);

    return length;
}
Beispiel #28
0
/* Computes scalar*point and stores the result in r.
 * point can not equal r.
 * Uses a modified algorithm 2P of
 *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
 *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
 *
 * To protect against side-channel attack the function uses constant time swap,
 * avoiding conditional branches.
 */
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
	const EC_POINT *point, BN_CTX *ctx)
	{
	BIGNUM *x1, *x2, *z1, *z2;
	int ret = 0, i;
	BN_ULONG mask,word;

	if (r == point)
		{
		ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
		return 0;
		}
	
	/* if result should be point at infinity */
	if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || 
		EC_POINT_is_at_infinity(group, point))
		{
		return EC_POINT_set_to_infinity(group, r);
		}

	/* only support affine coordinates */
	if (!point->Z_is_one) return 0;

	/* Since point_multiply is static we can guarantee that ctx != NULL. */
	BN_CTX_start(ctx);
	x1 = BN_CTX_get(ctx);
	z1 = BN_CTX_get(ctx);
	if (z1 == NULL) goto err;

	x2 = &r->X;
	z2 = &r->Y;

	bn_wexpand(x1, group->field.top);
	bn_wexpand(z1, group->field.top);
	bn_wexpand(x2, group->field.top);
	bn_wexpand(z2, group->field.top);

	if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
	if (!BN_one(z1)) goto err; /* z1 = 1 */
	if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
	if (!group->meth->field_sqr(group, x2, z2, ctx)) goto err;
	if (!BN_GF2m_add(x2, x2, &group->b)) goto err; /* x2 = x^4 + b */

	/* find top most bit and go one past it */
	i = scalar->top - 1;
	mask = BN_TBIT;
	word = scalar->d[i];
	while (!(word & mask)) mask >>= 1;
	mask >>= 1;
	/* if top most bit was at word break, go to next word */
	if (!mask) 
		{
		i--;
		mask = BN_TBIT;
		}

	for (; i >= 0; i--)
		{
		word = scalar->d[i];
		while (mask)
			{
			BN_consttime_swap(word & mask, x1, x2, group->field.top);
			BN_consttime_swap(word & mask, z1, z2, group->field.top);
			if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
			if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
			BN_consttime_swap(word & mask, x1, x2, group->field.top);
			BN_consttime_swap(word & mask, z1, z2, group->field.top);
			mask >>= 1;
			}
		mask = BN_TBIT;
		}

	/* convert out of "projective" coordinates */
	i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx);
	if (i == 0) goto err;
	else if (i == 1) 
		{
		if (!EC_POINT_set_to_infinity(group, r)) goto err;
		}
	else
		{
		if (!BN_one(&r->Z)) goto err;
		r->Z_is_one = 1;
		}

	/* GF(2^m) field elements should always have BIGNUM::neg = 0 */
	BN_set_negative(&r->X, 0);
	BN_set_negative(&r->Y, 0);

	ret = 1;

 err:
	BN_CTX_end(ctx);
	return ret;
	}
Beispiel #29
0
static void runtest(const char *json_base_fn, const char *ser_in_fn,
		    const char *block_in_hash, const char *tx_in_hash)
{
	/* read wallet data */
	char *json_fn = test_filename(json_base_fn);
	json_t *wallet = read_json(json_fn);
	assert(wallet != NULL);

	/* read block data containing incoming payment */
	char *fn = test_filename(ser_in_fn);
	void *data;
	size_t data_len;
	assert(bu_read_file(fn, &data, &data_len, 1 * 1024 * 1024) == true);

	struct bp_block block_in;
	bp_block_init(&block_in);
	struct const_buffer buf = { data, data_len };

	assert(deser_bp_block(&block_in, &buf) == true);
	bp_block_calc_sha256(&block_in);

	/* verify block-in data matches expected block-in hash */
	bu256_t check_hash;
	assert(hex_bu256(&check_hash, block_in_hash) == true);

	assert(bu256_equal(&block_in.sha256, &check_hash) == true);

	/* load key that has received an incoming payment */
	struct bp_key key;
	assert(bp_key_init(&key) == true);

	load_json_key(wallet, &key);

	/* load key into keyset */
	struct bp_keyset ks;
	bpks_init(&ks);

	assert(bpks_add(&ks, &key) == true);

	/* find key matches in block */
	parr *matches;
	matches = bp_block_match(&block_in, &ks);
	assert(matches != NULL);
	assert(matches->len == 1);

	struct bp_block_match *match = parr_idx(matches, 0);
	assert(match->n == 1);			/* match 2nd tx, index 1 */

	/* get matching transaction */
	struct bp_tx *tx = parr_idx(block_in.vtx, match->n);
	bp_tx_calc_sha256(tx);

	/* verify txid matches expected */
	char tx_hexstr[BU256_STRSZ];
	bu256_hex(tx_hexstr, &tx->sha256);
	assert(strcmp(tx_hexstr, tx_in_hash) == 0);

	/* verify mask matches 2nd txout (1 << 1) */
	BIGNUM tmp_mask;
	BN_init(&tmp_mask);
	BN_one(&tmp_mask);
	BN_lshift(&tmp_mask, &tmp_mask, 1);
	assert(BN_cmp(&tmp_mask, &match->mask) == 0);

	/* build merkle tree, tx's branch */
	parr *mtree = bp_block_merkle_tree(&block_in);
	assert(mtree != NULL);
	parr *mbranch = bp_block_merkle_branch(&block_in, mtree, match->n);
	assert(mbranch != NULL);

	/* verify merkle branch for tx matches expected */
	bu256_t mrk_check;
	bp_check_merkle_branch(&mrk_check, &tx->sha256, mbranch, match->n);
	assert(bu256_equal(&mrk_check, &block_in.hashMerkleRoot) == true);

	/* release resources */
	parr_free(mtree, true);
	parr_free(mbranch, true);
	BN_clear_free(&tmp_mask);
	parr_free(matches, true);
	bpks_free(&ks);
	bp_key_free(&key);
	bp_block_free(&block_in);
	json_decref(wallet);
	free(data);
	free(fn);
	free(json_fn);
}
Beispiel #30
0
void
printnumber(FILE *f, const struct number *b, u_int base)
{
	struct number	*int_part, *fract_part;
	int		digits;
	char		buf[11];
	size_t		sz;
	int		i;
	struct stack	stack;
	char		*p;

	charcount = 0;
	lastchar = -1;
	if (BN_is_zero(b->number))
		putcharwrap(f, '0');

	int_part = new_number();
	fract_part = new_number();
	fract_part->scale = b->scale;

	if (base <= 16)
		digits = 1;
	else {
		digits = snprintf(buf, sizeof(buf), "%u", base-1);
	}
	split_number(b, int_part->number, fract_part->number);

	i = 0;
	stack_init(&stack);
	while (!BN_is_zero(int_part->number)) {
		BN_ULONG rem = BN_div_word(int_part->number, base);
		stack_pushstring(&stack, get_digit(rem, digits, base));
		i++;
	}
	sz = i;
	if (BN_cmp(b->number, &zero) < 0)
		putcharwrap(f, '-');
	for (i = 0; i < sz; i++) {
		p = stack_popstring(&stack);
		if (base > 16)
			putcharwrap(f, ' ');
		printwrap(f, p);
		free(p);
	}
	stack_clear(&stack);
	if (b->scale > 0) {
		struct number	*num_base;
		BIGNUM		mult, stop;

		putcharwrap(f, '.');
		num_base = new_number();
		BN_set_word(num_base->number, base);
		BN_init(&mult);
		BN_one(&mult);
		BN_init(&stop);
		BN_one(&stop);
		scale_number(&stop, b->scale);

		i = 0;
		while (BN_cmp(&mult, &stop) < 0) {
			u_long	rem;

			if (i && base > 16)
				putcharwrap(f, ' ');
			i = 1;

			bmul_number(fract_part, fract_part, num_base);
			split_number(fract_part, int_part->number, NULL);
			rem = BN_get_word(int_part->number);
			p = get_digit(rem, digits, base);
			int_part->scale = 0;
			normalize(int_part, fract_part->scale);
			BN_sub(fract_part->number, fract_part->number,
			    int_part->number);
			printwrap(f, p);
			free(p);
			BN_mul_word(&mult, base);
		}
		free_number(num_base);
		BN_free(&mult);
		BN_free(&stop);
	}
	flushwrap(f);
	free_number(int_part);
	free_number(fract_part);
}