1 /* ecc-521.c
2 
3    Compile time constant (but machine dependent) tables.
4 
5    Copyright (C) 2013, 2014 Niels Möller
6 
7    This file is part of GNU Nettle.
8 
9    GNU Nettle is free software: you can redistribute it and/or
10    modify it under the terms of either:
11 
12      * the GNU Lesser General Public License as published by the Free
13        Software Foundation; either version 3 of the License, or (at your
14        option) any later version.
15 
16    or
17 
18      * the GNU General Public License as published by the Free
19        Software Foundation; either version 2 of the License, or (at your
20        option) any later version.
21 
22    or both in parallel, as here.
23 
24    GNU Nettle is distributed in the hope that it will be useful,
25    but WITHOUT ANY WARRANTY; without even the implied warranty of
26    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27    General Public License for more details.
28 
29    You should have received copies of the GNU General Public License and
30    the GNU Lesser General Public License along with this program.  If
31    not, see http://www.gnu.org/licenses/.
32 */
33 
34 /* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
35 
36 #if HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39 
40 #include "ecc.h"
41 #include "ecc-internal.h"
42 
43 #define USE_REDC 0
44 
45 #include "ecc-521.h"
46 
47 #if HAVE_NATIVE_ecc_521_modp
48 #define ecc_521_modp nettle_ecc_521_modp
49 void
50 ecc_521_modp (const struct ecc_modulo *m, mp_limb_t *rp);
51 
52 #else
53 
54 #define B_SHIFT (521 % GMP_NUMB_BITS)
55 #define BMODP_SHIFT (GMP_NUMB_BITS - B_SHIFT)
56 #define BMODP ((mp_limb_t) 1 << BMODP_SHIFT)
57 
58 /* Result may be *slightly* larger than 2^521 */
59 static void
ecc_521_modp(const struct ecc_modulo * m UNUSED,mp_limb_t * rp)60 ecc_521_modp (const struct ecc_modulo *m UNUSED, mp_limb_t *rp)
61 {
62   /* FIXME: Should use mpn_addlsh_n_ip1 */
63   mp_limb_t hi;
64   /* Reduce from 2*ECC_LIMB_SIZE to ECC_LIMB_SIZE + 1 */
65   rp[ECC_LIMB_SIZE]
66     = mpn_addmul_1 (rp, rp + ECC_LIMB_SIZE, ECC_LIMB_SIZE, BMODP);
67   hi = mpn_addmul_1 (rp, rp + ECC_LIMB_SIZE, 1, BMODP);
68   hi = sec_add_1 (rp + 1, rp + 1, ECC_LIMB_SIZE - 1, hi);
69 
70   /* Combine hi with top bits, and add in. */
71   hi = (hi << BMODP_SHIFT) | (rp[ECC_LIMB_SIZE-1] >> B_SHIFT);
72   rp[ECC_LIMB_SIZE-1] = (rp[ECC_LIMB_SIZE-1]
73 			 & (((mp_limb_t) 1 << B_SHIFT)-1))
74     + sec_add_1 (rp, rp, ECC_LIMB_SIZE - 1, hi);
75 }
76 #endif
77 
78 const struct ecc_curve _nettle_secp_521r1 =
79 {
80   {
81     521,
82     ECC_LIMB_SIZE,
83     ECC_BMODP_SIZE,
84     ECC_REDC_SIZE,
85     ECC_MOD_INV_ITCH (ECC_LIMB_SIZE),
86     0,
87 
88     ecc_p,
89     ecc_Bmodp,
90     ecc_Bmodp_shifted,
91     ecc_redc_ppm1,
92     ecc_pp1h,
93 
94     ecc_521_modp,
95     ecc_521_modp,
96     ecc_mod_inv,
97     NULL,
98   },
99   {
100     521,
101     ECC_LIMB_SIZE,
102     ECC_BMODQ_SIZE,
103     0,
104     ECC_MOD_INV_ITCH (ECC_LIMB_SIZE),
105     0,
106 
107     ecc_q,
108     ecc_Bmodq,
109     ecc_Bmodq_shifted,
110     NULL,
111     ecc_qp1h,
112 
113     ecc_mod,
114     ecc_mod,
115     ecc_mod_inv,
116     NULL,
117   },
118 
119   USE_REDC,
120   ECC_PIPPENGER_K,
121   ECC_PIPPENGER_C,
122 
123   ECC_ADD_JJJ_ITCH (ECC_LIMB_SIZE),
124   ECC_MUL_A_ITCH (ECC_LIMB_SIZE),
125   ECC_MUL_G_ITCH (ECC_LIMB_SIZE),
126   ECC_J_TO_A_ITCH (ECC_LIMB_SIZE),
127 
128   ecc_add_jjj,
129   ecc_mul_a,
130   ecc_mul_g,
131   ecc_j_to_a,
132 
133   ecc_b,
134   ecc_g,
135   NULL,
136   ecc_unit,
137   ecc_table
138 };
139 
nettle_get_secp_521r1(void)140 const struct ecc_curve *nettle_get_secp_521r1(void)
141 {
142   return &_nettle_secp_521r1;
143 }
144