security/nss/lib/freebl/ecl/ecp_384.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #include "ecp.h"
michael@0 6 #include "mpi.h"
michael@0 7 #include "mplogic.h"
michael@0 8 #include "mpi-priv.h"
michael@0 9
michael@0 10 /* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1. a can be r.
michael@0 11 * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to
michael@0 12 * Elliptic Curve Cryptography. */
michael@0 13 static mp_err
michael@0 14 ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
michael@0 15 {
michael@0 16 mp_err res = MP_OKAY;
michael@0 17 int a_bits = mpl_significant_bits(a);
michael@0 18 int i;
michael@0 19
michael@0 20 /* m1, m2 are statically-allocated mp_int of exactly the size we need */
michael@0 21 mp_int m[10];
michael@0 22
michael@0 23 #ifdef ECL_THIRTY_TWO_BIT
michael@0 24 mp_digit s[10][12];
michael@0 25 for (i = 0; i < 10; i++) {
michael@0 26 MP_SIGN(&m[i]) = MP_ZPOS;
michael@0 27 MP_ALLOC(&m[i]) = 12;
michael@0 28 MP_USED(&m[i]) = 12;
michael@0 29 MP_DIGITS(&m[i]) = s[i];
michael@0 30 }
michael@0 31 #else
michael@0 32 mp_digit s[10][6];
michael@0 33 for (i = 0; i < 10; i++) {
michael@0 34 MP_SIGN(&m[i]) = MP_ZPOS;
michael@0 35 MP_ALLOC(&m[i]) = 6;
michael@0 36 MP_USED(&m[i]) = 6;
michael@0 37 MP_DIGITS(&m[i]) = s[i];
michael@0 38 }
michael@0 39 #endif
michael@0 40
michael@0 41 #ifdef ECL_THIRTY_TWO_BIT
michael@0 42 /* for polynomials larger than twice the field size or polynomials
michael@0 43 * not using all words, use regular reduction */
michael@0 44 if ((a_bits > 768) || (a_bits <= 736)) {
michael@0 45 MP_CHECKOK(mp_mod(a, &meth->irr, r));
michael@0 46 } else {
michael@0 47 for (i = 0; i < 12; i++) {
michael@0 48 s[0][i] = MP_DIGIT(a, i);
michael@0 49 }
michael@0 50 s[1][0] = 0;
michael@0 51 s[1][1] = 0;
michael@0 52 s[1][2] = 0;
michael@0 53 s[1][3] = 0;
michael@0 54 s[1][4] = MP_DIGIT(a, 21);
michael@0 55 s[1][5] = MP_DIGIT(a, 22);
michael@0 56 s[1][6] = MP_DIGIT(a, 23);
michael@0 57 s[1][7] = 0;
michael@0 58 s[1][8] = 0;
michael@0 59 s[1][9] = 0;
michael@0 60 s[1][10] = 0;
michael@0 61 s[1][11] = 0;
michael@0 62 for (i = 0; i < 12; i++) {
michael@0 63 s[2][i] = MP_DIGIT(a, i+12);
michael@0 64 }
michael@0 65 s[3][0] = MP_DIGIT(a, 21);
michael@0 66 s[3][1] = MP_DIGIT(a, 22);
michael@0 67 s[3][2] = MP_DIGIT(a, 23);
michael@0 68 for (i = 3; i < 12; i++) {
michael@0 69 s[3][i] = MP_DIGIT(a, i+9);
michael@0 70 }
michael@0 71 s[4][0] = 0;
michael@0 72 s[4][1] = MP_DIGIT(a, 23);
michael@0 73 s[4][2] = 0;
michael@0 74 s[4][3] = MP_DIGIT(a, 20);
michael@0 75 for (i = 4; i < 12; i++) {
michael@0 76 s[4][i] = MP_DIGIT(a, i+8);
michael@0 77 }
michael@0 78 s[5][0] = 0;
michael@0 79 s[5][1] = 0;
michael@0 80 s[5][2] = 0;
michael@0 81 s[5][3] = 0;
michael@0 82 s[5][4] = MP_DIGIT(a, 20);
michael@0 83 s[5][5] = MP_DIGIT(a, 21);
michael@0 84 s[5][6] = MP_DIGIT(a, 22);
michael@0 85 s[5][7] = MP_DIGIT(a, 23);
michael@0 86 s[5][8] = 0;
michael@0 87 s[5][9] = 0;
michael@0 88 s[5][10] = 0;
michael@0 89 s[5][11] = 0;
michael@0 90 s[6][0] = MP_DIGIT(a, 20);
michael@0 91 s[6][1] = 0;
michael@0 92 s[6][2] = 0;
michael@0 93 s[6][3] = MP_DIGIT(a, 21);
michael@0 94 s[6][4] = MP_DIGIT(a, 22);
michael@0 95 s[6][5] = MP_DIGIT(a, 23);
michael@0 96 s[6][6] = 0;
michael@0 97 s[6][7] = 0;
michael@0 98 s[6][8] = 0;
michael@0 99 s[6][9] = 0;
michael@0 100 s[6][10] = 0;
michael@0 101 s[6][11] = 0;
michael@0 102 s[7][0] = MP_DIGIT(a, 23);
michael@0 103 for (i = 1; i < 12; i++) {
michael@0 104 s[7][i] = MP_DIGIT(a, i+11);
michael@0 105 }
michael@0 106 s[8][0] = 0;
michael@0 107 s[8][1] = MP_DIGIT(a, 20);
michael@0 108 s[8][2] = MP_DIGIT(a, 21);
michael@0 109 s[8][3] = MP_DIGIT(a, 22);
michael@0 110 s[8][4] = MP_DIGIT(a, 23);
michael@0 111 s[8][5] = 0;
michael@0 112 s[8][6] = 0;
michael@0 113 s[8][7] = 0;
michael@0 114 s[8][8] = 0;
michael@0 115 s[8][9] = 0;
michael@0 116 s[8][10] = 0;
michael@0 117 s[8][11] = 0;
michael@0 118 s[9][0] = 0;
michael@0 119 s[9][1] = 0;
michael@0 120 s[9][2] = 0;
michael@0 121 s[9][3] = MP_DIGIT(a, 23);
michael@0 122 s[9][4] = MP_DIGIT(a, 23);
michael@0 123 s[9][5] = 0;
michael@0 124 s[9][6] = 0;
michael@0 125 s[9][7] = 0;
michael@0 126 s[9][8] = 0;
michael@0 127 s[9][9] = 0;
michael@0 128 s[9][10] = 0;
michael@0 129 s[9][11] = 0;
michael@0 130
michael@0 131 MP_CHECKOK(mp_add(&m[0], &m[1], r));
michael@0 132 MP_CHECKOK(mp_add(r, &m[1], r));
michael@0 133 MP_CHECKOK(mp_add(r, &m[2], r));
michael@0 134 MP_CHECKOK(mp_add(r, &m[3], r));
michael@0 135 MP_CHECKOK(mp_add(r, &m[4], r));
michael@0 136 MP_CHECKOK(mp_add(r, &m[5], r));
michael@0 137 MP_CHECKOK(mp_add(r, &m[6], r));
michael@0 138 MP_CHECKOK(mp_sub(r, &m[7], r));
michael@0 139 MP_CHECKOK(mp_sub(r, &m[8], r));
michael@0 140 MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
michael@0 141 s_mp_clamp(r);
michael@0 142 }
michael@0 143 #else
michael@0 144 /* for polynomials larger than twice the field size or polynomials
michael@0 145 * not using all words, use regular reduction */
michael@0 146 if ((a_bits > 768) || (a_bits <= 736)) {
michael@0 147 MP_CHECKOK(mp_mod(a, &meth->irr, r));
michael@0 148 } else {
michael@0 149 for (i = 0; i < 6; i++) {
michael@0 150 s[0][i] = MP_DIGIT(a, i);
michael@0 151 }
michael@0 152 s[1][0] = 0;
michael@0 153 s[1][1] = 0;
michael@0 154 s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
michael@0 155 s[1][3] = MP_DIGIT(a, 11) >> 32;
michael@0 156 s[1][4] = 0;
michael@0 157 s[1][5] = 0;
michael@0 158 for (i = 0; i < 6; i++) {
michael@0 159 s[2][i] = MP_DIGIT(a, i+6);
michael@0 160 }
michael@0 161 s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
michael@0 162 s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
michael@0 163 for (i = 2; i < 6; i++) {
michael@0 164 s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32);
michael@0 165 }
michael@0 166 s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32;
michael@0 167 s[4][1] = MP_DIGIT(a, 10) << 32;
michael@0 168 for (i = 2; i < 6; i++) {
michael@0 169 s[4][i] = MP_DIGIT(a, i+4);
michael@0 170 }
michael@0 171 s[5][0] = 0;
michael@0 172 s[5][1] = 0;
michael@0 173 s[5][2] = MP_DIGIT(a, 10);
michael@0 174 s[5][3] = MP_DIGIT(a, 11);
michael@0 175 s[5][4] = 0;
michael@0 176 s[5][5] = 0;
michael@0 177 s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32;
michael@0 178 s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32;
michael@0 179 s[6][2] = MP_DIGIT(a, 11);
michael@0 180 s[6][3] = 0;
michael@0 181 s[6][4] = 0;
michael@0 182 s[6][5] = 0;
michael@0 183 s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32);
michael@0 184 for (i = 1; i < 6; i++) {
michael@0 185 s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32);
michael@0 186 }
michael@0 187 s[8][0] = MP_DIGIT(a, 10) << 32;
michael@0 188 s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32);
michael@0 189 s[8][2] = MP_DIGIT(a, 11) >> 32;
michael@0 190 s[8][3] = 0;
michael@0 191 s[8][4] = 0;
michael@0 192 s[8][5] = 0;
michael@0 193 s[9][0] = 0;
michael@0 194 s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32;
michael@0 195 s[9][2] = MP_DIGIT(a, 11) >> 32;
michael@0 196 s[9][3] = 0;
michael@0 197 s[9][4] = 0;
michael@0 198 s[9][5] = 0;
michael@0 199
michael@0 200 MP_CHECKOK(mp_add(&m[0], &m[1], r));
michael@0 201 MP_CHECKOK(mp_add(r, &m[1], r));
michael@0 202 MP_CHECKOK(mp_add(r, &m[2], r));
michael@0 203 MP_CHECKOK(mp_add(r, &m[3], r));
michael@0 204 MP_CHECKOK(mp_add(r, &m[4], r));
michael@0 205 MP_CHECKOK(mp_add(r, &m[5], r));
michael@0 206 MP_CHECKOK(mp_add(r, &m[6], r));
michael@0 207 MP_CHECKOK(mp_sub(r, &m[7], r));
michael@0 208 MP_CHECKOK(mp_sub(r, &m[8], r));
michael@0 209 MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r));
michael@0 210 s_mp_clamp(r);
michael@0 211 }
michael@0 212 #endif
michael@0 213
michael@0 214 CLEANUP:
michael@0 215 return res;
michael@0 216 }
michael@0 217
michael@0 218 /* Compute the square of polynomial a, reduce modulo p384. Store the
michael@0 219 * result in r. r could be a. Uses optimized modular reduction for p384.
michael@0 220 */
michael@0 221 static mp_err
michael@0 222 ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
michael@0 223 {
michael@0 224 mp_err res = MP_OKAY;
michael@0 225
michael@0 226 MP_CHECKOK(mp_sqr(a, r));
michael@0 227 MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
michael@0 228 CLEANUP:
michael@0 229 return res;
michael@0 230 }
michael@0 231
michael@0 232 /* Compute the product of two polynomials a and b, reduce modulo p384.
michael@0 233 * Store the result in r. r could be a or b; a could be b. Uses
michael@0 234 * optimized modular reduction for p384. */
michael@0 235 static mp_err
michael@0 236 ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r,
michael@0 237 const GFMethod *meth)
michael@0 238 {
michael@0 239 mp_err res = MP_OKAY;
michael@0 240
michael@0 241 MP_CHECKOK(mp_mul(a, b, r));
michael@0 242 MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth));
michael@0 243 CLEANUP:
michael@0 244 return res;
michael@0 245 }
michael@0 246
michael@0 247 /* Wire in fast field arithmetic and precomputation of base point for
michael@0 248 * named curves. */
michael@0 249 mp_err
michael@0 250 ec_group_set_gfp384(ECGroup *group, ECCurveName name)
michael@0 251 {
michael@0 252 if (name == ECCurve_NIST_P384) {
michael@0 253 group->meth->field_mod = &ec_GFp_nistp384_mod;
michael@0 254 group->meth->field_mul = &ec_GFp_nistp384_mul;
michael@0 255 group->meth->field_sqr = &ec_GFp_nistp384_sqr;
michael@0 256 }
michael@0 257 return MP_OKAY;
michael@0 258 }

mercurial