int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { BIGNUM *tmp; int ret = 0; #if defined(OPENSSL_BN_ASM_MONT) int num = mont->N.top; if (num > 1 && a->top == num && b->top == num) { if (bn_wexpand(r, num) == NULL) { return 0; } if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { r->neg = a->neg ^ b->neg; r->top = num; bn_correct_top(r); return 1; } } #endif BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); if (tmp == NULL) { goto err; } if (a == b) { if (!BN_sqr(tmp, a, ctx)) { goto err; } } else { if (!BN_mul(tmp, a, b, ctx)) { goto err; } } /* reduce from aRR to aR */ if (!BN_from_montgomery_word(r, tmp, mont)) { goto err; } ret = 1; err: BN_CTX_end(ctx); return ret; }
int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx) { int retn = 0; #ifdef MONT_WORD BIGNUM *t; BN_CTX_start(ctx); if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) retn = BN_from_montgomery_word(ret, t, mont); BN_CTX_end(ctx); #else /* !MONT_WORD */ BIGNUM *t1, *t2; BN_CTX_start(ctx); t1 = BN_CTX_get(ctx); t2 = BN_CTX_get(ctx); if (t1 == NULL || t2 == NULL) goto err; if (!BN_copy(t1, a)) goto err; BN_mask_bits(t1, mont->ri); if (!BN_mul(t2, t1, &mont->Ni, ctx)) goto err; BN_mask_bits(t2, mont->ri); if (!BN_mul(t1, t2, &mont->N, ctx)) goto err; if (!BN_add(t2, a, t1)) goto err; if (!BN_rshift(ret, t2, mont->ri)) goto err; #if !defined(BRANCH_FREE) || BRANCH_FREE==0 if (BN_ucmp(ret, &(mont->N)) >= 0) { if (!BN_usub(ret, ret, &(mont->N))) goto err; } #endif retn = 1; bn_check_top(ret); err: BN_CTX_end(ctx); #endif /* MONT_WORD */ return (retn); }
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_MONT_CTX *mont, BN_CTX *ctx) { BIGNUM *tmp; int ret = 0; #if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) int num = mont->N.top; if (num > 1 && a->top == num && b->top == num) { if (bn_wexpand(r, num) == NULL) return (0); if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { r->neg = a->neg^b->neg; r->top = num; bn_correct_top(r); return (1); } } #endif BN_CTX_start(ctx); if ((tmp = BN_CTX_get(ctx)) == NULL) goto err; bn_check_top(tmp); if (a == b) { if (!BN_sqr(tmp, a, ctx)) goto err; } else { if (!BN_mul(tmp, a,b, ctx)) goto err; } /* reduce from aRR to aR */ #ifdef MONT_WORD if (!BN_from_montgomery_word(r, tmp, mont)) goto err; #else if (!BN_from_montgomery(r, tmp, mont, ctx)) goto err; #endif bn_check_top(r); ret = 1; err: BN_CTX_end(ctx); return (ret); }
int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BN_MONT_CTX *mont, BN_CTX *ctx) { BIGNUM *tmp; int ret = 0; int num = mont->N.top; /* bn_mul_mont requires at least four limbs, at least for x86. */ if (num >= 4 && a->top == num && b->top == num) { if (bn_wexpand(r, num) == NULL) { return 0; } bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num); r->neg = a->neg ^ b->neg; r->top = num; bn_correct_top(r); return 1; } BN_CTX_start(ctx); tmp = BN_CTX_get(ctx); if (tmp == NULL) { goto err; } if (a == b) { if (!BN_sqr(tmp, a, ctx)) { goto err; } } else { if (!BN_mul(tmp, a, b, ctx)) { goto err; } } /* reduce from aRR to aR */ if (!BN_from_montgomery_word(r, tmp, mont)) { goto err; } ret = 1; err: BN_CTX_end(ctx); return ret; }
int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont, BN_CTX *ctx) { int retn = 0; BIGNUM *t; BN_CTX_start(ctx); t = BN_CTX_get(ctx); if (t == NULL) { return 0; } if (BN_copy(t, a)) { retn = BN_from_montgomery_word(ret, t, mont); } BN_CTX_end(ctx); return retn; }
int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont, BN_CTX *ctx) { int ret = 0; BIGNUM *t; BN_CTX_start(ctx); t = BN_CTX_get(ctx); if (t == NULL || !BN_copy(t, a)) { goto err; } ret = BN_from_montgomery_word(r, t, mont); err: BN_CTX_end(ctx); return ret; }
int BN_reduce_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mod_mont, BN_CTX *ctx) { BIGNUM tmp; BN_init(&tmp); if (!BN_copy(&tmp, a)) { OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); return 0; } int ret = 0; if (!BN_from_montgomery_word(r, &tmp, mod_mont) || !BN_to_montgomery(r, r, mod_mont, ctx)) { goto err; } ret = 1; err: BN_free(&tmp); return ret; }