security/nss/lib/freebl/ecl/ec2_233.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 "ec2.h"
     6 #include "mp_gf2m.h"
     7 #include "mp_gf2m-priv.h"
     8 #include "mpi.h"
     9 #include "mpi-priv.h"
    10 #include <stdlib.h>
    12 /* Fast reduction for polynomials over a 233-bit curve. Assumes reduction
    13  * polynomial with terms {233, 74, 0}. */
    14 mp_err
    15 ec_GF2m_233_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
    16 {
    17 	mp_err res = MP_OKAY;
    18 	mp_digit *u, z;
    20 	if (a != r) {
    21 		MP_CHECKOK(mp_copy(a, r));
    22 	}
    23 #ifdef ECL_SIXTY_FOUR_BIT
    24 	if (MP_USED(r) < 8) {
    25 		MP_CHECKOK(s_mp_pad(r, 8));
    26 	}
    27 	u = MP_DIGITS(r);
    28 	MP_USED(r) = 8;
    30 	/* u[7] only has 18 significant bits */
    31 	z = u[7];
    32 	u[4] ^= (z << 33) ^ (z >> 41);
    33 	u[3] ^= (z << 23);
    34 	z = u[6];
    35 	u[4] ^= (z >> 31);
    36 	u[3] ^= (z << 33) ^ (z >> 41);
    37 	u[2] ^= (z << 23);
    38 	z = u[5];
    39 	u[3] ^= (z >> 31);
    40 	u[2] ^= (z << 33) ^ (z >> 41);
    41 	u[1] ^= (z << 23);
    42 	z = u[4];
    43 	u[2] ^= (z >> 31);
    44 	u[1] ^= (z << 33) ^ (z >> 41);
    45 	u[0] ^= (z << 23);
    46 	z = u[3] >> 41;				/* z only has 23 significant bits */
    47 	u[1] ^= (z << 10);
    48 	u[0] ^= z;
    49 	/* clear bits above 233 */
    50 	u[7] = u[6] = u[5] = u[4] = 0;
    51 	u[3] ^= z << 41;
    52 #else
    53 	if (MP_USED(r) < 15) {
    54 		MP_CHECKOK(s_mp_pad(r, 15));
    55 	}
    56 	u = MP_DIGITS(r);
    57 	MP_USED(r) = 15;
    59 	/* u[14] only has 18 significant bits */
    60 	z = u[14];
    61 	u[9] ^= (z << 1);
    62 	u[7] ^= (z >> 9);
    63 	u[6] ^= (z << 23);
    64 	z = u[13];
    65 	u[9] ^= (z >> 31);
    66 	u[8] ^= (z << 1);
    67 	u[6] ^= (z >> 9);
    68 	u[5] ^= (z << 23);
    69 	z = u[12];
    70 	u[8] ^= (z >> 31);
    71 	u[7] ^= (z << 1);
    72 	u[5] ^= (z >> 9);
    73 	u[4] ^= (z << 23);
    74 	z = u[11];
    75 	u[7] ^= (z >> 31);
    76 	u[6] ^= (z << 1);
    77 	u[4] ^= (z >> 9);
    78 	u[3] ^= (z << 23);
    79 	z = u[10];
    80 	u[6] ^= (z >> 31);
    81 	u[5] ^= (z << 1);
    82 	u[3] ^= (z >> 9);
    83 	u[2] ^= (z << 23);
    84 	z = u[9];
    85 	u[5] ^= (z >> 31);
    86 	u[4] ^= (z << 1);
    87 	u[2] ^= (z >> 9);
    88 	u[1] ^= (z << 23);
    89 	z = u[8];
    90 	u[4] ^= (z >> 31);
    91 	u[3] ^= (z << 1);
    92 	u[1] ^= (z >> 9);
    93 	u[0] ^= (z << 23);
    94 	z = u[7] >> 9;				/* z only has 23 significant bits */
    95 	u[3] ^= (z >> 22);
    96 	u[2] ^= (z << 10);
    97 	u[0] ^= z;
    98 	/* clear bits above 233 */
    99 	u[14] = u[13] = u[12] = u[11] = u[10] = u[9] = u[8] = 0;
   100 	u[7] ^= z << 9;
   101 #endif
   102 	s_mp_clamp(r);
   104   CLEANUP:
   105 	return res;
   106 }
   108 /* Fast squaring for polynomials over a 233-bit curve. Assumes reduction
   109  * polynomial with terms {233, 74, 0}. */
   110 mp_err
   111 ec_GF2m_233_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
   112 {
   113 	mp_err res = MP_OKAY;
   114 	mp_digit *u, *v;
   116 	v = MP_DIGITS(a);
   118 #ifdef ECL_SIXTY_FOUR_BIT
   119 	if (MP_USED(a) < 4) {
   120 		return mp_bsqrmod(a, meth->irr_arr, r);
   121 	}
   122 	if (MP_USED(r) < 8) {
   123 		MP_CHECKOK(s_mp_pad(r, 8));
   124 	}
   125 	MP_USED(r) = 8;
   126 #else
   127 	if (MP_USED(a) < 8) {
   128 		return mp_bsqrmod(a, meth->irr_arr, r);
   129 	}
   130 	if (MP_USED(r) < 15) {
   131 		MP_CHECKOK(s_mp_pad(r, 15));
   132 	}
   133 	MP_USED(r) = 15;
   134 #endif
   135 	u = MP_DIGITS(r);
   137 #ifdef ECL_THIRTY_TWO_BIT
   138 	u[14] = gf2m_SQR0(v[7]);
   139 	u[13] = gf2m_SQR1(v[6]);
   140 	u[12] = gf2m_SQR0(v[6]);
   141 	u[11] = gf2m_SQR1(v[5]);
   142 	u[10] = gf2m_SQR0(v[5]);
   143 	u[9] = gf2m_SQR1(v[4]);
   144 	u[8] = gf2m_SQR0(v[4]);
   145 #endif
   146 	u[7] = gf2m_SQR1(v[3]);
   147 	u[6] = gf2m_SQR0(v[3]);
   148 	u[5] = gf2m_SQR1(v[2]);
   149 	u[4] = gf2m_SQR0(v[2]);
   150 	u[3] = gf2m_SQR1(v[1]);
   151 	u[2] = gf2m_SQR0(v[1]);
   152 	u[1] = gf2m_SQR1(v[0]);
   153 	u[0] = gf2m_SQR0(v[0]);
   154 	return ec_GF2m_233_mod(r, r, meth);
   156   CLEANUP:
   157 	return res;
   158 }
   160 /* Fast multiplication for polynomials over a 233-bit curve. Assumes
   161  * reduction polynomial with terms {233, 74, 0}. */
   162 mp_err
   163 ec_GF2m_233_mul(const mp_int *a, const mp_int *b, mp_int *r,
   164 				const GFMethod *meth)
   165 {
   166 	mp_err res = MP_OKAY;
   167 	mp_digit a3 = 0, a2 = 0, a1 = 0, a0, b3 = 0, b2 = 0, b1 = 0, b0;
   169 #ifdef ECL_THIRTY_TWO_BIT
   170 	mp_digit a7 = 0, a6 = 0, a5 = 0, a4 = 0, b7 = 0, b6 = 0, b5 = 0, b4 =
   171 		0;
   172 	mp_digit rm[8];
   173 #endif
   175 	if (a == b) {
   176 		return ec_GF2m_233_sqr(a, r, meth);
   177 	} else {
   178 		switch (MP_USED(a)) {
   179 #ifdef ECL_THIRTY_TWO_BIT
   180 		case 8:
   181 			a7 = MP_DIGIT(a, 7);
   182 		case 7:
   183 			a6 = MP_DIGIT(a, 6);
   184 		case 6:
   185 			a5 = MP_DIGIT(a, 5);
   186 		case 5:
   187 			a4 = MP_DIGIT(a, 4);
   188 #endif
   189 		case 4:
   190 			a3 = MP_DIGIT(a, 3);
   191 		case 3:
   192 			a2 = MP_DIGIT(a, 2);
   193 		case 2:
   194 			a1 = MP_DIGIT(a, 1);
   195 		default:
   196 			a0 = MP_DIGIT(a, 0);
   197 		}
   198 		switch (MP_USED(b)) {
   199 #ifdef ECL_THIRTY_TWO_BIT
   200 		case 8:
   201 			b7 = MP_DIGIT(b, 7);
   202 		case 7:
   203 			b6 = MP_DIGIT(b, 6);
   204 		case 6:
   205 			b5 = MP_DIGIT(b, 5);
   206 		case 5:
   207 			b4 = MP_DIGIT(b, 4);
   208 #endif
   209 		case 4:
   210 			b3 = MP_DIGIT(b, 3);
   211 		case 3:
   212 			b2 = MP_DIGIT(b, 2);
   213 		case 2:
   214 			b1 = MP_DIGIT(b, 1);
   215 		default:
   216 			b0 = MP_DIGIT(b, 0);
   217 		}
   218 #ifdef ECL_SIXTY_FOUR_BIT
   219 		MP_CHECKOK(s_mp_pad(r, 8));
   220 		s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
   221 		MP_USED(r) = 8;
   222 		s_mp_clamp(r);
   223 #else
   224 		MP_CHECKOK(s_mp_pad(r, 16));
   225 		s_bmul_4x4(MP_DIGITS(r) + 8, a7, a6, a5, a4, b7, b6, b5, b4);
   226 		s_bmul_4x4(MP_DIGITS(r), a3, a2, a1, a0, b3, b2, b1, b0);
   227 		s_bmul_4x4(rm, a7 ^ a3, a6 ^ a2, a5 ^ a1, a4 ^ a0, b7 ^ b3,
   228 				   b6 ^ b2, b5 ^ b1, b4 ^ b0);
   229 		rm[7] ^= MP_DIGIT(r, 7) ^ MP_DIGIT(r, 15);
   230 		rm[6] ^= MP_DIGIT(r, 6) ^ MP_DIGIT(r, 14);
   231 		rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 13);
   232 		rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 12);
   233 		rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 11);
   234 		rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 10);
   235 		rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 9);
   236 		rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 8);
   237 		MP_DIGIT(r, 11) ^= rm[7];
   238 		MP_DIGIT(r, 10) ^= rm[6];
   239 		MP_DIGIT(r, 9) ^= rm[5];
   240 		MP_DIGIT(r, 8) ^= rm[4];
   241 		MP_DIGIT(r, 7) ^= rm[3];
   242 		MP_DIGIT(r, 6) ^= rm[2];
   243 		MP_DIGIT(r, 5) ^= rm[1];
   244 		MP_DIGIT(r, 4) ^= rm[0];
   245 		MP_USED(r) = 16;
   246 		s_mp_clamp(r);
   247 #endif
   248 		return ec_GF2m_233_mod(r, r, meth);
   249 	}
   251   CLEANUP:
   252 	return res;
   253 }
   255 /* Wire in fast field arithmetic for 233-bit curves. */
   256 mp_err
   257 ec_group_set_gf2m233(ECGroup *group, ECCurveName name)
   258 {
   259 	group->meth->field_mod = &ec_GF2m_233_mod;
   260 	group->meth->field_mul = &ec_GF2m_233_mul;
   261 	group->meth->field_sqr = &ec_GF2m_233_sqr;
   262 	return MP_OKAY;
   263 }

mercurial