int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { int ret = 0; BIGNUM *Ri,*R; BN_CTX_start(ctx); if((Ri = BN_CTX_get(ctx)) == NULL) goto err; R= &(mont->RR); /* grab RR as a temp */ if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */ mont->N.neg = 0; #ifdef MONT_WORD { BIGNUM tmod; BN_ULONG buf[2]; BN_init(&tmod); tmod.d=buf; tmod.dmax=2; tmod.neg=0; mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; #if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) /* Only certain BN_BITS2<=32 platforms actually make use of * n0[1], and we could use the #else case (with a shorter R * value) for the others. However, currently only the assembler * files do know which is which. */ BN_zero(R); if (!(BN_set_bit(R,2*BN_BITS2))) goto err; tmod.top=0; if ((buf[0] = mod->d[0])) tmod.top=1; if ((buf[1] = mod->top>1 ? mod->d[1] : 0)) tmod.top=2; if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) goto err; if (!BN_lshift(Ri,Ri,2*BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri,1)) goto err; } else /* if N mod word size == 1 */ { if (bn_expand(Ri,(int)sizeof(BN_ULONG)*2) == NULL) goto err; /* Ri-- (mod double word size) */ Ri->neg=0; Ri->d[0]=BN_MASK2; Ri->d[1]=BN_MASK2; Ri->top=2; } if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; /* Ni = (R*Ri-1)/N, * keep only couple of least significant words: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; #else BN_zero(R); if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ buf[0]=mod->d[0]; /* tmod = N mod word size */ buf[1]=0; tmod.top = buf[0] != 0 ? 1 : 0; /* Ri = R^-1 mod N*/ if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) goto err; if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri,1)) goto err; } else /* if N mod word size == 1 */ { if (!BN_set_word(Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */ } if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; /* Ni = (R*Ri-1)/N, * keep only least significant word: */ mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; mont->n0[1] = 0; #endif } #else /* !MONT_WORD */ { /* bignum version */ mont->ri=BN_num_bits(&mont->N); BN_zero(R); if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */ /* Ri = R^-1 mod N*/ if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL) goto err; if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */ if (!BN_sub_word(Ri,1)) goto err; /* Ni = (R*Ri-1) / N */ if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err; } #endif /* setup RR for conversions */ BN_zero(&(mont->RR)); if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err; if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err; ret = 1; err: BN_CTX_end(ctx); return ret; }
int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { int ret = 0; BIGNUM *Ri,*R; BN_CTX_start(ctx); if((Ri = BN_CTX_get(ctx)) == NULL) goto err; R= &(mont->RR); /* grab RR as a temp */ if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */ mont->N.neg = 0; #ifdef MONT_WORD { BIGNUM tmod; BN_ULONG buf[2]; mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; BN_zero(R); if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */ buf[0]=mod->d[0]; /* tmod = N mod word size */ buf[1]=0; tmod.d=buf; tmod.top = buf[0] != 0 ? 1 : 0; tmod.dmax=2; tmod.neg=0; /* Ri = R^-1 mod N*/ if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL) goto err; if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */ if (!BN_is_zero(Ri)) { if (!BN_sub_word(Ri,1)) goto err; } else /* if N mod word size == 1 */ { if (!BN_set_word(Ri,BN_MASK2)) goto err; /* Ri-- (mod word size) */ } if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err; /* Ni = (R*Ri-1)/N, * keep only least significant word: */ mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0; } #else /* !MONT_WORD */ { /* bignum version */ mont->ri=BN_num_bits(&mont->N); BN_zero(R); if (!BN_set_bit(R,mont->ri)) goto err; /* R = 2^ri */ /* Ri = R^-1 mod N*/ if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL) goto err; if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */ if (!BN_sub_word(Ri,1)) goto err; /* Ni = (R*Ri-1) / N */ if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err; } #endif /* setup RR for conversions */ BN_zero(&(mont->RR)); if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err; if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err; ret = 1; err: BN_CTX_end(ctx); return ret; }
static int FIPS_dsa_builtin_paramgen(DSA *ret, int bits, unsigned char *seed_in, int seed_len, int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) { int ok=0; unsigned char seed[SHA_DIGEST_LENGTH]; unsigned char md[SHA_DIGEST_LENGTH]; unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH]; BIGNUM *r0,*W,*X,*c,*test; BIGNUM *g=NULL,*q=NULL,*p=NULL; BN_MONT_CTX *mont=NULL; int k,n=0,i,b,m=0; int counter=0; int r=0; BN_CTX *ctx=NULL; unsigned int h=2; if(FIPS_selftest_failed()) { FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN, FIPS_R_FIPS_SELFTEST_FAILED); goto err; } if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) { DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL); goto err; } if (bits < 512) bits=512; bits=(bits+63)/64*64; /* NB: seed_len == 0 is special case: copy generated seed to * seed_in if it is not NULL. */ if (seed_len && (seed_len < 20)) seed_in = NULL; /* seed buffer too small -- ignore */ if (seed_len > 20) seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED, * but our internal buffers are restricted to 160 bits*/ if ((seed_in != NULL) && (seed_len == 20)) { memcpy(seed,seed_in,seed_len); /* set seed_in to NULL to avoid it being copied back */ seed_in = NULL; } if ((ctx=BN_CTX_new()) == NULL) goto err; if ((mont=BN_MONT_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); r0 = BN_CTX_get(ctx); g = BN_CTX_get(ctx); W = BN_CTX_get(ctx); q = BN_CTX_get(ctx); X = BN_CTX_get(ctx); c = BN_CTX_get(ctx); p = BN_CTX_get(ctx); test = BN_CTX_get(ctx); if (!BN_lshift(test,BN_value_one(),bits-1)) goto err; for (;;) { for (;;) /* find q */ { int seed_is_random; /* step 1 */ if(!BN_GENCB_call(cb, 0, m++)) goto err; if (!seed_len) { RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH); seed_is_random = 1; } else { seed_is_random = 0; seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/ } memcpy(buf,seed,SHA_DIGEST_LENGTH); memcpy(buf2,seed,SHA_DIGEST_LENGTH); /* precompute "SEED + 1" for step 7: */ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } /* step 2 */ EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL); for (i=0; i<SHA_DIGEST_LENGTH; i++) md[i]^=buf2[i]; /* step 3 */ md[0]|=0x80; md[SHA_DIGEST_LENGTH-1]|=0x01; if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err; /* step 4 */ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb); if (r > 0) break; if (r != 0) goto err; /* do a callback call */ /* step 5 */ } if(!BN_GENCB_call(cb, 2, 0)) goto err; if(!BN_GENCB_call(cb, 3, 0)) goto err; /* step 6 */ counter=0; /* "offset = 2" */ n=(bits-1)/160; b=(bits-1)-n*160; for (;;) { if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) goto err; /* step 7 */ BN_zero(W); /* now 'buf' contains "SEED + offset - 1" */ for (k=0; k<=n; k++) { /* obtain "SEED + offset + k" by incrementing: */ for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--) { buf[i]++; if (buf[i] != 0) break; } EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL); /* step 8 */ if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0)) goto err; if (!BN_lshift(r0,r0,160*k)) goto err; if (!BN_add(W,W,r0)) goto err; } /* more of step 8 */ if (!BN_mask_bits(W,bits-1)) goto err; if (!BN_copy(X,W)) goto err; if (!BN_add(X,X,test)) goto err; /* step 9 */ if (!BN_lshift1(r0,q)) goto err; if (!BN_mod(c,X,r0,ctx)) goto err; if (!BN_sub(r0,c,BN_value_one())) goto err; if (!BN_sub(p,X,r0)) goto err; /* step 10 */ if (BN_cmp(p,test) >= 0) { /* step 11 */ r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); if (r > 0) goto end; /* found it */ if (r != 0) goto err; } /* step 13 */ counter++; /* "offset = offset + n + 1" */ /* step 14 */ if (counter >= 4096) break; } } end: if(!BN_GENCB_call(cb, 2, 1)) goto err; /* We now need to generate g */ /* Set r0=(p-1)/q */ if (!BN_sub(test,p,BN_value_one())) goto err; if (!BN_div(r0,NULL,test,q,ctx)) goto err; if (!BN_set_word(test,h)) goto err; if (!BN_MONT_CTX_set(mont,p,ctx)) goto err; for (;;) { /* g=test^r0%p */ if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err; if (!BN_is_one(g)) break; if (!BN_add(test,test,BN_value_one())) goto err; h++; } if(!BN_GENCB_call(cb, 3, 1)) goto err; ok=1; err: if (ok) { if(ret->p) BN_free(ret->p); if(ret->q) BN_free(ret->q); if(ret->g) BN_free(ret->g); ret->p=BN_dup(p); ret->q=BN_dup(q); ret->g=BN_dup(g); if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { ok=0; goto err; } if (seed_in != NULL) memcpy(seed_in,seed,20); if (counter_ret != NULL) *counter_ret=counter; if (h_ret != NULL) *h_ret=h; } if(ctx) { BN_CTX_end(ctx); BN_CTX_free(ctx); } if (mont != NULL) BN_MONT_CTX_free(mont); return ok; }
int RSA_check_key(const RSA *key) { BIGNUM *i, *j, *k, *l, *m; BN_CTX *ctx; int r; int ret=1; if (!key->p || !key->q || !key->n || !key->e || !key->d) { RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING); return 0; } i = BN_new(); j = BN_new(); k = BN_new(); l = BN_new(); m = BN_new(); ctx = BN_CTX_new(); if (i == NULL || j == NULL || k == NULL || l == NULL || m == NULL || ctx == NULL) { ret = -1; RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); goto err; } /* p prime? */ r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL); if (r != 1) { ret = r; if (r != 0) goto err; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); } /* q prime? */ r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL); if (r != 1) { ret = r; if (r != 0) goto err; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); } /* n = p*q? */ r = BN_mul(i, key->p, key->q, ctx); if (!r) { ret = -1; goto err; } if (BN_cmp(i, key->n) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); } /* d*e = 1 mod lcm(p-1,q-1)? */ r = BN_sub(i, key->p, BN_value_one()); if (!r) { ret = -1; goto err; } r = BN_sub(j, key->q, BN_value_one()); if (!r) { ret = -1; goto err; } /* now compute k = lcm(i,j) */ r = BN_mul(l, i, j, ctx); if (!r) { ret = -1; goto err; } r = BN_gcd(m, i, j, ctx); if (!r) { ret = -1; goto err; } r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */ if (!r) { ret = -1; goto err; } r = BN_mod_mul(i, key->d, key->e, k, ctx); if (!r) { ret = -1; goto err; } if (!BN_is_one(i)) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); } if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { /* dmp1 = d mod (p-1)? */ r = BN_sub(i, key->p, BN_value_one()); if (!r) { ret = -1; goto err; } r = BN_mod(j, key->d, i, ctx); if (!r) { ret = -1; goto err; } if (BN_cmp(j, key->dmp1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D); } /* dmq1 = d mod (q-1)? */ r = BN_sub(i, key->q, BN_value_one()); if (!r) { ret = -1; goto err; } r = BN_mod(j, key->d, i, ctx); if (!r) { ret = -1; goto err; } if (BN_cmp(j, key->dmq1) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); } /* iqmp = q^-1 mod p? */ if(!BN_mod_inverse(i, key->q, key->p, ctx)) { ret = -1; goto err; } if (BN_cmp(i, key->iqmp) != 0) { ret = 0; RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q); } } err: if (i != NULL) BN_free(i); if (j != NULL) BN_free(j); if (k != NULL) BN_free(k); if (l != NULL) BN_free(l); if (m != NULL) BN_free(m); if (ctx != NULL) BN_CTX_free(ctx); return (ret); }
/* * 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; }
extern "C" void Java_java_math_NativeBN_BN_1div(JNIEnv* env, jclass, jlong dv, jlong rem, jlong m, jlong d) { if (!fourValidHandles(env, (rem ? rem : dv), (dv ? dv : rem), m, d)) return; Unique_BN_CTX ctx(BN_CTX_new()); BN_div(toBigNum(dv), toBigNum(rem), toBigNum(m), toBigNum(d), ctx.get()); throwExceptionIfNecessary(env); }
static int vg_prefix_context_add_patterns(vg_context_t *vcp, const char ** const patterns, int npatterns) { vg_prefix_context_t *vcpp = (vg_prefix_context_t *) vcp; prefix_case_iter_t caseiter; vg_prefix_t *vp, *vp2; BN_CTX *bnctx; BIGNUM bntmp, bntmp2, bntmp3; BIGNUM *ranges[4]; int ret = 0; int i, impossible = 0; int case_impossible; unsigned long npfx; char *dbuf; bnctx = BN_CTX_new(); BN_init(&bntmp); BN_init(&bntmp2); BN_init(&bntmp3); npfx = 0; for (i = 0; i < npatterns; i++) { if (!vcpp->vcp_caseinsensitive) { vp = NULL; ret = get_prefix_ranges(vcpp->base.vc_addrtype, patterns[i], ranges, bnctx); if (!ret) { vp = vg_prefix_add_ranges(&vcpp->vcp_avlroot, patterns[i], ranges, NULL); } } else { /* Case-enumerate the prefix */ if (!prefix_case_iter_init(&caseiter, patterns[i])) { fprintf(stderr, "Prefix '%s' is too long\n", patterns[i]); continue; } if (caseiter.ci_nbits > 16) { fprintf(stderr, "WARNING: Prefix '%s' has " "2^%d case-varied derivatives\n", patterns[i], caseiter.ci_nbits); } case_impossible = 0; vp = NULL; do { ret = get_prefix_ranges(vcpp->base.vc_addrtype, caseiter.ci_prefix, ranges, bnctx); if (ret == -2) { case_impossible++; ret = 0; continue; } if (ret) break; vp2 = vg_prefix_add_ranges(&vcpp->vcp_avlroot, patterns[i], ranges, vp); if (!vp2) { ret = -1; break; } if (!vp) vp = vp2; } while (prefix_case_iter_next(&caseiter)); if (!vp && case_impossible) ret = -2; if (ret && vp) { vg_prefix_delete(&vcpp->vcp_avlroot, vp); vp = NULL; } } if (ret == -2) { fprintf(stderr, "Prefix '%s' not possible\n", patterns[i]); impossible++; } if (!vp) continue; npfx++; /* Determine the probability of finding a match */ vg_prefix_range_sum(vp, &bntmp, &bntmp2); BN_add(&bntmp2, &vcpp->vcp_difficulty, &bntmp); BN_copy(&vcpp->vcp_difficulty, &bntmp2); if (vcp->vc_verbose > 1) { BN_clear(&bntmp2); BN_set_bit(&bntmp2, 192); BN_div(&bntmp3, NULL, &bntmp2, &bntmp, bnctx); dbuf = BN_bn2dec(&bntmp3); fprintf(stderr, "Prefix difficulty: %20s %s\n", dbuf, patterns[i]); OPENSSL_free(dbuf); } } vcpp->base.vc_npatterns += npfx; vcpp->base.vc_npatterns_start += npfx; if (!npfx && impossible) { const char *ats = "bitcoin", *bw = "\"1\""; switch (vcpp->base.vc_addrtype) { case 5: ats = "bitcoin script"; bw = "\"3\""; break; case 48: ats = "litecoin"; bw = "\"L\""; break; case 111: ats = "testnet"; bw = "\"m\" or \"n\""; break; case 52: ats = "namecoin"; bw = "\"M\" or \"N\""; break; default: break; } fprintf(stderr, "Hint: valid %s addresses begin with %s\n", ats, bw); } if (npfx) vg_prefix_context_next_difficulty(vcpp, &bntmp, &bntmp2, bnctx); ret = (npfx != 0); BN_clear_free(&bntmp); BN_clear_free(&bntmp2); BN_clear_free(&bntmp3); BN_CTX_free(bnctx); return ret; }
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; }
BIGNUM *BN_mod_inverse(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; BIGNUM *ret = NULL; int sign; if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { return BN_mod_inverse_no_branch(in, a, n, ctx); } bn_check_top(a); bn_check_top(n); BN_CTX_start(ctx); A = BN_CTX_get(ctx); B = BN_CTX_get(ctx); X = BN_CTX_get(ctx); D = BN_CTX_get(ctx); M = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); T = BN_CTX_get(ctx); if (T == NULL) goto err; if (in == NULL) R = BN_new(); else R = in; if (R == NULL) goto err; BN_one(X); BN_zero(Y); if (BN_copy(B, a) == NULL) goto err; if (BN_copy(A, n) == NULL) goto err; A->neg = 0; if (B->neg || (BN_ucmp(B, A) >= 0)) { if (!BN_nnmod(B, B, A, ctx)) goto err; } sign = -1; /*- * From B = a mod |n|, A = |n| it follows that * * 0 <= B < A, * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). */ if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { /* * Binary inversion algorithm; requires odd modulus. This is faster * than the general algorithm if the modulus is sufficiently small * (about 400 .. 500 bits on 32-bit sytems, but much more on 64-bit * systems) */ int shift; while (!BN_is_zero(B)) { /*- * 0 < B < |n|, * 0 < A <= |n|, * (1) -sign*X*a == B (mod |n|), * (2) sign*Y*a == A (mod |n|) */ /* * Now divide B by the maximum possible power of two in the * integers, and divide X by the same value mod |n|. When we're * done, (1) still holds. */ shift = 0; while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */ shift++; if (BN_is_odd(X)) { if (!BN_uadd(X, X, n)) goto err; } /* * now X is even, so we can easily divide it by two */ if (!BN_rshift1(X, X)) goto err; } if (shift > 0) { if (!BN_rshift(B, B, shift)) goto err; } /* * Same for A and Y. Afterwards, (2) still holds. */ shift = 0; while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */ shift++; if (BN_is_odd(Y)) { if (!BN_uadd(Y, Y, n)) goto err; } /* now Y is even */ if (!BN_rshift1(Y, Y)) goto err; } if (shift > 0) { if (!BN_rshift(A, A, shift)) goto err; } /*- * We still have (1) and (2). * Both A and B are odd. * The following computations ensure that * * 0 <= B < |n|, * 0 < A < |n|, * (1) -sign*X*a == B (mod |n|), * (2) sign*Y*a == A (mod |n|), * * and that either A or B is even in the next iteration. */ if (BN_ucmp(B, A) >= 0) { /* -sign*(X + Y)*a == B - A (mod |n|) */ if (!BN_uadd(X, X, Y)) goto err; /* * NB: we could use BN_mod_add_quick(X, X, Y, n), but that * actually makes the algorithm slower */ if (!BN_usub(B, B, A)) goto err; } else { /* sign*(X + Y)*a == A - B (mod |n|) */ if (!BN_uadd(Y, Y, X)) goto err; /* * as above, BN_mod_add_quick(Y, Y, X, n) would slow things * down */ if (!BN_usub(A, A, B)) goto err; } } } else { /* general inversion algorithm */ while (!BN_is_zero(B)) { BIGNUM *tmp; /*- * 0 < B < A, * (*) -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|) */ /* (D, M) := (A/B, A%B) ... */ if (BN_num_bits(A) == BN_num_bits(B)) { if (!BN_one(D)) goto err; if (!BN_sub(M, A, B)) goto err; } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { /* A/B is 1, 2, or 3 */ if (!BN_lshift1(T, B)) goto err; if (BN_ucmp(A, T) < 0) { /* A < 2*B, so D=1 */ if (!BN_one(D)) goto err; if (!BN_sub(M, A, B)) goto err; } else { /* A >= 2*B, so D=2 or D=3 */ if (!BN_sub(M, A, T)) goto err; if (!BN_add(D, T, B)) goto err; /* use D (:= 3*B) as temp */ if (BN_ucmp(A, D) < 0) { /* A < 3*B, so D=2 */ if (!BN_set_word(D, 2)) goto err; /* * M (= A - 2*B) already has the correct value */ } else { /* only D=3 remains */ if (!BN_set_word(D, 3)) goto err; /* * currently M = A - 2*B, but we need M = A - 3*B */ if (!BN_sub(M, M, B)) goto err; } } } else { if (!BN_div(D, M, A, B, ctx)) goto err; } /*- * Now * A = D*B + M; * thus we have * (**) sign*Y*a == D*B + M (mod |n|). */ tmp = A; /* keep the BIGNUM object, the value does not * matter */ /* (A, B) := (B, A mod B) ... */ A = B; B = M; /* ... so we have 0 <= B < A again */ /*- * Since the former M is now B and the former B is now A, * (**) translates into * sign*Y*a == D*A + B (mod |n|), * i.e. * sign*Y*a - D*A == B (mod |n|). * Similarly, (*) translates into * -sign*X*a == A (mod |n|). * * Thus, * sign*Y*a + D*sign*X*a == B (mod |n|), * i.e. * sign*(Y + D*X)*a == B (mod |n|). * * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). * Note that X and Y stay non-negative all the time. */ /* * most of the time D is very small, so we can optimize tmp := * D*X+Y */ if (BN_is_one(D)) { if (!BN_add(tmp, X, Y)) goto err; } else { if (BN_is_word(D, 2)) { if (!BN_lshift1(tmp, X)) goto err; } else if (BN_is_word(D, 4)) { if (!BN_lshift(tmp, X, 2)) goto err; } else if (D->top == 1) { if (!BN_copy(tmp, X)) goto err; if (!BN_mul_word(tmp, D->d[0])) goto err; } else { if (!BN_mul(tmp, D, X, ctx)) goto err; } if (!BN_add(tmp, tmp, Y)) goto err; } M = Y; /* keep the BIGNUM object, the value does not * matter */ Y = X; X = tmp; sign = -sign; } } /*- * The while loop (Euclid's algorithm) ends when * A == gcd(a,n); * we have * sign*Y*a == A (mod |n|), * where Y is non-negative. */ if (sign < 0) { if (!BN_sub(Y, n, Y)) goto err; } /* Now Y*a == A (mod |n|). */ if (BN_is_one(A)) { /* Y*a == 1 (mod |n|) */ if (!Y->neg && BN_ucmp(Y, n) < 0) { if (!BN_copy(R, Y)) goto err; } else { if (!BN_nnmod(R, Y, n, ctx)) goto err; } } else { BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE); goto err; } ret = R; err: if ((ret == NULL) && (in == NULL)) BN_free(R); BN_CTX_end(ctx); bn_check_top(ret); return (ret); }
/* * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does * not contain branches that may leak sensitive information. */ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) { BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; BIGNUM local_A, local_B; BIGNUM *pA, *pB; BIGNUM *ret = NULL; int sign; bn_check_top(a); bn_check_top(n); BN_CTX_start(ctx); A = BN_CTX_get(ctx); B = BN_CTX_get(ctx); X = BN_CTX_get(ctx); D = BN_CTX_get(ctx); M = BN_CTX_get(ctx); Y = BN_CTX_get(ctx); T = BN_CTX_get(ctx); if (T == NULL) goto err; if (in == NULL) R = BN_new(); else R = in; if (R == NULL) goto err; BN_one(X); BN_zero(Y); if (BN_copy(B, a) == NULL) goto err; if (BN_copy(A, n) == NULL) goto err; A->neg = 0; if (B->neg || (BN_ucmp(B, A) >= 0)) { /* * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, * BN_div_no_branch will be called eventually. */ pB = &local_B; local_B.flags = 0; BN_with_flags(pB, B, BN_FLG_CONSTTIME); if (!BN_nnmod(B, pB, A, ctx)) goto err; } sign = -1; /*- * From B = a mod |n|, A = |n| it follows that * * 0 <= B < A, * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). */ while (!BN_is_zero(B)) { BIGNUM *tmp; /*- * 0 < B < A, * (*) -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|) */ /* * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, * BN_div_no_branch will be called eventually. */ pA = &local_A; local_A.flags = 0; BN_with_flags(pA, A, BN_FLG_CONSTTIME); /* (D, M) := (A/B, A%B) ... */ if (!BN_div(D, M, pA, B, ctx)) goto err; /*- * Now * A = D*B + M; * thus we have * (**) sign*Y*a == D*B + M (mod |n|). */ tmp = A; /* keep the BIGNUM object, the value does not * matter */ /* (A, B) := (B, A mod B) ... */ A = B; B = M; /* ... so we have 0 <= B < A again */ /*- * Since the former M is now B and the former B is now A, * (**) translates into * sign*Y*a == D*A + B (mod |n|), * i.e. * sign*Y*a - D*A == B (mod |n|). * Similarly, (*) translates into * -sign*X*a == A (mod |n|). * * Thus, * sign*Y*a + D*sign*X*a == B (mod |n|), * i.e. * sign*(Y + D*X)*a == B (mod |n|). * * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at * -sign*X*a == B (mod |n|), * sign*Y*a == A (mod |n|). * Note that X and Y stay non-negative all the time. */ if (!BN_mul(tmp, D, X, ctx)) goto err; if (!BN_add(tmp, tmp, Y)) goto err; M = Y; /* keep the BIGNUM object, the value does not * matter */ Y = X; X = tmp; sign = -sign; } /*- * The while loop (Euclid's algorithm) ends when * A == gcd(a,n); * we have * sign*Y*a == A (mod |n|), * where Y is non-negative. */ if (sign < 0) { if (!BN_sub(Y, n, Y)) goto err; } /* Now Y*a == A (mod |n|). */ if (BN_is_one(A)) { /* Y*a == 1 (mod |n|) */ if (!Y->neg && BN_ucmp(Y, n) < 0) { if (!BN_copy(R, Y)) goto err; } else { if (!BN_nnmod(R, Y, n, ctx)) goto err; } } else { BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE); goto err; } ret = R; err: if ((ret == NULL) && (in == NULL)) BN_free(R); BN_CTX_end(ctx); bn_check_top(ret); return (ret); }
static void pollard_rho(BIGNUM *val) { BIGNUM *x, *y, *tmp, *num; BN_ULONG a; unsigned int steps_taken, steps_limit; x = BN_new(); y = BN_new(); tmp = BN_new(); num = BN_new(); a = 1; restart: steps_taken = 0; steps_limit = 2; BN_set_word(x, 1); BN_copy(y, x); for (;;) { BN_sqr(tmp, x, ctx); BN_add_word(tmp, a); BN_mod(x, tmp, val, ctx); BN_sub(tmp, x, y); if (BN_is_zero(tmp)) { #ifdef DEBUG printf(" (loop)"); #endif a++; goto restart; } BN_gcd(tmp, tmp, val, ctx); if (!BN_is_one(tmp)) { if (BN_is_prime(tmp, PRIME_CHECKS, NULL, NULL, NULL) == 1) { putchar(' '); BN_print_dec_fp(stdout, tmp); } else { #ifdef DEBUG printf(" (recurse for "); BN_print_dec_fp(stdout, tmp); putchar(')'); #endif pollard_rho(BN_dup(tmp)); #ifdef DEBUG printf(" (back)"); #endif } fflush(stdout); BN_div(num, NULL, val, tmp, ctx); if (BN_is_one(num)) return; if (BN_is_prime(num, PRIME_CHECKS, NULL, NULL, NULL) == 1) { putchar(' '); BN_print_dec_fp(stdout, num); fflush(stdout); return; } BN_copy(val, num); goto restart; } steps_taken++; if (steps_taken == steps_limit) { BN_copy(y, x); /* teleport the turtle */ steps_taken = 0; steps_limit *= 2; if (steps_limit == 0) { #ifdef DEBUG printf(" (overflow)"); #endif a++; goto restart; } } } }
int test_div(BIO *bp, BN_CTX *ctx) { BIGNUM a,b,c,d,e; int i; BN_init(&a); BN_init(&b); BN_init(&c); BN_init(&d); BN_init(&e); for (i=0; i<num0+num1; i++) { if (i < num1) { BN_bntest_rand(&a,400,0,0); BN_copy(&b,&a); BN_lshift(&a,&a,i); BN_add_word(&a,i); } else BN_bntest_rand(&b,50+3*(i-num1),0,0); a.neg=rand_neg(); b.neg=rand_neg(); BN_div(&d,&c,&a,&b,ctx); if (bp != NULL) { if (!results) { BN_print(bp,&a); BIO_puts(bp," / "); BN_print(bp,&b); BIO_puts(bp," - "); } BN_print(bp,&d); BIO_puts(bp,"\n"); if (!results) { BN_print(bp,&a); BIO_puts(bp," % "); BN_print(bp,&b); BIO_puts(bp," - "); } BN_print(bp,&c); BIO_puts(bp,"\n"); } BN_mul(&e,&d,&b,ctx); BN_add(&d,&e,&c); BN_sub(&d,&d,&a); if(!BN_is_zero(&d)) { fprintf(stderr,"Division test failed!\n"); return 0; } } BN_free(&a); BN_free(&b); BN_free(&c); BN_free(&d); BN_free(&e); return(1); }
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, int nHashType) { CAutoBN_CTX pctx; CScript::const_iterator pc = script.begin(); CScript::const_iterator pend = script.end(); CScript::const_iterator pbegincodehash = script.begin(); vector<bool> vfExec; vector<valtype> altstack; if (script.size() > 10000) return false; int nOpCount = 0; try { while (pc < pend) { bool fExec = !count(vfExec.begin(), vfExec.end(), false); // // Read instruction // opcodetype opcode; valtype vchPushValue; if (!script.GetOp(pc, opcode, vchPushValue)) return false; if (vchPushValue.size() > 5000) return false; if (opcode > OP_16 && nOpCount++ > 200) return false; if (fExec && opcode <= OP_PUSHDATA4) stack.push_back(vchPushValue); else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF)) switch (opcode) { // // Push value // case OP_1NEGATE: case OP_1: case OP_2: case OP_3: case OP_4: case OP_5: case OP_6: case OP_7: case OP_8: case OP_9: case OP_10: case OP_11: case OP_12: case OP_13: case OP_14: case OP_15: case OP_16: { // ( -- value) CBigNum bn((int)opcode - (int)(OP_1 - 1)); stack.push_back(bn.getvch()); } break; // // Control // case OP_NOP: case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: break; case OP_VER: case OP_VERIF: case OP_VERNOTIF: { return false; } break; case OP_IF: case OP_NOTIF: { // <expression> if [statements] [else [statements]] endif bool fValue = false; if (fExec) { if (stack.size() < 1) return false; valtype& vch = stacktop(-1); fValue = CastToBool(vch); if (opcode == OP_NOTIF) fValue = !fValue; stack.pop_back(); } vfExec.push_back(fValue); } break; case OP_ELSE: { if (vfExec.empty()) return false; vfExec.back() = !vfExec.back(); } break; case OP_ENDIF: { if (vfExec.empty()) return false; vfExec.pop_back(); } break; case OP_VERIFY: { // (true -- ) or // (false -- false) and return if (stack.size() < 1) return false; bool fValue = CastToBool(stacktop(-1)); if (fValue) stack.pop_back(); else return false; } break; case OP_RETURN: { return false; } break; // // Stack ops // case OP_TOALTSTACK: { if (stack.size() < 1) return false; altstack.push_back(stacktop(-1)); stack.pop_back(); } break; case OP_FROMALTSTACK: { if (altstack.size() < 1) return false; stack.push_back(altstacktop(-1)); altstack.pop_back(); } break; case OP_2DROP: { // (x1 x2 -- ) stack.pop_back(); stack.pop_back(); } break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) if (stack.size() < 2) return false; valtype vch1 = stacktop(-2); valtype vch2 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) if (stack.size() < 3) return false; valtype vch1 = stacktop(-3); valtype vch2 = stacktop(-2); valtype vch3 = stacktop(-1); stack.push_back(vch1); stack.push_back(vch2); stack.push_back(vch3); } break; case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) if (stack.size() < 4) return false; valtype vch1 = stacktop(-4); valtype vch2 = stacktop(-3); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) if (stack.size() < 6) return false; valtype vch1 = stacktop(-6); valtype vch2 = stacktop(-5); stack.erase(stack.end()-6, stack.end()-4); stack.push_back(vch1); stack.push_back(vch2); } break; case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) if (stack.size() < 4) return false; swap(stacktop(-4), stacktop(-2)); swap(stacktop(-3), stacktop(-1)); } break; case OP_IFDUP: { // (x - 0 | x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); if (CastToBool(vch)) stack.push_back(vch); } break; case OP_DEPTH: { // -- stacksize CBigNum bn(stack.size()); stack.push_back(bn.getvch()); } break; case OP_DROP: { // (x -- ) if (stack.size() < 1) return false; stack.pop_back(); } break; case OP_DUP: { // (x -- x x) if (stack.size() < 1) return false; valtype vch = stacktop(-1); stack.push_back(vch); } break; case OP_NIP: { // (x1 x2 -- x2) if (stack.size() < 2) return false; stack.erase(stack.end() - 2); } break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) if (stack.size() < 2) return false; valtype vch = stacktop(-2); stack.push_back(vch); } break; case OP_PICK: case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) if (stack.size() < 2) return false; int n = CBigNum(stacktop(-1)).getint(); stack.pop_back(); if (n < 0 || n >= stack.size()) return false; valtype vch = stacktop(-n-1); if (opcode == OP_ROLL) stack.erase(stack.end()-n-1); stack.push_back(vch); } break; case OP_ROT: { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap if (stack.size() < 3) return false; swap(stacktop(-3), stacktop(-2)); swap(stacktop(-2), stacktop(-1)); } break; case OP_SWAP: { // (x1 x2 -- x2 x1) if (stack.size() < 2) return false; swap(stacktop(-2), stacktop(-1)); } break; case OP_TUCK: { // (x1 x2 -- x2 x1 x2) if (stack.size() < 2) return false; valtype vch = stacktop(-1); stack.insert(stack.end()-2, vch); } break; // // Splice ops // case OP_CAT: { // (x1 x2 -- out) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); vch1.insert(vch1.end(), vch2.begin(), vch2.end()); stack.pop_back(); if (stacktop(-1).size() > 5000) return false; } break; case OP_SUBSTR: { // (in begin size -- out) if (stack.size() < 3) return false; valtype& vch = stacktop(-3); int nBegin = CBigNum(stacktop(-2)).getint(); int nEnd = nBegin + CBigNum(stacktop(-1)).getint(); if (nBegin < 0 || nEnd < nBegin) return false; if (nBegin > vch.size()) nBegin = vch.size(); if (nEnd > vch.size()) nEnd = vch.size(); vch.erase(vch.begin() + nEnd, vch.end()); vch.erase(vch.begin(), vch.begin() + nBegin); stack.pop_back(); stack.pop_back(); } break; case OP_LEFT: case OP_RIGHT: { // (in size -- out) if (stack.size() < 2) return false; valtype& vch = stacktop(-2); int nSize = CBigNum(stacktop(-1)).getint(); if (nSize < 0) return false; if (nSize > vch.size()) nSize = vch.size(); if (opcode == OP_LEFT) vch.erase(vch.begin() + nSize, vch.end()); else vch.erase(vch.begin(), vch.end() - nSize); stack.pop_back(); } break; case OP_SIZE: { // (in -- in size) if (stack.size() < 1) return false; CBigNum bn(stacktop(-1).size()); stack.push_back(bn.getvch()); } break; // // Bitwise logic // case OP_INVERT: { // (in - out) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); for (int i = 0; i < vch.size(); i++) vch[i] = ~vch[i]; } break; case OP_AND: case OP_OR: case OP_XOR: { // (x1 x2 - out) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); MakeSameSize(vch1, vch2); if (opcode == OP_AND) { for (int i = 0; i < vch1.size(); i++) vch1[i] &= vch2[i]; } else if (opcode == OP_OR) { for (int i = 0; i < vch1.size(); i++) vch1[i] |= vch2[i]; } else if (opcode == OP_XOR) { for (int i = 0; i < vch1.size(); i++) vch1[i] ^= vch2[i]; } stack.pop_back(); } break; case OP_EQUAL: case OP_EQUALVERIFY: //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL { // (x1 x2 - bool) if (stack.size() < 2) return false; valtype& vch1 = stacktop(-2); valtype& vch2 = stacktop(-1); bool fEqual = (vch1 == vch2); // OP_NOTEQUAL is disabled because it would be too easy to say // something like n != 1 and have some wiseguy pass in 1 with extra // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001) //if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; stack.pop_back(); stack.pop_back(); stack.push_back(fEqual ? vchTrue : vchFalse); if (opcode == OP_EQUALVERIFY) { if (fEqual) stack.pop_back(); else return false; } } break; // // Numeric // case OP_1ADD: case OP_1SUB: case OP_2MUL: case OP_2DIV: case OP_NEGATE: case OP_ABS: case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) if (stack.size() < 1) return false; if (stacktop(-1).size() > nMaxNumSize) return false; CBigNum bn(stacktop(-1)); switch (opcode) { case OP_1ADD: bn += bnOne; break; case OP_1SUB: bn -= bnOne; break; case OP_2MUL: bn <<= 1; break; case OP_2DIV: bn >>= 1; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: if (bn < bnZero) bn = -bn; break; case OP_NOT: bn = (bn == bnZero); break; case OP_0NOTEQUAL: bn = (bn != bnZero); break; } stack.pop_back(); stack.push_back(bn.getvch()); } break; case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_LSHIFT: case OP_RSHIFT: case OP_BOOLAND: case OP_BOOLOR: case OP_NUMEQUAL: case OP_NUMEQUALVERIFY: case OP_NUMNOTEQUAL: case OP_LESSTHAN: case OP_GREATERTHAN: case OP_LESSTHANOREQUAL: case OP_GREATERTHANOREQUAL: case OP_MIN: case OP_MAX: { // (x1 x2 -- out) if (stack.size() < 2) return false; if (stacktop(-2).size() > nMaxNumSize || stacktop(-1).size() > nMaxNumSize) return false; CBigNum bn1(stacktop(-2)); CBigNum bn2(stacktop(-1)); CBigNum bn; switch (opcode) { case OP_ADD: bn = bn1 + bn2; break; case OP_SUB: bn = bn1 - bn2; break; case OP_MUL: if (!BN_mul(&bn, &bn1, &bn2, pctx)) return false; break; case OP_DIV: if (!BN_div(&bn, NULL, &bn1, &bn2, pctx)) return false; break; case OP_MOD: if (!BN_mod(&bn, &bn1, &bn2, pctx)) return false; break; case OP_LSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 << bn2.getulong(); break; case OP_RSHIFT: if (bn2 < bnZero || bn2 > CBigNum(2048)) return false; bn = bn1 >> bn2.getulong(); break; case OP_BOOLAND: bn = (bn1 != bnZero && bn2 != bnZero); break; case OP_BOOLOR: bn = (bn1 != bnZero || bn2 != bnZero); break; case OP_NUMEQUAL: bn = (bn1 == bn2); break; case OP_NUMEQUALVERIFY: bn = (bn1 == bn2); break; case OP_NUMNOTEQUAL: bn = (bn1 != bn2); break; case OP_LESSTHAN: bn = (bn1 < bn2); break; case OP_GREATERTHAN: bn = (bn1 > bn2); break; case OP_LESSTHANOREQUAL: bn = (bn1 <= bn2); break; case OP_GREATERTHANOREQUAL: bn = (bn1 >= bn2); break; case OP_MIN: bn = (bn1 < bn2 ? bn1 : bn2); break; case OP_MAX: bn = (bn1 > bn2 ? bn1 : bn2); break; } stack.pop_back(); stack.pop_back(); stack.push_back(bn.getvch()); if (opcode == OP_NUMEQUALVERIFY) { if (CastToBool(stacktop(-1))) stack.pop_back(); else return false; } } break; case OP_WITHIN: { // (x min max -- out) if (stack.size() < 3) return false; if (stacktop(-3).size() > nMaxNumSize || stacktop(-2).size() > nMaxNumSize || stacktop(-1).size() > nMaxNumSize) return false; CBigNum bn1(stacktop(-3)); CBigNum bn2(stacktop(-2)); CBigNum bn3(stacktop(-1)); bool fValue = (bn2 <= bn1 && bn1 < bn3); stack.pop_back(); stack.pop_back(); stack.pop_back(); stack.push_back(fValue ? vchTrue : vchFalse); } break; // // Crypto // case OP_RIPEMD160: case OP_SHA1: case OP_SHA256: case OP_HASH160: case OP_HASH256: { // (in -- hash) if (stack.size() < 1) return false; valtype& vch = stacktop(-1); valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32); if (opcode == OP_RIPEMD160) RIPEMD160(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA1) SHA1(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_SHA256) SHA256(&vch[0], vch.size(), &vchHash[0]); else if (opcode == OP_HASH160) { uint160 hash160 = Hash160(vch); memcpy(&vchHash[0], &hash160, sizeof(hash160)); } else if (opcode == OP_HASH256) { uint256 hash = Hash(vch.begin(), vch.end()); memcpy(&vchHash[0], &hash, sizeof(hash)); } stack.pop_back(); stack.push_back(vchHash); } break; case OP_CODESEPARATOR: { // Hash starts after the code separator pbegincodehash = pc; } break; case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { // (sig pubkey -- bool) if (stack.size() < 2) return false; valtype& vchSig = stacktop(-2); valtype& vchPubKey = stacktop(-1); ////// debug print //PrintHex(vchSig.begin(), vchSig.end(), "sig: %s\n"); //PrintHex(vchPubKey.begin(), vchPubKey.end(), "pubkey: %s\n"); // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); bool fSuccess = CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType); stack.pop_back(); stack.pop_back(); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKSIGVERIFY) { if (fSuccess) stack.pop_back(); else return false; } } break; case OP_CHECKMULTISIG: case OP_CHECKMULTISIGVERIFY: { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) int i = 1; if (stack.size() < i) return false; int nKeysCount = CBigNum(stacktop(-i)).getint(); if (nKeysCount < 0) return false; int ikey = ++i; i += nKeysCount; if (stack.size() < i) return false; int nSigsCount = CBigNum(stacktop(-i)).getint(); if (nSigsCount < 0 || nSigsCount > nKeysCount) return false; int isig = ++i; i += nSigsCount; if (stack.size() < i) return false; // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); // Drop the signatures, since there's no way for a signature to sign itself for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); scriptCode.FindAndDelete(CScript(vchSig)); } bool fSuccess = true; while (fSuccess && nSigsCount > 0) { valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); // Check signature if (CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, nHashType)) { isig++; nSigsCount--; } ikey++; nKeysCount--; // If there are more signatures left than keys left, // then too many signatures have failed if (nSigsCount > nKeysCount) fSuccess = false; } while (i-- > 0) stack.pop_back(); stack.push_back(fSuccess ? vchTrue : vchFalse); if (opcode == OP_CHECKMULTISIGVERIFY) { if (fSuccess) stack.pop_back(); else return false; } } break; default: return false; } // Size limits if (stack.size() + altstack.size() > 1000) return false; } } catch (...) { return false; } if (!vfExec.empty()) return false; return true; }
int RSA_recover_crt_params(RSA *rsa) { BN_CTX *ctx; BIGNUM *totient, *rem, *multiple, *p_plus_q, *p_minus_q; int ok = 0; if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); return 0; } if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) { OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN); return 0; } if (rsa->additional_primes != NULL) { OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY); return 0; } /* This uses the algorithm from section 9B of the RSA paper: * http://people.csail.mit.edu/rivest/Rsapaper.pdf */ ctx = BN_CTX_new(); if (ctx == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } BN_CTX_start(ctx); totient = BN_CTX_get(ctx); rem = BN_CTX_get(ctx); multiple = BN_CTX_get(ctx); p_plus_q = BN_CTX_get(ctx); p_minus_q = BN_CTX_get(ctx); if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL || p_minus_q == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } /* ed-1 is a small multiple of φ(n). */ if (!BN_mul(totient, rsa->e, rsa->d, ctx) || !BN_sub_word(totient, 1) || /* φ(n) = * pq - p - q + 1 = * n - (p + q) + 1 * * Thus n is a reasonable estimate for φ(n). So, (ed-1)/n will be very * close. But, when we calculate the quotient, we'll be truncating it * because we discard the remainder. Thus (ed-1)/multiple will be >= n, * which the totient cannot be. So we add one to the estimate. * * Consider ed-1 as: * * multiple * (n - (p+q) + 1) = * multiple*n - multiple*(p+q) + multiple * * When we divide by n, the first term becomes multiple and, since * multiple and p+q is tiny compared to n, the second and third terms can * be ignored. Thus I claim that subtracting one from the estimate is * sufficient. */ !BN_div(multiple, NULL, totient, rsa->n, ctx) || !BN_add_word(multiple, 1) || !BN_div(totient, rem, totient, multiple, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } if (!BN_is_zero(rem)) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); goto err; } rsa->p = BN_new(); rsa->q = BN_new(); rsa->dmp1 = BN_new(); rsa->dmq1 = BN_new(); rsa->iqmp = BN_new(); if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 == NULL || rsa->iqmp == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); goto err; } /* φ(n) = n - (p + q) + 1 => * n - totient + 1 = p + q */ if (!BN_sub(p_plus_q, rsa->n, totient) || !BN_add_word(p_plus_q, 1) || /* p - q = sqrt((p+q)^2 - 4n) */ !BN_sqr(rem, p_plus_q, ctx) || !BN_lshift(multiple, rsa->n, 2) || !BN_sub(rem, rem, multiple) || !BN_sqrt(p_minus_q, rem, ctx) || /* q is 1/2 (p+q)-(p-q) */ !BN_sub(rsa->q, p_plus_q, p_minus_q) || !BN_rshift1(rsa->q, rsa->q) || !BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) || !BN_mul(multiple, rsa->p, rsa->q, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } if (BN_cmp(multiple, rsa->n) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); goto err; } if (!BN_sub(rem, rsa->p, BN_value_one()) || !BN_mod(rsa->dmp1, rsa->d, rem, ctx) || !BN_sub(rem, rsa->q, BN_value_one()) || !BN_mod(rsa->dmq1, rsa->d, rem, ctx) || !BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB); goto err; } ok = 1; err: BN_CTX_end(ctx); BN_CTX_free(ctx); if (!ok) { bn_free_and_null(&rsa->p); bn_free_and_null(&rsa->q); bn_free_and_null(&rsa->dmp1); bn_free_and_null(&rsa->dmq1); bn_free_and_null(&rsa->iqmp); } return ok; }
int RSA_check_key(const RSA *key) { BIGNUM n, pm1, qm1, lcm, gcd, de, dmp1, dmq1, iqmp_times_q; BN_CTX *ctx; int ok = 0, has_crt_values; if (RSA_is_opaque(key)) { /* Opaque keys can't be checked. */ return 1; } if ((key->p != NULL) != (key->q != NULL)) { OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); return 0; } if (!key->n || !key->e) { OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); return 0; } if (!key->d || !key->p) { /* For a public key, or without p and q, there's nothing that can be * checked. */ return 1; } ctx = BN_CTX_new(); if (ctx == NULL) { OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); return 0; } BN_init(&n); BN_init(&pm1); BN_init(&qm1); BN_init(&lcm); BN_init(&gcd); BN_init(&de); BN_init(&dmp1); BN_init(&dmq1); BN_init(&iqmp_times_q); if (!BN_mul(&n, key->p, key->q, ctx) || /* lcm = lcm(prime-1, for all primes) */ !BN_sub(&pm1, key->p, BN_value_one()) || !BN_sub(&qm1, key->q, BN_value_one()) || !BN_mul(&lcm, &pm1, &qm1, ctx) || !BN_gcd(&gcd, &pm1, &qm1, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } size_t num_additional_primes = 0; if (key->additional_primes != NULL) { num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes); } for (size_t i = 0; i < num_additional_primes; i++) { const RSA_additional_prime *ap = sk_RSA_additional_prime_value(key->additional_primes, i); if (!BN_mul(&n, &n, ap->prime, ctx) || !BN_sub(&pm1, ap->prime, BN_value_one()) || !BN_mul(&lcm, &lcm, &pm1, ctx) || !BN_gcd(&gcd, &gcd, &pm1, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } } if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) || !BN_gcd(&gcd, &pm1, &qm1, ctx) || /* de = d*e mod lcm(prime-1, for all primes). */ !BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } if (BN_cmp(&n, key->n) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); goto out; } if (!BN_is_one(&de)) { OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); goto out; } has_crt_values = key->dmp1 != NULL; if (has_crt_values != (key->dmq1 != NULL) || has_crt_values != (key->iqmp != NULL)) { OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); goto out; } if (has_crt_values && num_additional_primes == 0) { if (/* dmp1 = d mod (p-1) */ !BN_mod(&dmp1, key->d, &pm1, ctx) || /* dmq1 = d mod (q-1) */ !BN_mod(&dmq1, key->d, &qm1, ctx) || /* iqmp = q^-1 mod p */ !BN_mod_mul(&iqmp_times_q, key->iqmp, key->q, key->p, ctx)) { OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); goto out; } if (BN_cmp(&dmp1, key->dmp1) != 0 || BN_cmp(&dmq1, key->dmq1) != 0 || BN_cmp(key->iqmp, key->p) >= 0 || !BN_is_one(&iqmp_times_q)) { OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT); goto out; } } ok = 1; out: BN_free(&n); BN_free(&pm1); BN_free(&qm1); BN_free(&lcm); BN_free(&gcd); BN_free(&de); BN_free(&dmp1); BN_free(&dmq1); BN_free(&iqmp_times_q); BN_CTX_free(ctx); return ok; }