/src/nss/lib/freebl/ecl/ec_naf.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #include "ecl-priv.h" |
6 | | |
7 | | /* Returns 2^e as an integer. This is meant to be used for small powers of |
8 | | * two. */ |
9 | | int |
10 | | ec_twoTo(int e) |
11 | 0 | { |
12 | 0 | int a = 1; |
13 | 0 | int i; |
14 | |
|
15 | 0 | for (i = 0; i < e; i++) { |
16 | 0 | a *= 2; |
17 | 0 | } |
18 | 0 | return a; |
19 | 0 | } |
20 | | |
21 | | /* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should |
22 | | * be an array of signed char's to output to, bitsize should be the number |
23 | | * of bits of out, in is the original scalar, and w is the window size. |
24 | | * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A. |
25 | | * Menezes, "Software implementation of elliptic curve cryptography over |
26 | | * binary fields", Proc. CHES 2000. */ |
27 | | mp_err |
28 | | ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w) |
29 | 0 | { |
30 | 0 | mp_int k; |
31 | 0 | mp_err res = MP_OKAY; |
32 | 0 | int i, twowm1, mask; |
33 | |
|
34 | 0 | twowm1 = ec_twoTo(w - 1); |
35 | 0 | mask = 2 * twowm1 - 1; |
36 | |
|
37 | 0 | MP_DIGITS(&k) = 0; |
38 | 0 | MP_CHECKOK(mp_init_copy(&k, in)); |
39 | | |
40 | 0 | i = 0; |
41 | | /* Compute wNAF form */ |
42 | 0 | while (mp_cmp_z(&k) > 0) { |
43 | 0 | if (mp_isodd(&k)) { |
44 | 0 | out[i] = MP_DIGIT(&k, 0) & mask; |
45 | 0 | if (out[i] >= twowm1) |
46 | 0 | out[i] -= 2 * twowm1; |
47 | | |
48 | | /* Subtract off out[i]. Note mp_sub_d only works with |
49 | | * unsigned digits */ |
50 | 0 | if (out[i] >= 0) { |
51 | 0 | MP_CHECKOK(mp_sub_d(&k, out[i], &k)); |
52 | 0 | } else { |
53 | 0 | MP_CHECKOK(mp_add_d(&k, -(out[i]), &k)); |
54 | 0 | } |
55 | 0 | } else { |
56 | 0 | out[i] = 0; |
57 | 0 | } |
58 | 0 | MP_CHECKOK(mp_div_2(&k, &k)); |
59 | 0 | i++; |
60 | 0 | } |
61 | | /* Zero out the remaining elements of the out array. */ |
62 | 0 | for (; i < bitsize + 1; i++) { |
63 | 0 | out[i] = 0; |
64 | 0 | } |
65 | 0 | CLEANUP: |
66 | 0 | mp_clear(&k); |
67 | 0 | return res; |
68 | 0 | } |