version 1.55, 2017/11/28 17:43:45 |
version 1.56, 2017/11/29 19:13:31 |
|
|
static void bmod(void); |
static void bmod(void); |
static void bdivmod(void); |
static void bdivmod(void); |
static void bexp(void); |
static void bexp(void); |
static bool bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *); |
|
static void bsqrt(void); |
static void bsqrt(void); |
static void not(void); |
static void not(void); |
static void equal_numbers(void); |
static void equal_numbers(void); |
|
|
free_number(p); |
free_number(p); |
} |
} |
|
|
static bool |
|
bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount) |
|
{ |
|
BIGNUM *r; |
|
bool ret; |
|
|
|
r = BN_new(); |
|
bn_checkp(r); |
|
bn_check(BN_sub(r, x, y)); |
|
if (BN_is_one(r)) |
|
(*onecount)++; |
|
ret = BN_is_zero(r); |
|
BN_free(r); |
|
return ret || *onecount > 1; |
|
} |
|
|
|
static void |
static void |
bsqrt(void) |
bsqrt(void) |
{ |
{ |
struct number *n; |
struct number *n; |
struct number *r; |
struct number *r; |
BIGNUM *x, *y; |
BIGNUM *x, *y, *t; |
u_int scale, onecount; |
u_int scale, onecount; |
BN_CTX *ctx; |
BN_CTX *ctx; |
|
|
|
|
bn_checkp(y); |
bn_checkp(y); |
ctx = BN_CTX_new(); |
ctx = BN_CTX_new(); |
bn_checkp(ctx); |
bn_checkp(ctx); |
for (;;) { |
do { |
bn_checkp(BN_copy(y, x)); |
bn_check(BN_div(y, NULL, n->number, x, ctx)); |
bn_check(BN_div(x, NULL, n->number, x, ctx)); |
bn_check(BN_add(y, x, y)); |
bn_check(BN_add(x, x, y)); |
bn_check(BN_rshift1(y, y)); |
bn_check(BN_rshift1(x, x)); |
bn_check(BN_sub(x, y, x)); |
if (bsqrt_stop(x, y, &onecount)) |
t = x; |
break; |
x = y; |
} |
y = t; |
|
} while (!BN_is_zero(y) && (onecount += BN_is_one(y)) < 2); |
|
bn_check(BN_sub(y, x, y)); |
r = bmalloc(sizeof(*r)); |
r = bmalloc(sizeof(*r)); |
r->scale = scale; |
r->scale = scale; |
r->number = y; |
r->number = y; |