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
,