Back to index

lightning-sunbird  0.9+nobinonly
Functions
ecp.h File Reference
#include "ecl-priv.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

mp_err ec_GFp_pt_is_inf_aff (const mp_int *px, const mp_int *py)
mp_err ec_GFp_pt_set_inf_aff (mp_int *px, mp_int *py)
mp_err ec_GFp_pt_add_aff (const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, mp_int *rx, mp_int *ry, const ECGroup *group)
mp_err ec_GFp_pt_sub_aff (const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, mp_int *rx, mp_int *ry, const ECGroup *group)
mp_err ec_GFp_pt_dbl_aff (const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group)
mp_err ec_GFp_validate_point (const mp_int *px, const mp_int *py, const ECGroup *group)
mp_err ec_GFp_pt_aff2jac (const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
mp_err ec_GFp_pt_jac2aff (const mp_int *px, const mp_int *py, const mp_int *pz, mp_int *rx, mp_int *ry, const ECGroup *group)
mp_err ec_GFp_pt_is_inf_jac (const mp_int *px, const mp_int *py, const mp_int *pz)
mp_err ec_GFp_pt_set_inf_jac (mp_int *px, mp_int *py, mp_int *pz)
mp_err ec_GFp_pt_add_jac_aff (const mp_int *px, const mp_int *py, const mp_int *pz, const mp_int *qx, const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
mp_err ec_GFp_pt_dbl_jac (const mp_int *px, const mp_int *py, const mp_int *pz, mp_int *rx, mp_int *ry, mp_int *rz, const ECGroup *group)
mp_err ec_GFp_pts_mul_jac (const mp_int *k1, const mp_int *k2, const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group)
mp_err ec_GFp_pt_mul_jm_wNAF (const mp_int *n, const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group)

Function Documentation

mp_err ec_GFp_pt_add_aff ( const mp_int px,
const mp_int py,
const mp_int qx,
const mp_int qy,
mp_int rx,
mp_int ry,
const ECGroup *  group 
)

Definition at line 75 of file ecp_aff.c.

{
       mp_err res = MP_OKAY;
       mp_int lambda, temp, tempx, tempy;

       MP_DIGITS(&lambda) = 0;
       MP_DIGITS(&temp) = 0;
       MP_DIGITS(&tempx) = 0;
       MP_DIGITS(&tempy) = 0;
       MP_CHECKOK(mp_init(&lambda));
       MP_CHECKOK(mp_init(&temp));
       MP_CHECKOK(mp_init(&tempx));
       MP_CHECKOK(mp_init(&tempy));
       /* if P = inf, then R = Q */
       if (ec_GFp_pt_is_inf_aff(px, py) == 0) {
              MP_CHECKOK(mp_copy(qx, rx));
              MP_CHECKOK(mp_copy(qy, ry));
              res = MP_OKAY;
              goto CLEANUP;
       }
       /* if Q = inf, then R = P */
       if (ec_GFp_pt_is_inf_aff(qx, qy) == 0) {
              MP_CHECKOK(mp_copy(px, rx));
              MP_CHECKOK(mp_copy(py, ry));
              res = MP_OKAY;
              goto CLEANUP;
       }
       /* if px != qx, then lambda = (py-qy) / (px-qx) */
       if (mp_cmp(px, qx) != 0) {
              MP_CHECKOK(group->meth->field_sub(py, qy, &tempy, group->meth));
              MP_CHECKOK(group->meth->field_sub(px, qx, &tempx, group->meth));
              MP_CHECKOK(group->meth->
                               field_div(&tempy, &tempx, &lambda, group->meth));
       } else {
              /* if py != qy or qy = 0, then R = inf */
              if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) {
                     mp_zero(rx);
                     mp_zero(ry);
                     res = MP_OKAY;
                     goto CLEANUP;
              }
              /* lambda = (3qx^2+a) / (2qy) */
              MP_CHECKOK(group->meth->field_sqr(qx, &tempx, group->meth));
              MP_CHECKOK(mp_set_int(&temp, 3));
              if (group->meth->field_enc) {
                     MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
              }
              MP_CHECKOK(group->meth->
                               field_mul(&tempx, &temp, &tempx, group->meth));
              MP_CHECKOK(group->meth->
                               field_add(&tempx, &group->curvea, &tempx, group->meth));
              MP_CHECKOK(mp_set_int(&temp, 2));
              if (group->meth->field_enc) {
                     MP_CHECKOK(group->meth->field_enc(&temp, &temp, group->meth));
              }
              MP_CHECKOK(group->meth->field_mul(qy, &temp, &tempy, group->meth));
              MP_CHECKOK(group->meth->
                               field_div(&tempx, &tempy, &lambda, group->meth));
       }
       /* rx = lambda^2 - px - qx */
       MP_CHECKOK(group->meth->field_sqr(&lambda, &tempx, group->meth));
       MP_CHECKOK(group->meth->field_sub(&tempx, px, &tempx, group->meth));
       MP_CHECKOK(group->meth->field_sub(&tempx, qx, &tempx, group->meth));
       /* ry = (x1-x2) * lambda - y1 */
       MP_CHECKOK(group->meth->field_sub(qx, &tempx, &tempy, group->meth));
       MP_CHECKOK(group->meth->
                        field_mul(&tempy, &lambda, &tempy, group->meth));
       MP_CHECKOK(group->meth->field_sub(&tempy, qy, &tempy, group->meth));
       MP_CHECKOK(mp_copy(&tempx, rx));
       MP_CHECKOK(mp_copy(&tempy, ry));

  CLEANUP:
       mp_clear(&lambda);
       mp_clear(&temp);
       mp_clear(&tempx);
       mp_clear(&tempy);
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_add_jac_aff ( const mp_int px,
const mp_int py,
const mp_int pz,
const mp_int qx,
const mp_int qy,
mp_int rx,
mp_int ry,
mp_int rz,
const ECGroup *  group 
)

Definition at line 143 of file ecp_jac.c.

{
       mp_err res = MP_OKAY;
       mp_int A, B, C, D, C2, C3;

       MP_DIGITS(&A) = 0;
       MP_DIGITS(&B) = 0;
       MP_DIGITS(&C) = 0;
       MP_DIGITS(&D) = 0;
       MP_DIGITS(&C2) = 0;
       MP_DIGITS(&C3) = 0;
       MP_CHECKOK(mp_init(&A));
       MP_CHECKOK(mp_init(&B));
       MP_CHECKOK(mp_init(&C));
       MP_CHECKOK(mp_init(&D));
       MP_CHECKOK(mp_init(&C2));
       MP_CHECKOK(mp_init(&C3));

       /* If either P or Q is the point at infinity, then return the other
        * point */
       if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
              MP_CHECKOK(ec_GFp_pt_aff2jac(qx, qy, rx, ry, rz, group));
              goto CLEANUP;
       }
       if (ec_GFp_pt_is_inf_aff(qx, qy) == MP_YES) {
              MP_CHECKOK(mp_copy(px, rx));
              MP_CHECKOK(mp_copy(py, ry));
              MP_CHECKOK(mp_copy(pz, rz));
              goto CLEANUP;
       }

       /* A = qx * pz^2, B = qy * pz^3 */
       MP_CHECKOK(group->meth->field_sqr(pz, &A, group->meth));
       MP_CHECKOK(group->meth->field_mul(&A, pz, &B, group->meth));
       MP_CHECKOK(group->meth->field_mul(&A, qx, &A, group->meth));
       MP_CHECKOK(group->meth->field_mul(&B, qy, &B, group->meth));

       /* C = A - px, D = B - py */
       MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
       MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));

       /* C2 = C^2, C3 = C^3 */
       MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
       MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));

       /* rz = pz * C */
       MP_CHECKOK(group->meth->field_mul(pz, &C, rz, group->meth));

       /* C = px * C^2 */
       MP_CHECKOK(group->meth->field_mul(px, &C2, &C, group->meth));
       /* A = D^2 */
       MP_CHECKOK(group->meth->field_sqr(&D, &A, group->meth));

       /* rx = D^2 - (C^3 + 2 * (px * C^2)) */
       MP_CHECKOK(group->meth->field_add(&C, &C, rx, group->meth));
       MP_CHECKOK(group->meth->field_add(&C3, rx, rx, group->meth));
       MP_CHECKOK(group->meth->field_sub(&A, rx, rx, group->meth));

       /* C3 = py * C^3 */
       MP_CHECKOK(group->meth->field_mul(py, &C3, &C3, group->meth));

       /* ry = D * (px * C^2 - rx) - py * C^3 */
       MP_CHECKOK(group->meth->field_sub(&C, rx, ry, group->meth));
       MP_CHECKOK(group->meth->field_mul(&D, ry, ry, group->meth));
       MP_CHECKOK(group->meth->field_sub(ry, &C3, ry, group->meth));

  CLEANUP:
       mp_clear(&A);
       mp_clear(&B);
       mp_clear(&C);
       mp_clear(&D);
       mp_clear(&C2);
       mp_clear(&C3);
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_aff2jac ( const mp_int px,
const mp_int py,
mp_int rx,
mp_int ry,
mp_int rz,
const ECGroup *  group 
)

