1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/freebl/ecl/ec_naf.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,69 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "ecl-priv.h" 1.9 + 1.10 +/* Returns 2^e as an integer. This is meant to be used for small powers of 1.11 + * two. */ 1.12 +int 1.13 +ec_twoTo(int e) 1.14 +{ 1.15 + int a = 1; 1.16 + int i; 1.17 + 1.18 + for (i = 0; i < e; i++) { 1.19 + a *= 2; 1.20 + } 1.21 + return a; 1.22 +} 1.23 + 1.24 +/* Computes the windowed non-adjacent-form (NAF) of a scalar. Out should 1.25 + * be an array of signed char's to output to, bitsize should be the number 1.26 + * of bits of out, in is the original scalar, and w is the window size. 1.27 + * NAF is discussed in the paper: D. Hankerson, J. Hernandez and A. 1.28 + * Menezes, "Software implementation of elliptic curve cryptography over 1.29 + * binary fields", Proc. CHES 2000. */ 1.30 +mp_err 1.31 +ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, int w) 1.32 +{ 1.33 + mp_int k; 1.34 + mp_err res = MP_OKAY; 1.35 + int i, twowm1, mask; 1.36 + 1.37 + twowm1 = ec_twoTo(w - 1); 1.38 + mask = 2 * twowm1 - 1; 1.39 + 1.40 + MP_DIGITS(&k) = 0; 1.41 + MP_CHECKOK(mp_init_copy(&k, in)); 1.42 + 1.43 + i = 0; 1.44 + /* Compute wNAF form */ 1.45 + while (mp_cmp_z(&k) > 0) { 1.46 + if (mp_isodd(&k)) { 1.47 + out[i] = MP_DIGIT(&k, 0) & mask; 1.48 + if (out[i] >= twowm1) 1.49 + out[i] -= 2 * twowm1; 1.50 + 1.51 + /* Subtract off out[i]. Note mp_sub_d only works with 1.52 + * unsigned digits */ 1.53 + if (out[i] >= 0) { 1.54 + mp_sub_d(&k, out[i], &k); 1.55 + } else { 1.56 + mp_add_d(&k, -(out[i]), &k); 1.57 + } 1.58 + } else { 1.59 + out[i] = 0; 1.60 + } 1.61 + mp_div_2(&k, &k); 1.62 + i++; 1.63 + } 1.64 + /* Zero out the remaining elements of the out array. */ 1.65 + for (; i < bitsize + 1; i++) { 1.66 + out[i] = 0; 1.67 + } 1.68 + CLEANUP: 1.69 + mp_clear(&k); 1.70 + return res; 1.71 + 1.72 +}