Commit 9422a551 authored by Niels Möller's avatar Niels Möller

Integrated ECC internals.

parent 75a1291e
2013-02-15 Niels Möller <nisse@lysator.liu.se>
Integrate ECC internals.
* ecc-curve.h: New file.
* ecc-internal.h: New file.
* cnd-copy.c: New file.
* ecc-192.c: New file.
* ecc-224.c: New file.
* ecc-256.c: New file.
* ecc-384.c: New file.
* ecc-521.c: New file.
* ecc-generic-modp.c: New file.
* ecc-generic-modq.c: New file.
* ecc-generic-redc.c: New file.
* ecc-mod.c: New file.
* ecc-modp.c: New file.
* ecc-modq.c: New file.
* sec-add-1.c: New file.
* sec-modinv.c: New file.
* sec-sub-1.c: New file.
* Makefile.in (hogweed_SOURCES): Added new files.
(HEADERS): Added ecc-curve.h.
(DISTFILES): Added ecc-internal.h.
* testsuite/ecc-mod-test.c: New file.
* testsuite/ecc-modinv-test.c: New file.
* testsuite/ecc-redc-test.c: New file.
* testsuite/testutils.c (ecc_curves): New constant array.
* testsuite/testutils.h: Include ecc-related headers. Declare
ecc_curves array.
* testsuite/Makefile.in (TS_HOGWEED_SOURCES): Added ecc-mod-test.c
ecc-modinv-test.c ecc-redc-test.c.
* gmp-glue.c: New file, mpn <-> mpz conversions.
* gmp-glue.h: New file.
* Makefile.in: Added to hogweed_SOURCES and DISTFILES, respectively.
......
......@@ -123,21 +123,24 @@ hogweed_SOURCES = sexp.c sexp-format.c \
dsa2sexp.c sexp2dsa.c \
pgp-encode.c rsa2openpgp.c \
der-iterator.c der2rsa.c der2dsa.c \
gmp-glue.c
sec-add-1.c sec-sub-1.c sec-modinv.c sec-tabselect.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
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 gcm.h \
des.h des-compat.h dsa.h \
hmac.h \
pbkdf2.h \
cbc.h ctr.h \
des.h des-compat.h dsa.h ecc-curve.h \
gcm.h gosthash94.h hmac.h \
knuth-lfib.h \
macros.h \
md2.h md4.h \
gosthash94.h \
md5.h md5-compat.h \
memxor.h \
nettle-meta.h nettle-types.h \
pbkdf2.h \
pgp.h pkcs1.h realloc.h ripemd160.h rsa.h rsa-compat.h \
salsa20.h sexp.h \
serpent.h sha.h sha1.h sha2.h sha3.h twofish.h \
......@@ -160,7 +163,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h .bootstrap run-tests \
aes-internal.h camellia-internal.h serpent-internal.h \
cast128_sboxes.h desinfo.h desCode.h \
nettle-internal.h nettle-write.h prime-list.h \
gmp-glue.h \
gmp-glue.h ecc-internal.h \
asm.m4 \
nettle.texinfo nettle.info nettle.html nettle.pdf sha-example.c
......
/* cnd-copy.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-internal.h"
void
cnd_copy (int cnd, mp_limb_t *rp, const mp_limb_t *ap, mp_size_t n)
{
mp_limb_t mask, keep;
mp_size_t i;
mask = -(mp_limb_t) (cnd !=0);
keep = ~mask;
for (i = 0; i < n; i++)
rp[i] = (rp[i] & keep) + (ap[i] & mask);
}
/* ecc-192.c */
/* Compile time constant (but machine dependent) tables. */
/* 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-internal.h"
#define USE_REDC 0
#include "ecc-192.h"
/* Use that p = 2^{192} - 2^64 - 1, to eliminate 128 bits at a time. */
#if GMP_NUMB_BITS == 32
/* p is 6 limbs, p = B^6 - B^2 - 1 */
static void
ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
{
mp_limb_t cy;
/* Reduce from 12 to 9 limbs (top limb small)*/
cy = mpn_add_n (rp + 2, rp + 2, rp + 8, 4);
cy = sec_add_1 (rp + 6, rp + 6, 2, cy);
cy += mpn_add_n (rp + 4, rp + 4, rp + 8, 4);
assert (cy <= 2);
rp[8] = cy;
/* Reduce from 9 to 6 limbs */
cy = mpn_add_n (rp, rp, rp + 6, 3);
cy = sec_add_1 (rp + 3, rp + 3, 2, cy);
cy += mpn_add_n (rp + 2, rp + 2, rp + 6, 3);
cy = sec_add_1 (rp + 5, rp + 5, 1, cy);
assert (cy <= 1);
cy = cnd_add_n (cy, rp, ecc_Bmodp, 3);
assert (cy == 0);
}
#elif GMP_NUMB_BITS == 64
/* p is 3 limbs, p = B^3 - B - 1 */
static void
ecc_192_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)
{
mp_limb_t cy;
/* Reduce from 6 to 5 limbs (top limb small)*/
cy = mpn_add_n (rp + 1, rp + 1, rp + 4, 2);
cy = sec_add_1 (rp + 3, rp + 3, 1, cy);
cy += mpn_add_n (rp + 2, rp + 2, rp + 4, 2);
assert (cy <= 2);
rp[4] = cy;
/* Reduce from 5 to 4 limbs (high limb small) */
cy = mpn_add_n (rp, rp, rp + 3, 2);
cy = sec_add_1 (rp + 2, rp + 2, 1, cy);
cy += mpn_add_n (rp + 1, rp + 1, rp + 3, 2);
assert (cy <= 1);
cy = cnd_add_n (cy, rp, ecc_Bmodp, 3);
assert (cy == 0);
}
#else
#define ecc_192_modp ecc_generoc_modp
#endif
const struct ecc_curve nettle_secp_192r1 =
{
192,
ECC_LIMB_SIZE,
ECC_BMODP_SIZE,
ECC_BMODQ_SIZE,
USE_REDC,
ECC_REDC_SIZE,
ECC_PIPPENGER_K,
ECC_PIPPENGER_C,
ecc_p,
ecc_b,
ecc_q,
ecc_g,
ecc_redc_g,
ecc_192_modp,
ecc_generic_redc,
ecc_192_modp,
ecc_generic_modq,
ecc_Bmodp,
ecc_Bmodp_shifted,
ecc_pp1h,
ecc_redc_ppm1,
ecc_unit,
ecc_Bmodq,
ecc_Bmodq_shifted,
ecc_qp1h,
ecc_table
};
/* ecc-224.c.c */
/* Compile time constant (but machine dependent) tables. */
/* 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-internal.h"
#define USE_REDC (ECC_REDC_SIZE != 0)
#include "ecc-224.h"
const struct ecc_curve nettle_secp_224r1 =
{
224,
ECC_LIMB_SIZE,
ECC_BMODP_SIZE,
ECC_BMODQ_SIZE,
USE_REDC,
ECC_REDC_SIZE,
ECC_PIPPENGER_K,
ECC_PIPPENGER_C,
ecc_p,
ecc_b,
ecc_q,
ecc_g,
ecc_redc_g,
ecc_generic_modp,
ecc_generic_redc,
USE_REDC ? ecc_generic_redc : ecc_generic_modp,
ecc_generic_modq,
ecc_Bmodp,
ecc_Bmodp_shifted,
ecc_pp1h,
ecc_redc_ppm1,
ecc_unit,
ecc_Bmodq,
ecc_Bmodq_shifted,
ecc_qp1h,
ecc_table
};
/* ecc-256.c.c */
/* Compile time constant (but machine dependent) tables. */
/* 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-internal.h"
#define USE_REDC (ECC_REDC_SIZE != 0)
#include "ecc-256.h"
#if ECC_BMODP_SIZE < ECC_LIMB_SIZE
#define ecc_256_modp ecc_generic_modp
#define ecc_256_modq ecc_generic_modq
#elif GMP_NUMB_BITS == 64
static void
ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
{
mp_limb_t u1, u0;
mp_size_t n;
n = 2*ecc->size;
u1 = rp[--n];
u0 = rp[n-1];
/* This is not particularly fast, but should work well with assembly implementation. */
for (; n >= ecc->size; n--)
{
mp_limb_t q2, q1, q0, t, cy;
/* <q2, q1, q0> = v * u1 + <u1,u0>, with v = 2^32 - 1:
+---+---+
| u1| u0|
+---+---+
|-u1|
+-+-+-+
| u1|
+---+-+-+-+-+
| q2| q1| q0|
+---+---+---+
*/
q1 = u1 - (u1 > u0);
q0 = u0 - u1;
t = u1 << 32;
q0 += t;
t = (u1 >> 32) + (q0 < t) + 1;
q1 += t;
q2 = q1 < t;
/* Compute candidate remainder */
u1 = u0 + (q1 << 32) - q1;
t = -(mp_limb_t) (u1 > q0);
u1 -= t & 0xffffffff;
q1 += t;
q2 += t + (q1 < t);
assert (q2 < 2);
/* We multiply by two low limbs of p, 2^96 - 1, so we could use
shifts rather than mul. */
t = mpn_submul_1 (rp + n - 4, ecc->p, 2, q1);
t += cnd_sub_n (q2, rp + n - 3, ecc->p, 1);
t += (-q2) & 0xffffffff;
u0 = rp[n-2];
cy = (u0 < t);
u0 -= t;
t = (u1 < cy);
u1 -= cy;
u1 += cnd_add_n (t, rp + n - 4, ecc->p, 3);
u1 -= (-t) & 0xffffffff;
}
rp[2] = u0;
rp[3] = u1;
}
static void
ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
{
mp_limb_t u2, u1, u0;
mp_size_t n;
n = 2*ecc->size;
u2 = rp[--n];
u1 = rp[n-1];
/* This is not particularly fast, but should work well with assembly implementation. */
for (; n >= ecc->size; n--)
{
mp_limb_t q2, q1, q0, t, c1, c0;
u0 = rp[n-2];
/* <q2, q1, q0> = v * u2 + <u2,u1>, same method as above.
+---+---+
| u2| u1|
+---+---+
|-u2|
+-+-+-+
| u2|
+---+-+-+-+-+
| q2| q1| q0|
+---+---+---+
*/
q1 = u2 - (u2 > u1);
q0 = u1 - u2;
t = u2 << 32;
q0 += t;
t = (u2 >> 32) + (q0 < t) + 1;
q1 += t;
q2 = q1 < t;
/* Compute candidate remainder, <u1, u0> - <q2, q1> * (2^128 - 2^96 + 2^64 - 1)
<u1, u0> + 2^64 q2 + (2^96 - 2^64 + 1) q1 (mod 2^128)
+---+---+
| u1| u0|
+---+---+
| q2| q1|
+---+---+
|-q1|
+-+-+-+
| q1|
--+-+-+-+---+
| u2| u1|
+---+---+
*/
u2 = u1 + q2 - q1;
u1 = u0 + q1;
u2 += (u1 < q1);
u2 += (q1 << 32);
t = -(mp_limb_t) (u2 >= q0);
q1 += t;
q2 += t + (q1 < t);
u1 += t;
u2 += (t << 32) + (u1 < t);
assert (q2 < 2);
c0 = cnd_sub_n (q2, rp + n - 3, ecc->q, 1);
c0 += (-q2) & ecc->q[1];
t = mpn_submul_1 (rp + n - 4, ecc->q, 2, q1);
c0 += t;
c1 = c0 < t;
/* Construct underflow condition. */
c1 += (u1 < c0);
t = - (mp_limb_t) (u2 < c1);
u1 -= c0;
u2 -= c1;
/* Conditional add of p */
u1 += t;
u2 += (t<<32) + (u0 < t);
t = cnd_add_n (t, rp + n - 4, ecc->q, 2);
u1 += t;
u2 += (u1 < t);
}
rp[2] = u1;
rp[3] = u2;
}
#else
#error Unsupported parameters
#endif
const struct ecc_curve nettle_secp_256r1 =
{
256,
ECC_LIMB_SIZE,
ECC_BMODP_SIZE,
ECC_BMODQ_SIZE,
USE_REDC,
ECC_REDC_SIZE,
ECC_PIPPENGER_K,
ECC_PIPPENGER_C,
ecc_p,
ecc_b,
ecc_q,
ecc_g,
ecc_redc_g,
ecc_256_modp,
ecc_generic_redc,
USE_REDC ? ecc_generic_redc : ecc_generic_modp,
ecc_256_modq,
ecc_Bmodp,
ecc_Bmodp_shifted,
ecc_pp1h,
ecc_redc_ppm1,
ecc_unit,
ecc_Bmodq,
ecc_Bmodq_shifted,
ecc_qp1h,
ecc_table
};
/* ecc-384.c.c */
/* Compile time constant (but machine dependent) tables. */
/* 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-internal.h"
#define USE_REDC 0
#include "ecc-384.h"
/* Use that 2^{384} = 2^{128} + 2^{96} - 2^{32} + 1, and eliminate 256
bits at a time.
We can get carry == 2 in the first iteration, and I think *only* in
the first iteration. */
#if GMP_NUMB_BITS == 32
/* p is 12 limbs, and B^12 - p = B^4 + B^3 - B + 1. We can eliminate
almost 8 at a time. Do only 7, to avoid additional carry
propagation, followed by 5. */
static void
ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
{
mp_limb_t cy, bw;
/* Reduce from 24 to 17 limbs. */
cy = mpn_add_n (rp + 4, rp + 4, rp + 16, 8);
cy = sec_add_1 (rp + 12, rp + 12, 3, cy);
bw = mpn_sub_n (rp + 5, rp + 5, rp + 16, 8);
bw = sub_1_sec (rp + 13, rp + 13, 3, bw);
cy += mpn_add_n (rp + 7, rp + 7, rp + 16, 8);
cy = sec_add_1 (rp + 15, rp + 15, 1, cy);
cy += mpn_add_n (rp + 8, rp + 8, rp + 16, 8);
assert (bw <= cy);
cy -= bw;
assert (cy <= 2);
rp[16] = cy;
/* Reduce from 17 to 12 limbs */
cy = mpn_add_n (rp, rp, rp + 12, 5);
cy = sec_add_1 (rp + 5, rp + 5, 3, cy);
bw = mpn_sub_n (rp + 1, rp + 1, rp + 12, 5);
bw = sub_1_sec (rp + 6, rp + 6, 6, bw);
cy += mpn_add_n (rp + 3, rp + 3, rp + 12, 5);
cy = sec_add_1 (rp + 8, rp + 8, 1, cy);
cy += mpn_add_n (rp + 4, rp + 4, rp + 12, 5);
cy = sec_add_1 (rp + 9, rp + 9, 3, cy);
assert (cy >= bw);
cy -= bw;
assert (cy <= 1);
cy = cnd_add_n (cy, rp, ecc->Bmodp, ECC_LIMB_SIZE);
assert (cy == 0);
}
#elif GMP_NUMB_BITS == 64
/* p is 6 limbs, and B^6 - p = B^2 + 2^32 (B - 1) + 1. Eliminate 3
(almost 4) limbs at a time. */
static void
ecc_384_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
{
mp_limb_t tp[6];
mp_limb_t cy;
/* Reduce from 12 to 9 limbs */
tp[0] = 0; /* FIXME: Could use mpn_sub_nc */
mpn_copyi (tp + 1, rp + 8, 3);
tp[4] = rp[11] - mpn_sub_n (tp, tp, rp + 8, 4);
tp[5] = mpn_lshift (tp, tp, 5, 32);
cy = mpn_add_n (rp + 2, rp + 2, rp + 8, 4);
cy = sec_add_1 (rp + 6, rp + 6, 2, cy);
cy += mpn_add_n (rp + 2, rp + 2, tp, 6);
cy += mpn_add_n (rp + 4, rp + 4, rp + 8, 4);
assert (cy <= 2);
rp[8] = cy;
/* Reduce from 9 to 6 limbs */
tp[0] = 0;
mpn_copyi (tp + 1, rp + 6, 2);
tp[3] = rp[8] -= mpn_sub_n (tp, tp, rp + 6, 3);
tp[4] = mpn_lshift (tp, tp, 4, 32);
cy = mpn_add_n (rp, rp, rp + 6, 3);
cy = sec_add_1 (rp + 3, rp + 3, 2, cy);
cy += mpn_add_n (rp, rp, tp, 5);
cy += mpn_add_n (rp + 2, rp + 2, rp + 6, 3);
cy = sec_add_1 (rp + 5, rp + 5, 1, cy);
assert (cy <= 1);
cy = cnd_add_n (cy, rp, ecc->Bmodp, ECC_LIMB_SIZE);
assert (cy == 0);
}
#else
#define ecc_384_modp ecc_generic_modp
#endif
const struct ecc_curve nettle_secp_384r1 =
{
384,
ECC_LIMB_SIZE,
ECC_BMODP_SIZE,
ECC_BMODQ_SIZE,
USE_REDC,
ECC_REDC_SIZE,
ECC_PIPPENGER_K,
ECC_PIPPENGER_C,
ecc_p,
ecc_b,
ecc_q,
ecc_g,
ecc_redc_g,
ecc_384_modp,
ECC_REDC_SIZE != 0 ? ecc_generic_redc : NULL,
ecc_384_modp,
ecc_generic_modq,
ecc_Bmodp,
ecc_Bmodp_shifted,
ecc_pp1h,
ecc_redc_ppm1,
ecc_unit,
ecc_Bmodq,
ecc_Bmodq_shifted,
ecc_qp1h,
ecc_table
};
/* ecc-521.c.c */
/* Compile time constant (but machine dependent) tables. */
/* 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-internal.h"
#define USE_REDC 0
#include "ecc-521.h"
#define B_SHIFT (521 % GMP_NUMB_BITS)
#define BMODP_SHIFT (GMP_NUMB_BITS - B_SHIFT)
#define BMODP ((mp_limb_t) 1 << BMODP_SHIFT)
/* Result may be *slightly* larger than 2^521 */
static void
ecc_521_modp (const struct ecc_curve *ecc UNUSED, mp_limb_t *rp)