Definition at line 56 of file ecp_jac.c.

{
       mp_err res = MP_OKAY;

       if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
              MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
       } else {
              MP_CHECKOK(mp_copy(px, rx));
              MP_CHECKOK(mp_copy(py, ry));
              MP_CHECKOK(mp_set_int(rz, 1));
              if (group->meth->field_enc) {
                     MP_CHECKOK(group->meth->field_enc(rz, rz, group->meth));
              }
       }
  CLEANUP:
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_dbl_aff ( const mp_int px,
const mp_int py,
mp_int rx,
mp_int ry,
const ECGroup *  group 
)

Definition at line 182 of file ecp_aff.c.

{
       return ec_GFp_pt_add_aff(px, py, px, py, rx, ry, group);
}

Here is the call graph for this function:

mp_err ec_GFp_pt_dbl_jac ( const mp_int px,
const mp_int py,
const mp_int pz,
mp_int rx,
mp_int ry,
mp_int rz,
const ECGroup *  group 
)

Definition at line 232 of file ecp_jac.c.

{
       mp_err res = MP_OKAY;
       mp_int t0, t1, M, S;

       MP_DIGITS(&t0) = 0;
       MP_DIGITS(&t1) = 0;
       MP_DIGITS(&M) = 0;
       MP_DIGITS(&S) = 0;
       MP_CHECKOK(mp_init(&t0));
       MP_CHECKOK(mp_init(&t1));
       MP_CHECKOK(mp_init(&M));
       MP_CHECKOK(mp_init(&S));

       if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
              MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
              goto CLEANUP;
       }

       if (mp_cmp_d(pz, 1) == 0) {
              /* M = 3 * px^2 + a */
              MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
              MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
              MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
              MP_CHECKOK(group->meth->
                               field_add(&t0, &group->curvea, &M, group->meth));
       } else if (mp_cmp_int(&group->curvea, -3) == 0) {
              /* M = 3 * (px + pz^2) * (px - pz^2) */
              MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
              MP_CHECKOK(group->meth->field_add(px, &M, &t0, group->meth));
              MP_CHECKOK(group->meth->field_sub(px, &M, &t1, group->meth));
              MP_CHECKOK(group->meth->field_mul(&t0, &t1, &M, group->meth));
              MP_CHECKOK(group->meth->field_add(&M, &M, &t0, group->meth));
              MP_CHECKOK(group->meth->field_add(&t0, &M, &M, group->meth));
       } else {
              /* M = 3 * (px^2) + a * (pz^4) */
              MP_CHECKOK(group->meth->field_sqr(px, &t0, group->meth));
              MP_CHECKOK(group->meth->field_add(&t0, &t0, &M, group->meth));
              MP_CHECKOK(group->meth->field_add(&t0, &M, &t0, group->meth));
              MP_CHECKOK(group->meth->field_sqr(pz, &M, group->meth));
              MP_CHECKOK(group->meth->field_sqr(&M, &M, group->meth));
              MP_CHECKOK(group->meth->
                               field_mul(&M, &group->curvea, &M, group->meth));
              MP_CHECKOK(group->meth->field_add(&M, &t0, &M, group->meth));
       }

       /* rz = 2 * py * pz */
       /* t0 = 4 * py^2 */
       if (mp_cmp_d(pz, 1) == 0) {
              MP_CHECKOK(group->meth->field_add(py, py, rz, group->meth));
              MP_CHECKOK(group->meth->field_sqr(rz, &t0, group->meth));
       } else {
              MP_CHECKOK(group->meth->field_add(py, py, &t0, group->meth));
              MP_CHECKOK(group->meth->field_mul(&t0, pz, rz, group->meth));
              MP_CHECKOK(group->meth->field_sqr(&t0, &t0, group->meth));
       }

       /* S = 4 * px * py^2 = px * (2 * py)^2 */
       MP_CHECKOK(group->meth->field_mul(px, &t0, &S, group->meth));

       /* rx = M^2 - 2 * S */
       MP_CHECKOK(group->meth->field_add(&S, &S, &t1, group->meth));
       MP_CHECKOK(group->meth->field_sqr(&M, rx, group->meth));
       MP_CHECKOK(group->meth->field_sub(rx, &t1, rx, group->meth));

       /* ry = M * (S - rx) - 8 * py^4 */
       MP_CHECKOK(group->meth->field_sqr(&t0, &t1, group->meth));
       if (mp_isodd(&t1)) {
              MP_CHECKOK(mp_add(&t1, &group->meth->irr, &t1));
       }
       MP_CHECKOK(mp_div_2(&t1, &t1));
       MP_CHECKOK(group->meth->field_sub(&S, rx, &S, group->meth));
       MP_CHECKOK(group->meth->field_mul(&M, &S, &M, group->meth));
       MP_CHECKOK(group->meth->field_sub(&M, &t1, ry, group->meth));

  CLEANUP:
       mp_clear(&t0);
       mp_clear(&t1);
       mp_clear(&M);
       mp_clear(&S);
       return res;
}

Here is the call graph for this function:

Definition at line 50 of file ecp_aff.c.

{

       if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) {
              return MP_YES;
       } else {
              return MP_NO;
       }

}

Here is the call graph for this function:

Definition at line 121 of file ecp_jac.c.

{
       return mp_cmp_z(pz);
}

Here is the call graph for this function:

mp_err ec_GFp_pt_jac2aff ( const mp_int px,
const mp_int py,
const mp_int pz,
mp_int rx,
mp_int ry,
const ECGroup *  group 
)

Definition at line 80 of file ecp_jac.c.

{
       mp_err res = MP_OKAY;
       mp_int z1, z2, z3;

       MP_DIGITS(&z1) = 0;
       MP_DIGITS(&z2) = 0;
       MP_DIGITS(&z3) = 0;
       MP_CHECKOK(mp_init(&z1));
       MP_CHECKOK(mp_init(&z2));
       MP_CHECKOK(mp_init(&z3));

       /* if point at infinity, then set point at infinity and exit */
       if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) {
              MP_CHECKOK(ec_GFp_pt_set_inf_aff(rx, ry));
              goto CLEANUP;
       }

       /* transform (px, py, pz) into (px / pz^2, py / pz^3) */
       if (mp_cmp_d(pz, 1) == 0) {
              MP_CHECKOK(mp_copy(px, rx));
              MP_CHECKOK(mp_copy(py, ry));
       } else {
              MP_CHECKOK(group->meth->field_div(NULL, pz, &z1, group->meth));
              MP_CHECKOK(group->meth->field_sqr(&z1, &z2, group->meth));
              MP_CHECKOK(group->meth->field_mul(&z1, &z2, &z3, group->meth));
              MP_CHECKOK(group->meth->field_mul(px, &z2, rx, group->meth));
              MP_CHECKOK(group->meth->field_mul(py, &z3, ry, group->meth));
       }

  CLEANUP:
       mp_clear(&z1);
       mp_clear(&z2);
       mp_clear(&z3);
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_mul_jm_wNAF ( const mp_int n,
const mp_int px,
const mp_int py,
mp_int rx,
mp_int ry,
const ECGroup *  group 
)

Definition at line 223 of file ecp_jm.c.

{
       mp_err res = MP_OKAY;
       mp_int precomp[16][2], rz, tpx, tpy;
       mp_int raz4;
       signed char *naf = NULL;
       int i, orderBitSize;

       MP_DIGITS(&rz) = 0;
       MP_DIGITS(&raz4) = 0;
       MP_DIGITS(&tpx) = 0;
       MP_DIGITS(&tpy) = 0;
       for (i = 0; i < 16; i++) {
              MP_DIGITS(&precomp[i][0]) = 0;
              MP_DIGITS(&precomp[i][1]) = 0;
       }

       ARGCHK(group != NULL, MP_BADARG);
       ARGCHK((n != NULL) && (px != NULL) && (py != NULL), MP_BADARG);

       /* initialize precomputation table */
       MP_CHECKOK(mp_init(&tpx));
       MP_CHECKOK(mp_init(&tpy));;
       MP_CHECKOK(mp_init(&rz));
       MP_CHECKOK(mp_init(&raz4));

       for (i = 0; i < 16; i++) {
              MP_CHECKOK(mp_init(&precomp[i][0]));
              MP_CHECKOK(mp_init(&precomp[i][1]));
       }

       /* Set out[8] = P */
       MP_CHECKOK(mp_copy(px, &precomp[8][0]));
       MP_CHECKOK(mp_copy(py, &precomp[8][1]));

       /* Set (tpx, tpy) = 2P */
       MP_CHECKOK(group->
                        point_dbl(&precomp[8][0], &precomp[8][1], &tpx, &tpy,
                                           group));

       /* Set 3P, 5P, ..., 15P */
       for (i = 8; i < 15; i++) {
              MP_CHECKOK(group->
                               point_add(&precomp[i][0], &precomp[i][1], &tpx, &tpy,
                                                  &precomp[i + 1][0], &precomp[i + 1][1],
                                                  group));
       }

       /* Set -15P, -13P, ..., -P */
       for (i = 0; i < 8; i++) {
              MP_CHECKOK(mp_copy(&precomp[15 - i][0], &precomp[i][0]));
              MP_CHECKOK(group->meth->
                               field_neg(&precomp[15 - i][1], &precomp[i][1],
                                                  group->meth));
       }

       /* R = inf */
       MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));

       orderBitSize = mpl_significant_bits(&group->order);

       /* Allocate memory for NAF */
       naf = (signed char *) malloc(sizeof(signed char) * (orderBitSize + 1));
       if (naf == NULL) {
              res = MP_MEM;
              goto CLEANUP;
       }

       /* Compute 5NAF */
       ec_compute_wNAF(naf, orderBitSize, n, 5);

       /* wNAF method */
       for (i = orderBitSize; i >= 0; i--) {
              /* R = 2R */
              ec_GFp_pt_dbl_jm(rx, ry, &rz, &raz4, rx, ry, &rz, &raz4, group);
              if (naf[i] != 0) {
                     ec_GFp_pt_add_jm_aff(rx, ry, &rz, &raz4,
                                                         &precomp[(naf[i] + 15) / 2][0],
                                                         &precomp[(naf[i] + 15) / 2][1], rx, ry,
                                                         &rz, &raz4, group);
              }
       }

       /* convert result S to affine coordinates */
       MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));

  CLEANUP:
       for (i = 0; i < 16; i++) {
              mp_clear(&precomp[i][0]);
              mp_clear(&precomp[i][1]);
       }
       mp_clear(&tpx);
       mp_clear(&tpy);
       mp_clear(&rz);
       mp_clear(&raz4);
       free(naf);
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_set_inf_aff ( mp_int px,
mp_int py 
)

