Exemplo n.º 1
0
BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
{
    BIGNUM *kv = NULL, *gb = NULL;
    BIGNUM *B = NULL, *k = NULL;
    BN_CTX *bn_ctx;

    if (b == NULL || N == NULL || g == NULL || v == NULL ||
        (bn_ctx = BN_CTX_new()) == NULL)
        return NULL;

    if ((kv = BN_new()) == NULL ||
        (gb = BN_new()) == NULL || (B = BN_new()) == NULL)
        goto err;

    /* B = g**b + k*v */

    if (!BN_mod_exp(gb, g, b, N, bn_ctx)
        || (k = srp_Calc_k(N, g)) == NULL
        || !BN_mod_mul(kv, v, k, N, bn_ctx)
        || !BN_mod_add(B, gb, kv, N, bn_ctx)) {
        BN_free(B);
        B = NULL;
    }
 err:
    BN_CTX_free(bn_ctx);
    BN_clear_free(kv);
    BN_clear_free(gb);
    BN_free(k);
    return B;
}
Exemplo n.º 2
0
BIGNUM *ClientSide::Calc_S(BIGNUM *B,BIGNUM *k,BIGNUM *g,BIGNUM *a,BIGNUM *u,BIGNUM *x,BIGNUM *N)
{
//S = (B - kg^x) ^ (a + ux)   (computes session key)
    BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *S = NULL;
    BN_CTX *bn_ctx;
    if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL
            || a == NULL || (bn_ctx = BN_CTX_new()) == NULL || k == NULL)
        return NULL;
    if ((tmp = BN_new()) == NULL ||
            (tmp2 = BN_new()) == NULL ||
            (tmp3 = BN_new()) == NULL || (S = BN_new()) == NULL)
    {
        BN_CTX_free(bn_ctx);
        BN_clear_free(tmp);
        BN_clear_free(tmp2);
        BN_clear_free(tmp3);
        BN_free(S);
        return NULL;
    }
    if(BN_mod_exp(tmp, g, x, N, bn_ctx))
        if(BN_mod_mul(tmp2, tmp, k, N, bn_ctx))
            if(BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
                if(BN_mod_mul(tmp3, u, x, N, bn_ctx))
                    if(BN_mod_add(tmp2, a, tmp3, N, bn_ctx))
                        if(BN_mod_exp(S, tmp, tmp2, N, bn_ctx))
                            ;
    BN_CTX_free(bn_ctx);
    BN_clear_free(tmp);
    BN_clear_free(tmp2);
    BN_clear_free(tmp3);
    return S;

}
Exemplo n.º 3
0
static int verifystep2(const JPakeUser * us, const JPakeUserPublic * them,
                       const JPakeParameters * params)
{
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    int ret = 0;

    printf("\n%s verifies %s:\n\n", us->p.name, them->name);

    // g' = g^{xc + xa + xb} [from our POV]
    // t1 = xa + xb
    BN_mod_add(t1, us->xa, us->xb, params->q, params->ctx);
    // t2 = g^{t1} = g^{xa+xb}
    BN_mod_exp(t2, params->g, t1, params->p, params->ctx);
    // t1 = g^{xc} * t2 = g^{xc + xa + xb}
    BN_mod_mul(t1, us->p.s1c.gx, t2, params->p, params->ctx);

    if (VerifyZKP
        (&us->p.s2.zkpxbs, us->p.s2.X, them, t1, params, them->base + 1,
         " * s"))
        ret = 1;

    // cleanup
    BN_free(t2);
    BN_free(t1);

    return ret;
}
Exemplo n.º 4
0
int Omega_vrfy(void *inner)
{
    assert(inner!=NULL);
    OmegaInner *self = (OmegaInner*)inner;
    
    int ret;
    BIGNUM *rbn;

    /* Derive e0~,e1~ from d0, d1 */
    rbn = BN_bin2bn(self->h0, self->bytelen_q, self->v_e0);
    assert(rbn!=NULL);
    rbn = BN_bin2bn(self->d1, self->bytelen_q, self->v_e1);
    assert(rbn!=NULL);
    
    assert(BN_cmp(self->v_e0, self->e0)==0);
    assert(BN_cmp(self->v_e1, self->e1)==0);


    /* Compute a~=g^z*h^(e0+e1) */
    ret = BN_mod_exp(self->gz, self->g, self->z, self->p, self->bnctx);
    assert(ret==1);
    ret = BN_mod_add(self->e0e1, self->e0, self->e1, self->q, self->bnctx);
    assert(ret==1);
    ret = BN_mod_exp(self->he0e1, self->h, self->e0e1, self->p, self->bnctx);
    assert(ret==1);
    ret = BN_mod_mul(self->v_a, self->gz, self->he0e1, self->p, self->bnctx);
    assert(ret==1);
    
    assert(BN_cmp(self->v_a, self->a)==0);

    /* Convert a~ to a~_bytes */
    BN2LenBin(self->v_a, self->v_a_bytes, self->bytelen_p);
    
    {
        int i;
        for (i=0; i<self->bytelen_p; i++)
            assert(self->v_a_bytes[i]==self->a_bytes[i]);
    }

    /* Compute h0~=H(a~bytes||00) */
    self->v_a_bytes[self->bytelen_p] = 0x00;
    VHash(self->v_a_bytes, self->bytelen_p+1, self->v_h0, self->bytelen_red);

    /* Check h0~==h0 */
    int i;
    int flag = 0;
    for (i=0; i<self->bytelen_red; i++)
        flag |= (self->h0[i] != self->v_h0[i]);
    assert(flag == 0);
    
    /* Compute h1~=H(a~bytes||01) */
    self->v_a_bytes[self->bytelen_p] = 0x01;
    VHash(self->v_a_bytes, self->bytelen_p+1, self->v_h1, self->bytelen_rec);

    /* Copmute m = h1~ xor d1*/
    for (i=0; i<self->bytelen_rec; i++)
        self->v_m[i] = self->v_h1[i]^self->d1[i];
    
    return 0;
}
Exemplo n.º 5
0
int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
    {
    BIGNUM *t1 = BN_new();
    BIGNUM *t2 = BN_new();
    int ret = 0;

   /*
    * g' = g^{xc + xa + xb} [from our POV]
    * t1 = xa + xb
    */
    BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
   /* t2 = g^{t1} = g^{xa+xb} */
    BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
   /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
    BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);

    if(verify_zkp(received, t1, ctx))
	ret = 1;
    else
	JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);

    compute_key(ctx, received->gx);

   /* cleanup */
    BN_free(t2);
    BN_free(t1);

    return ret;
    }
Exemplo n.º 6
0
static DSA *extract_dsa_pub_key(CPK_PUBLIC_PARAMS *param, const char *id)
{
	int e = 1;
	DSA *dsa = NULL;
	BIGNUM *bn = BN_new();
	BN_CTX *ctx = BN_CTX_new();	
	const unsigned char *p;
	int *index = NULL;
	int i, num_indexes, bn_size;

	
	if (!bn || !ctx) {
		goto err;
	}
	if (!(dsa = X509_ALGOR_get1_DSA(param->pkey_algor))) {
		goto err;
	}
	
	if ((num_indexes = CPK_MAP_num_indexes(param->map_algor)) <= 0) {
		goto err;
	}
	if (!(index = OPENSSL_malloc(sizeof(int) * num_indexes))) {
		goto err;
	}		
	if (!CPK_MAP_str2index(param->map_algor, id, index)) {
		goto err;
	}
	if (!dsa->pub_key) {
		if (!(dsa->pub_key = BN_new())) {
			goto err;
		}
	}
	BN_zero(dsa->pub_key);
	bn_size = BN_num_bytes(dsa->p);
	
	for (i = 0; i < num_indexes; i++) {
		p = M_ASN1_STRING_data(param->public_factors) + bn_size * index[i];
		if (!BN_bin2bn(p, bn_size, bn)) {
			goto err;
		}
		if (BN_is_zero(bn) || BN_cmp(bn, dsa->p) >= 0) {
			goto err;
		}
		if (!BN_mod_add(dsa->pub_key, dsa->pub_key, bn, dsa->p, ctx)) {
			goto err;
		}
	}
	e = 0;
	
err:
	if (e && dsa) {
		DSA_free(dsa);
		dsa = NULL;
	}
	if (bn) BN_free(bn);
	if (ctx) BN_CTX_free(ctx);
	if (index) OPENSSL_free(index);
	return dsa;
}
Exemplo n.º 7
0
// BCPKI
CKey CKey::GetDerivedKey(std::vector<unsigned char> ticket) const
{
  BIGNUM *bn = BN_bin2bn(&ticket[0],ticket.size(),BN_new());

  BN_CTX *ctx = NULL;
  if ((ctx = BN_CTX_new()) == NULL)
    throw key_error("CKey::DeriveKey() : BN_CTX_new failed");

  CKey key;
  if (HasPrivKey())
    { // privkey = privkey + ticket
      // snippet from ECDSA_SIG_recover_key_GFp
      // TODO check this again
      BIGNUM *order = NULL;
      if ((order = BN_new()) == NULL)
	throw key_error("CKey::DeriveKey() : BN_new failed");
      //      BN_CTX_start(ctx);
      //order = BN_CTX_get(ctx);
      if (!EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx)) 
      	throw key_error("CKey::DeriveKey() : EC_GROUP_get_order failed");
      if (!BN_mod_add(bn, bn, EC_KEY_get0_private_key(pkey), order, ctx))
      	throw key_error("CKey::DeriveKey() : BN_mod_add failed");
      if (!EC_KEY_regenerate_key(key.pkey,bn)) // sets private AND public key
        throw key_error("CKey::DeriveKey() : EC_KEY_regenerate_key failed");
      //      if (!EC_KEY_set_private_key(key.pkey, bn)) 
      //  throw key_error("CKey::DeriveKey() : EC_KEY_set_private_key failed");
      if (!EC_KEY_check_key(key.pkey))
	throw key_error("CKey::DeriveKey() : EC_KEY_check_key failed");
    }
  else
    { // add to pub key
      // begin snippet from EC_KEY_regenerate_key
      EC_POINT *pub_key = NULL;
      const EC_GROUP *group = EC_KEY_get0_group(pkey);

      pub_key = EC_POINT_new(group);
      if (pub_key == NULL)
        throw key_error("CKey::DeriveKey() : EC_POINT_new failed");

      if (!EC_POINT_mul(group, pub_key, bn, NULL, NULL, ctx))
        throw key_error("CKey::DeriveKey() : EC_POINT_mul failed");
      // end snippet from EC_KEY_regenerate_key
      // now pub_key = ticket * basepoint

      //const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
      //int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
      if (!EC_POINT_add(group, pub_key, pub_key, EC_KEY_get0_public_key(pkey), ctx))
        throw key_error("CKey::DeriveKey() : EC_POINT_add failed");

      //int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
      if (!EC_KEY_set_public_key(key.pkey, pub_key)) 
        throw key_error("CKey::DeriveKey() : EC_KEY_set_public_key failed");
    };

  key.fSet = true;
  key.SetCompressedPubKey();
  return key;
};
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
/* encrypts (or decrypts) with private key, not sensitive to
   timing attacks (blind encryption)
*/
void rsa_encrypt_secure(BIGNUM* m, const BIGNUM* d,
                        const BIGNUM* e, const BIGNUM* n,
                        const unsigned char * r_bin, int r_len) {
  BN_CTX *ctx;
  BIGNUM *tmp = BN_new();
  BIGNUM *r = BN_new();
  BIGNUM *r_inv = BN_new();

  ctx = BN_CTX_new();
  BN_bin2bn(r_bin, r_len, r);
  BN_mod(r, r, n, ctx); /* r = r % n */

  /*
  printf(" r input: ");BN_print_fp(stdout, r);
  printf(" n: ");BN_print_fp(stdout, n);
  printf("\n");
  */

  BN_mod(tmp, n, r, ctx);
  /*printf("r=");BN_print_fp(stdout, r); printf("; tmp=");BN_print_fp(stdout, tmp);*/
  while (BN_is_zero(tmp)) { /*  */
    BN_mod_add(r, r, BN_value_one(), n, ctx);
    BN_mod(tmp, n, r, ctx);
    /*printf("r=");BN_print_fp(stdout, r); printf("; tmp=");BN_print_fp(stdout, tmp);*/
  }
  /*printf("\n");*/

  BN_mod_inverse(r_inv, r, n, ctx);

  /*
  printf(" r = ");BN_print_fp(stdout, r);
  printf(" r_inv = ");BN_print_fp(stdout, r_inv);
  printf(" n = ");BN_print_fp(stdout, n);
  printf("\n");
  */

  BN_mod_exp(r, r, e, n, ctx);  /* r = r^e % n */
  BN_mod_mul(m, m, r, n, ctx);  /* m = m * r % n */

  rsa_encrypt(m, d, n);

  BN_mod_mul(m, m, r_inv, n, ctx);

  BN_free(r);
  BN_free(r_inv);
  BN_free(tmp);
  BN_CTX_free(ctx);
}
Exemplo n.º 10
0
/**
 * Helper method to calculate the y-value
 * for a given x-value and a polynomial
 *
 * @param x X-value
 * @param polynomial The underlying polynomial
 * @param t Threshold (determines the degree of the polynomial)
 * @param prime Prime for finite field arithmetic
 * @param y Pointer for storage of calculated y-value
 */
static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const unsigned char t, const BIGNUM prime, BIGNUM *y) {

	BIGNUM **pp;
	BIGNUM temp;
	BIGNUM exponent;

	unsigned long exp;
	BN_CTX *ctx;

	// Create context for temporary variables of OpenSSL engine
	ctx = BN_CTX_new();
	BN_CTX_init(ctx);

	BN_init(&temp);
	BN_init(&exponent);

	// Set y to ZERO
	BN_zero(y);

	/* Initialize the result using the secret value at position 0 of the polynomial */
	pp = polynomial;
	BN_copy(y, *pp);

	pp++;

	for (exp = 1; exp < t; exp++) {

		BN_copy(&temp, &x);

		BN_set_word(&exponent, exp);
		// temp = x^exponent mod prime
		BN_mod_exp(&temp, &x, &exponent, &prime, ctx);
		// exponent = temp * a = a * x^exponent mod prime
		BN_mod_mul(&exponent, &temp, *pp, &prime, ctx);
		// add the temp value from exponent to y
		BN_copy(&temp, y);
		BN_mod_add(y, &temp, &exponent, &prime, ctx);
		pp++;
	}

	BN_clear_free(&temp);
	BN_clear_free(&exponent);

	BN_CTX_free(ctx);
}
Exemplo n.º 11
0
BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x,
                            BIGNUM *a, BIGNUM *u)
{
    BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL;
    BN_CTX *bn_ctx;

    if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL
        || a == NULL || (bn_ctx = BN_CTX_new()) == NULL)
        return NULL;

    if ((tmp = BN_new()) == NULL ||
        (tmp2 = BN_new()) == NULL ||
        (tmp3 = BN_new()) == NULL ||
        (K = BN_new()) == NULL)
        goto err;

    if (!BN_mod_exp(tmp, g, x, N, bn_ctx))
        goto err;
    if ((k = srp_Calc_k(N, g)) == NULL)
        goto err;
    if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx))
        goto err;
    if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
        goto err;
    if (!BN_mod_mul(tmp3, u, x, N, bn_ctx))
        goto err;
    if (!BN_mod_add(tmp2, a, tmp3, N, bn_ctx))
        goto err;
    if (!BN_mod_exp(K, tmp, tmp2, N, bn_ctx))
        goto err;

 err:
    BN_CTX_free(bn_ctx);
    BN_clear_free(tmp);
    BN_clear_free(tmp2);
    BN_clear_free(tmp3);
    BN_free(k);
    return K;
}
Exemplo n.º 12
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;
}  
Exemplo n.º 13
0
// unsigned char *rgbHashData, 哈希
// unsigned char *rgbKeyDb, 私钥
// unsigned char *rs             签名
void eccHashSign(unsigned char *rgbHashData, unsigned char *rgbKeyDb, unsigned char *rs)
{
	int ok = 0;
	const EC_GROUP *ec_group;
	BIGNUM *priv_key;
	const BIGNUM *ck;
	BIGNUM *k = NULL;
	BN_CTX *ctx = NULL;
	BIGNUM *order = NULL;
	BIGNUM *e = NULL;
	BIGNUM *bn = NULL;
	int i;
	BIGNUM *r= BN_new(), *s = BN_new();


	EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
	ec_group = EC_KEY_get0_group(ec_key);
	priv_key = BN_new();
	BN_bin2bn(rgbKeyDb, 32, priv_key);
	EC_KEY_set_private_key(ec_key, priv_key);
	if (!ec_group || !priv_key) {
	}

	ctx = BN_CTX_new();
	order = BN_new();
	e = BN_new();
	bn = BN_new();
	if (!ctx || !order || !e || !bn) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_GROUP_get_order(ec_group, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
		goto err;
	}

	/* convert dgst to e */
	i = BN_num_bits(order);
#if 0
	if (8 * dgst_len > i) {
		dgst_len = (i + 7)/8;
	}
#endif
	if (!BN_bin2bn(rgbHashData, 32, e)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}

#if 0
	if ((8 * dgst_len > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
		ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
		goto err;
	}
#endif

	do {
		/* use or compute k and (kG).x */
			if (!sm2_sign_setup(ec_key, ctx, &k, &r)) {
				ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
				goto err;
			}
			ck = k;


		/* r = e + x (mod n) */	
		if (!BN_mod_add(r, r, e, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}


		if (!BN_mod_add(bn, r, ck, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}

		/* check r != 0 && r + k != n */
		if (BN_is_zero(r) || BN_is_zero(bn)) {
				continue;
		}

		/* s = ((1 + d)^-1 * (k - rd)) mod n */
		if (!BN_one(bn)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_add(s, priv_key, bn, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_inverse(s, s, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}

		if (!BN_mod_mul(bn, r, priv_key, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_sub(bn, ck, bn, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}
		if (!BN_mod_mul(s, s, bn, order, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
			goto err;
		}

		/* check s != 0 */
		if (!BN_is_zero(s)) 
			break;

	} while (1);

	ok = 1;
	BN_bn2bin(r, rs);
	BN_bn2bin(s, rs + 32);

err:
	if (k) BN_free(k);	
	if (ctx) BN_CTX_free(ctx);
	if (order) BN_free(order);
	if (e) BN_free(e);
	if (bn) BN_free(bn);	

}
Exemplo n.º 14
0
int StealthSecretSpend(ec_secret& scanSecret, ec_point& ephemPubkey, ec_secret& spendSecret, ec_secret& secretOut)
{
    /*
    
    c  = H(dP)
    R' = R + cG     [without decrypting wallet]
       = (f + c)G   [after decryption of wallet]
         Remember: mod curve.order, pad with 0x00s where necessary?
    */
    
    int rv = 0;
    std::vector<uint8_t> vchOutP;
    
    BN_CTX* bnCtx           = NULL;
    BIGNUM* bnScanSecret    = NULL;
    BIGNUM* bnP             = NULL;
    EC_POINT* P             = NULL;
    BIGNUM* bnOutP          = NULL;
    BIGNUM* bnc             = NULL;
    BIGNUM* bnOrder         = NULL;
    BIGNUM* bnSpend         = NULL;
    
    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
    
    if (!ecgrp)
    {
        printf("StealthSecretSpend(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };
    
    if (!(bnCtx = BN_CTX_new()))
    {
        printf("StealthSecretSpend(): BN_CTX_new failed.\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnScanSecret = BN_bin2bn(&scanSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnScanSecret BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnP = BN_bin2bn(&ephemPubkey[0], ephemPubkey.size(), BN_new())))
    {
        printf("StealthSecretSpend(): bnP BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(P = EC_POINT_bn2point(ecgrp, bnP, NULL, bnCtx)))
    {
        printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };
    
    // -- dP
    if (!EC_POINT_mul(ecgrp, P, NULL, P, bnScanSecret, bnCtx))
    {
        printf("StealthSecretSpend(): dP EC_POINT_mul failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnOutP = EC_POINT_point2bn(ecgrp, P, POINT_CONVERSION_COMPRESSED, BN_new(), bnCtx)))
    {
        printf("StealthSecretSpend(): P EC_POINT_bn2point failed\n");
        rv = 1;
        goto End;
    };
    
    
    vchOutP.resize(ec_compressed_size);
    if (BN_num_bytes(bnOutP) != (int) ec_compressed_size
        || BN_bn2bin(bnOutP, &vchOutP[0]) != (int) ec_compressed_size)
    {
        printf("StealthSecretSpend(): bnOutP incorrect length.\n");
        rv = 1;
        goto End;
    };
    
    uint8_t hash1[32];
    SHA256(&vchOutP[0], vchOutP.size(), (uint8_t*)hash1);
    
    
    if (!(bnc = BN_bin2bn(&hash1[0], 32, BN_new())))
    {
        printf("StealthSecretSpend(): BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnOrder = BN_new())
        || !EC_GROUP_get_order(ecgrp, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): EC_GROUP_get_order failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnSpend = BN_bin2bn(&spendSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnSpend BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };
    
    //if (!BN_add(r, a, b)) return 0;
    //return BN_nnmod(r, r, m, ctx);
    if (!BN_mod_add(bnSpend, bnSpend, bnc, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): bnSpend BN_mod_add failed.\n");
        rv = 1;
        goto End;
    };
    
    if (BN_is_zero(bnSpend)) // possible?
    {
        printf("StealthSecretSpend(): bnSpend is zero.\n");
        rv = 1;
        goto End;
    };
    
    if (BN_num_bytes(bnSpend) != (int) ec_secret_size
        || BN_bn2bin(bnSpend, &secretOut.e[0]) != (int) ec_secret_size)
    {
        printf("StealthSecretSpend(): bnSpend incorrect length.\n");
        rv = 1;
        goto End;
    };
    
    End:
    if (bnSpend)        BN_free(bnSpend);
    if (bnOrder)        BN_free(bnOrder);
    if (bnc)            BN_free(bnc);
    if (bnOutP)         BN_free(bnOutP);
    if (P)              EC_POINT_free(P);
    if (bnP)            BN_free(bnP);
    if (bnScanSecret)   BN_free(bnScanSecret);
    if (bnCtx)          BN_CTX_free(bnCtx);
    EC_GROUP_free(ecgrp);
    
    return rv;
};
Exemplo n.º 15
0
int StealthSharedToSecretSpend(ec_secret& sharedS, ec_secret& spendSecret, ec_secret& secretOut)
{
    
    int rv = 0;
    std::vector<uint8_t> vchOutP;
    
    BN_CTX* bnCtx           = NULL;
    BIGNUM* bnc             = NULL;
    BIGNUM* bnOrder         = NULL;
    BIGNUM* bnSpend         = NULL;
    
    EC_GROUP* ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1);
    
    if (!ecgrp)
    {
        printf("StealthSecretSpend(): EC_GROUP_new_by_curve_name failed.\n");
        return 1;
    };
    
    if (!(bnCtx = BN_CTX_new()))
    {
        printf("StealthSecretSpend(): BN_CTX_new failed.\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnc = BN_bin2bn(&sharedS.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): BN_bin2bn failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnOrder = BN_new())
        || !EC_GROUP_get_order(ecgrp, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): EC_GROUP_get_order failed\n");
        rv = 1;
        goto End;
    };
    
    if (!(bnSpend = BN_bin2bn(&spendSecret.e[0], ec_secret_size, BN_new())))
    {
        printf("StealthSecretSpend(): bnSpend BN_bin2bn failed.\n");
        rv = 1;
        goto End;
    };
    
    //if (!BN_add(r, a, b)) return 0;
    //return BN_nnmod(r, r, m, ctx);
    if (!BN_mod_add(bnSpend, bnSpend, bnc, bnOrder, bnCtx))
    {
        printf("StealthSecretSpend(): bnSpend BN_mod_add failed.\n");
        rv = 1;
        goto End;
    };
    
    if (BN_is_zero(bnSpend)) // possible?
    {
        printf("StealthSecretSpend(): bnSpend is zero.\n");
        rv = 1;
        goto End;
    };
    
    if (BN_num_bytes(bnSpend) != (int) ec_secret_size
        || BN_bn2bin(bnSpend, &secretOut.e[0]) != (int) ec_secret_size)
    {
        printf("StealthSecretSpend(): bnSpend incorrect length.\n");
        rv = 1;
        goto End;
    };
    
    End:
    if (bnSpend)        BN_free(bnSpend);
    if (bnOrder)        BN_free(bnOrder);
    if (bnc)            BN_free(bnc);
    if (bnCtx)          BN_CTX_free(bnCtx);
    EC_GROUP_free(ecgrp);
    
    return rv;
};
Exemplo n.º 16
0
ProductEvidence ProductEvidence_New(ProductStatement st, 
    const BIGNUM *a, const BIGNUM *r_a, const BIGNUM *r_b, const BIGNUM *r_c)
{
  ProductEvidence ev = safe_malloc(sizeof(*ev));

  const BIGNUM* g = IntegerGroup_GetG(st->group);
  const BIGNUM* h = IntegerGroup_GetH(st->group);
  const BIGNUM* q = IntegerGroup_GetQ(st->group);
  BN_CTX* ctx = IntegerGroup_GetCtx(st->group);

  // A = g^a h^{r_a}
  // B = g^b h^{r_b}
  // C = g^{ab} h^{r_c}

  // r_prod = r_c - a*r_b 
  BIGNUM* r_prod;
  CHECK_CALL(r_prod = BN_dup(a));
  CHECK_CALL(BN_mod_mul(r_prod, r_prod, r_b, q, ctx));
  CHECK_CALL(BN_mod_sub(r_prod, r_c, r_prod, q, ctx));
  
  // == Commitment == 
  // x, s1, s2 in [0, q)

  BIGNUM *x = IntegerGroup_RandomExponent(st->group);
  BIGNUM *s1 = IntegerGroup_RandomExponent(st->group);
  BIGNUM *s2 = IntegerGroup_RandomExponent(st->group);

  CHECK_CALL(x);
  CHECK_CALL(s1);
  CHECK_CALL(s2);

  // m1 = g^x h^s1
  BIGNUM* m1 = IntegerGroup_CascadeExponentiate(st->group, g, x, h, s1);
  CHECK_CALL(m1);
    
  // m2 = B^x h^s2
  BIGNUM* m2 = IntegerGroup_CascadeExponentiate(st->group, st->commit_b, x, h, s2);
  CHECK_CALL(m2);

  // == Challenge == 
  // c = H(g, h, q, p, A, B, C, m1, m2)
  ev->c = Commit(st, m1, m2);

  // == Response ==
  // z = x + ca mod q
  ev->z = BN_dup(ev->c);
  CHECK_CALL(ev->z);
  CHECK_CALL(BN_mod_mul(ev->z, ev->z, a, q, ctx));
  CHECK_CALL(BN_mod_add(ev->z, ev->z, x, q, ctx));

  // w1 = s1 + (c r_a) mod q
  ev->w1 = BN_dup(r_a);
  CHECK_CALL(ev->w1);
  CHECK_CALL(BN_mod_mul(ev->w1, ev->w1, ev->c, q, ctx));
  CHECK_CALL(BN_mod_add(ev->w1, ev->w1, s1, q, ctx));

  // w2 = s2 + (c r_prod) mod q
  ev->w2 = BN_dup(r_prod);
  CHECK_CALL(ev->w2);
  CHECK_CALL(BN_mod_mul(ev->w2, ev->w2, ev->c, q, ctx));
  CHECK_CALL(BN_mod_add(ev->w2, ev->w2, s2, q, ctx));

  // proof is (c, z, w1, w2)

  BN_free(m1);
  BN_free(m2);
  BN_clear_free(x);
  BN_clear_free(s1);
  BN_clear_free(s2);
  BN_clear_free(r_prod);

  return ev;
}
Exemplo n.º 17
0
ECDSA_SIG *
gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey)
{
	ECDSA_SIG *newsig = NULL;
	BIGNUM *order = NULL;
	const EC_GROUP *group;
	const BIGNUM *priv_key;
	BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, *k =
	    NULL, *e = NULL;
	EC_POINT *C = NULL;
	BN_CTX *ctx = BN_CTX_new();
	int ok = 0;

	if (ctx == NULL) {
		GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	BN_CTX_start(ctx);
	newsig = ECDSA_SIG_new();
	if (newsig == NULL) {
		GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	s = newsig->s;
	r = newsig->r;
	group = GOST_KEY_get0_group(eckey);
	if ((order = BN_CTX_get(ctx)) == NULL)
		goto err;
	if (EC_GROUP_get_order(group, order, ctx) == 0)
		goto err;
	priv_key = GOST_KEY_get0_private_key(eckey);
	if ((e = BN_CTX_get(ctx)) == NULL)
		goto err;
	if (BN_mod(e, md, order, ctx) == 0)
		goto err;
	if (BN_is_zero(e))
		BN_one(e);
	if ((k = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((X = BN_CTX_get(ctx)) == NULL)
		goto err;
	if ((C = EC_POINT_new(group)) == NULL)
		goto err;
	do {
		do {
			if (!BN_rand_range(k, order)) {
				GOSTerr(GOST_F_GOST2001_DO_SIGN,
					GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
				goto err;
			}
			/*
			 * We do not want timing information to leak the length
			 * of k, so we compute G*k using an equivalent scalar
			 * of fixed bit-length.
			 */
			if (BN_add(k, k, order) == 0)
				goto err;
			if (BN_num_bits(k) <= BN_num_bits(order))
				if (BN_add(k, k, order) == 0)
					goto err;

			if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) {
				GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
				goto err;
			}
			if (EC_POINT_get_affine_coordinates_GFp(group, C, X,
			    NULL, ctx) == 0) {
				GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
				goto err;
			}
			if (BN_nnmod(r, X, order, ctx) == 0)
				goto err;
		} while (BN_is_zero(r));
		/* s = (r*priv_key+k*e) mod order */
		if (tmp == NULL) {
			if ((tmp = BN_CTX_get(ctx)) == NULL)
				goto err;
		}
		if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0)
			goto err;
		if (tmp2 == NULL) {
			if ((tmp2 = BN_CTX_get(ctx)) == NULL)
				goto err;
		}
		if (BN_mod_mul(tmp2, k, e, order, ctx) == 0)
			goto err;
		if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0)
			goto err;
	} while (BN_is_zero(s));
	ok = 1;

err:
	EC_POINT_free(C);
	if (ctx != NULL) {
		BN_CTX_end(ctx);
		BN_CTX_free(ctx);
	}
	if (ok == 0) {
		ECDSA_SIG_free(newsig);
		newsig = NULL;
	}
	return newsig;
}
Exemplo n.º 18
0
int generateRingSignature(data_chunk &keyImage, uint256 &txnHash, int nRingSize, int nSecretOffset, ec_secret secret, const uint8_t *pPubkeys, uint8_t *pSigc, uint8_t *pSigr)
{
    if (fDebugRingSig)
        LogPrintf("%s: Ring size %d.\n", __func__, nRingSize);

    int rv = 0;
    int nBytes;

    BN_CTX_start(bnCtx);

    BIGNUM   *bnKS  = BN_CTX_get(bnCtx);
    BIGNUM   *bnK1  = BN_CTX_get(bnCtx);
    BIGNUM   *bnK2  = BN_CTX_get(bnCtx);
    BIGNUM   *bnT   = BN_CTX_get(bnCtx);
    BIGNUM   *bnH   = BN_CTX_get(bnCtx);
    BIGNUM   *bnSum = BN_CTX_get(bnCtx);
    EC_POINT *ptT1  = NULL;
    EC_POINT *ptT2  = NULL;
    EC_POINT *ptT3  = NULL;
    EC_POINT *ptPk  = NULL;
    EC_POINT *ptKi  = NULL;
    EC_POINT *ptL   = NULL;
    EC_POINT *ptR   = NULL;

    uint8_t tempData[66]; // hold raw point data to hash
    uint256 commitHash;
    ec_secret scData1, scData2;

    CHashWriter ssCommitHash(SER_GETHASH, PROTOCOL_VERSION);

    ssCommitHash << txnHash;

    // zero signature
    memset(pSigc, 0, EC_SECRET_SIZE * nRingSize);
    memset(pSigr, 0, EC_SECRET_SIZE * nRingSize);


    // ks = random 256 bit int mod P
    if (GenerateRandomSecret(scData1)
    && (rv = errorN(1, "%s: GenerateRandomSecret failed.", __func__)))
        goto End;

    if (!bnKS || !(BN_bin2bn(&scData1.e[0], EC_SECRET_SIZE, bnKS)))
    {
        LogPrintf("%s: BN_bin2bn failed.\n", __func__);
        rv = 1; goto End;
    };

    // zero sum
    if (!bnSum || !(BN_zero(bnSum)))
    {
        LogPrintf("%s: BN_zero failed.\n", __func__);
        rv = 1; goto End;
    };

    if (   !(ptT1 = EC_POINT_new(ecGrp))
        || !(ptT2 = EC_POINT_new(ecGrp))
        || !(ptT3 = EC_POINT_new(ecGrp))
        || !(ptPk = EC_POINT_new(ecGrp))
        || !(ptKi = EC_POINT_new(ecGrp))
        || !(ptL  = EC_POINT_new(ecGrp))
        || !(ptR  = EC_POINT_new(ecGrp)))
    {
        LogPrintf("%s: EC_POINT_new failed.\n", __func__);
        rv = 1; goto End;
    };

    // get keyimage as point
    if (!(bnT = BN_bin2bn(&keyImage[0], EC_COMPRESSED_SIZE, bnT))
        || !(ptKi) || !(ptKi = EC_POINT_bn2point(ecGrp, bnT, ptKi, bnCtx)))
    {
        LogPrintf("%s: extract ptKi failed.\n", __func__);
        rv = 1; goto End;
    };

    for (int i = 0; i < nRingSize; ++i)
    {
        if (i == nSecretOffset)
        {
            // k = random 256 bit int mod P
            // L = k * G
            // R = k * HashToEC(PKi)

            if (!EC_POINT_mul(ecGrp, ptL, bnKS, NULL, NULL, bnCtx))
            {
                LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
                rv = 1; goto End;
            };

            if (hashToEC(&pPubkeys[i * EC_COMPRESSED_SIZE], EC_COMPRESSED_SIZE, bnT, ptT1) != 0)
            {
                LogPrintf("%s: hashToEC failed.\n", __func__);
                rv = 1; goto End;
            };

            if (!EC_POINT_mul(ecGrp, ptR, NULL, ptT1, bnKS, bnCtx))
            {
                LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
                rv = 1; goto End;
            };

        } else
        {
            // k1 = random 256 bit int mod P
            // k2 = random 256 bit int mod P
            // Li = k1 * Pi + k2 * G
            // Ri = k1 * I + k2 * Hp(Pi)
            // ci = k1
            // ri = k2

            if (GenerateRandomSecret(scData1) != 0
                || !bnK1 || !(BN_bin2bn(&scData1.e[0], EC_SECRET_SIZE, bnK1))
                || GenerateRandomSecret(scData2) != 0
                || !bnK2 || !(BN_bin2bn(&scData2.e[0], EC_SECRET_SIZE, bnK2)))
            {
                LogPrintf("%s: k1 and k2 failed.\n", __func__);
                rv = 1; goto End;
            };

            // get Pk i as point
            if (!(bnT = BN_bin2bn(&pPubkeys[i * EC_COMPRESSED_SIZE], EC_COMPRESSED_SIZE, bnT))
                || !(ptPk) || !(ptPk = EC_POINT_bn2point(ecGrp, bnT, ptPk, bnCtx)))
            {
                LogPrintf("%s: extract ptPk failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptT1 = k1 * Pi
            if (!EC_POINT_mul(ecGrp, ptT1, NULL, ptPk, bnK1, bnCtx))
            {
                LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptT2 = k2 * G
            if (!EC_POINT_mul(ecGrp, ptT2, bnK2, NULL, NULL, bnCtx))
            {
                LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptL = ptT1 + ptT2
            if (!EC_POINT_add(ecGrp, ptL, ptT1, ptT2, bnCtx))
            {
                LogPrintf("%s: EC_POINT_add failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptT3 = Hp(Pi)
            if (hashToEC(&pPubkeys[i * EC_COMPRESSED_SIZE], EC_COMPRESSED_SIZE, bnT, ptT3) != 0)
            {
                LogPrintf("%s: hashToEC failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptT1 = k1 * I
            if (!EC_POINT_mul(ecGrp, ptT1, NULL, ptKi, bnK1, bnCtx))
            {
                LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptT2 = k2 * ptT3
            if (!EC_POINT_mul(ecGrp, ptT2, NULL, ptT3, bnK2, bnCtx))
            {
                LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
                rv = 1; goto End;
            };

            // ptR = ptT1 + ptT2
            if (!EC_POINT_add(ecGrp, ptR, ptT1, ptT2, bnCtx))
            {
                LogPrintf("%s: EC_POINT_add failed.\n", __func__);
                rv = 1; goto End;
            };

            memcpy(&pSigc[i * EC_SECRET_SIZE], &scData1.e[0], EC_SECRET_SIZE);
            memcpy(&pSigr[i * EC_SECRET_SIZE], &scData2.e[0], EC_SECRET_SIZE);

            // sum = (sum + sigc) % N , sigc == bnK1
            if (!BN_mod_add(bnSum, bnSum, bnK1, bnOrder, bnCtx))
            {
                LogPrintf("%s: BN_mod_add failed.\n", __func__);
                rv = 1; goto End;
            };
        };

        // -- add ptL and ptR to hash
        if (   !(EC_POINT_point2oct(ecGrp, ptL, POINT_CONVERSION_COMPRESSED, &tempData[0],  33, bnCtx) == (int) EC_COMPRESSED_SIZE)
            || !(EC_POINT_point2oct(ecGrp, ptR, POINT_CONVERSION_COMPRESSED, &tempData[33], 33, bnCtx) == (int) EC_COMPRESSED_SIZE))
        {
            LogPrintf("%s: extract ptL and ptR failed.\n", __func__);
            rv = 1; goto End;
        };

        ssCommitHash.write((const char*)&tempData[0], 66);
    };

    commitHash = ssCommitHash.GetHash();

    if (!(bnH) || !(bnH = BN_bin2bn(commitHash.begin(), EC_SECRET_SIZE, bnH)))
    {
        LogPrintf("%s: commitHash -> bnH failed.\n", __func__);
        rv = 1; goto End;
    };


    if (!BN_mod(bnH, bnH, bnOrder, bnCtx)) // this is necessary
    {
        LogPrintf("%s: BN_mod failed.\n", __func__);
        rv = 1; goto End;
    };

    // sigc[nSecretOffset] = (bnH - bnSum) % N
    if (!BN_mod_sub(bnT, bnH, bnSum, bnOrder, bnCtx))
    {
        LogPrintf("%s: BN_mod_sub failed.\n", __func__);
        rv = 1; goto End;
    };

    if ((nBytes = BN_num_bytes(bnT)) > (int)EC_SECRET_SIZE
        || BN_bn2bin(bnT, &pSigc[nSecretOffset * EC_SECRET_SIZE + (EC_SECRET_SIZE-nBytes)]) != nBytes)
    {
        LogPrintf("%s: bnT -> pSigc failed.\n", __func__);
        rv = 1; goto End;
    };

    // sigr[nSecretOffset] = (bnKS - sigc[nSecretOffset] * bnSecret) % N
    // reuse bnH for bnSecret
    if (!bnH || !(BN_bin2bn(&secret.e[0], EC_SECRET_SIZE, bnH)))
    {
        LogPrintf("%s: BN_bin2bn failed.\n", __func__);
        rv = 1; goto End;
    };

    // bnT = sigc[nSecretOffset] * bnSecret , TODO: mod N ?
    if (!BN_mul(bnT, bnT, bnH, bnCtx))
    {
        LogPrintf("%s: BN_mul failed.\n", __func__);
        rv = 1; goto End;
    };

    if (!BN_mod_sub(bnT, bnKS, bnT, bnOrder, bnCtx))
    {
        LogPrintf("%s: BN_mod_sub failed.\n", __func__);
        rv = 1; goto End;
    };

    if ((nBytes = BN_num_bytes(bnT)) > (int) EC_SECRET_SIZE
        || BN_bn2bin(bnT, &pSigr[nSecretOffset * EC_SECRET_SIZE + (EC_SECRET_SIZE-nBytes)]) != nBytes)
    {
        LogPrintf("%s: bnT -> pSigr failed.\n", __func__);
        rv = 1; goto End;
    };

    End:
    EC_POINT_free(ptT1);
    EC_POINT_free(ptT2);
    EC_POINT_free(ptT3);
    EC_POINT_free(ptPk);
    EC_POINT_free(ptKi);
    EC_POINT_free(ptL);
    EC_POINT_free(ptR);

    BN_CTX_end(bnCtx);

    return rv;
};
Exemplo n.º 19
0
void f( BIGNUM * x, BIGNUM * m ) {
    BN_mod_mul( x, x, x, m, bnctx ) ;
    BN_mod_add( x, x, bn_one, m, bnctx ) ;
}
Exemplo n.º 20
0
int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
{
    int ret = 0;
    BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
    const BIGNUM *p = group->field;
    BN_CTX *new_ctx = NULL;

    if (ctx == NULL) {
        ctx = new_ctx = BN_CTX_new();
        if (ctx == NULL) {
            ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
                  ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }
    BN_CTX_start(ctx);
    a = BN_CTX_get(ctx);
    b = BN_CTX_get(ctx);
    tmp_1 = BN_CTX_get(ctx);
    tmp_2 = BN_CTX_get(ctx);
    order = BN_CTX_get(ctx);
    if (order == NULL)
        goto err;

    if (group->meth->field_decode) {
        if (!group->meth->field_decode(group, a, group->a, ctx))
            goto err;
        if (!group->meth->field_decode(group, b, group->b, ctx))
            goto err;
    } else {
        if (!BN_copy(a, group->a))
            goto err;
        if (!BN_copy(b, group->b))
            goto err;
    }

    /*-
     * check the discriminant:
     * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
     * 0 =< a, b < p
     */
    if (BN_is_zero(a)) {
        if (BN_is_zero(b))
            goto err;
    } else if (!BN_is_zero(b)) {
        if (!BN_mod_sqr(tmp_1, a, p, ctx))
            goto err;
        if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
            goto err;
        if (!BN_lshift(tmp_1, tmp_2, 2))
            goto err;
        /* tmp_1 = 4*a^3 */

        if (!BN_mod_sqr(tmp_2, b, p, ctx))
            goto err;
        if (!BN_mul_word(tmp_2, 27))
            goto err;
        /* tmp_2 = 27*b^2 */

        if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
            goto err;
        if (BN_is_zero(a))
            goto err;
    }
    ret = 1;

 err:
    if (ctx != NULL)
        BN_CTX_end(ctx);
    BN_CTX_free(new_ctx);
    return ret;
}
Exemplo n.º 21
0
int main() {
    clock_t begin, end;
    double time_spent;

    printf("====================================================================\n");
    BIGNUM *a, *b, *c, *d, *gen, *prime_mod;
    char *c_str;
    BN_CTX *ctx; /* used internally by the bignum lib */
    //DH *dhparms;
    int csize;

    ctx = BN_CTX_new();
    a = BN_new();
    b = BN_new();
    c = BN_new();
    d = BN_new();
    
    prime_mod = BN_new();    

    BN_set_word(a, 6);
    BN_set_word(b, 7);

    BN_mul(c, a, b, ctx);

    BN_generate_prime(prime_mod,1024,0,0,0,0,0);
    //char * primeMOD= "D3BAAE3CE4015583027B1D822109B874CDC6A805BEFEB3DA4B6AD9C3DC1D90B1CF04D70906A1897AF231A03041D6456E7113C573E038DE0EDCF7CAE1B237AC2328110681C83AE86CC5E3268B5808551575E066858684448336E32A9BBCDDAA248BC2685C94142E88C6A68B021941B1C60744E137122A20A7D2CB1641B01E0117";
    //BN_hex2bn(&prime_mod, primeMOD);
    c_str = BN_bn2hex(prime_mod); /* there's also a BN_d ec2bn() */
    csize = BN_num_bits(prime_mod);
    //printf("prime_mod = %s size = %d\n", c_str, csize);

    // BN_rand(c, 1024, 0, 0);
    // c_str = BN_bn2hex(c);  //there's also a BN_d ec2bn() 
    // csize = BN_num_bits(c);
    // printf("C = %s size = %d\n", c_str, csize);


    //char * BN_T= "DFB9E8DC1BA16AD6EB2ABE6C02E5A9C7B279EEB52DEEBFD550172FC59CAF08534DFEC64BDDE9BD1BE6F9FBDA376C917E615C1F639FE81B8A594812D3E64B3AE4D7BB3F735106845571E16C348CB5100B71B805B70D0CF293727FEAF48F3FFD2A88B09D14AD9D6E314E35BB72238DFAD2549FCF7554F3E1645B118AADACCA35FA";

    // BN_hex2bn(&d, BN_T);
    // c_str = BN_bn2hex(d); 
    // csize = BN_num_bits(d);
    // printf("D = %s size = %d\n", c_str, csize);

    // BN_sqr(c, d, ctx); // c = d^2
    // c_str = BN_bn2hex(c); 
    // csize = BN_num_bits(c);
    // printf("c sq = %s size = %d\n", c_str, csize);

    // BN_mod_add(b, b, c, prime_mod, ctx); //b = b+c mod p

    // BN_mod(d, c, prime_mod, ctx); // d = c mod p
    // c_str = BN_bn2hex(d); 
    // csize = BN_num_bits(d);
    // printf("c mod d = %s size = %d\n", c_str, csize);

    // BN_mod_exp(b, c, d, prime_mod, ctx); // b = c^d mod p
    // c_str = BN_bn2hex(b); 
    // csize = BN_num_bits(b);
    // printf("c exp d = %s size = %d\n", c_str, csize);





    int i, j, _ITERATION_NOR, _ITERATION_EXP;
    _ITERATION_NOR = 1000000;
    _ITERATION_EXP = 1000;
    time_t now;
    time(&now);

    struct tm* now_tm;
    now_tm = localtime(&now);

    char out[80];
    char fileNameT[80];
    strftime (out, 80, "%Y-%m-%d %H:%M:%S", now_tm);
    strftime (fileNameT, 80, "%Y.%m.%d.%H.%M.%S", now_tm);

    char filename[20];
    strcpy (filename,"Bignumber_");
    strcat (filename,fileNameT);
    strcat (filename,".txt");

    FILE *f = fopen(filename, "a+");
    //setbuf(f, NULL);
    if (f == NULL)
    {
        printf("Error opening file!\n");
        exit(1);
    }
    
    fprintf(f, "\nTested started on %s\n", out);
    fprintf(f, "Normal iteration = %d\n", _ITERATION_NOR);
    fprintf(f, "Exp    iteration = %d\n", _ITERATION_EXP);
    fprintf(f, "MOD    iteration = %d\n", _ITERATION_NOR*10);
    fprintf(f, "===================================\n");


for(j=0;j<100;j++){ 
    printf("Iteration\t#%d\n", j+1);
    fprintf(f, "Iteration #%d\n", j+1);
    fflush(f);
BN_rand(a, 1024, 0, 0);
BN_rand(d, 1024, 0, 0);

// d^2
begin = clock();
    for(i=0;i<_ITERATION_NOR;i++){
        BN_sqr(c, d, ctx);
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Square %f\n", time_spent);
fprintf(f, "Square\t%f\n", time_spent);
fflush(f);

BN_rand(b, 1024, 0, 0);
BN_rand(c, 1024, 0, 0);
// b+c
begin = clock();
    for(i=0;i<_ITERATION_NOR;i++){
        BN_mod_add(b, b, c, prime_mod, ctx);
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Addition %f\n", time_spent);
fprintf(f, "Addition\t%f\n", time_spent);
fflush(f);

BN_rand(b, 1024, 0, 0);
// b mod p
begin = clock();
    for(i=0;i<_ITERATION_NOR*10;i++){
        BN_mod(d, b, prime_mod, ctx);
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("Modulus %f\n", time_spent);
fprintf(f, "Modulus\t%f\n", time_spent);
fflush(f);

BN_rand(c, 1024, 0, 0);
BN_rand(d, 1024, 0, 0);
// c ^ d mod p
begin = clock();
    for(i=0;i<_ITERATION_EXP;i++){
        BN_mod_exp(b, c, d, prime_mod, ctx); // b = c^d mod p
    }
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("exponetial %f\n", time_spent);
fprintf(f, "exponetial\t%f\n", time_spent);
fflush(f);
}
    time(&now);
    now_tm = localtime(&now);
    strftime (out, 80, "%Y-%m-%d %H:%M:%S", now_tm);
    fprintf(f, "\nTested ended on %s\n", out);








    BN_CTX_free(ctx);
    printf("====================================================================\n");
    fclose(f);

    return 0;
}
Exemplo n.º 22
0
/* Out: bytes_B, len_B.
 *
 * On failure, bytes_B will be set to NULL and len_B will be set to 0
 */
struct SRPVerifier *  srp_verifier_new( SRP_HashAlgorithm alg, SRP_NGType ng_type, const char * username,
                                        const unsigned char * bytes_s, int len_s,
                                        const unsigned char * bytes_v, int len_v,
                                        const unsigned char * bytes_A, int len_A,
                                        const unsigned char ** bytes_B, int * len_B,
                                        const char * n_hex, const char * g_hex,
                                        int rfc5054_compat )
{
    BIGNUM             *s    = BN_bin2bn(bytes_s, len_s, NULL);
    BIGNUM             *v    = BN_bin2bn(bytes_v, len_v, NULL);
    BIGNUM             *A    = BN_bin2bn(bytes_A, len_A, NULL);
    BIGNUM             *u    = 0;
    BIGNUM             *B    = BN_new();
    BIGNUM             *S    = BN_new();
    BIGNUM             *b    = BN_new();
    BIGNUM             *k    = 0;
    BIGNUM             *tmp1 = BN_new();
    BIGNUM             *tmp2 = BN_new();
    BN_CTX             *ctx  = BN_CTX_new();
    int                 ulen = strlen(username) + 1;
    NGConstant         *ng   = new_ng( ng_type, n_hex, g_hex );
    struct SRPVerifier *ver  = 0;

    *len_B   = 0;
    *bytes_B = 0;

    if( !s || !v || !A || !B || !S || !b || !tmp1 || !tmp2 || !ctx || !ng )
       goto cleanup_and_exit;

    ver = (struct SRPVerifier *) malloc( sizeof(struct SRPVerifier) );

    if (!ver)
       goto cleanup_and_exit;

    init_random(); /* Only happens once */

    ver->username = (char *) malloc( ulen );
    ver->hash_alg = alg;
    ver->ng       = ng;

    if (!ver->username)
    {
       free(ver);
       ver = 0;
       goto cleanup_and_exit;
    }

    memcpy( (char*)ver->username, username, ulen );

    ver->authenticated = 0;
    ver->rfc5054 = rfc5054_compat;

    /* SRP-6a safety check */
    BN_mod(tmp1, A, ng->N, ctx);
    if ( !BN_is_zero(tmp1) )
    {
       BN_rand(b, 256, -1, 0);

       if (rfc5054_compat)
          k = H_nn_rfc5054(alg, ng->N, ng->N, ng->g);
       else
          k = H_nn_orig(alg, ng->N, ng->g);

       /* B = kv + g^b */
       if (rfc5054_compat)
       {
          BN_mod_mul(tmp1, k, v, ng->N, ctx);
          BN_mod_exp(tmp2, ng->g, b, ng->N, ctx);
          BN_mod_add(B, tmp1, tmp2, ng->N, ctx);
       }
       else
       {
          BN_mul(tmp1, k, v, ctx);
          BN_mod_exp(tmp2, ng->g, b, ng->N, ctx);
          BN_add(B, tmp1, tmp2);
       }

       if (rfc5054_compat)
          u = H_nn_rfc5054(alg, ng->N, A, B);
       else
          u = H_nn_orig(alg, A, B);

       /* S = (A *(v^u)) ^ b */
       BN_mod_exp(tmp1, v, u, ng->N, ctx);
       BN_mul(tmp2, A, tmp1, ctx);
       BN_mod_exp(S, tmp2, b, ng->N, ctx);

       hash_num(alg, S, ver->session_key);

       calculate_M( alg, ng, ver->M, username, s, A, B, ver->session_key );
       calculate_H_AMK( alg, ver->H_AMK, A, ver->M, ver->session_key );

       *len_B   = BN_num_bytes(B);
       *bytes_B = (const unsigned char *)malloc( *len_B );

       if( !((const unsigned char *)*bytes_B) )
       {
          free( (void*) ver->username );
          free( ver );
          ver = 0;
          *len_B = 0;
          goto cleanup_and_exit;
       }

       BN_bn2bin( B, (unsigned char *) *bytes_B );

       ver->bytes_B = *bytes_B;
    }

 cleanup_and_exit:
    BN_free(s);
    BN_free(v);
    BN_free(A);
    if (u) BN_free(u);
    if (k) BN_free(k);
    BN_free(B);
    BN_free(S);
    BN_free(b);
    BN_free(tmp1);
    BN_free(tmp2);
    BN_CTX_free(ctx);

    return ver;
}
Exemplo n.º 23
0
int verifyRingSignature(data_chunk &keyImage, uint256 &txnHash, int nRingSize, const uint8_t *pPubkeys, const uint8_t *pSigc, const uint8_t *pSigr)
{
    if (fDebugRingSig)
    {
        // LogPrintf("%s size %d\n", __func__, nRingSize); // happens often
    };

    int rv = 0;

    BN_CTX_start(bnCtx);

    BIGNUM   *bnT   = BN_CTX_get(bnCtx);
    BIGNUM   *bnH   = BN_CTX_get(bnCtx);
    BIGNUM   *bnC   = BN_CTX_get(bnCtx);
    BIGNUM   *bnR   = BN_CTX_get(bnCtx);
    BIGNUM   *bnSum = BN_CTX_get(bnCtx);
    EC_POINT *ptT1  = NULL;
    EC_POINT *ptT2  = NULL;
    EC_POINT *ptT3  = NULL;
    EC_POINT *ptPk  = NULL;
    EC_POINT *ptKi  = NULL;
    EC_POINT *ptL   = NULL;
    EC_POINT *ptR   = NULL;
    EC_POINT *ptSi  = NULL;

    uint8_t tempData[66]; // hold raw point data to hash
    uint256 commitHash;
    CHashWriter ssCommitHash(SER_GETHASH, PROTOCOL_VERSION);

    ssCommitHash << txnHash;

    // zero sum
    if (!bnSum || !(BN_zero(bnSum)))
    {
        LogPrintf("%s: BN_zero failed.\n", __func__);
        rv = 1; goto End;
    };

    if (   !(ptT1 = EC_POINT_new(ecGrp))
        || !(ptT2 = EC_POINT_new(ecGrp))
        || !(ptT3 = EC_POINT_new(ecGrp))
        || !(ptPk = EC_POINT_new(ecGrp))
        || !(ptKi = EC_POINT_new(ecGrp))
        || !(ptL  = EC_POINT_new(ecGrp))
        || !(ptSi = EC_POINT_new(ecGrp))
        || !(ptR  = EC_POINT_new(ecGrp)))
    {
        LogPrintf("%s: EC_POINT_new failed.\n", __func__);
        rv = 1; goto End;
    };

    // get keyimage as point
    if (!(bnT = BN_bin2bn(&keyImage[0], EC_COMPRESSED_SIZE, bnT))
        || !(ptKi) || !(ptKi = EC_POINT_bn2point(ecGrp, bnT, ptKi, bnCtx)))
    {
        LogPrintf("%s: extract ptKi failed.\n", __func__);
        rv = 1; goto End;
    };

    for (int i = 0; i < nRingSize; ++i)
    {
        // Li = ci * Pi + ri * G
        // Ri = ci * I + ri * Hp(Pi)

        if (   !bnC || !(bnC = BN_bin2bn(&pSigc[i * EC_SECRET_SIZE], EC_SECRET_SIZE, bnC))
            || !bnR || !(bnR = BN_bin2bn(&pSigr[i * EC_SECRET_SIZE], EC_SECRET_SIZE, bnR)))
        {
            LogPrintf("%s: extract bnC and bnR failed.\n", __func__);
            rv = 1; goto End;
        };

        // get Pk i as point
        if (!(bnT = BN_bin2bn(&pPubkeys[i * EC_COMPRESSED_SIZE], EC_COMPRESSED_SIZE, bnT))
            || !(ptPk) || !(ptPk = EC_POINT_bn2point(ecGrp, bnT, ptPk, bnCtx)))
        {
            LogPrintf("%s: extract ptPk failed.\n", __func__);
            rv = 1; goto End;
        };

        // ptT1 = ci * Pi
        if (!EC_POINT_mul(ecGrp, ptT1, NULL, ptPk, bnC, bnCtx))
        {
            LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
            rv = 1; goto End;
        };

        // ptT2 = ri * G
        if (!EC_POINT_mul(ecGrp, ptT2, bnR, NULL, NULL, bnCtx))
        {
            LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
            rv = 1; goto End;
        };

        // ptL = ptT1 + ptT2
        if (!EC_POINT_add(ecGrp, ptL, ptT1, ptT2, bnCtx))
        {
            LogPrintf("%s: EC_POINT_add failed.\n", __func__);
            rv = 1; goto End;
        };

        // ptT3 = Hp(Pi)
        if (hashToEC(&pPubkeys[i * EC_COMPRESSED_SIZE], EC_COMPRESSED_SIZE, bnT, ptT3) != 0)
        {
            LogPrintf("%s: hashToEC failed.\n", __func__);
            rv = 1; goto End;
        };

        // DEBUGGING: ------- check if we can find the signer...
        // ptSi = Pi * bnT
        if ((!EC_POINT_mul(ecGrp, ptSi, NULL, ptPk, bnT, bnCtx)
           || false)
        && (rv = errorN(1, "%s: EC_POINT_mul failed.1", __func__)))
            goto End;

        if (0 == EC_POINT_cmp(ecGrp, ptSi, ptKi, bnCtx) )
            LogPrintf("signer is index %d\n", i);
        // DEBUGGING: - End - check if we can find the signer...

        // ptT1 = k1 * I
        if (!EC_POINT_mul(ecGrp, ptT1, NULL, ptKi, bnC, bnCtx))
        {
            LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
            rv = 1; goto End;
        };

        // ptT2 = k2 * ptT3
        if (!EC_POINT_mul(ecGrp, ptT2, NULL, ptT3, bnR, bnCtx))
        {
            LogPrintf("%s: EC_POINT_mul failed.\n", __func__);
            rv = 1; goto End;
        };

        // ptR = ptT1 + ptT2
        if (!EC_POINT_add(ecGrp, ptR, ptT1, ptT2, bnCtx))
        {
            LogPrintf("%s: EC_POINT_add failed.\n", __func__);
            rv = 1; goto End;
        };

        // sum = (sum + ci) % N
        if (!BN_mod_add(bnSum, bnSum, bnC, bnOrder, bnCtx))
        {
            LogPrintf("%s: BN_mod_add failed.\n", __func__);
            rv = 1; goto End;
        };

        // -- add ptL and ptR to hash
        if (   !(EC_POINT_point2oct(ecGrp, ptL, POINT_CONVERSION_COMPRESSED, &tempData[0],  33, bnCtx) == (int) EC_COMPRESSED_SIZE)
            || !(EC_POINT_point2oct(ecGrp, ptR, POINT_CONVERSION_COMPRESSED, &tempData[33], 33, bnCtx) == (int) EC_COMPRESSED_SIZE))
        {
            LogPrintf("%s: extract ptL and ptR failed.\n", __func__);
            rv = 1; goto End;
        };

        ssCommitHash.write((const char*)&tempData[0], 66);
    };

    commitHash = ssCommitHash.GetHash();

    if (!(bnH) || !(bnH = BN_bin2bn(commitHash.begin(), EC_SECRET_SIZE, bnH)))
    {
        LogPrintf("%s: commitHash -> bnH failed.\n", __func__);
        rv = 1; goto End;
    };

    if (!BN_mod(bnH, bnH, bnOrder, bnCtx))
    {
        LogPrintf("%s: BN_mod failed.\n", __func__);
        rv = 1; goto End;
    };

    // bnT = (bnH - bnSum) % N
    if (!BN_mod_sub(bnT, bnH, bnSum, bnOrder, bnCtx))
    {
        LogPrintf("%s: BN_mod_sub failed.\n", __func__);
        rv = 1; goto End;
    };

    // test bnT == 0  (bnSum == bnH)
    if (!BN_is_zero(bnT))
    {
        LogPrintf("%s: signature does not verify.\n", __func__);
        rv = 2;
    };

    End:

    EC_POINT_free(ptT1);
    EC_POINT_free(ptT2);
    EC_POINT_free(ptT3);
    EC_POINT_free(ptPk);
    EC_POINT_free(ptKi);
    EC_POINT_free(ptL);
    EC_POINT_free(ptR);
    EC_POINT_free(ptSi);

    BN_CTX_end(bnCtx);

    return rv;
};
Exemplo n.º 24
0
int
ecdh_im_compute_key(PACE_CTX * ctx, const BUF_MEM * s, const BUF_MEM * in,
        BN_CTX *bn_ctx)
{
    int ret = 0;
    BUF_MEM * x_mem = NULL;
    BIGNUM * a = NULL, *b = NULL, *p = NULL;
    BIGNUM * x = NULL, *y = NULL, *v = NULL, *u = NULL;
    BIGNUM * tmp = NULL, *tmp2 = NULL, *bn_inv = NULL;
    BIGNUM * two = NULL, *three = NULL, *four = NULL, *six = NULL;
    BIGNUM * twentyseven = NULL;
    EC_KEY *static_key = NULL, *ephemeral_key = NULL;
    EC_POINT *g = NULL;

    BN_CTX_start(bn_ctx);

    check((ctx && ctx->static_key && s && ctx->ka_ctx), "Invalid arguments"); 

    static_key = EVP_PKEY_get1_EC_KEY(ctx->static_key);
    if (!static_key)
        goto err;

    /* Setup all the variables*/
    a = BN_CTX_get(bn_ctx);
    b = BN_CTX_get(bn_ctx);
    p = BN_CTX_get(bn_ctx);
    x = BN_CTX_get(bn_ctx);
    y = BN_CTX_get(bn_ctx);
    v = BN_CTX_get(bn_ctx);
    two = BN_CTX_get(bn_ctx);
    three = BN_CTX_get(bn_ctx);
    four = BN_CTX_get(bn_ctx);
    six = BN_CTX_get(bn_ctx);
    twentyseven = BN_CTX_get(bn_ctx);
    tmp = BN_CTX_get(bn_ctx);
    tmp2 = BN_CTX_get(bn_ctx);
    bn_inv = BN_CTX_get(bn_ctx);
    if (!bn_inv)
        goto err;

    /* Encrypt the Nonce using the symmetric key in */
    x_mem = cipher_no_pad(ctx->ka_ctx, NULL, in, s, 1);
    if (!x_mem)
        goto err;

    /* Fetch the curve parameters */
    if (!EC_GROUP_get_curve_GFp(EC_KEY_get0_group(static_key), p, a, b, bn_ctx))
        goto err;

    /* Assign constants */
    if (    !BN_set_word(two,2)||
            !BN_set_word(three,3)||
            !BN_set_word(four,4)||
            !BN_set_word(six,6)||
            !BN_set_word(twentyseven,27)
            ) goto err;

    /* Check prerequisites for curve parameters */
    check(
            /* p > 3;*/
           (BN_cmp(p, three) == 1) &&
           /* p mod 3 = 2; (p has the form p=q^n, q prime) */
           BN_nnmod(tmp, p, three, bn_ctx) &&
           (BN_cmp(tmp, two) == 0),
        "Unsuited curve");

    /* Convert encrypted nonce to BIGNUM */
    u = BN_bin2bn((unsigned char *) x_mem->data, x_mem->length, u);
    if (!u)
        goto err;

    if ( /* v = (3a - u^4) / 6u mod p */
            !BN_mod_mul(tmp, three, a, p, bn_ctx) ||
            !BN_mod_exp(tmp2, u, four, p, bn_ctx) ||
            !BN_mod_sub(v, tmp, tmp2, p, bn_ctx) ||
            !BN_mod_mul(tmp, u, six, p, bn_ctx) ||
            /* For division within a galois field we need to compute
             * the multiplicative inverse of a number */
            !BN_mod_inverse(bn_inv, tmp, p, bn_ctx) ||
            !BN_mod_mul(v, v, bn_inv, p, bn_ctx) ||

            /* x = (v^2 - b - ((u^6)/27)) */
            !BN_mod_sqr(tmp, v, p, bn_ctx) ||
            !BN_mod_sub(tmp2, tmp, b, p, bn_ctx) ||
            !BN_mod_exp(tmp, u, six, p, bn_ctx) ||
            !BN_mod_inverse(bn_inv, twentyseven, p, bn_ctx) ||
            !BN_mod_mul(tmp, tmp, bn_inv, p, bn_ctx) ||
            !BN_mod_sub(x, tmp2, tmp, p, bn_ctx) ||

            /* x -> x^(1/3) = x^((2p^n -1)/3) */
            !BN_mul(tmp, two, p, bn_ctx) ||
            !BN_sub(tmp, tmp, BN_value_one()) ||

            /* Division is defined, because p^n = 2 mod 3 */
            !BN_div(tmp, y, tmp, three, bn_ctx) ||
            !BN_mod_exp(tmp2, x, tmp, p, bn_ctx) ||
            !BN_copy(x, tmp2) ||

            /* x += (u^2)/3 */
            !BN_mod_sqr(tmp, u, p, bn_ctx) ||
            !BN_mod_inverse(bn_inv, three, p, bn_ctx) ||
            !BN_mod_mul(tmp2, tmp, bn_inv, p, bn_ctx) ||
            !BN_mod_add(tmp, x, tmp2, p, bn_ctx) ||
            !BN_copy(x, tmp) ||

            /* y = ux + v */
            !BN_mod_mul(y, u, x, p, bn_ctx) ||
            !BN_mod_add(tmp, y, v, p, bn_ctx) ||
            !BN_copy(y, tmp)
            )
        goto err;

    /* Initialize ephemeral parameters with parameters from the static key */
    ephemeral_key = EC_KEY_dup(static_key);
    if (!ephemeral_key)
        goto err;
    EVP_PKEY_set1_EC_KEY(ctx->ka_ctx->key, ephemeral_key);

    /* configure the new EC_KEY */
    g = EC_POINT_new(EC_KEY_get0_group(ephemeral_key));
    if (!g)
        goto err;
    if (!EC_POINT_set_affine_coordinates_GFp(EC_KEY_get0_group(ephemeral_key), g,
            x, y, bn_ctx))
        goto err;

    ret = 1;

err:
    if (x_mem)
        BUF_MEM_free(x_mem);
    if (u)
        BN_free(u);
    BN_CTX_end(bn_ctx);
    if (g)
        EC_POINT_clear_free(g);
    /* Decrement reference count, keys are still available via PACE_CTX */
    if (static_key)
        EC_KEY_free(static_key);
    if (ephemeral_key)
        EC_KEY_free(ephemeral_key);

    return ret;
}
Exemplo n.º 25
0
static EC_KEY *extract_ec_priv_key(CPK_MASTER_SECRET *master, const char *id)
{
	int e = 1;
	EC_KEY *ec_key = NULL;
	const EC_GROUP *ec_group;
	EC_POINT *pub_key = NULL;
	BIGNUM *priv_key = BN_new();
	BIGNUM *order = BN_new();
	BIGNUM *bn = BN_new();
	BN_CTX *ctx = BN_CTX_new();
	int *index = NULL;
	int i, num_indexes, bn_size;

	
	if (!priv_key || !bn || !order || !ctx) {
		goto err;
	}
	
	if (!(ec_key = X509_ALGOR_get1_EC_KEY(master->pkey_algor))) {
		goto err;
	}
	ec_group = EC_KEY_get0_group(ec_key);
	if (!(pub_key = EC_POINT_new(ec_group))) {
		goto err;
	}

	if ((num_indexes = CPK_MAP_num_indexes(master->map_algor)) <= 0) {
		goto err;
	}
	if (!(index = OPENSSL_malloc(sizeof(int) * num_indexes))) {
		goto err;
	}		
	if (!CPK_MAP_str2index(master->map_algor, id, index)) {
		goto err;
	}
	
	BN_zero(priv_key);
	if (!(EC_GROUP_get_order(EC_KEY_get0_group(ec_key), order, ctx))) {
		goto err;
	}
	bn_size = BN_num_bytes(order);
	
	for (i = 0; i < num_indexes; i++) {
		const unsigned char *p = 
			M_ASN1_STRING_data(master->secret_factors) + 
			bn_size * index[i];
		
		if (!BN_bin2bn(p, bn_size, bn)) {
			goto err;
		}
		if (BN_is_zero(bn) || BN_cmp(bn, order) >= 0) {
			goto err;
		}		
		if (!BN_mod_add(priv_key, priv_key, bn, order, ctx)) {
			goto err;
		}
	}
	if (!EC_KEY_set_private_key(ec_key, priv_key)) {
		goto err;
	}

	if (!EC_POINT_mul(ec_group, pub_key, priv_key, NULL, NULL, ctx)) {
		goto err;
	}
	if (!EC_KEY_set_public_key(ec_key, pub_key)) {
		goto err;
	}
	e = 0;
	
err:
	if (e && ec_key) {
		EC_KEY_free(ec_key);
		ec_key = NULL;
	}
	if (priv_key) BN_free(priv_key);
	if (pub_key) EC_POINT_free(pub_key);
	if (order) BN_free(order);
	if (bn) BN_free(bn);
	if (ctx) BN_CTX_free(ctx);
	if (index) OPENSSL_free(index);
	return ec_key;
}
Exemplo n.º 26
0
// unsigned char *rgbHashData, 哈希数值
// unsigned char *rgbKeyPb, SM2公钥数据,Px Py 不含标志位 point_conversion_form_t
// unsigned char *rs 待验证的签名数据
unsigned char eccVerifySignature(unsigned char *rgbHashData, unsigned char *rgbKeyPb, unsigned char *rs)
{
	int ret = SM2_VERIFY_INNER_ERROR;
	EC_POINT *point = NULL;
	BN_CTX *ctx = NULL;
	BIGNUM *order = NULL;
	BIGNUM *e = NULL;
	BIGNUM *t = NULL;
	int i;

	EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);

	BIGNUM *x = BN_new();;
	BIGNUM *y = BN_new();;
	if (!BN_bin2bn(rgbKeyPb, 32, x)) {
		goto err;
	}
	if (!BN_bin2bn(rgbKeyPb + 32, 32, y)) {
		goto err;
	}
	if (!EC_KEY_set_public_key_affine_coordinates(ec_key, x, y)) {
		goto err;
	}
	const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);

	BIGNUM *r= BN_new(), *s = BN_new();
	BN_bin2bn(rs, 32, r);
	BN_bin2bn(rs + 32, 32, s);

	//// 相当于
	//EC_KEY *ret = EC_KEY_new();
	EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(NID_sm2p256v1);

	ctx = BN_CTX_new();
	order = BN_new();
	e = BN_new();
	t = BN_new();

	if (!ctx || !order || !e || !t) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_GROUP_get_order(ec_group, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}

	/* check r, s in [1, n-1] and r + s != 0 (mod n) */ 
	if (BN_is_zero(r) ||
		BN_is_negative(r) ||
		BN_ucmp(r, order) >= 0 || 
		BN_is_zero(s) ||
		BN_is_negative(s) || 
		BN_ucmp(s, order) >= 0) {

			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
			ret = 0;
			goto err;
	}

	/* check t = r + s != 0 */
	if (!BN_mod_add(t, r, s, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	if (BN_is_zero(t)) {
		ret = 0;
		goto err;
	}

	/* convert digest to e */
	i = BN_num_bits(order);
#if 0
	if (8 * dgstlen > i) {
		dgstlen = (i + 7)/8;
	}
#endif
	if (!BN_bin2bn(rgbHashData, 32, e)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
#if 0
	if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
#endif

	/* compute (x, y) = sG + tP, P is pub_key */
	if (!(point = EC_POINT_new(ec_group))) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
		goto err;
	}
	if (!EC_POINT_mul(ec_group, point, s, pub_key, t, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
		goto err;
	}
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
		if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, t, NULL, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	} else /* NID_X9_62_characteristic_two_field */ { 
		if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, t, NULL, ctx)) {
			ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
			goto err;
		}
	}
	if (!BN_nnmod(t, t, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}

	/* check (sG + tP).x + e  == sig.r */
	if (!BN_mod_add(t, t, e, order, ctx)) {
		ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
		goto err;
	}
	if (BN_ucmp(t, r) == 0) {
		ret = SM2_VERIFY_SUCCESS;
	} else {
		ret = SM2_VERIFY_FAILED;
	}

err:
	if (point) EC_POINT_free(point);
	if (order) BN_free(order);
	if (e) BN_free(e);
	if (t) BN_free(t);
	if (ctx) BN_CTX_free(ctx);
	return 0;
}
Exemplo n.º 27
0
/*
 * Computes gost_ec signature as DSA_SIG structure
 *
 */
DSA_SIG *gost_ec_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
    DSA_SIG *newsig = NULL, *ret = NULL;
    BIGNUM *md = NULL;
    BIGNUM *order = NULL;
    const EC_GROUP *group;
    const BIGNUM *priv_key;
    BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL,
        *k = NULL, *e = NULL;
    EC_POINT *C = NULL;
    BN_CTX *ctx;

    OPENSSL_assert(dgst != NULL && eckey != NULL);

    if (!(ctx = BN_CTX_new())) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    BN_CTX_start(ctx);
    OPENSSL_assert(dlen == 32 || dlen == 64);
    md = hashsum2bn(dgst, dlen);
    newsig = DSA_SIG_new();
    if (!newsig || !md) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    group = EC_KEY_get0_group(eckey);
    if (!group) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    order = BN_CTX_get(ctx);
    if (!order || !EC_GROUP_get_order(group, order, ctx)) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    priv_key = EC_KEY_get0_private_key(eckey);
    if (!priv_key) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    e = BN_CTX_get(ctx);
    if (!e || !BN_mod(e, md, order, ctx)) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR);
        goto err;
    }
#ifdef DEBUG_SIGN
    fprintf(stderr, "digest as bignum=");
    BN_print_fp(stderr, md);
    fprintf(stderr, "\ndigest mod q=");
    BN_print_fp(stderr, e);
    fprintf(stderr, "\n");
#endif
    if (BN_is_zero(e)) {
        BN_one(e);
    }
    k = BN_CTX_get(ctx);
    C = EC_POINT_new(group);
    if (!k || !C) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    do {
        do {
            if (!BN_rand_range(k, order)) {
                GOSTerr(GOST_F_GOST_EC_SIGN, GOST_R_RNG_ERROR);
                goto err;
            }
            /*
             * To avoid timing information leaking the length of k,
             * compute C*k using an equivalent scalar of fixed bit-length */
            if (!BN_add(k, k, order)
                || (BN_num_bits(k) <= BN_num_bits(order)
                    && !BN_add(k, k, order))) {
                goto err;
            }
            if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) {
                GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_EC_LIB);
                goto err;
            }
            if (!X)
                X = BN_CTX_get(ctx);
            if (!r)
                r = BN_CTX_get(ctx);
            if (!X || !r) {
                GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) {
                GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_EC_LIB);
                goto err;
            }

            if (!BN_nnmod(r, X, order, ctx)) {
                GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR);
                goto err;
            }
        }
        while (BN_is_zero(r));
        /* s =  (r*priv_key+k*e) mod order */
        if (!tmp)
            tmp = BN_CTX_get(ctx);
        if (!tmp2)
            tmp2 = BN_CTX_get(ctx);
        if (!s)
            s = BN_CTX_get(ctx);
        if (!tmp || !tmp2 || !s) {
            GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE);
            goto err;
        }

        if (!BN_mod_mul(tmp, priv_key, r, order, ctx)
            || !BN_mod_mul(tmp2, k, e, order, ctx)
            || !BN_mod_add(s, tmp, tmp2, order, ctx)) {
            GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR);
            goto err;
        }
    }
    while (BN_is_zero(s));

    newsig->s = BN_dup(s);
    newsig->r = BN_dup(r);
    if (!newsig->s || !newsig->r) {
        GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    ret = newsig;
 err:
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    if (C)
        EC_POINT_free(C);
    if (md)
        BN_free(md);
    if (!ret && newsig) {
        DSA_SIG_free(newsig);
    }
    return ret;
}
Exemplo n.º 28
0
/*
 * Computes gost2001 signature as DSA_SIG structure 
 *
 *
 */ 
DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
	{
	DSA_SIG *newsig = NULL;
	BIGNUM *md = hashsum2bn(dgst);
	BIGNUM *order = NULL;
	const EC_GROUP *group;
	const BIGNUM *priv_key;
	BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL;
	EC_POINT *C=NULL;
	BN_CTX *ctx = BN_CTX_new();	
	BN_CTX_start(ctx);
	OPENSSL_assert(dlen==32);
	newsig=DSA_SIG_new();
	if (!newsig) 
		{
		GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY);
		goto err;
		}	
	group = EC_KEY_get0_group(eckey);
	order=BN_CTX_get(ctx);
	EC_GROUP_get_order(group,order,ctx);
	priv_key = EC_KEY_get0_private_key(eckey);
	e = BN_CTX_get(ctx);
	BN_mod(e,md,order,ctx);
#ifdef DEBUG_SIGN
	fprintf(stderr,"digest as bignum=");
	BN_print_fp(stderr,md);
	fprintf(stderr,"\ndigest mod q=");
	BN_print_fp(stderr,e);
	fprintf(stderr,"\n");
#endif		
	if (BN_is_zero(e))
		{
		BN_one(e);
		}   
	k =BN_CTX_get(ctx);
	C=EC_POINT_new(group);
	do 
		{
		do 
			{
			if (!BN_rand_range(k,order)) 
				{
				GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
				DSA_SIG_free(newsig);
				goto err;
				}	
			if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
				{
				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
				DSA_SIG_free(newsig);
				goto err;
				}	
			if (!X) X=BN_CTX_get(ctx);
			if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
				{
				GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
				DSA_SIG_free(newsig);
				goto err;
				}	
			if (!r) r=BN_CTX_get(ctx);
			BN_nnmod(r,X,order,ctx);
			}
		while (BN_is_zero(r));
		/* s =  (r*priv_key+k*e) mod order */
		if (!tmp) tmp = BN_CTX_get(ctx);
		BN_mod_mul(tmp,priv_key,r,order,ctx);
		if (!tmp2) tmp2 = BN_CTX_get(ctx);
		BN_mod_mul(tmp2,k,e,order,ctx);
		if (!s) s=BN_CTX_get(ctx);
		BN_mod_add(s,tmp,tmp2,order,ctx);
		}
	while (BN_is_zero(s));	

	newsig->s=BN_dup(s);
	newsig->r=BN_dup(r);
	err:			
	BN_CTX_end(ctx);
	BN_CTX_free(ctx);
	EC_POINT_free(C);
	BN_free(md);
	return newsig;
	}