Commit 2b9b43ce authored by Niels Möller's avatar Niels Möller

eccdata: Use separate is_zero flag to represent the neutral element.

parent 51a22f02
2014-07-06 Niels Möller <nisse@lysator.liu.se>
* eccdata.c: Use separate is_zero flag to represent the neutral
element.
2014-07-04 Niels Möller <nisse@lysator.liu.se> 2014-07-04 Niels Möller <nisse@lysator.liu.se>
* ecc-25519.c: New file. * ecc-25519.c: New file.
......
...@@ -40,12 +40,11 @@ ...@@ -40,12 +40,11 @@
#include "mini-gmp.c" #include "mini-gmp.c"
/* Affine coordinates, for simplicity. Infinity point represented as x /* Affine coordinates, for simplicity. Infinity point, i.e., te
== y == 0. FIXME: Doesn't quite work for Montgomery curves, where neutral group element, is represented as is_zero. */
(0,0) is a normal finite point. Shouldn't occur in these
computations, though. */
struct ecc_point struct ecc_point
{ {
int is_zero;
mpz_t x; mpz_t x;
mpz_t y; mpz_t y;
}; };
...@@ -107,25 +106,26 @@ ecc_clear (struct ecc_point *p) ...@@ -107,25 +106,26 @@ ecc_clear (struct ecc_point *p)
static int static int
ecc_zero_p (const struct ecc_point *p) ecc_zero_p (const struct ecc_point *p)
{ {
return mpz_sgn (p->x) == 0 && mpz_sgn (p->y) == 0; return p->is_zero;
} }
static int static int
ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q) ecc_equal_p (const struct ecc_point *p, const struct ecc_point *q)
{ {
return mpz_cmp (p->x, q->x) == 0 && mpz_cmp (p->y, q->y) == 0; return p->is_zero ? q->is_zero
: !q->is_zero && mpz_cmp (p->x, q->x) == 0 && mpz_cmp (p->y, q->y) == 0;
} }
static void static void
ecc_set_zero (struct ecc_point *r) ecc_set_zero (struct ecc_point *r)
{ {
mpz_set_ui (r->x, 0); r->is_zero = 1;
mpz_set_ui (r->y, 0);
} }
static void static void
ecc_set (struct ecc_point *r, const struct ecc_point *p) ecc_set (struct ecc_point *r, const struct ecc_point *p)
{ {
r->is_zero = p->is_zero;
mpz_set (r->x, p->x); mpz_set (r->x, p->x);
mpz_set (r->y, p->y); mpz_set (r->y, p->y);
} }
...@@ -186,9 +186,10 @@ ecc_dup (const struct ecc_curve *ecc, ...@@ -186,9 +186,10 @@ ecc_dup (const struct ecc_curve *ecc,
mpz_sub (y, y, p->y); mpz_sub (y, y, p->y);
mpz_mod (y, y, ecc->p); mpz_mod (y, y, ecc->p);
r->is_zero = 0;
mpz_swap (x, r->x); mpz_swap (x, r->x);
mpz_swap (y, r->y); mpz_swap (y, r->y);
mpz_clear (m); mpz_clear (m);
mpz_clear (t); mpz_clear (t);
mpz_clear (x); mpz_clear (x);
...@@ -243,6 +244,7 @@ ecc_add (const struct ecc_curve *ecc, ...@@ -243,6 +244,7 @@ ecc_add (const struct ecc_curve *ecc,
mpz_sub (y, y, p->y); mpz_sub (y, y, p->y);
mpz_mod (y, y, ecc->p); mpz_mod (y, y, ecc->p);
r->is_zero = 0;
mpz_swap (x, r->x); mpz_swap (x, r->x);
mpz_swap (y, r->y); mpz_swap (y, r->y);
...@@ -296,6 +298,7 @@ static void ...@@ -296,6 +298,7 @@ static void
ecc_set_str (struct ecc_point *p, ecc_set_str (struct ecc_point *p,
const char *x, const char *y) const char *x, const char *y)
{ {
p->is_zero = 0;
mpz_set_str (p->x, x, 16); mpz_set_str (p->x, x, 16);
mpz_set_str (p->y, y, 16); mpz_set_str (p->y, y, 16);
} }
...@@ -506,7 +509,7 @@ ecc_curve_init (struct ecc_curve *ecc, unsigned bit_size) ...@@ -506,7 +509,7 @@ ecc_curve_init (struct ecc_curve *ecc, unsigned bit_size)
case 255: case 255:
/* curve25519, y^2 = x^3 + 486662 x^2 + x (mod p), with p = 2^{255} - 19. /* curve25519, y^2 = x^3 + 486662 x^2 + x (mod p), with p = 2^{255} - 19.
Acccording to http://cr.yp.to/papers.html#newelliptic, this According to http://cr.yp.to/papers.html#newelliptic, this
is birationally equivalent to the Edwards curve is birationally equivalent to the Edwards curve
x^2 + y^2 = 1 + (121665/121666) x^2 y^2 (mod p). x^2 + y^2 = 1 + (121665/121666) x^2 y^2 (mod p).
...@@ -644,20 +647,30 @@ ecc_mul_pippenger (const struct ecc_curve *ecc, ...@@ -644,20 +647,30 @@ ecc_mul_pippenger (const struct ecc_curve *ecc,
mpz_clear (n); mpz_clear (n);
} }
static void
ecc_point_out (FILE *f, const struct ecc_point *p)
{
if (p->is_zero)
fprintf (f, "zero");
else
{
fprintf (stderr, "(");
mpz_out_str (stderr, 16, p->x);
fprintf (stderr, ",\n ");
mpz_out_str (stderr, 16, (p)->y);
fprintf (stderr, ")");
}
}
#define ASSERT_EQUAL(p, q) do { \ #define ASSERT_EQUAL(p, q) do { \
if (!ecc_equal_p (p, q)) \ if (!ecc_equal_p (p, q)) \
{ \ { \
fprintf (stderr, "%s:%d: ASSERT_EQUAL (%s, %s) failed.\n", \ fprintf (stderr, "%s:%d: ASSERT_EQUAL (%s, %s) failed.\n", \
__FILE__, __LINE__, #p, #q); \ __FILE__, __LINE__, #p, #q); \
fprintf (stderr, "p = ("); \ fprintf (stderr, "p = "); \
mpz_out_str (stderr, 16, (p)->x); \ ecc_point_out (stderr, (p)); \
fprintf (stderr, ",\n "); \ fprintf (stderr, "\nq = "); \
mpz_out_str (stderr, 16, (p)->y); \ ecc_point_out (stderr, (q)); \
fprintf (stderr, ")\nq = ("); \ fprintf (stderr, "\n"); \
mpz_out_str (stderr, 16, (q)->x); \
fprintf (stderr, ",\n "); \
mpz_out_str (stderr, 16, (q)->y); \
fprintf (stderr, ")\n"); \
abort(); \ abort(); \
} \ } \
} while (0) } while (0)
...@@ -667,11 +680,9 @@ ecc_mul_pippenger (const struct ecc_curve *ecc, ...@@ -667,11 +680,9 @@ ecc_mul_pippenger (const struct ecc_curve *ecc,
{ \ { \
fprintf (stderr, "%s:%d: ASSERT_ZERO (%s) failed.\n", \ fprintf (stderr, "%s:%d: ASSERT_ZERO (%s) failed.\n", \
__FILE__, __LINE__, #p); \ __FILE__, __LINE__, #p); \
fprintf (stderr, "p = ("); \ fprintf (stderr, "p = "); \
mpz_out_str (stderr, 16, (p)->x); \ ecc_point_out (stderr, (p)); \
fprintf (stderr, ",\n "); \ fprintf (stderr, "\n"); \
mpz_out_str (stderr, 16, (p)->y); \
fprintf (stderr, ")\n"); \
abort(); \ abort(); \
} \ } \
} while (0) } while (0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment