示例#1
0
void
ecc_add_jja (const struct ecc_curve *ecc,
	     mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q,
	     mp_limb_t *scratch)
{
  /* Formulas, from djb,
     http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b):

     Computation		Operation	Live variables
     
      ZZ = Z_1^2		sqr		ZZ
      H = X_2*ZZ - X_1		mul (djb: U_2)	ZZ, H
      HH = H^2			sqr		ZZ, H, HH
      ZZZ = ZZ*Z_1		mul		ZZ, H, HH, ZZZ
      Z_3 = (Z_1+H)^2-ZZ-HH	sqr		H, HH, ZZZ
      W = 2 (Y_2*ZZZ - Y_1)	mul (djb: S_2)	H, HH, W
      I = 4*HH					H, W, I
      J = H*I			mul		W, I, J
      V = X_1*I			mul		W, J, V
      X_3 = W^2-J-2*V		sqr		W, J, V
      Y_3 = W*(V-X_3)-2*Y_1*J	mul, mul
  */
#define zz  scratch
#define h  (scratch + ecc->p.size)
#define hh (scratch + 2*ecc->p.size)
#define w  (scratch + 3*ecc->p.size)
#define j  (scratch + 4*ecc->p.size)
#define v   scratch

#define x1  p
#define y1 (p + ecc->p.size)
#define z1 (p + 2*ecc->p.size)
#define x2  q
#define y2 (q + ecc->p.size)

  /* zz */
  ecc_modp_sqr (ecc, zz, z1);
  /* h*/
  ecc_modp_mul (ecc, h, x2, zz);
  ecc_modp_sub (ecc, h, h, x1);
  /* hh */
  ecc_modp_sqr (ecc, hh, h);
  /* Do z^3 early, store at w. */
  ecc_modp_mul (ecc, w, zz, z1);
  /* z_3, use j area for scratch */
  ecc_modp_add (ecc, r + 2*ecc->p.size, p + 2*ecc->p.size, h);
  ecc_modp_sqr (ecc, j, r + 2*ecc->p.size);
  ecc_modp_sub (ecc, j, j, zz);
  ecc_modp_sub (ecc, r + 2*ecc->p.size, j, hh);
  
  /* w */
  ecc_modp_mul (ecc, j, y2, w);
  ecc_modp_sub (ecc, w, j, y1);
  ecc_modp_mul_1 (ecc, w, w, 2);
  
  /* i replaces hh, j */
  ecc_modp_mul_1 (ecc, hh, hh, 4);
  ecc_modp_mul (ecc, j, hh, h);

  /* v */
  ecc_modp_mul (ecc, v, x1, hh);

  /* x_3, use (h, hh) as sqratch */  
  ecc_modp_sqr (ecc, h, w);
  ecc_modp_sub (ecc, r, h, j);
  ecc_modp_submul_1 (ecc, r, v, 2);

  /* y_3, use (h, hh) as sqratch */
  ecc_modp_mul (ecc, h, y1, j); /* frees j */
  ecc_modp_sub (ecc, r + ecc->p.size, v, r);
  ecc_modp_mul (ecc, j, r + ecc->p.size, w);
  ecc_modp_submul_1 (ecc, j, h, 2);
  mpn_copyi (r + ecc->p.size, j, ecc->p.size);
}
示例#2
0
/* Add two points on an Edwards curve, in homogeneous coordinates */
void
ecc_add_ehh (const struct ecc_curve *ecc,
	     mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q,
	     mp_limb_t *scratch)
{
#define x1 p
#define y1 (p + ecc->p.size)
#define z1 (p + 2*ecc->p.size)

#define x2 q
#define y2 (q + ecc->p.size)
#define z2 (q + 2*ecc->p.size)

#define x3 r
#define y3 (r + ecc->p.size)
#define z3 (r + 2*ecc->p.size)

  /* Formulas (from djb,
     http://www.hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#addition-add-2007-bl):

     Computation	Operation	Live variables

     C = x1*x2		mul		C
     D = y1*y2		mul		C, D
     T = (x1+y1)(x2+y2) - C - D, mul	C, D, T
     E = b*C*D		2 mul		C, E, T (Replace C <-- D - C)
     A = z1*z2		mul		A, C, E, T
     B = A^2		sqr		A, B, C, E, T
     F = B - E				A, B, C, E, F, T
     G = B + E     			A, C, F, G, T
     x3 = A*F*T		2 mul		A, C, G
     y3 = A*G*(D-C)	2 mul		F, G
     z3 = F*G		mul

     But when working with the twist curve, we have to negate the
     factor C = x1*x2. We change subtract to add in the y3
     expression, and swap F and G.
  */
#define C scratch
#define D (scratch + ecc->p.size)
#define T (scratch + 2*ecc->p.size)
#define E (scratch + 3*ecc->p.size) 
#define A (scratch + 4*ecc->p.size)
#define B (scratch + 5*ecc->p.size)
#define F D
#define G E

  ecc_modp_mul (ecc, C, x1, x2);
  ecc_modp_mul (ecc, D, y1, y2);
  ecc_modp_add (ecc, A, x1, y1);
  ecc_modp_add (ecc, B, x2, y2);
  ecc_modp_mul (ecc, T, A, B);
  ecc_modp_sub (ecc, T, T, C);
  ecc_modp_sub (ecc, T, T, D);
  ecc_modp_mul (ecc, x3, C, D);
  ecc_modp_mul (ecc, E, x3, ecc->b);
  ecc_modp_add (ecc, C, D, C);	/* ! */
  
  ecc_modp_mul (ecc, A, z1, z2);
  ecc_modp_sqr (ecc, B, A);

  ecc_modp_sub (ecc, F, B, E);
  ecc_modp_add (ecc, G, B, E);

  /* x3 */
  ecc_modp_mul (ecc, B, G, T); /* ! */
  ecc_modp_mul (ecc, x3, B, A);

  /* y3 */
  ecc_modp_mul (ecc, B, F, C); /* ! */
  ecc_modp_mul (ecc, y3, B, A);

  /* z3 */
  ecc_modp_mul (ecc, B, F, G);
  mpn_copyi (z3, B, ecc->p.size);
}
示例#3
0
void
ecc_add_jjj (const struct ecc_curve *ecc,
	     mp_limb_t *r, const mp_limb_t *p, const mp_limb_t *q,
	     mp_limb_t *scratch)
{
  /* Formulas, from djb,
     http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl:

     Computation		Operation	Live variables

      Z1Z1 = Z1^2		sqr		Z1Z1
      Z2Z2 = Z2^2		sqr		Z1Z1, Z2Z2
      U1 = X1*Z2Z2		mul		Z1Z1, Z2Z2, U1
      U2 = X2*Z1Z1		mul		Z1Z1, Z2Z2, U1, U2
      H = U2-U1					Z1Z1, Z2Z2, U1, H
      Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H sqr, mul	Z1Z1, Z2Z2, U1, H
      S1 = Y1*Z2*Z2Z2		mul, mul	Z1Z1, U1, H, S1
      S2 = Y2*Z1*Z1Z1		mul, mul	U1, H, S1, S2
      W = 2*(S2-S1)	(djb: r)		U1, H, S1, W
      I = (2*H)^2		sqr		U1, H, S1, W, I
      J = H*I			mul		U1, S1, W, J, V
      V = U1*I			mul		S1, W, J, V
      X3 = W^2-J-2*V		sqr		S1, W, J, V
      Y3 = W*(V-X3)-2*S1*J	mul, mul
  */
  mp_limb_t *z1z1 = scratch;
  mp_limb_t *z2z2 = scratch + ecc->size;
  mp_limb_t *u1   = scratch + 2*ecc->size;
  mp_limb_t *u2   = scratch + 3*ecc->size;
  mp_limb_t *s1   = scratch; /* overlap z1z1 */
  mp_limb_t *s2   = scratch + ecc->size; /* overlap z2z2 */
  mp_limb_t *i    = scratch + 4*ecc->size;
  mp_limb_t *j    = scratch + 5*ecc->size;
  mp_limb_t *v    = scratch + 6*ecc->size;

  /* z1^2, z2^2, u1 = x1 x2^2, u2 = x2 z1^2 - u1 */
  ecc_modp_sqr (ecc, z1z1, p + 2*ecc->size);
  ecc_modp_sqr (ecc, z2z2, q + 2*ecc->size);
  ecc_modp_mul (ecc, u1, p, z2z2);
  ecc_modp_mul (ecc, u2, q, z1z1);
  ecc_modp_sub (ecc, u2, u2, u1);  /* Store h in u2 */

  /* z3, use i, j, v as scratch, result at i. */
  ecc_modp_add (ecc, i, p + 2*ecc->size, q + 2*ecc->size);
  ecc_modp_sqr (ecc, v, i);
  ecc_modp_sub (ecc, v, v, z1z1);
  ecc_modp_sub (ecc, v, v, z2z2);
  ecc_modp_mul (ecc, i, v, u2);
  /* Delayed write, to support in-place operation. */

  /* s1 = y1 z2^3, s2 = y2 z1^3, scratch at j and v */
  ecc_modp_mul (ecc, j, z1z1, p + 2*ecc->size); /* z1^3 */
  ecc_modp_mul (ecc, v, z2z2, q + 2*ecc->size); /* z2^3 */
  ecc_modp_mul (ecc, s1, p + ecc->size, v);
  ecc_modp_mul (ecc, v, j, q + ecc->size);
  ecc_modp_sub (ecc, s2, v, s1);
  ecc_modp_mul_1 (ecc, s2, s2, 2);

  /* Store z3 */
  mpn_copyi (r + 2*ecc->size, i, ecc->size);

  /* i, j, v */
  ecc_modp_sqr (ecc, i, u2);
  ecc_modp_mul_1 (ecc, i, i, 4);
  ecc_modp_mul (ecc, j, u2, i);
  ecc_modp_mul (ecc, v, u1, i);

  /* now, u1, u2 and i are free for reuse .*/
  /* x3, use u1, u2 as scratch */
  ecc_modp_sqr (ecc, u1, s2);
  ecc_modp_sub (ecc, r, u1, j);
  ecc_modp_submul_1 (ecc, r, v, 2);

  /* y3 */
  ecc_modp_mul (ecc, u1, s1, j); /* Frees j */
  ecc_modp_sub (ecc, u2, v, r);  /* Frees v */
  ecc_modp_mul (ecc, i, s2, u2);
  ecc_modp_submul_1 (ecc, i, u1, 2);
  mpn_copyi (r + ecc->size, i, ecc->size);
}