+2013-02-27 Niels Möller <nisse@lysator.liu.se>
+
+ * gmp-glue.h: Check if GMP provides mpz_limbs_read (expected in
+ next release).
+ * gmp-glue.c: Use GMP's mpz_limbs_read and friends if available.
+ Renamed all functions for consistency with GMP. Updated all
+ callers.
+
2013-02-20 Niels Möller <nisse@lysator.liu.se>
* examples/Makefile.in (HOGWEED_TARGETS): Added
if (length > ((unsigned) ecc->bit_size + 7) / 8)
length = (ecc->bit_size + 7) / 8;
- _mpn_set_base256 (hp, ecc->size + 1, digest, length);
+ mpn_set_base256 (hp, ecc->size + 1, digest, length);
if (8 * length > ecc->bit_size)
/* We got a few extra bits, at the low end. Discard them. */
ecc_point_init (struct ecc_point *p, const struct ecc_curve *ecc)
{
p->ecc = ecc;
- p->p = _gmp_alloc_limbs (2*ecc->size);
+ p->p = gmp_alloc_limbs (2*ecc->size);
}
void
ecc_point_clear (struct ecc_point *p)
{
- _gmp_free_limbs (p->p, 2*p->ecc->size);
+ gmp_free_limbs (p->p, 2*p->ecc->size);
}
int
size = p->ecc->size;
- if (mpz_sgn (x) < 0 || _mpz_cmp_limbs (x, p->ecc->p, size) >= 0
- || mpz_sgn (y) < 0 || _mpz_cmp_limbs (y, p->ecc->p, size) >= 0)
+ if (mpz_sgn (x) < 0 || mpz_limbs_cmp (x, p->ecc->p, size) >= 0
+ || mpz_sgn (y) < 0 || mpz_limbs_cmp (y, p->ecc->p, size) >= 0)
return 0;
mpz_init (lhs);
mpz_mul (rhs, x, x);
mpz_sub_ui (rhs, rhs, 3);
mpz_mul (rhs, rhs, x);
- mpz_add (rhs, rhs, _mpz_init_mpn (t, p->ecc->b, size));
+ mpz_add (rhs, rhs, mpz_roinit_n (t, p->ecc->b, size));
- res = mpz_congruent_p (lhs, rhs, _mpz_init_mpn (t, p->ecc->p, size));
+ res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, p->ecc->p, size));
mpz_clear (lhs);
mpz_clear (rhs);
if (!res)
return 0;
- _mpz_copy_limbs (p->p, x, size);
- _mpz_copy_limbs (p->p + size, y, size);
+ mpz_limbs_copy (p->p, x, size);
+ mpz_limbs_copy (p->p + size, y, size);
return 1;
}
ecc_point_get (const struct ecc_point *p, mpz_t x, mpz_t y)
{
mp_size_t size = p->ecc->size;
- _mpz_set_mpn (x, p->p, size);
- _mpz_set_mpn (y, p->p + size, size);
+ mpz_set_n (x, p->p, size);
+ mpz_set_n (y, p->p + size, size);
}
random (ctx, nbytes, buf);
buf[0] &= 0xff >> (nbytes * 8 - ecc->bit_size);
- _mpn_set_base256 (xp, ecc->size, buf, nbytes);
+ mpn_set_base256 (xp, ecc->size, buf, nbytes);
}
while (!ecdsa_in_range (ecc, xp, scratch));
}
ecc_scalar_init (struct ecc_scalar *s, const struct ecc_curve *ecc)
{
s->ecc = ecc;
- s->p = _gmp_alloc_limbs (ecc->size);
+ s->p = gmp_alloc_limbs (ecc->size);
}
void
ecc_scalar_clear (struct ecc_scalar *s)
{
- _gmp_free_limbs (s->p, s->ecc->size);
+ gmp_free_limbs (s->p, s->ecc->size);
}
int
{
mp_size_t size = s->ecc->size;
- if (mpz_sgn (z) <= 0 || _mpz_cmp_limbs (z, s->ecc->q, size) >= 0)
+ if (mpz_sgn (z) <= 0 || mpz_limbs_cmp (z, s->ecc->q, size) >= 0)
return 0;
- _mpz_copy_limbs (s->p, z, size);
+ mpz_limbs_copy (s->p, z, size);
return 1;
}
void
ecc_scalar_get (const struct ecc_scalar *s, mpz_t z)
{
- _mpz_set_mpn (z, s->p, s->ecc->size);
+ mpz_set_n (z, s->p, s->ecc->size);
}
/* At most 936 bytes. */
TMP_DECL(k, mp_limb_t, ECC_MAX_SIZE + ECC_ECDSA_SIGN_ITCH (ECC_MAX_SIZE));
mp_limb_t size = key->ecc->size;
- mp_limb_t *rp = _mpz_write_limbs (signature->r, size);
- mp_limb_t *sp = _mpz_write_limbs (signature->s, size);
+ mp_limb_t *rp = mpz_limbs_write (signature->r, size);
+ mp_limb_t *sp = mpz_limbs_write (signature->s, size);
TMP_ALLOC (k, size + ECC_ECDSA_SIGN_ITCH (size));
ecc_modq_random (key->ecc, k, random_ctx, random, k + size);
ecc_ecdsa_sign (key->ecc, key->p, k, digest_length, digest,
rp, sp, k + size);
- _mpz_done_limbs (signature->r, size);
- _mpz_done_limbs (signature->s, size);
+ mpz_limbs_finish (signature->r, size);
+ mpz_limbs_finish (signature->s, size);
}
while (mpz_sgn (signature->r) == 0 || mpz_sgn (signature->s) == 0);
}
/* For ECC_MUL_A_WBITS == 0, at most 1512 bytes. With
ECC_MUL_A_WBITS == 4, currently needs 67 * ecc->size, at most
4824 bytes. Don't use stack allocation for this. */
- mp_limb_t *scratch = _gmp_alloc_limbs (itch);
+ mp_limb_t *scratch = gmp_alloc_limbs (itch);
int res;
#define rp scratch
|| mpz_sgn (signature->s) <= 0 || mpz_size (signature->s) > size)
return 0;
- _mpz_copy_limbs (rp, signature->r, size);
- _mpz_copy_limbs (sp, signature->s, size);
+ mpz_limbs_copy (rp, signature->r, size);
+ mpz_limbs_copy (sp, signature->s, size);
res = ecc_ecdsa_verify (pub->ecc, pub->p, length, digest, rp, sp, scratch_out);
- _gmp_free_limbs (scratch, itch);
+ gmp_free_limbs (scratch, itch);
return res;
#undef rp
#include "gmp-glue.h"
+#if !GMP_HAVE_mpz_limbs_read
+
/* This implementation tries to make a minimal use of GMP internals.
We access and _mp_size and _mp_d, but not _mp_alloc. */
#define MPZ_NEWALLOC MPZ_REALLOC
-int
-_mpz_cmp_limbs (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn)
-{
- mp_size_t an = SIZ (a);
- if (an < bn)
- return -1;
- if (an > bn)
- return 1;
- if (an == 0)
- return 0;
-
- return mpn_cmp (PTR(a), bp, an);
-}
-
-
/* Read access to mpz numbers. */
/* Return limb pointer, for read-only operations. Use mpz_size to get
the number of limbs. */
const mp_limb_t *
-_mpz_read_limbs (mpz_srcptr x)
+mpz_limbs_read (mpz_srcptr x)
{
return PTR (x);
}
-/* Get a pointer to an n limb area, for read-only operation. n must be
- greater or equal to the current size, and the mpz is zero-padded if
- needed. */
-const mp_limb_t *
-_mpz_read_limbs_n (mpz_ptr x, mp_size_t n)
-{
- mp_size_t xn = ABSIZ (x);
-
- assert (xn <= n);
-
- if (xn < n)
- {
- /* Makes an unnecessary realloc if allocation is already large
- enough. */
- mpz_realloc (x, n);
- mpn_zero (PTR(x) + xn, n - xn);
- }
-
- return PTR(x);
-}
-
-void
-_mpz_copy_limbs (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
-{
- mp_size_t xn = ABSIZ (x);
-
- assert (xn <= n);
- mpn_copyi (xp, PTR(x), xn);
- if (xn < n)
- mpn_zero (xp + xn, n - xn);
-}
-
/* Write access to mpz numbers. */
/* Get a limb pointer for writing, previous contents may be
destroyed. */
mp_limb_t *
-_mpz_write_limbs (mpz_ptr x, mp_size_t n)
+mpz_limbs_write (mpz_ptr x, mp_size_t n)
{
assert (n > 0);
return MPZ_NEWALLOC (x, n);
/* Get a limb pointer for writing, previous contents is intact. */
mp_limb_t *
-_mpz_modify_limbs (mpz_ptr x, mp_size_t n)
+mpz_limbs_modify (mpz_ptr x, mp_size_t n)
{
assert (n > 0);
return MPZ_REALLOC (x, n);
}
void
-_mpz_done_limbs (mpz_ptr x, mp_size_t n)
+mpz_limbs_finish (mpz_ptr x, mp_size_t n)
{
assert (n >= 0);
MPN_NORMALIZE (PTR(x), n);
SIZ (x) = n;
}
-void
-_mpz_set_mpn (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
-{
- mpn_copyi (_mpz_write_limbs (r, xn), xp, xn);
- _mpz_done_limbs (r, xn);
-}
-
/* Needs some ugly casts. */
mpz_srcptr
-_mpz_init_mpn (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
+mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
{
mp_size_t xn = ABS (xs);
x->_mp_d = (mp_limb_t *) xp;
return x;
}
+#endif /* !GMP_HAVE_mpz_limbs_read */
+
+/* Additional convenience functions. */
+
+int
+mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn)
+{
+ mp_size_t an = SIZ (a);
+ if (an < bn)
+ return -1;
+ if (an > bn)
+ return 1;
+ if (an == 0)
+ return 0;
+
+ return mpn_cmp (PTR(a), bp, an);
+}
+
+/* Get a pointer to an n limb area, for read-only operation. n must be
+ greater or equal to the current size, and the mpz is zero-padded if
+ needed. */
+const mp_limb_t *
+mpz_limbs_read_n (mpz_ptr x, mp_size_t n)
+{
+ mp_size_t xn = mpz_size (x);
+ mp_ptr xp;
+
+ assert (xn <= n);
+
+ xp = mpz_limbs_modify (x, n);
+
+ if (xn < n)
+ mpn_zero (xp + xn, n - xn);
+
+ return xp;
+}
+
+void
+mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
+{
+ mp_size_t xn = mpz_size (x);
+
+ assert (xn <= n);
+ mpn_copyi (xp, mpz_limbs_read (x), xn);
+ if (xn < n)
+ mpn_zero (xp + xn, n - xn);
+}
+
+void
+mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
+{
+ mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
+ mpz_limbs_finish (r, xn);
+}
void
-_mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
+mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
const uint8_t *xp, size_t xn)
{
size_t xi;
}
mp_limb_t *
-_gmp_alloc_limbs (mp_size_t n)
+gmp_alloc_limbs (mp_size_t n)
{
void *(*alloc_func)(size_t);
}
void
-_gmp_free_limbs (mp_limb_t *p, mp_size_t n)
+gmp_free_limbs (mp_limb_t *p, mp_size_t n)
{
void (*free_func)(void *, size_t);
assert (n > 0);
#include "nettle-stdint.h"
+#ifdef mpz_limbs_read
+#define GMP_HAVE_mpz_limbs_read 1
+#else
+#define GMP_HAVE_mpz_limbs_read 0
+#endif
+
/* Name mangling. */
-#define _mpz_cmp_limbs _nettle_mpz_cmp_limbs
-#define _mpz_read_limbs _nettle_mpz_read_limbs
-#define _mpz_read_limbs_n _nettle_mpz_read_limbs_n
-#define _mpz_copy_limbs _nettle_mpz_copy_limbs
-#define _mpz_write_limbs _nettle_mpz_write_limbs
-#define _mpz_modify_limbs _nettle_mpz_modify_limbs
-#define _mpz_done_limbs _nettle_mpz_done_limbs
-#define _mpz_set_mpn _nettle_mpz_set_mpn
-#define _mpz_init_mpn _nettle_mpz_init_mpn
-#define _mpn_set_base256 _nettle_mpn_set_base256
-#define _gmp_alloc_limbs _nettle_gmp_alloc_limbs
-#define _gmp_free_limbs _nettle_gmp_free_limbs
+#if !GMP_HAVE_mpz_limbs_read
+#define mpz_limbs_read _nettle_mpz_limbs_read
+#define mpz_limbs_write _nettle_mpz_limbs_write
+#define mpz_limbs_modify _nettle_mpz_limbs_modify
+#define mpz_limbs_finish _nettle_mpz_limbs_finish
+#define mpz_roinit_n _nettle_mpz_roinit_n
+#endif
+
+#define mpz_limbs_cmp _nettle_mpz_limbs_cmp
+#define mpz_limbs_read_n _nettle_mpz_limbs_read_n
+#define mpz_limbs_copy _nettle_mpz_limbs_copy
+#define mpz_set_n _nettle_mpz_set_n
+#define mpn_set_base256 _nettle_mpn_set_base256
+#define gmp_alloc_limbs _nettle_gmp_alloc_limbs
+#define gmp_free_limbs _nettle_gmp_free_limbs
/* Some functions for interfacing between mpz and mpn code. Signs of
the mpz numbers are generally ignored. */
-int
-_mpz_cmp_limbs (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn);
-
+#if !GMP_HAVE_mpz_limbs_read
/* Read access to mpz numbers. */
/* Return limb pointer, for read-only operations. Use mpz_size to get
the number of limbs. */
const mp_limb_t *
-_mpz_read_limbs (const mpz_srcptr x);
-
-/* Get a pointer to an n limb area, for read-only operation. n must be
- greater or equal to the current size, and the mpz is zero-padded if
- needed. */
-const mp_limb_t *
-_mpz_read_limbs_n (mpz_ptr x, mp_size_t n);
-
-/* Copy limbs, with zero-padding. */
-/* FIXME: Reorder arguments, on the theory that the first argument of
- an _mpz_* fucntion should be an mpz_t? Or rename to _mpz_get_limbs,
- with argument order consistent with mpz_get_*. */
-void
-_mpz_copy_limbs (mp_limb_t *xp, mpz_srcptr x, mp_size_t n);
+mpz_limbs_read (const mpz_srcptr x);
/* Write access to mpz numbers. */
/* Get a limb pointer for writing, previous contents may be
destroyed. */
mp_limb_t *
-_mpz_write_limbs (mpz_ptr x, mp_size_t n);
+mpz_limbs_write (mpz_ptr x, mp_size_t n);
/* Get a limb pointer for writing, previous contents is intact. */
mp_limb_t *
-_mpz_modify_limbs (mpz_ptr x, mp_size_t n);
+mpz_limbs_modify (mpz_ptr x, mp_size_t n);
/* Update size. */
void
-_mpz_done_limbs (mpz_ptr x, mp_size_t n);
-
-void
-_mpz_set_mpn (mpz_t r, const mp_limb_t *xp, mp_size_t xn);
+mpz_limbs_finish (mpz_ptr x, mp_size_t n);
/* Using an mpn number as an mpz. Can be used for read-only access
only. x must not be cleared or reallocated. */
mpz_srcptr
-_mpz_init_mpn (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs);
+mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs);
+
+#endif /* !GMP_HAVE_mpz_limbs_read */
+
+/* Convenience functions */
+int
+mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn);
+
+/* Get a pointer to an n limb area, for read-only operation. n must be
+ greater or equal to the current size, and the mpz is zero-padded if
+ needed. */
+const mp_limb_t *
+mpz_limbs_read_n (mpz_ptr x, mp_size_t n);
+
+/* Copy limbs, with zero-padding. */
+/* FIXME: Reorder arguments, on the theory that the first argument of
+ an _mpz_* fucntion should be an mpz_t? Or rename to _mpz_get_limbs,
+ with argument order consistent with mpz_get_*. */
+void
+mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n);
+
+void
+mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn);
/* Like mpn_set_str, but always writes rn limbs. If input is larger,
higher bits are ignored. */
void
-_mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
- const uint8_t *xp, size_t xn);
+mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
+ const uint8_t *xp, size_t xn);
mp_limb_t *
-_gmp_alloc_limbs (mp_size_t n);
+gmp_alloc_limbs (mp_size_t n);
void
-_gmp_free_limbs (mp_limb_t *p, mp_size_t n);
+gmp_free_limbs (mp_limb_t *p, mp_size_t n);
#endif /* NETTLE_GMP_GLUE_H_INCLUDED */
else
mpz_urandomb (r, state, 2*ecc->size * GMP_NUMB_BITS);
- _mpz_copy_limbs (a, r, 2*ecc->size);
+ mpz_limbs_copy (a, r, 2*ecc->size);
ref_mod (ref, a, ecc->p, ecc->size);
else
mpz_urandomb (r, state, ecc->size * GMP_NUMB_BITS);
- _mpz_copy_limbs (a, r, ecc->size);
+ mpz_limbs_copy (a, r, ecc->size);
if (!ref_modinv (ref, a, ecc->p, ecc->size))
{
abort ();
}
- _mpz_copy_limbs (a, r, ecc->size);
+ mpz_limbs_copy (a, r, ecc->size);
if (!ref_modinv (ref, a, ecc->q, ecc->size))
{
mpz_urandomb (r, state, size * GMP_NUMB_BITS);
/* Reduce so that (almost surely) n < q */
- _mpz_copy_limbs (n, r, size);
+ mpz_limbs_copy (n, r, size);
n[size - 1] %= ecc->q[size - 1];
ecc_mul_a (ecc, 1, p, n, ecc->g, scratch);
mpz_init (t);
mpz_setbit (t, mn * GMP_NUMB_BITS);
- _mpz_init_mpn (m, mp, mn);
+ mpz_roinit_n (m, mp, mn);
an = 2*mn;
while (an > 0 && ap[an-1] == 0)
an--;
- _mpz_init_mpn (a, ap, an);
+ mpz_roinit_n (a, ap, an);
mpz_invert (t, t, m);
mpz_mul (t, t, a);
mpz_mod (t, t, m);
- _mpz_copy_limbs (rp, t, mn);
+ mpz_limbs_copy (rp, t, mn);
mpz_clear (t);
}
else
mpz_urandomb (r, state, 2*ecc->size * GMP_NUMB_BITS);
- _mpz_copy_limbs (a, r, 2*ecc->size);
+ mpz_limbs_copy (a, r, 2*ecc->size);
ref_redc (ref, a, ecc->p, ecc->size);
mpz_init (lhs);
mpz_init (rhs);
- _mpz_init_mpn (x, pub->p, size);
- _mpz_init_mpn (y, pub->p + size, size);
+ mpz_roinit_n (x, pub->p, size);
+ mpz_roinit_n (y, pub->p + size, size);
mpz_mul (lhs, y, y);
mpz_mul (rhs, x, x);
mpz_sub_ui (rhs, rhs, 3);
mpz_mul (rhs, rhs, x);
- mpz_add (rhs, rhs, _mpz_init_mpn (t, pub->ecc->b, size));
+ mpz_add (rhs, rhs, mpz_roinit_n (t, pub->ecc->b, size));
- res = mpz_congruent_p (lhs, rhs, _mpz_init_mpn (t, pub->ecc->p, size));
+ res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p, size));
mpz_clear (lhs);
mpz_clear (rhs);
mpz_init_set_str (z, sz, 16);
mpz_init_set_str (k, sk, 16);
- ecc_ecdsa_sign (ecc, _mpz_read_limbs_n (z, ecc->size),
- _mpz_read_limbs_n (k, ecc->size),
+ ecc_ecdsa_sign (ecc, mpz_limbs_read_n (z, ecc->size),
+ mpz_limbs_read_n (k, ecc->size),
h->length, h->data, rp, sp, scratch);
mpz_set_str (ref.r, r, 16);
mpz_set_str (ref.s, s, 16);
- if (_mpz_cmp_limbs (ref.r, rp, ecc->size) != 0
- || _mpz_cmp_limbs (ref.s, sp, ecc->size) != 0)
+ if (mpz_limbs_cmp (ref.r, rp, ecc->size) != 0
+ || mpz_limbs_cmp (ref.s, sp, ecc->size) != 0)
{
fprintf (stderr, "_ecdsa_sign failed, bit_size = %u\n", ecc->bit_size);
gmp_fprintf (stderr, "r = %Nx\n", rp, ecc->size);
while (n > 0 && xp[n-1] == 0)
n--;
- res = (_mpz_cmp_limbs (r, xp, n) == 0);
+ res = (mpz_limbs_cmp (r, xp, n) == 0);
mpz_clear (r);
return res;
}