Definition at line 63 of file ecp_aff.c.

{
       mp_zero(px);
       mp_zero(py);
       return MP_OKAY;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_set_inf_jac ( mp_int px,
mp_int py,
mp_int pz 
)

Definition at line 129 of file ecp_jac.c.

{
       mp_zero(pz);
       return MP_OKAY;
}

Here is the call graph for this function:

mp_err ec_GFp_pt_sub_aff ( const mp_int px,
const mp_int py,
const mp_int qx,
const mp_int qy,
mp_int rx,
mp_int ry,
const ECGroup *  group 
)

Definition at line 161 of file ecp_aff.c.

{
       mp_err res = MP_OKAY;
       mp_int nqy;

       MP_DIGITS(&nqy) = 0;
       MP_CHECKOK(mp_init(&nqy));
       /* nqy = -qy */
       MP_CHECKOK(group->meth->field_neg(qy, &nqy, group->meth));
       res = group->point_add(px, py, qx, &nqy, rx, ry, group);
  CLEANUP:
       mp_clear(&nqy);
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_pts_mul_jac ( const mp_int k1,
const mp_int k2,
const mp_int px,
const mp_int py,
mp_int rx,
mp_int ry,
const ECGroup *  group 
)

Definition at line 406 of file ecp_jac.c.

{
       mp_err res = MP_OKAY;
       mp_int precomp[4][4][2];
       mp_int rz;
       const mp_int *a, *b;
       int i, j;
       int ai, bi, d;

       for (i = 0; i < 4; i++) {
              for (j = 0; j < 4; j++) {
                     MP_DIGITS(&precomp[i][j][0]) = 0;
                     MP_DIGITS(&precomp[i][j][1]) = 0;
              }
       }
       MP_DIGITS(&rz) = 0;

       ARGCHK(group != NULL, MP_BADARG);
       ARGCHK(!((k1 == NULL)
                      && ((k2 == NULL) || (px == NULL)
                             || (py == NULL))), MP_BADARG);

       /* if some arguments are not defined used ECPoint_mul */
       if (k1 == NULL) {
              return ECPoint_mul(group, k2, px, py, rx, ry);
       } else if ((k2 == NULL) || (px == NULL) || (py == NULL)) {
              return ECPoint_mul(group, k1, NULL, NULL, rx, ry);
       }

       /* initialize precomputation table */
       for (i = 0; i < 4; i++) {
              for (j = 0; j < 4; j++) {
                     MP_CHECKOK(mp_init(&precomp[i][j][0]));
                     MP_CHECKOK(mp_init(&precomp[i][j][1]));
              }
       }

       /* fill precomputation table */
       /* assign {k1, k2} = {a, b} such that len(a) >= len(b) */
       if (mpl_significant_bits(k1) < mpl_significant_bits(k2)) {
              a = k2;
              b = k1;
              if (group->meth->field_enc) {
                     MP_CHECKOK(group->meth->
                                      field_enc(px, &precomp[1][0][0], group->meth));
                     MP_CHECKOK(group->meth->
                                      field_enc(py, &precomp[1][0][1], group->meth));
              } else {
                     MP_CHECKOK(mp_copy(px, &precomp[1][0][0]));
                     MP_CHECKOK(mp_copy(py, &precomp[1][0][1]));
              }
              MP_CHECKOK(mp_copy(&group->genx, &precomp[0][1][0]));
              MP_CHECKOK(mp_copy(&group->geny, &precomp[0][1][1]));
       } else {
              a = k1;
              b = k2;
              MP_CHECKOK(mp_copy(&group->genx, &precomp[1][0][0]));
              MP_CHECKOK(mp_copy(&group->geny, &precomp[1][0][1]));
              if (group->meth->field_enc) {
                     MP_CHECKOK(group->meth->
                                      field_enc(px, &precomp[0][1][0], group->meth));
                     MP_CHECKOK(group->meth->
                                      field_enc(py, &precomp[0][1][1], group->meth));
              } else {
                     MP_CHECKOK(mp_copy(px, &precomp[0][1][0]));
                     MP_CHECKOK(mp_copy(py, &precomp[0][1][1]));
              }
       }
       /* precompute [*][0][*] */
       mp_zero(&precomp[0][0][0]);
       mp_zero(&precomp[0][0][1]);
       MP_CHECKOK(group->
                        point_dbl(&precomp[1][0][0], &precomp[1][0][1],
                                           &precomp[2][0][0], &precomp[2][0][1], group));
       MP_CHECKOK(group->
                        point_add(&precomp[1][0][0], &precomp[1][0][1],
                                           &precomp[2][0][0], &precomp[2][0][1],
                                           &precomp[3][0][0], &precomp[3][0][1], group));
       /* precompute [*][1][*] */
       for (i = 1; i < 4; i++) {
              MP_CHECKOK(group->
                               point_add(&precomp[0][1][0], &precomp[0][1][1],
                                                  &precomp[i][0][0], &precomp[i][0][1],
                                                  &precomp[i][1][0], &precomp[i][1][1], group));
       }
       /* precompute [*][2][*] */
       MP_CHECKOK(group->
                        point_dbl(&precomp[0][1][0], &precomp[0][1][1],
                                           &precomp[0][2][0], &precomp[0][2][1], group));
       for (i = 1; i < 4; i++) {
              MP_CHECKOK(group->
                               point_add(&precomp[0][2][0], &precomp[0][2][1],
                                                  &precomp[i][0][0], &precomp[i][0][1],
                                                  &precomp[i][2][0], &precomp[i][2][1], group));
       }
       /* precompute [*][3][*] */
       MP_CHECKOK(group->
                        point_add(&precomp[0][1][0], &precomp[0][1][1],
                                           &precomp[0][2][0], &precomp[0][2][1],
                                           &precomp[0][3][0], &precomp[0][3][1], group));
       for (i = 1; i < 4; i++) {
              MP_CHECKOK(group->
                               point_add(&precomp[0][3][0], &precomp[0][3][1],
                                                  &precomp[i][0][0], &precomp[i][0][1],
                                                  &precomp[i][3][0], &precomp[i][3][1], group));
       }

       d = (mpl_significant_bits(a) + 1) / 2;

       /* R = inf */
       MP_CHECKOK(mp_init(&rz));
       MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, &rz));

       for (i = d - 1; i >= 0; i--) {
              ai = MP_GET_BIT(a, 2 * i + 1);
              ai <<= 1;
              ai |= MP_GET_BIT(a, 2 * i);
              bi = MP_GET_BIT(b, 2 * i + 1);
              bi <<= 1;
              bi |= MP_GET_BIT(b, 2 * i);
              /* R = 2^2 * R */
              MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
              MP_CHECKOK(ec_GFp_pt_dbl_jac(rx, ry, &rz, rx, ry, &rz, group));
              /* R = R + (ai * A + bi * B) */
              MP_CHECKOK(ec_GFp_pt_add_jac_aff
                               (rx, ry, &rz, &precomp[ai][bi][0], &precomp[ai][bi][1],
                                   rx, ry, &rz, group));
       }

       MP_CHECKOK(ec_GFp_pt_jac2aff(rx, ry, &rz, rx, ry, group));

       if (group->meth->field_dec) {
              MP_CHECKOK(group->meth->field_dec(rx, rx, group->meth));
              MP_CHECKOK(group->meth->field_dec(ry, ry, group->meth));
       }

  CLEANUP:
       mp_clear(&rz);
       for (i = 0; i < 4; i++) {
              for (j = 0; j < 4; j++) {
                     mp_clear(&precomp[i][j][0]);
                     mp_clear(&precomp[i][j][1]);
              }
       }
       return res;
}

