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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial