Ejemplo n.º 1
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 );
	}
Ejemplo n.º 2
0
bool android_pubkey_encode(const RSA* key, uint8_t* key_buffer, size_t size) {
  RSAPublicKey* key_struct = (RSAPublicKey*)key_buffer;
  bool ret = false;
  BN_CTX* ctx = BN_CTX_new();
  BIGNUM* r32 = BN_new();
  BIGNUM* n0inv = BN_new();
  BIGNUM* rr = BN_new();

  if (sizeof(RSAPublicKey) > size ||
      RSA_size(key) != ANDROID_PUBKEY_MODULUS_SIZE) {
    goto cleanup;
  }

  // Store the modulus size.
  key_struct->modulus_size_words = ANDROID_PUBKEY_MODULUS_SIZE_WORDS;

  // Compute and store n0inv = -1 / N[0] mod 2^32.
  if (!ctx || !r32 || !n0inv || !BN_set_bit(r32, 32) ||
      !BN_mod(n0inv, key->n, r32, ctx) ||
      !BN_mod_inverse(n0inv, n0inv, r32, ctx) || !BN_sub(n0inv, r32, n0inv)) {
    goto cleanup;
  }
  key_struct->n0inv = (uint32_t)BN_get_word(n0inv);

  // Store the modulus.
  if (!android_pubkey_encode_bignum(key->n, key_struct->modulus)) {
    goto cleanup;
  }

  // Compute and store rr = (2^(rsa_size)) ^ 2 mod N.
  if (!ctx || !rr || !BN_set_bit(rr, ANDROID_PUBKEY_MODULUS_SIZE * 8) ||
      !BN_mod_sqr(rr, rr, key->n, ctx) ||
      !android_pubkey_encode_bignum(rr, key_struct->rr)) {
    goto cleanup;
  }

  // Store the exponent.
  key_struct->exponent = (uint32_t)BN_get_word(key->e);

  ret = true;

cleanup:
  BN_free(rr);
  BN_free(n0inv);
  BN_free(r32);
  BN_CTX_free(ctx);
  return ret;
}
Ejemplo n.º 3
0
static u_long
get_ulong(struct number *n)
{

	normalize(n, 0);
	return (BN_get_word(n->number));
}
Ejemplo n.º 4
0
bool MakePrime(RsaParams params, const BIGNUM* value, BIGNUM** delta_ret, 
    BN_CTX* ctx)
{
  BIGNUM* tmp = BN_dup(value);
  CHECK_CALL(tmp);

  // Find a delta such that 
  //    p = value + delta
  // is prime
  const int delta_max = RsaParams_GetDeltaMax(params);

  bool is_even = !BN_is_odd(tmp);
  if(is_even) {
    CHECK_CALL(BN_add_word(tmp, 1));
  }

  if(!RsaPrime(*delta_ret, tmp, ctx)) return false;
 
  if(is_even) {
    CHECK_CALL(BN_add_word(*delta_ret, 1));
  }

//  printf("%llu %d\n", BN_get_word(*delta_ret), delta_max);
  if(BN_get_word(*delta_ret) > delta_max) return false;

  BN_clear_free(tmp);

  return true;
}
Ejemplo n.º 5
0
static int
test_BN_import_export(void)
{
    BIGNUM *bn;
    int ret = 0;
    int i;

    bn = BN_new();

    for (i = 0; i < sizeof(ietests)/sizeof(ietests[0]); i++) {
	size_t len;
	unsigned char *p;
	if (!BN_bin2bn((unsigned char*)ietests[i].data, ietests[i].len, bn))
	    return 1;
	if (BN_get_word(bn) != ietests[i].num)
	    return 1;
	len = BN_num_bytes(bn);
	if (len != ietests[i].len)
	    return 1;
	p = malloc(len + 1);
	p[len] = 0xf4;
	BN_bn2bin(bn, p);
	if (p[len] != 0xf4)
	    return 1;
	if (memcmp(p, ietests[i].data, ietests[i].len) != 0)
	    return 1;
	free(p);
    }

    BN_free(bn);
    return ret;
}
Ejemplo n.º 6
0
static void
to_ascii(void)
{
	struct number *n;
	struct value *value;
	char str[2];

	value = pop();
	if (value != NULL) {
		str[1] = '\0';
		switch (value->type) {
		case BCODE_NONE:
			return;
		case BCODE_NUMBER:
			n = value->u.num;
			normalize(n, 0);
			if (BN_num_bits(n->number) > 8)
				bn_check(BN_mask_bits(n->number, 8));
			str[0] = (char)BN_get_word(n->number);
			break;
		case BCODE_STRING:
			str[0] = value->u.string[0];
			break;
		}
		stack_free_value(value);
		push_string(bstrdup(str));
	}
}
Ejemplo n.º 7
0
Archivo: mpkgen.c Proyecto: 9cat/misc
void b58encode_check(void *buf, size_t len, char *result)
{
	unsigned char hash1[32];
	unsigned char hash2[32];

	int d, p;

	BN_CTX *bnctx;
	BIGNUM *bn, *bndiv, *bntmp;
	BIGNUM bna, bnb, bnbase, bnrem;
	unsigned char *binres;
	int brlen, zpfx;

	bnctx = BN_CTX_new();
	BN_init(&bna);
	BN_init(&bnb);
	BN_init(&bnbase);
	BN_init(&bnrem);
	BN_set_word(&bnbase, 58);

	bn = &bna;
	bndiv = &bnb;

	brlen = (2 * len) + 4;
	binres = (unsigned char*) malloc(brlen);
	memcpy(binres, buf, len);

	SHA256(binres, len, hash1);
	SHA256(hash1, sizeof(hash1), hash2);
	memcpy(&binres[len], hash2, 4);

	BN_bin2bn(binres, len + 4, bn);

	for (zpfx = 0; zpfx < (len + 4) && binres[zpfx] == 0; zpfx++);

	p = brlen;
	while (!BN_is_zero(bn)) {
		BN_div(bndiv, &bnrem, bn, &bnbase, bnctx);
		bntmp = bn;
		bn = bndiv;
		bndiv = bntmp;
		d = BN_get_word(&bnrem);
		binres[--p] = b58alphabet[d];
	}

	while (zpfx--) {
		binres[--p] = b58alphabet[0];
	}

	memcpy(result, &binres[p], brlen - p);
	result[brlen - p] = '\0';

	free(binres);
	BN_clear_free(&bna);
	BN_clear_free(&bnb);
	BN_clear_free(&bnbase);
	BN_clear_free(&bnrem);
	BN_CTX_free(bnctx);
}
Ejemplo n.º 8
0
int rsa_plaintext_to_word(const rsa_plaintext_t *m, unsigned long *a)
{
	OPENSSL_assert(m);
	OPENSSL_assert(a);
	
	*a = BN_get_word(m);
	return 0;
}
Ejemplo n.º 9
0
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
			  BIGNUM *num, int num_bits)
{
	int nwords = num_bits / 32;
	int size;
	uint32_t *buf, *ptr;
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -ENOMEM;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -ENOMEM;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	size = nwords * sizeof(uint32_t);
	buf = malloc(size);
	if (!buf) {
		fprintf(stderr, "Out of memory (%d bytes)\n", size);
		return -ENOMEM;
	}

	/* Write out modulus as big endian array of integers */
	for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		*ptr = cpu_to_fdt32(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	/*
	 * We try signing with successively increasing size values, so this
	 * might fail several times
	 */
	ret = fdt_setprop(blob, noffset, prop_name, buf, size);
	if (ret)
		return -FDT_ERR_NOSPACE;
	free(buf);
	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return ret;
}
Ejemplo n.º 10
0
/*
 * rsa_get_exponent(): - Get the public exponent from an RSA key
 */
static int rsa_get_exponent(RSA *key, uint64_t *e)
{
	int ret;
	BIGNUM *bn_te;
	uint64_t te;

	ret = -EINVAL;
	bn_te = NULL;

	if (!e)
		goto cleanup;

	if (BN_num_bits(key->e) > 64)
		goto cleanup;

	*e = BN_get_word(key->e);

	if (BN_num_bits(key->e) < 33) {
		ret = 0;
		goto cleanup;
	}

	bn_te = BN_dup(key->e);
	if (!bn_te)
		goto cleanup;

	if (!BN_rshift(bn_te, bn_te, 32))
		goto cleanup;

	if (!BN_mask_bits(bn_te, 32))
		goto cleanup;

	te = BN_get_word(bn_te);
	te <<= 32;
	*e |= te;
	ret = 0;

cleanup:
	if (bn_te)
		BN_free(bn_te);

	return ret;
}
Ejemplo n.º 11
0
static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
			  BIGNUM *num, int num_bits)
{
	int nwords = num_bits / 32;
	int size;
	uint32_t *buf, *ptr;
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -ENOMEM;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -ENOMEM;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	size = nwords * sizeof(uint32_t);
	buf = malloc(size);
	if (!buf) {
		fprintf(stderr, "Out of memory (%d bytes)\n", size);
		return -ENOMEM;
	}

	/* Write out modulus as big endian array of integers */
	for (ptr = buf + nwords - 1; ptr >= buf; ptr--) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		*ptr = cpu_to_fdt32(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	ret = fdt_setprop(blob, noffset, prop_name, buf, size);
	if (ret) {
		fprintf(stderr, "Failed to write public key to FIT\n");
		return -ENOSPC;
	}
	free(buf);
	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return ret;
}
Ejemplo n.º 12
0
static void
not(void)
{
	struct number *a;

	a = pop_number();
	if (a == NULL)
		return;
	a->scale = 0;
	bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
	push_number(a);
}
Ejemplo n.º 13
0
static int stackint(GPtrArray *stack, int index)
{
	struct buffer *buf = stacktop(stack, index);
	BIGNUM bn;
	BN_init(&bn);

	int ret = -1;

	if (!CastToBigNum(&bn, buf))
		goto out;

	if (!BN_is_negative(&bn))
		ret = BN_get_word(&bn);
	else {
		BN_set_negative(&bn, 0);
		ret = BN_get_word(&bn);
		ret = -ret;
	}

out:
	BN_clear_free(&bn);
	return ret;
}
Ejemplo n.º 14
0
int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx)
{
    int i;
    BIGNUM *offset_index;
    BIGNUM *offset_count;
    int ret = 0;

    OPENSSL_assert(bits > prime_multiplier_bits);

    BN_CTX_start(ctx);
    if ((offset_index = BN_CTX_get(ctx)) == NULL)
        goto err;
    if ((offset_count = BN_CTX_get(ctx)) == NULL)
        goto err;

    if (!BN_add_word(offset_count, prime_offset_count))
        goto err;

 loop:
    if (!BN_rand(rnd, bits - prime_multiplier_bits,
                 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
        goto err;
    if (BN_is_bit_set(rnd, bits))
        goto loop;
    if (!BN_rand_range(offset_index, offset_count))
        goto err;

    if (!BN_mul_word(rnd, prime_multiplier)
        || !BN_add_word(rnd, prime_offsets[BN_get_word(offset_index)]))
        goto err;

    /* we now have a random number 'rand' to test. */

    /* skip coprimes */
    for (i = first_prime_index; i < NUMPRIMES; i++) {
        /* check that rnd is a prime */
        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
        if (mod == (BN_ULONG)-1)
            goto err;
        if (mod <= 1)
            goto loop;
    }
    ret = 1;

 err:
    BN_CTX_end(ctx);
    bn_check_top(rnd);
    return ret;
}
Ejemplo n.º 15
0
static int
set_get(unsigned long num)
{
    BIGNUM *bn;

    bn = BN_new();
    if (!BN_set_word(bn, num))
	return 1;

    if (BN_get_word(bn) != num)
	return 1;

    BN_free(bn);
    return 0;
}
Ejemplo n.º 16
0
/*place base58 encoding of data into result*/
void base58_encode(unsigned char *data, unsigned int len, char *result) {
	const char code_string[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

    BIGNUM *x, *rem, *base, *tmp, *tmp2;
    x = BN_new();
	rem = BN_new();
	base = BN_new();
	tmp = BN_new();
	char * output_string = malloc(64);

	x = BN_bin2bn(data, len, x);

	BN_set_word(rem, 1);
	BN_set_word(base, 58);

	BN_CTX *bnctx;
	bnctx = BN_CTX_new();

	int i = 0;
	while (!BN_is_zero(x)) {
		BN_div(tmp, rem, x, base, bnctx);
		output_string[i++] = code_string[BN_get_word(rem)];
		tmp2 = x;
		x = tmp;
		tmp = tmp2;
	}

	//public key
	int i2 = 0;
	while (data[i2] == 0) {
		output_string[i++] = code_string[0];
		i2++;
	}

	int base58len = i;
	while (i>=0) {
		result[base58len-i] = output_string[i-1];
		i--;
	}
	result[base58len] = 0;

	BN_free(x);
	BN_free(base);
	BN_free(rem);
	BN_free(tmp);
	BN_CTX_free(bnctx);
	free(output_string);
}
Ejemplo n.º 17
0
int check(RSA* key) {
  int public_exponent = BN_get_word(key->e);
  int modulus = BN_num_bits(key->n);

  if (public_exponent != 65537) {
    fprintf(stderr, "WARNING: Public exponent should be 65537 (but is %d).\n",
            public_exponent);
  }

  if (modulus != 1024 && modulus != 2048 && modulus != 4096
      && modulus != 8192) {
    fprintf(stderr, "ERROR: Unknown modulus length = %d.\n", modulus);
    return 0;
  }
  return 1;
}
qint32 CryptoUtils::checkDHParams (BIGNUM *p, qint32 g) {
    if (g < 2 || g > 7) { return -1; }
    BIGNUM t;
    BN_init (&t);

    BIGNUM dh_g;
    BN_init (&dh_g);
    Utils::ensure (BN_set_word (&dh_g, 4 * g));

    Utils::ensure (BN_mod (&t, p, &dh_g, BN_ctx));
    qint32 x = BN_get_word (&t);
    Q_ASSERT(x >= 0 && x < 4 * g);

    BN_free (&dh_g);

    switch (g) {
    case 2:
        if (x != 7) { return -1; }
        break;
    case 3:
        if (x % 3 != 2 ) { return -1; }
        break;
    case 4:
        break;
    case 5:
        if (x % 5 != 1 && x % 5 != 4) { return -1; }
        break;
    case 6:
        if (x != 19 && x != 23) { return -1; }
        break;
    case 7:
        if (x % 7 != 3 && x % 7 != 5 && x % 7 != 6) { return -1; }
        break;
    }

    if (!checkPrime (p)) { return -1; }

    BIGNUM b;
    BN_init (&b);
    Utils::ensure (BN_set_word (&b, 2));
    Utils::ensure (BN_div (&t, 0, p, &b, BN_ctx));
    if (!checkPrime (&t)) { return -1; }
    BN_free (&b);
    BN_free (&t);
    return 0;
}
Ejemplo n.º 19
0
int check(RSA* key) {
  const BIGNUM *n, *e;
  int public_exponent, modulus;

  RSA_get0_key(key, &n, &e, NULL);
  public_exponent = BN_get_word(e);
  modulus = BN_num_bits(n);

  if (public_exponent != 3 && public_exponent != 65537) {
    fprintf(stderr,
            "WARNING: Public exponent should be 3 or 65537 (but is %d).\n",
            public_exponent);
  }

  if (modulus != 1024 && modulus != 2048 && modulus != 3072 && modulus != 4096
      && modulus != 8192) {
    fprintf(stderr, "ERROR: Unknown modulus length = %d.\n", modulus);
    return 0;
  }
  return 1;
}
int paillier_decryptll(long long *plain, const BIGNUM *c, const privKey *key, BN_CTX *ctx)
{
    int ret = 1;
    BN_CTX_start(ctx);
    BIGNUM *plain_BN = BN_CTX_get(ctx);

    if (paillier_decrypt(plain_BN, c, key, ctx) != 0)
        goto end;

    *plain = BN_get_word(plain_BN);
    if (*plain == 0xffffffffL)
        goto end;

    ret = 0;
end:
    if (ret)
    {
        ERR_load_crypto_strings();
        fprintf(stderr, "Can't decrypt: %s", ERR_error_string(ERR_get_error(), NULL));
    }

    BN_CTX_end(ctx);
    return ret;
}
static int get_key_bignum(BIGNUM *num, int num_bits, uint32_t *key_mod)
{
	BIGNUM *tmp, *big2, *big32, *big2_32;
	BN_CTX *ctx;
	int ret;

	tmp = BN_new();
	big2 = BN_new();
	big32 = BN_new();
	big2_32 = BN_new();
	if (!tmp || !big2 || !big32 || !big2_32) {
		fprintf(stderr, "Out of memory (bignum)\n");
		return -1;
	}
	ctx = BN_CTX_new();
	if (!tmp) {
		fprintf(stderr, "Out of memory (bignum context)\n");
		return -1;
	}
	BN_set_word(big2, 2L);
	BN_set_word(big32, 32L);
	BN_exp(big2_32, big2, big32, ctx); /* B = 2^32 */

	for (ret = 0; ret <= 63; ret++) {
		BN_mod(tmp, num, big2_32, ctx); /* n = N mod B */
		key_mod[ret] = htonl(BN_get_word(tmp));
		BN_rshift(num, num, 32); /*  N = N/B */
	}

	BN_free(tmp);
	BN_free(big2);
	BN_free(big32);
	BN_free(big2_32);

	return 0;
}
Ejemplo n.º 22
0
static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods)
{
    int i;
    BN_ULONG delta;
    BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
    char is_single_word = bits <= BN_BITS2;

 again:
    if (!BN_priv_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD))
        return 0;
    /* we now have a random number 'rnd' to test. */
    for (i = 1; i < NUMPRIMES; i++) {
        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
        if (mod == (BN_ULONG)-1)
            return 0;
        mods[i] = (prime_t) mod;
    }
    /*
     * If bits is so small that it fits into a single word then we
     * additionally don't want to exceed that many bits.
     */
    if (is_single_word) {
        BN_ULONG size_limit;

        if (bits == BN_BITS2) {
            /*
             * Shifting by this much has undefined behaviour so we do it a
             * different way
             */
            size_limit = ~((BN_ULONG)0) - BN_get_word(rnd);
        } else {
            size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1;
        }
        if (size_limit < maxdelta)
            maxdelta = size_limit;
    }
    delta = 0;
 loop:
    if (is_single_word) {
        BN_ULONG rnd_word = BN_get_word(rnd);

        /*-
         * In the case that the candidate prime is a single word then
         * we check that:
         *   1) It's greater than primes[i] because we shouldn't reject
         *      3 as being a prime number because it's a multiple of
         *      three.
         *   2) That it's not a multiple of a known prime. We don't
         *      check that rnd-1 is also coprime to all the known
         *      primes because there aren't many small primes where
         *      that's true.
         */
        for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) {
            if ((mods[i] + delta) % primes[i] == 0) {
                delta += 2;
                if (delta > maxdelta)
                    goto again;
                goto loop;
            }
        }
    } else {
        for (i = 1; i < NUMPRIMES; i++) {
            /*
             * check that rnd is not a prime and also that gcd(rnd-1,primes)
             * == 1 (except for 2)
             */
            if (((mods[i] + delta) % primes[i]) <= 1) {
                delta += 2;
                if (delta > maxdelta)
                    goto again;
                goto loop;
            }
        }
    }
    if (!BN_add_word(rnd, delta))
        return 0;
    if (BN_num_bits(rnd) != bits)
        goto again;
    bn_check_top(rnd);
    return 1;
}
Ejemplo n.º 23
0
static int
test_BN_uadd(void)
{
    BIGNUM *a, *b, *c;
    char *p;

    a = BN_new();
    b = BN_new();
    c = BN_new();

    BN_set_word(a, 1);
    BN_set_word(b, 2);

    BN_uadd(c, a, b);

    if (BN_get_word(c) != 3)
	return 1;

    BN_uadd(c, b, a);

    if (BN_get_word(c) != 3)
	return 1;

    BN_set_word(b, 0xff);

    BN_uadd(c, a, b);
    if (BN_get_word(c) != 0x100)
	return 1;

    BN_uadd(c, b, a);
    if (BN_get_word(c) != 0x100)
	return 1;

    BN_set_word(a, 0xff);

    BN_uadd(c, a, b);
    if (BN_get_word(c) != 0x1fe)
	return 1;

    BN_uadd(c, b, a);
    if (BN_get_word(c) != 0x1fe)
	return 1;


    BN_free(a);
    BN_free(b);

    BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
    BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA");

    BN_uadd(c, b, a);
    p = BN_bn2hex(c);
    if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
	free(p);
	return 1;
    }
    free(p);

    BN_uadd(c, a, b);
    p = BN_bn2hex(c);
    if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
	free(p);
	return 1;
    }
    free(p);

    BN_free(a);
    BN_free(b);
    BN_free(c);

    return 0;
}
Ejemplo n.º 24
0
static int probable_prime(BIGNUM *rnd, int bits)
	{
	int i;
	prime_t mods[NUMPRIMES];
	BN_ULONG delta;
	BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES-1];
	char is_single_word = bits <= BN_BITS2;

again:
	if (!BN_rand(rnd,bits,1,1)) return(0);
	/* we now have a random number 'rnd' to test. */
	for (i=1; i<NUMPRIMES; i++)
		mods[i]=(prime_t)BN_mod_word(rnd,(BN_ULONG)primes[i]);
	/* If bits is so small that it fits into a single word then we
	 * additionally don't want to exceed that many bits. */
	if (is_single_word)
		{
		BN_ULONG size_limit = (((BN_ULONG) 1) << bits) - BN_get_word(rnd) - 1;
		if (size_limit < maxdelta)
			maxdelta = size_limit;
		}
	delta=0;
loop:
	if (is_single_word)
		{
		BN_ULONG rnd_word = BN_get_word(rnd);

		/* In the case that the candidate prime is a single word then
		 * we check that:
		 *   1) It's greater than primes[i] because we shouldn't reject
		 *      3 as being a prime number because it's a multiple of
		 *      three.
		 *   2) That it's not a multiple of a known prime. We don't
		 *      check that rnd-1 is also coprime to all the known
		 *      primes because there aren't many small primes where
		 *      that's true. */
		for (i=1; i<NUMPRIMES && primes[i]<rnd_word; i++)
			{
			if ((mods[i]+delta)%primes[i] == 0)
				{
				delta+=2;
				if (delta > maxdelta) goto again;
				goto loop;
				}
			}
		}
	else
		{
		for (i=1; i<NUMPRIMES; i++)
			{
			/* check that rnd is not a prime and also
			 * that gcd(rnd-1,primes) == 1 (except for 2) */
			if (((mods[i]+delta)%primes[i]) <= 1)
				{
				delta+=2;
				if (delta > maxdelta) goto again;
				goto loop;
				}
			}
		}
	if (!BN_add_word(rnd,delta)) return(0);
	if (BN_num_bits(rnd) != bits)
		goto again;
	bn_check_top(rnd);
	return(1);
	}