Here is the call graph for this function:

mp_err ec_GFp_validate_point ( const mp_int px,
const mp_int py,
const ECGroup *  group 
)

Definition at line 288 of file ecp_aff.c.

{
       mp_err res = MP_NO;
       mp_int accl, accr, tmp, pxt, pyt;

       MP_DIGITS(&accl) = 0;
       MP_DIGITS(&accr) = 0;
       MP_DIGITS(&tmp) = 0;
       MP_DIGITS(&pxt) = 0;
       MP_DIGITS(&pyt) = 0;
       MP_CHECKOK(mp_init(&accl));
       MP_CHECKOK(mp_init(&accr));
       MP_CHECKOK(mp_init(&tmp));
       MP_CHECKOK(mp_init(&pxt));
       MP_CHECKOK(mp_init(&pyt));

    /* 1: Verify that publicValue is not the point at infinity */
       if (ec_GFp_pt_is_inf_aff(px, py) == MP_YES) {
              res = MP_NO;
              goto CLEANUP;
       }
    /* 2: Verify that the coordinates of publicValue are elements 
     *    of the field.
     */
       if ((MP_SIGN(px) == MP_NEG) || (mp_cmp(px, &group->meth->irr) >= 0) || 
              (MP_SIGN(py) == MP_NEG) || (mp_cmp(py, &group->meth->irr) >= 0)) {
              res = MP_NO;
              goto CLEANUP;
       }
    /* 3: Verify that publicValue is on the curve. */
       if (group->meth->field_enc) {
              group->meth->field_enc(px, &pxt, group->meth);
              group->meth->field_enc(py, &pyt, group->meth);
       } else {
              mp_copy(px, &pxt);
              mp_copy(py, &pyt);
       }
       /* left-hand side: y^2  */
       MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
       /* right-hand side: x^3 + a*x + b */
       MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
       MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
       MP_CHECKOK( group->meth->field_mul(&group->curvea, &pxt, &tmp, group->meth) );
       MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
       MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
       /* check LHS - RHS == 0 */
       MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
       if (mp_cmp_z(&accr) != 0) {
              res = MP_NO;
              goto CLEANUP;
       }
    /* 4: Verify that the order of the curve times the publicValue
     *    is the point at infinity.
     */
       MP_CHECKOK( ECPoint_mul(group, &group->order, px, py, &pxt, &pyt) );
       if (ec_GFp_pt_is_inf_aff(&pxt, &pyt) != MP_YES) {
              res = MP_NO;
              goto CLEANUP;
       }

       res = MP_YES;

CLEANUP:
       mp_clear(&accl);
       mp_clear(&accr);
       mp_clear(&tmp);
       mp_clear(&pxt);
       mp_clear(&pyt);
       return res;
}

Here is the call graph for this function: