Commit 3e33071e authored by Niels Möller's avatar Niels Möller

Integrate ecc_mul_g.

parent a3dd891c
2013-02-15 Niels Möller <nisse@lysator.liu.se>
Integrate ecc_mul_g.
* ecc.h: New file.
* ecc-j-to-a.c: New file.
* ecc-size.c: New file.
* ecc-add-jja.c: New file.
* ecc-dup-jj.c: New file.
* ecc-mul-g.c: New file.
* sec-tabselect.c: New file.
* Makefile.in (hogweed_SOURCES): Added new files.
(HEADERS): Added ecc.h
* testsuite/ecc-mul-g-test.c: New file.
* testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added
ecc-mul-g-test.c.
* testsuite/testutils.c (xalloc_limbs): New function.
(test_mpn): New function.
(test_ecc_point): New function.
(test_ecc_mul_a): New function.
(test_ecc_mul_j): New function.
* testsuite/testutils.h: Corresponding declarations.
Integrate ECC internals.
* ecc-curve.h: New file.
* ecc-internal.h: New file.
......
......@@ -127,12 +127,14 @@ hogweed_SOURCES = sexp.c sexp-format.c \
gmp-glue.c cnd-copy.c \
ecc-mod.c ecc-generic-modp.c ecc-generic-modq.c \
ecc-modp.c ecc-modq.c ecc-generic-redc.c \
ecc-192.c ecc-224.c ecc-256.c ecc-384.c ecc-521.c
ecc-192.c ecc-224.c ecc-256.c ecc-384.c ecc-521.c \
ecc-size.c ecc-j-to-a.c ecc-dup-jj.c ecc-add-jja.c \
ecc-mul-g.c
HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
base16.h base64.h buffer.h camellia.h cast128.h \
cbc.h ctr.h \
des.h des-compat.h dsa.h ecc-curve.h \
des.h des-compat.h dsa.h ecc-curve.h ecc.h \
gcm.h gosthash94.h hmac.h \
knuth-lfib.h \
macros.h \
......
/* ecc-dup-jj.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
/* Development of Nettle's ECC support was funded by Internetfonden. */
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "ecc.h"
#include "ecc-internal.h"
/* NOTE: Behaviour for corner cases:
+ p = 0 ==> r = 0 (invalid except if also q = 0)
+ q = 0 ==> r = invalid
+ p = -q ==> r = 0, correct!
+ p = q ==> r = 0, invalid
*/
mp_size_t
ecc_add_jja_itch (const struct ecc_curve *ecc)
{
return ECC_ADD_JJA_ITCH (ecc->size);
}
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->size)
#define hh (scratch + 2*ecc->size)
#define w (scratch + 3*ecc->size)
#define j (scratch + 4*ecc->size)
#define v scratch
#define x1 p
#define y1 (p + ecc->size)
#define z1 (p + 2*ecc->size)
#define x2 q
#define y2 (q + ecc->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->size, p + 2*ecc->size, h);
ecc_modp_sqr (ecc, j, r + 2*ecc->size);
ecc_modp_sub (ecc, j, j, zz);
ecc_modp_sub (ecc, r + 2*ecc->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->size, v, r);
ecc_modp_mul (ecc, j, r + ecc->size, w);
ecc_modp_submul_1 (ecc, j, h, 2);
mpn_copyi (r + ecc->size, j, ecc->size);
}
/* ecc-dup-jj.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
/* Development of Nettle's ECC support was funded by Internetfonden. */
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "ecc.h"
#include "ecc-internal.h"
/* NOTE: Behaviour for corner cases:
+ p = 0 ==> r = 0, correct!
*/
mp_size_t
ecc_dup_jj_itch (const struct ecc_curve *ecc)
{
return ECC_DUP_JJ_ITCH (ecc->size);
}
void
ecc_dup_jj (const struct ecc_curve *ecc,
mp_limb_t *r, const mp_limb_t *p,
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
delta = z^2 sqr delta
gamma = y^2 sqr delta, gamma
z' = (y+z)^2-gamma-delta sqr delta, gamma
alpha = 3*(x-delta)*(x+delta) mul gamma, beta, alpha
beta = x*gamma mul gamma, beta, alpha
x' = alpha^2-8*beta sqr gamma, beta, alpha
y' = alpha*(4*beta-x')-8*gamma^2 mul, sqr
*/
#define delta scratch
#define gamma (scratch + ecc->size)
#define beta (scratch + 2*ecc->size)
#define g2 (scratch + 3*ecc->size)
#define sum (scratch + 4*ecc->size)
#define alpha scratch /* Overlap delta */
#define xp p
#define yp (p + ecc->size)
#define zp (p + 2*ecc->size)
/* delta */
ecc_modp_sqr (ecc, delta, zp);
/* gamma */
ecc_modp_sqr (ecc, gamma, yp);
/* z'. Can use beta area as scratch. */
ecc_modp_add (ecc, r + 2*ecc->size, yp, zp);
ecc_modp_sqr (ecc, beta, r + 2*ecc->size);
ecc_modp_sub (ecc, beta, beta, gamma);
ecc_modp_sub (ecc, r + 2*ecc->size, beta, delta);
/* alpha. Can use beta area as scratch, and overwrite delta. */
ecc_modp_add (ecc, sum, xp, delta);
ecc_modp_sub (ecc, delta, xp, delta);
ecc_modp_mul (ecc, beta, sum, delta);
ecc_modp_mul_1 (ecc, alpha, beta, 3);
/* beta */
ecc_modp_mul (ecc, beta, xp, gamma);
/* Do gamma^2 and 4*beta early, to get them out of the way. We can
then use the old area at gamma as scratch. */
ecc_modp_sqr (ecc, g2, gamma);
ecc_modp_mul_1 (ecc, sum, beta, 4);
/* x' */
ecc_modp_sqr (ecc, gamma, alpha); /* Overwrites gamma and beta */
ecc_modp_submul_1 (ecc, gamma, sum, 2);
mpn_copyi (r, gamma, ecc->size);
/* y' */
ecc_modp_sub (ecc, sum, sum, r);
ecc_modp_mul (ecc, gamma, sum, alpha);
ecc_modp_submul_1 (ecc, gamma, g2, 8);
mpn_copyi (r + ecc->size, gamma, ecc->size);
}
/* ecc-j-to-a.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
/* Development of Nettle's ECC support was funded by Internetfonden. */
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "ecc.h"
#include "ecc-internal.h"
mp_size_t
ecc_j_to_a_itch (const struct ecc_curve *ecc)
{
/* Needs 2*ecc->size + scratch for ecc_modq_inv */
return ECC_J_TO_A_ITCH (ecc->size);
}
void
ecc_j_to_a (const struct ecc_curve *ecc,
int flags,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch)
{
#define izp scratch
#define up (scratch + ecc->size)
#define iz2p (scratch + ecc->size)
#define iz3p (scratch + 2*ecc->size)
#define tp scratch
mp_limb_t cy;
if (ecc->use_redc)
{
/* Set v = (r_z / B^2)^-1,
r_x = p_x v^2 / B^3 = ((v/B * v)/B * p_x)/B
r_y = p_y v^3 / B^4 = (((v/B * v)/B * v)/B * p_x)/B
Skip the first redc, if we want to stay in Montgomery
representation.
*/
mpn_copyi (up, p + 2*ecc->size, ecc->size);
mpn_zero (up + ecc->size, ecc->size);
ecc->redc (ecc, up);
mpn_zero (up + ecc->size, ecc->size);
ecc->redc (ecc, up);
ecc_modp_inv (ecc, izp, up, up + ecc->size);
if (flags & 1)
{
/* Divide this common factor by B */
mpn_copyi (iz3p, izp, ecc->size);
mpn_zero (iz3p + ecc->size, ecc->size);
ecc->redc (ecc, iz3p);
ecc_modp_mul (ecc, iz2p, izp, iz3p);
}
else
ecc_modp_sqr (ecc, iz2p, izp);
}
else
{
/* Set s = p_z^{-1}, r_x = p_x s^2, r_y = p_y s^3 */
mpn_copyi (up, p+2*ecc->size, ecc->size); /* p_z */
ecc_modp_inv (ecc, izp, up, up + ecc->size);
ecc_modp_sqr (ecc, iz2p, izp);
}
ecc_modp_mul (ecc, iz3p, iz2p, p);
/* ecc_modp (and ecc_modp_mul) may return a value up to 2p - 1, so
do a conditional subtraction. */
cy = mpn_sub_n (r, iz3p, ecc->p, ecc->size);
cnd_copy (cy, r, iz3p, ecc->size);
if (flags & 2)
/* Skip y coordinate */
return;
ecc_modp_mul (ecc, iz3p, iz2p, izp);
ecc_modp_mul (ecc, tp, iz3p, p + ecc->size);
/* And a similar subtraction. */
cy = mpn_sub_n (r + ecc->size, tp, ecc->p, ecc->size);
cnd_copy (cy, r + ecc->size, tp, ecc->size);
#undef izp
#undef up
#undef iz2p
#undef iz3p
#undef tp
}
/* ecc-mul-g.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
/* Development of Nettle's ECC support was funded by Internetfonden. */
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include "ecc.h"
#include "ecc-internal.h"
mp_size_t
ecc_mul_g_itch (const struct ecc_curve *ecc)
{
/* Needs 3*ecc->size + scratch for ecc_add_jja. */
return ECC_MUL_G_ITCH (ecc->size);
}
void
ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r,
const mp_limb_t *np, mp_limb_t *scratch)
{
/* Scratch need determined by the ecc_add_jja call. Current total is
9 * ecc->size, at most 648 bytes. */
#define tp scratch
#define scratch_out (scratch + 3*ecc->size)
unsigned k, c;
unsigned i, j;
unsigned bit_rows;
int is_zero;
k = ecc->pippenger_k;
c = ecc->pippenger_c;
bit_rows = (ecc->bit_size + k - 1) / k;
mpn_zero (r, 3*ecc->size);
for (i = k, is_zero = 1; i-- > 0; )
{
ecc_dup_jj (ecc, r, r, scratch);
for (j = 0; j * c < bit_rows; j++)
{
unsigned bits;
mp_bitcnt_t bit_index;
/* Extract c bits from n, stride k, starting at i + kcj,
ending at i + k (cj + c - 1)*/
for (bits = 0, bit_index = i + k*(c*j+c); bit_index > i + k*c*j; )
{
mp_size_t limb_index;
unsigned shift;
bit_index -= k;
limb_index = bit_index / GMP_NUMB_BITS;
if (limb_index >= ecc->size)
continue;
shift = bit_index % GMP_NUMB_BITS;
bits = (bits << 1) | ((np[limb_index] >> shift) & 1);
}
sec_tabselect (tp, 2*ecc->size,
(ecc->pippenger_table
+ (2*ecc->size * (mp_size_t) j << c)),
1<<c, bits);
cnd_copy (is_zero, r, tp, 2*ecc->size);
cnd_copy (is_zero, r + 2*ecc->size, ecc->unit, ecc->size);
ecc_add_jja (ecc, tp, r, tp, scratch_out);
/* Use the sum when valid. ecc_add_jja produced garbage if
is_zero != 0 or bits == 0, . */
cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->size);
is_zero &= (bits == 0);
}
}
#undef tp
#undef scratch_out
}
/* ecc-size.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
/* Development of Nettle's ECC support was funded by Internetfonden. */
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "ecc.h"
#include "ecc-internal.h"
mp_size_t
ecc_size (const struct ecc_curve *ecc)
{
return ecc->size;
}
mp_size_t
ecc_size_a (const struct ecc_curve *ecc)
{
return 2*ecc->size;
}
mp_size_t
ecc_size_j (const struct ecc_curve *ecc)
{
return 3*ecc->size;
}
/* ecc.h */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
/* Development of Nettle's ECC support was funded by Internetfonden. */
#ifndef NETTLE_ECC_H_INCLUDED
#define NETTLE_ECC_H_INCLUDED
#include <stdint.h>
#include <gmp.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define ecc_size nettle_ecc_size
#define ecc_size_a nettle_ecc_size_a
#define ecc_size_j nettle_ecc_size_j
#define ecc_a_to_a_itch nettle_ecc_a_to_a_itch
#define ecc_a_to_a nettle_ecc_a_to_a
#define ecc_a_to_j nettle_ecc_a_to_j
#define ecc_j_to_a_itch nettle_ecc_j_to_a_itch
#define ecc_j_to_a nettle_ecc_j_to_a
#define ecc_dup_ja_itch nettle_ecc_dup_ja_itch
#define ecc_dup_ja nettle_ecc_dup_ja
#define ecc_dup_jj_itch nettle_ecc_dup_jj_itch
#define ecc_dup_jj nettle_ecc_dup_jj
#define ecc_add_jja_itch nettle_ecc_add_jja_itch
#define ecc_add_jja nettle_ecc_add_jja
#define ecc_add_jjj_itch nettle_ecc_add_jjj_itch
#define ecc_add_jjj nettle_ecc_add_jjj
#define ecc_mul_g_itch nettle_ecc_mul_g_itch
#define ecc_mul_g nettle_ecc_mul_g
#define ecc_mul_a_itch nettle_ecc_mul_a_itch
#define ecc_mul_a nettle_ecc_mul_a
struct ecc_curve;
/* Points on a curve are represented as arrays of mp_limb_t. For some
curves, point coordinates are represented in montgomery form. We
use either affine coordinates x,y, or Jacobian coordinates X, Y, Z,
where x = X/Z^2 and y = X/Z^2.
Since we use additive notation for the groups, the infinity point
on the curve is denoted 0. The infinity point can be represented
with x = y = 0 in affine coordinates, and Z = 0 in Jacobian
coordinates. However, note that most of the ECC functions do *not*
support infinity as an input or output.
*/
/* FIXME: Also provided some compile time constants? */
/* Returns the size of a single coordinate. */
mp_size_t
ecc_size (const struct ecc_curve *ecc);
/* Size of a point, using affine coordinates x, y. */
mp_size_t
ecc_size_a (const struct ecc_curve *ecc);
/* Size of a point, using jacobian coordinates X, Y and Z. */
mp_size_t
ecc_size_j (const struct ecc_curve *ecc);
/* FIXME: Rename the low-level (and side-channel silent) functions to
_ecc_*, and provide public ecc_* functions which handle the
infinity points properly? */
/* Converts the affine coordinates of a point into montgomery form, if
used for this curve. */
mp_size_t
ecc_a_to_a_itch (const struct ecc_curve *ecc);
void
ecc_a_to_a (const struct ecc_curve *ecc,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch);
/* Converts a point P in affine coordinates into a point R in jacobian
coordinates. If INITIAL is non-zero, and the curve uses montgomery
coordinates, also convert coordinates to montgomery form. */
void
ecc_a_to_j (const struct ecc_curve *ecc,
int initial,
mp_limb_t *r, const mp_limb_t *p);
/* Converts a point P in jacobian coordinates into a point R in affine
coordinates. If FLAGS has bit 0 set, and the curve uses montgomery
coordinates, also undo the montgomery conversion. If flags has bit
1 set, produce x coordinate only. */
mp_size_t
ecc_j_to_a_itch (const struct ecc_curve *ecc);
void
ecc_j_to_a (const struct ecc_curve *ecc,
int flags,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch);
/* Group operations */
/* Point doubling, with jacobian output and affine input. Corner
cases: Correctly sets R = 0 (r_Z = 0) if p = 0 or 2p = 0. */
mp_size_t
ecc_dup_ja_itch (const struct ecc_curve *ecc);
void
ecc_dup_ja (const struct ecc_curve *ecc,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch);
/* Point doubling, with jacobian input and output. Corner cases:
Correctly sets R = 0 (r_Z = 0) if p = 0 or 2p = 0. */
mp_size_t
ecc_dup_jj_itch (const struct ecc_curve *ecc);
void
ecc_dup_jj (const struct ecc_curve *ecc,
mp_limb_t *r, const mp_limb_t *p,
mp_limb_t *scratch);
/* Point addition, with jacobian output, one jacobian input and one
affine input. Corner cases: Fails for the cases
P = Q != 0 Duplication of non-zero point
P = 0, Q != 0 or P != 0, Q = 0 One input zero
Correctly gives R = 0 if P = Q = 0 or P = -Q. */
mp_size_t
ecc_add_jja_itch (const struct ecc_curve *ecc);
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);
/* Point addition with Jacobian input and output. */
mp_size_t
ecc_add_jjj_itch (const struct ecc_curve *ecc);
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);
/* Computes N * the group generator. N is an array of ecc_size()
limbs. It must be in the range 0 < N < group order, then R != 0,
and the algorithm can work without any intermediate values getting
to zero. */
mp_size_t
ecc_mul_g_itch (const struct ecc_curve *ecc);
void
ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r,
const mp_limb_t *np, mp_limb_t *scratch);