3 /* nettle, low-level cryptographics library
5 * Copyright (C) 2013 Niels Möller
7 * The nettle library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or (at your
10 * option) any later version.
12 * The nettle library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with the nettle library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
23 /* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
32 #include "ecc-internal.h"
35 ecc_mul_a_itch (const struct ecc_curve
*ecc
)
37 /* Binary algorithm needs 6*ecc->size + scratch for ecc_add_jja.
38 Current total is 12 ecc->size, at most 864 bytes.
40 Window algorithm needs (3<<w) * ecc->size for the table,
41 3*ecc->size for a temporary point, and scratch for
43 return ECC_MUL_A_ITCH (ecc
->size
);
46 #if ECC_MUL_A_WBITS == 0
48 ecc_mul_a (const struct ecc_curve
*ecc
,
49 int initial
, mp_limb_t
*r
,
50 const mp_limb_t
*np
, const mp_limb_t
*p
,
54 #define pj (scratch + 3*ecc->size)
55 #define scratch_out (scratch + 6*ecc->size)
61 ecc_a_to_j (ecc
, initial
, pj
, p
);
62 mpn_zero (r
, 3*ecc
->size
);
64 for (i
= ecc
->size
, is_zero
= 1; i
-- > 0; )
69 for (bit
= (mp_limb_t
) 1 << (GMP_NUMB_BITS
- 1);
75 ecc_dup_jj (ecc
, r
, r
, scratch_out
);
76 ecc_add_jja (ecc
, tp
, r
, pj
, scratch_out
);
78 digit
= (w
& bit
) > 0;
79 /* If is_zero is set, r is the zero point,
80 and ecc_add_jja produced garbage. */
81 cnd_copy (is_zero
, tp
, pj
, 3*ecc
->size
);
83 /* If we had a one-bit, use the sum. */
84 cnd_copy (digit
, r
, tp
, 3*ecc
->size
);
88 #else /* ECC_MUL_A_WBITS > 1 */
90 #define TABLE_SIZE (1U << ECC_MUL_A_WBITS)
91 #define TABLE_MASK (TABLE_SIZE - 1)
93 #define TABLE(j) (table + (j) * 3*ecc->size)
96 table_init (const struct ecc_curve
*ecc
,
97 mp_limb_t
*table
, unsigned bits
,
98 int initial
, const mp_limb_t
*p
,
101 unsigned size
= 1 << bits
;
104 mpn_zero (TABLE(0), 3*ecc
->size
);
105 ecc_a_to_j (ecc
, initial
, TABLE(1), p
);
107 for (j
= 2; j
< size
; j
+= 2)
109 ecc_dup_jj (ecc
, TABLE(j
), TABLE(j
/2), scratch
);
110 ecc_add_jja (ecc
, TABLE(j
+1), TABLE(j
), TABLE(1), scratch
);
115 ecc_mul_a (const struct ecc_curve
*ecc
,
116 int initial
, mp_limb_t
*r
,
117 const mp_limb_t
*np
, const mp_limb_t
*p
,
121 #define table (scratch + 3*ecc->size)
122 mp_limb_t
*scratch_out
= table
+ (3*ecc
->size
<< ECC_MUL_A_WBITS
);
125 /* Avoid the mp_bitcnt_t type for compatibility with older GMP
127 unsigned blocks
= (ecc
->bit_size
+ ECC_MUL_A_WBITS
- 1) / ECC_MUL_A_WBITS
;
128 unsigned bit_index
= (blocks
-1) * ECC_MUL_A_WBITS
;
130 mp_size_t limb_index
= bit_index
/ GMP_NUMB_BITS
;
131 unsigned shift
= bit_index
% GMP_NUMB_BITS
;
134 table_init (ecc
, table
, ECC_MUL_A_WBITS
, initial
, p
, scratch_out
);
138 if (limb_index
< ecc
->size
- 1)
139 bits
|= np
[limb_index
+ 1] << (GMP_NUMB_BITS
- shift
);
141 assert (bits
< TABLE_SIZE
);
143 sec_tabselect (r
, 3*ecc
->size
, table
, TABLE_SIZE
, bits
);
144 is_zero
= (bits
== 0);
149 if (shift
>= ECC_MUL_A_WBITS
)
151 shift
-= ECC_MUL_A_WBITS
;
161 bits
= w
<< (ECC_MUL_A_WBITS
- shift
);
162 w
= np
[--limb_index
];
163 shift
= shift
+ GMP_NUMB_BITS
- ECC_MUL_A_WBITS
;
166 for (j
= 0; j
< ECC_MUL_A_WBITS
; j
++)
167 ecc_dup_jj (ecc
, r
, r
, scratch_out
);
170 sec_tabselect (tp
, 3*ecc
->size
, table
, TABLE_SIZE
, bits
);
171 cnd_copy (is_zero
, r
, tp
, 3*ecc
->size
);
172 ecc_add_jjj (ecc
, tp
, tp
, r
, scratch_out
);
174 /* Use the sum when valid. ecc_add_jja produced garbage if
175 is_zero != 0 or bits == 0, . */
176 cnd_copy (bits
& (is_zero
- 1), r
, tp
, 3*ecc
->size
);
177 is_zero
&= (bits
== 0);
183 #endif /* ECC_MUL_A_WBITS > 1 */