Ejemplo n.º 25
0
void *
vg_thread_loop(void *arg)
{
	unsigned char hash_buf[128];
	unsigned char *eckey_buf;
	unsigned char hash1[32];

	int i, c, len, output_interval;
	int hash_len;

	const BN_ULONG rekey_max = 10000000;
	BN_ULONG npoints, rekey_at, nbatch;

	vg_context_t *vcp = (vg_context_t *) arg;
	EC_KEY *pkey = NULL;
	const EC_GROUP *pgroup;
	const EC_POINT *pgen;
	const int ptarraysize = 256;
	EC_POINT *ppnt[ptarraysize];
	EC_POINT *pbatchinc;

	vg_test_func_t test_func = vcp->vc_test;
	vg_exec_context_t ctx;
	vg_exec_context_t *vxcp;

	struct timeval tvstart;


	memset(&ctx, 0, sizeof(ctx));
	vxcp = &ctx;

	vg_exec_context_init(vcp, &ctx);

	pkey = vxcp->vxc_key;
	pgroup = EC_KEY_get0_group(pkey);
	pgen = EC_GROUP_get0_generator(pgroup);

	for (i = 0; i < ptarraysize; i++) {
		ppnt[i] = EC_POINT_new(pgroup);
		if (!ppnt[i]) {
			fprintf(stderr, "ERROR: out of memory?\n");
			exit(1);
		}
	}
	pbatchinc = EC_POINT_new(pgroup);
	if (!pbatchinc) {
		fprintf(stderr, "ERROR: out of memory?\n");
		exit(1);
	}

	BN_set_word(&vxcp->vxc_bntmp, ptarraysize);
	EC_POINT_mul(pgroup, pbatchinc, &vxcp->vxc_bntmp, NULL, NULL,
		     vxcp->vxc_bnctx);
	EC_POINT_make_affine(pgroup, pbatchinc, vxcp->vxc_bnctx);

	npoints = 0;
	rekey_at = 0;
	nbatch = 0;
	vxcp->vxc_key = pkey;
	vxcp->vxc_binres[0] = vcp->vc_addrtype;
	c = 0;
	output_interval = 1000;
	gettimeofday(&tvstart, NULL);

	if (vcp->vc_format == VCF_SCRIPT) {
		hash_buf[ 0] = 0x51;  // OP_1
		hash_buf[ 1] = 0x41;  // pubkey length
		// gap for pubkey
		hash_buf[67] = 0x51;  // OP_1
		hash_buf[68] = 0xae;  // OP_CHECKMULTISIG
		eckey_buf = hash_buf + 2;
		hash_len = 69;

	} else {
		eckey_buf = hash_buf;
		hash_len = 65;
	}

	while (!vcp->vc_halt) {
		if (++npoints >= rekey_at) {
			vg_exec_context_upgrade_lock(vxcp);
			/* Generate a new random private key */
			EC_KEY_generate_key(pkey);
			npoints = 0;

			/* Determine rekey interval */
			EC_GROUP_get_order(pgroup, &vxcp->vxc_bntmp,
					   vxcp->vxc_bnctx);
			BN_sub(&vxcp->vxc_bntmp2,
			       &vxcp->vxc_bntmp,
			       EC_KEY_get0_private_key(pkey));
			rekey_at = BN_get_word(&vxcp->vxc_bntmp2);
			if ((rekey_at == BN_MASK2) || (rekey_at > rekey_max))
				rekey_at = rekey_max;
			assert(rekey_at > 0);

			EC_POINT_copy(ppnt[0], EC_KEY_get0_public_key(pkey));
			vg_exec_context_downgrade_lock(vxcp);

			npoints++;
			vxcp->vxc_delta = 0;

			if (vcp->vc_pubkey_base)
				EC_POINT_add(pgroup,
					     ppnt[0],
					     ppnt[0],
					     vcp->vc_pubkey_base,
					     vxcp->vxc_bnctx);

			for (nbatch = 1;
			     (nbatch < ptarraysize) && (npoints < rekey_at);
			     nbatch++, npoints++) {
				EC_POINT_add(pgroup,
					     ppnt[nbatch],
					     ppnt[nbatch-1],
					     pgen, vxcp->vxc_bnctx);
			}

		} else {
			/*
			 * Common case
			 *
			 * EC_POINT_add() can skip a few multiplies if
			 * one or both inputs are affine (Z_is_one).
			 * This is the case for every point in ppnt, as
			 * well as pbatchinc.
			 */
			assert(nbatch == ptarraysize);
			for (nbatch = 0;
			     (nbatch < ptarraysize) && (npoints < rekey_at);
			     nbatch++, npoints++) {
				EC_POINT_add(pgroup,
					     ppnt[nbatch],
					     ppnt[nbatch],
					     pbatchinc,
					     vxcp->vxc_bnctx);
			}
		}

		/*
		 * The single most expensive operation performed in this
		 * loop is modular inversion of ppnt->Z.  There is an
		 * algorithm implemented in OpenSSL to do batched inversion
		 * that only does one actual BN_mod_inverse(), and saves
		 * a _lot_ of time.
		 *
		 * To take advantage of this, we batch up a few points,
		 * and feed them to EC_POINTs_make_affine() below.
		 */

		EC_POINTs_make_affine(pgroup, nbatch, ppnt, vxcp->vxc_bnctx);

		for (i = 0; i < nbatch; i++, vxcp->vxc_delta++) {
			/* Hash the public key */
			len = EC_POINT_point2oct(pgroup, ppnt[i],
						 POINT_CONVERSION_UNCOMPRESSED,
						 eckey_buf,
						 65,
						 vxcp->vxc_bnctx);
			assert(len == 65);

			SHA256(hash_buf, hash_len, hash1);
			RIPEMD160(hash1, sizeof(hash1), &vxcp->vxc_binres[1]);

			switch (test_func(vxcp)) {
			case 1:
				npoints = 0;
				rekey_at = 0;
				i = nbatch;
				break;
			case 2:
				goto out;
			default:
				break;
			}
		}

		c += i;
		if (c >= output_interval) {
			output_interval = vg_output_timing(vcp, c, &tvstart);
			if (output_interval > 250000)
				output_interval = 250000;
			c = 0;
		}

		vg_exec_context_yield(vxcp);
	}

out:
	vg_exec_context_del(&ctx);
	vg_context_thread_exit(vcp);

	for (i = 0; i < ptarraysize; i++)
		if (ppnt[i])
			EC_POINT_free(ppnt[i]);
	if (pbatchinc)
		EC_POINT_free(pbatchinc);
	return NULL;
}
Ejemplo n.º 26
0
/*
 * Find the bignum ranges that produce a given prefix.
 */
