3 /* Compile time constant (but machine dependent) tables. */
5 /* nettle, low-level cryptographics library
7 * Copyright (C) 2013 Niels Möller
9 * The nettle library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or (at your
12 * option) any later version.
14 * The nettle library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the nettle library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 /* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
33 #include "ecc-internal.h"
35 #if HAVE_NATIVE_ecc_256_redc
38 # define USE_REDC (ECC_REDC_SIZE != 0)
43 #if HAVE_NATIVE_ecc_256_redc
44 # define ecc_256_redc nettle_ecc_256_redc
46 ecc_256_redc (const struct ecc_curve *ecc, mp_limb_t *rp);
47 #else /* !HAVE_NATIVE_ecc_256_redc */
48 # define ecc_256_redc ecc_generic_redc
51 #if ECC_BMODP_SIZE < ECC_LIMB_SIZE
52 #define ecc_256_modp ecc_generic_modp
53 #define ecc_256_modq ecc_generic_modq
54 #elif GMP_NUMB_BITS == 64
57 ecc_256_modp (const struct ecc_curve *ecc, mp_limb_t *rp)
66 /* This is not particularly fast, but should work well with assembly implementation. */
67 for (; n >= ecc->size; n--)
69 mp_limb_t q2, q1, q0, t, cy;
71 /* <q2, q1, q0> = v * u1 + <u1,u0>, with v = 2^32 - 1:
87 t = (u1 >> 32) + (q0 < t) + 1;
91 /* Compute candidate remainder */
92 u1 = u0 + (q1 << 32) - q1;
93 t = -(mp_limb_t) (u1 > q0);
100 /* We multiply by two low limbs of p, 2^96 - 1, so we could use
101 shifts rather than mul. */
102 t = mpn_submul_1 (rp + n - 4, ecc->p, 2, q1);
103 t += cnd_sub_n (q2, rp + n - 3, ecc->p, 1);
104 t += (-q2) & 0xffffffff;
111 u1 += cnd_add_n (t, rp + n - 4, ecc->p, 3);
112 u1 -= (-t) & 0xffffffff;
119 ecc_256_modq (const struct ecc_curve *ecc, mp_limb_t *rp)
121 mp_limb_t u2, u1, u0;
128 /* This is not particularly fast, but should work well with assembly implementation. */
129 for (; n >= ecc->size; n--)
131 mp_limb_t q2, q1, q0, t, c1, c0;
135 /* <q2, q1, q0> = v * u2 + <u2,u1>, same method as above.
151 t = (u2 >> 32) + (q0 < t) + 1;
155 /* Compute candidate remainder, <u1, u0> - <q2, q1> * (2^128 - 2^96 + 2^64 - 1)
156 <u1, u0> + 2^64 q2 + (2^96 - 2^64 + 1) q1 (mod 2^128)
175 t = -(mp_limb_t) (u2 >= q0);
179 u2 += (t << 32) + (u1 < t);
183 c0 = cnd_sub_n (q2, rp + n - 3, ecc->q, 1);
184 c0 += (-q2) & ecc->q[1];
185 t = mpn_submul_1 (rp + n - 4, ecc->q, 2, q1);
189 /* Construct underflow condition. */
191 t = - (mp_limb_t) (u2 < c1);
196 /* Conditional add of p */
198 u2 += (t<<32) + (u0 < t);
200 t = cnd_add_n (t, rp + n - 4, ecc->q, 2);
209 #error Unsupported parameters
212 const struct ecc_curve nettle_secp_256r1 =
229 USE_REDC ? ecc_256_redc : ecc_256_modp,