Using Horner's algorithm to evaluate the ec polynomial
(suggested by Adam Young <ayoung@cigital.com>) Submitted by: Nils Larsch
This commit is contained in:
parent
5906e8d5fe
commit
7f5b4dd1e8
@ -805,13 +805,18 @@ int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
|
|||||||
*/
|
*/
|
||||||
int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
|
int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
BN_CTX *new_ctx = NULL;
|
|
||||||
BIGNUM *rh, *lh, *tmp1;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
BN_CTX *new_ctx = NULL;
|
||||||
|
BIGNUM *lh, *y2;
|
||||||
|
int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||||
|
int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||||
|
|
||||||
if (EC_POINT_is_at_infinity(group, point))
|
if (EC_POINT_is_at_infinity(group, point))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
field_mul = group->meth->field_mul;
|
||||||
|
field_sqr = group->meth->field_sqr;
|
||||||
|
|
||||||
/* only support affine coordinates */
|
/* only support affine coordinates */
|
||||||
if (!point->Z_is_one) goto err;
|
if (!point->Z_is_one) goto err;
|
||||||
|
|
||||||
@ -823,37 +828,23 @@ int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_
|
|||||||
}
|
}
|
||||||
|
|
||||||
BN_CTX_start(ctx);
|
BN_CTX_start(ctx);
|
||||||
rh = BN_CTX_get(ctx);
|
y2 = BN_CTX_get(ctx);
|
||||||
lh = BN_CTX_get(ctx);
|
lh = BN_CTX_get(ctx);
|
||||||
tmp1 = BN_CTX_get(ctx);
|
if (lh == NULL) goto err;
|
||||||
if (tmp1 == NULL) goto err;
|
|
||||||
|
|
||||||
/* We have a curve defined by a Weierstrass equation
|
/* We have a curve defined by a Weierstrass equation
|
||||||
* y^2 + x*y = x^3 + a*x^2 + b.
|
* y^2 + x*y = x^3 + a*x^2 + b.
|
||||||
* To test this, we add up the right-hand side in 'rh'
|
* <=> x^3 + a*x^2 + x*y + b + y^2 = 0
|
||||||
* and the left-hand side in 'lh'.
|
* <=> ((x + a) * x + y ) * x + b + y^2 = 0
|
||||||
*/
|
*/
|
||||||
|
if (!BN_GF2m_add(lh, &point->X, &group->a)) goto err;
|
||||||
/* rh := X^3 */
|
if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
|
||||||
if (!group->meth->field_sqr(group, tmp1, &point->X, ctx)) goto err;
|
if (!BN_GF2m_add(lh, lh, &point->Y)) goto err;
|
||||||
if (!group->meth->field_mul(group, rh, tmp1, &point->X, ctx)) goto err;
|
if (!field_mul(group, lh, lh, &point->X, ctx)) goto err;
|
||||||
|
if (!BN_GF2m_add(lh, lh, &group->b)) goto err;
|
||||||
/* rh := rh + a*X^2 */
|
if (!field_sqr(group, y2, &point->Y, ctx)) goto err;
|
||||||
if (!group->meth->field_mul(group, tmp1, tmp1, &group->a, ctx)) goto err;
|
if (!BN_GF2m_add(lh, lh, y2)) goto err;
|
||||||
if (!BN_GF2m_add(rh, rh, tmp1)) goto err;
|
ret = BN_is_zero(lh);
|
||||||
|
|
||||||
/* rh := rh + b */
|
|
||||||
if (!BN_GF2m_add(rh, rh, &group->b)) goto err;
|
|
||||||
|
|
||||||
/* lh := Y^2 */
|
|
||||||
if (!group->meth->field_sqr(group, lh, &point->Y, ctx)) goto err;
|
|
||||||
|
|
||||||
/* lh := lh + x*y */
|
|
||||||
if (!group->meth->field_mul(group, tmp1, &point->X, &point->Y, ctx)) goto err;
|
|
||||||
if (!BN_GF2m_add(lh, lh, tmp1)) goto err;
|
|
||||||
|
|
||||||
ret = (0 == BN_GF2m_cmp(lh, rh));
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (ctx) BN_CTX_end(ctx);
|
if (ctx) BN_CTX_end(ctx);
|
||||||
if (new_ctx) BN_CTX_free(new_ctx);
|
if (new_ctx) BN_CTX_free(new_ctx);
|
||||||
|
@ -1301,7 +1301,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
|
|||||||
int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
|
int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
|
||||||
const BIGNUM *p;
|
const BIGNUM *p;
|
||||||
BN_CTX *new_ctx = NULL;
|
BN_CTX *new_ctx = NULL;
|
||||||
BIGNUM *rh, *tmp1, *tmp2, *Z4, *Z6;
|
BIGNUM *rh, *tmp, *Z4, *Z6;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (EC_POINT_is_at_infinity(group, point))
|
if (EC_POINT_is_at_infinity(group, point))
|
||||||
@ -1320,8 +1320,7 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
|
|||||||
|
|
||||||
BN_CTX_start(ctx);
|
BN_CTX_start(ctx);
|
||||||
rh = BN_CTX_get(ctx);
|
rh = BN_CTX_get(ctx);
|
||||||
tmp1 = BN_CTX_get(ctx);
|
tmp = BN_CTX_get(ctx);
|
||||||
tmp2 = BN_CTX_get(ctx);
|
|
||||||
Z4 = BN_CTX_get(ctx);
|
Z4 = BN_CTX_get(ctx);
|
||||||
Z6 = BN_CTX_get(ctx);
|
Z6 = BN_CTX_get(ctx);
|
||||||
if (Z6 == NULL) goto err;
|
if (Z6 == NULL) goto err;
|
||||||
@ -1335,59 +1334,49 @@ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_C
|
|||||||
* To test this, we add up the right-hand side in 'rh'.
|
* To test this, we add up the right-hand side in 'rh'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* rh := X^3 */
|
/* rh := X^2 */
|
||||||
if (!field_sqr(group, rh, &point->X, ctx)) goto err;
|
if (!field_sqr(group, rh, &point->X, ctx)) goto err;
|
||||||
if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
|
|
||||||
|
|
||||||
if (!point->Z_is_one)
|
if (!point->Z_is_one)
|
||||||
{
|
{
|
||||||
if (!field_sqr(group, tmp1, &point->Z, ctx)) goto err;
|
if (!field_sqr(group, tmp, &point->Z, ctx)) goto err;
|
||||||
if (!field_sqr(group, Z4, tmp1, ctx)) goto err;
|
if (!field_sqr(group, Z4, tmp, ctx)) goto err;
|
||||||
if (!field_mul(group, Z6, Z4, tmp1, ctx)) goto err;
|
if (!field_mul(group, Z6, Z4, tmp, ctx)) goto err;
|
||||||
|
|
||||||
/* rh := rh + a*X*Z^4 */
|
/* rh := (rh + a*Z^4)*X */
|
||||||
if (!field_mul(group, tmp1, &point->X, Z4, ctx)) goto err;
|
|
||||||
if (group->a_is_minus3)
|
if (group->a_is_minus3)
|
||||||
{
|
{
|
||||||
if (!BN_mod_lshift1_quick(tmp2, tmp1, p)) goto err;
|
if (!BN_mod_lshift1_quick(tmp, Z4, p)) goto err;
|
||||||
if (!BN_mod_add_quick(tmp2, tmp2, tmp1, p)) goto err;
|
if (!BN_mod_add_quick(tmp, tmp, Z4, p)) goto err;
|
||||||
if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err;
|
if (!BN_mod_sub_quick(rh, rh, tmp, p)) goto err;
|
||||||
|
if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!field_mul(group, tmp2, tmp1, &group->a, ctx)) goto err;
|
if (!field_mul(group, tmp, Z4, &group->a, ctx)) goto err;
|
||||||
if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err;
|
if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
|
||||||
|
if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rh := rh + b*Z^6 */
|
/* rh := rh + b*Z^6 */
|
||||||
if (!field_mul(group, tmp1, &group->b, Z6, ctx)) goto err;
|
if (!field_mul(group, tmp, &group->b, Z6, ctx)) goto err;
|
||||||
if (!BN_mod_add_quick(rh, rh, tmp1, p)) goto err;
|
if (!BN_mod_add_quick(rh, rh, tmp, p)) goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* point->Z_is_one */
|
/* point->Z_is_one */
|
||||||
|
|
||||||
/* rh := rh + a*X */
|
/* rh := (rh + a)*X */
|
||||||
if (group->a_is_minus3)
|
if (!BN_mod_add_quick(rh, rh, &group->a, p)) goto err;
|
||||||
{
|
if (!field_mul(group, rh, rh, &point->X, ctx)) goto err;
|
||||||
if (!BN_mod_lshift1_quick(tmp2, &point->X, p)) goto err;
|
|
||||||
if (!BN_mod_add_quick(tmp2, tmp2, &point->X, p)) goto err;
|
|
||||||
if (!BN_mod_sub_quick(rh, rh, tmp2, p)) goto err;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!field_mul(group, tmp2, &point->X, &group->a, ctx)) goto err;
|
|
||||||
if (!BN_mod_add_quick(rh, rh, tmp2, p)) goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rh := rh + b */
|
/* rh := rh + b */
|
||||||
if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
|
if (!BN_mod_add_quick(rh, rh, &group->b, p)) goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 'lh' := Y^2 */
|
/* 'lh' := Y^2 */
|
||||||
if (!field_sqr(group, tmp1, &point->Y, ctx)) goto err;
|
if (!field_sqr(group, tmp, &point->Y, ctx)) goto err;
|
||||||
|
|
||||||
ret = (0 == BN_cmp(tmp1, rh));
|
ret = (0 == BN_ucmp(tmp, rh));
|
||||||
|
|
||||||
err:
|
err:
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user