static int
get_prefix_ranges(int addrtype, const char *pfx, BIGNUM **result,
		  BN_CTX *bnctx)
{
	int i, p, c;
	int zero_prefix = 0;
	int check_upper = 0;
	int b58pow, b58ceil, b58top = 0;
	int ret = -1;

	BIGNUM bntarg, bnceil, bnfloor;
	BIGNUM bnbase;
	BIGNUM *bnap, *bnbp, *bntp;
	BIGNUM *bnhigh = NULL, *bnlow = NULL, *bnhigh2 = NULL, *bnlow2 = NULL;
	BIGNUM bntmp, bntmp2;

	BN_init(&bntarg);
	BN_init(&bnceil);
	BN_init(&bnfloor);
	BN_init(&bnbase);
	BN_init(&bntmp);
	BN_init(&bntmp2);

	BN_set_word(&bnbase, 58);

	p = strlen(pfx);

	for (i = 0; i < p; i++) {
		c = vg_b58_reverse_map[(int)pfx[i]];
		if (c == -1) {
			fprintf(stderr,
				"Invalid character '%c' in prefix '%s'\n",
				pfx[i], pfx);
			goto out;
		}
		if (i == zero_prefix) {
			if (c == 0) {
				/* Add another zero prefix */
				zero_prefix++;
				if (zero_prefix > 19) {
					fprintf(stderr,
						"Prefix '%s' is too long\n",
						pfx);
					goto out;
				}
				continue;
			}

			/* First non-zero character */
			b58top = c;
			BN_set_word(&bntarg, c);

		} else {
			BN_set_word(&bntmp2, c);
			BN_mul(&bntmp, &bntarg, &bnbase, bnctx);
			BN_add(&bntarg, &bntmp, &bntmp2);
		}
	}

	/* Power-of-two ceiling and floor values based on leading 1s */
	BN_clear(&bntmp);
	BN_set_bit(&bntmp, 200 - (zero_prefix * 8));
	BN_sub(&bnceil, &bntmp, BN_value_one());
	BN_set_bit(&bnfloor, 192 - (zero_prefix * 8));

	bnlow = BN_new();
	bnhigh = BN_new();

	if (b58top) {
		/*
		 * If a non-zero was given in the prefix, find the
		 * numeric boundaries of the prefix.
		 */

		BN_copy(&bntmp, &bnceil);
		bnap = &bntmp;
		bnbp = &bntmp2;
		b58pow = 0;
		while (BN_cmp(bnap, &bnbase) > 0) {
			b58pow++;
			BN_div(bnbp, NULL, bnap, &bnbase, bnctx);
			bntp = bnap;
			bnap = bnbp;
			bnbp = bntp;
		}
		b58ceil = BN_get_word(bnap);

		if ((b58pow - (p - zero_prefix)) < 6) {
			/*
			 * Do not allow the prefix to constrain the
			 * check value, this is ridiculous.
			 */
			fprintf(stderr, "Prefix '%s' is too long\n", pfx);
			goto out;
		}

		BN_set_word(&bntmp2, b58pow - (p - zero_prefix));
		BN_exp(&bntmp, &bnbase, &bntmp2, bnctx);
		BN_mul(bnlow, &bntmp, &bntarg, bnctx);
		BN_sub(&bntmp2, &bntmp, BN_value_one());
		BN_add(bnhigh, bnlow, &bntmp2);

		if (b58top <= b58ceil) {
			/* Fill out the upper range too */
			check_upper = 1;
			bnlow2 = BN_new();
			bnhigh2 = BN_new();

			BN_mul(bnlow2, bnlow, &bnbase, bnctx);
			BN_mul(&bntmp2, bnhigh, &bnbase, bnctx);
			BN_set_word(&bntmp, 57);
			BN_add(bnhigh2, &bntmp2, &bntmp);

			/*
			 * Addresses above the ceiling will have one
			 * fewer "1" prefix in front than we require.
			 */
			if (BN_cmp(&bnceil, bnlow2) < 0) {
				/* High prefix is above the ceiling */
				check_upper = 0;
				BN_free(bnhigh2);
				bnhigh2 = NULL;
				BN_free(bnlow2);
				bnlow2 = NULL;
			}
			else if (BN_cmp(&bnceil, bnhigh2) < 0)
				/* High prefix is partly above the ceiling */
				BN_copy(bnhigh2, &bnceil);

			/*
			 * Addresses below the floor will have another
			 * "1" prefix in front instead of our target.
			 */
			if (BN_cmp(&bnfloor, bnhigh) >= 0) {
				/* Low prefix is completely below the floor */
				assert(check_upper);
				check_upper = 0;
				BN_free(bnhigh);
				bnhigh = bnhigh2;
				bnhigh2 = NULL;
				BN_free(bnlow);
				bnlow = bnlow2;
				bnlow2 = NULL;
			}			
			else if (BN_cmp(&bnfloor, bnlow) > 0) {
				/* Low prefix is partly below the floor */
				BN_copy(bnlow, &bnfloor);
			}
		}

	} else {
		BN_copy(bnhigh, &bnceil);
		BN_clear(bnlow);
	}

	/* Limit the prefix to the address type */
	BN_clear(&bntmp);
	BN_set_word(&bntmp, addrtype);
	BN_lshift(&bntmp2, &bntmp, 192);

	if (check_upper) {
		if (BN_cmp(&bntmp2, bnhigh2) > 0) {
			check_upper = 0;
			BN_free(bnhigh2);
			bnhigh2 = NULL;
			BN_free(bnlow2);
			bnlow2 = NULL;
		}
		else if (BN_cmp(&bntmp2, bnlow2) > 0)
			BN_copy(bnlow2, &bntmp2);
	}

	if (BN_cmp(&bntmp2, bnhigh) > 0) {
		if (!check_upper)
			goto not_possible;
		check_upper = 0;
		BN_free(bnhigh);
		bnhigh = bnhigh2;
		bnhigh2 = NULL;
		BN_free(bnlow);
		bnlow = bnlow2;
		bnlow2 = NULL;
	}
	else if (BN_cmp(&bntmp2, bnlow) > 0) {
		BN_copy(bnlow, &bntmp2);
	}

	BN_set_word(&bntmp, addrtype + 1);
	BN_lshift(&bntmp2, &bntmp, 192);

	if (check_upper) {
		if (BN_cmp(&bntmp2, bnlow2) < 0) {
			check_upper = 0;
			BN_free(bnhigh2);
			bnhigh2 = NULL;
			BN_free(bnlow2);
			bnlow2 = NULL;
		}
		else if (BN_cmp(&bntmp2, bnhigh2) < 0)
			BN_copy(bnlow2, &bntmp2);
	}

	if (BN_cmp(&bntmp2, bnlow) < 0) {
		if (!check_upper)
			goto not_possible;
		check_upper = 0;
		BN_free(bnhigh);
		bnhigh = bnhigh2;
		bnhigh2 = NULL;
		BN_free(bnlow);
		bnlow = bnlow2;
		bnlow2 = NULL;
	}
	else if (BN_cmp(&bntmp2, bnhigh) < 0) {
		BN_copy(bnhigh, &bntmp2);
	}

	/* Address ranges are complete */
	assert(check_upper || ((bnlow2 == NULL) && (bnhigh2 == NULL)));
	result[0] = bnlow;
	result[1] = bnhigh;
	result[2] = bnlow2;
	result[3] = bnhigh2;
	bnlow = NULL;
	bnhigh = NULL;
	bnlow2 = NULL;
	bnhigh2 = NULL;
	ret = 0;

	if (0) {
	not_possible:
		ret = -2;
	}

out:
	BN_clear_free(&bntarg);
	BN_clear_free(&bnceil);
	BN_clear_free(&bnfloor);
	BN_clear_free(&bnbase);
	BN_clear_free(&bntmp);
	BN_clear_free(&bntmp2);
	if (bnhigh)
		BN_free(bnhigh);
	if (bnlow)
		BN_free(bnlow);
	if (bnhigh2)
		BN_free(bnhigh2);
	if (bnlow2)
		BN_free(bnlow2);

	return ret;
}
Ejemplo n.º 27
0
Archivo: d2i.c Proyecto: bupt007/deo
void *
d2i_bio_max(const ASN1_ITEM *it, BIO *in, void *x, unsigned int max)
{
    AUTO(uint8_t, buf);
    AUTO(BIGNUM, size);
    AUTO(BIGNUM, cmp);
    size_t blocks = 0;
    ssize_t need = 0;
    size_t have = 0;
    int rd;

    size = BN_new();
    if (size == NULL)
        return NULL;

    while (true) {
        need = get_size(buf, have, size);
        if (need < 0)
            return NULL;
        else if (need == 0)
            break;

        if (have + need > max)
            return NULL;

        if (have + (size_t) need >= blocks * BLOCKSIZE) {
            uint8_t *tmp;

            blocks = (have + need + BLOCKSIZE - 1) / BLOCKSIZE;
            tmp = realloc(buf, blocks * BLOCKSIZE);
            if (tmp == NULL)
                return NULL;

            buf = tmp;
        }

        rd = BIO_read(in, buf + have, need);
        have += need;
        if (rd <= 0 || rd != need)
            return NULL;
    }

    cmp = BN_new();
    if (cmp == NULL)
        return NULL;

    if (BN_set_word(cmp, max) <= 0)
        return NULL;

    if (BN_cmp(size, cmp) > 0)
        return NULL;

    if (BN_set_word(cmp, BLOCKSIZE) <= 0)
        return NULL;

    while (true) {
        need = BLOCKSIZE;
        if (BN_cmp(size, cmp) < 0)
            need = BN_get_word(size);
        if (need == 0)
            break;

        if (BN_sub_word(size, need) <= 0)
            return NULL;

        if (have + (size_t) need >= blocks * BLOCKSIZE) {
            uint8_t *tmp;

            blocks = (have + need + BLOCKSIZE - 1) / BLOCKSIZE;
            tmp = realloc(buf, blocks * BLOCKSIZE);
            if (tmp == NULL)
                return NULL;

            buf = tmp;
        }

        while (need > 0) {
            rd = BIO_read(in, buf + have, need);
            if (rd <= 0)
                return NULL;

            have += rd;
            need -= rd;
        }
    }

    return ASN1_item_d2i(x, &(const uint8_t *) { buf }, have, it);
}
Ejemplo n.º 28
0
static int
test_BN_bit(void)
{
    BIGNUM *bn;
    int ret = 0;

    bn = BN_new();

    /* test setting and getting of "word" */
    if (!BN_set_word(bn, 1))
	return 1;
    if (!BN_is_bit_set(bn, 0))
	ret += 1;
    if (!BN_is_bit_set(bn, 0))
	ret += 1;

    if (!BN_set_word(bn, 2))
	return 1;
    if (!BN_is_bit_set(bn, 1))
	ret += 1;

    if (!BN_set_word(bn, 3))
	return 1;
    if (!BN_is_bit_set(bn, 0))
	ret += 1;
    if (!BN_is_bit_set(bn, 1))
	ret += 1;

    if (!BN_set_word(bn, 0x100))
	return 1;
    if (!BN_is_bit_set(bn, 8))
	ret += 1;

    if (!BN_set_word(bn, 0x1000))
	return 1;
    if (!BN_is_bit_set(bn, 12))
	ret += 1;

    /* test bitsetting */
    if (!BN_set_word(bn, 1))
	return 1;
    if (!BN_set_bit(bn, 1))
	return 1;
    if (BN_get_word(bn) != 3)
	return 1;
    if (!BN_clear_bit(bn, 0))
	return 1;
    if (BN_get_word(bn) != 2)
	return 1;

    /* test bitsetting past end of current end */
    BN_clear(bn);
    if (!BN_set_bit(bn, 12))
	return 1;
    if (BN_get_word(bn) != 0x1000)
	return 1;

    /* test bit and byte counting functions */
    if (BN_num_bits(bn) != 13)
	return 1;
    if (BN_num_bytes(bn) != 2)
	return 1;

    BN_free(bn);
    return ret;
}
Ejemplo n.º 29
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);
}
Ejemplo n.º 30
0
static int
vg_regex_test(vg_exec_context_t *vxcp)
{
	vg_regex_context_t *vcrp = (vg_regex_context_t *) vxcp->vxc_vc;

	unsigned char hash1[32], hash2[32];
	int i, zpfx, p, d, nres, re_vec[9];
	char b58[40];
	BIGNUM bnrem;
	BIGNUM *bn, *bndiv, *bnptmp;
	int res = 0;

	pcre *re;

	BN_init(&bnrem);

	/* Hash the hash and write the four byte check code */
	SHA256(vxcp->vxc_binres, 21, hash1);
	SHA256(hash1, sizeof(hash1), hash2);
	memcpy(&vxcp->vxc_binres[21], hash2, 4);

	bn = &vxcp->vxc_bntmp;
	bndiv = &vxcp->vxc_bntmp2;

	BN_bin2bn(vxcp->vxc_binres, 25, bn);

	/* Compute the complete encoded address */
	for (zpfx = 0; zpfx < 25 && vxcp->vxc_binres[zpfx] == 0; zpfx++);
	p = sizeof(b58) - 1;
	b58[p] = '\0';
	while (!BN_is_zero(bn)) {
		BN_div(bndiv, &bnrem, bn, &vxcp->vxc_bnbase, vxcp->vxc_bnctx);
		bnptmp = bn;
		bn = bndiv;
		bndiv = bnptmp;
		d = BN_get_word(&bnrem);
		b58[--p] = vg_b58_alphabet[d];
	}
	while (zpfx--) {
		b58[--p] = vg_b58_alphabet[0];
	}

	/*
	 * Run the regular expressions on it
	 * SLOW, runs in linear time with the number of REs
	 */
restart_loop:
	nres = vcrp->base.vc_npatterns;
	if (!nres) {
		res = 2;
		goto out;
	}
	for (i = 0; i < nres; i++) {
		d = pcre_exec(vcrp->vcr_regex[i],
			      vcrp->vcr_regex_extra[i],
			      &b58[p], (sizeof(b58) - 1) - p, 0,
			      0,
			      re_vec, sizeof(re_vec)/sizeof(re_vec[0]));

		if (d <= 0) {
			if (d != PCRE_ERROR_NOMATCH) {
				fprintf(stderr, "PCRE error: %d\n", d);
				res = 2;
				goto out;
			}
			continue;
		}

		re = vcrp->vcr_regex[i];

		if (vg_exec_context_upgrade_lock(vxcp) &&
		    ((i >= vcrp->base.vc_npatterns) ||
		     (vcrp->vcr_regex[i] != re)))
			goto restart_loop;

		vg_exec_context_consolidate_key(vxcp);
		vcrp->base.vc_output_match(&vcrp->base, vxcp->vxc_key,
					   vcrp->vcr_regex_pat[i]);
		vcrp->base.vc_found++;

		if (vcrp->base.vc_only_one) {
			res = 2;
			goto out;
		}

		if (vcrp->base.vc_remove_on_match) {
			pcre_free(vcrp->vcr_regex[i]);
			if (vcrp->vcr_regex_extra[i])
				pcre_free(vcrp->vcr_regex_extra[i]);
			nres -= 1;
			vcrp->base.vc_npatterns = nres;
			if (!nres) {
				res = 2;
				goto out;
			}
			vcrp->vcr_regex[i] = vcrp->vcr_regex[nres];
			vcrp->vcr_regex_extra[i] =
				vcrp->vcr_regex_extra[nres];
			vcrp->vcr_regex_pat[i] = vcrp->vcr_regex_pat[nres];
			vcrp->base.vc_npatterns = nres;
			vcrp->base.vc_pattern_generation++;
		}
		res = 1;
	}
out:
	BN_clear_free(&bnrem);
	return res;
}