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

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:7e0a7b28c5cf
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 "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>
11
12 /* Fast reduction for polynomials over a 163-bit curve. Assumes reduction
13 * polynomial with terms {163, 7, 6, 3, 0}. */
14 mp_err
15 ec_GF2m_163_mod(const mp_int *a, mp_int *r, const GFMethod *meth)
16 {
17 mp_err res = MP_OKAY;
18 mp_digit *u, z;
19
20 if (a != r) {
21 MP_CHECKOK(mp_copy(a, r));
22 }
23 #ifdef ECL_SIXTY_FOUR_BIT
24 if (MP_USED(r) < 6) {
25 MP_CHECKOK(s_mp_pad(r, 6));
26 }
27 u = MP_DIGITS(r);
28 MP_USED(r) = 6;
29
30 /* u[5] only has 6 significant bits */
31 z = u[5];
32 u[2] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
33 z = u[4];
34 u[2] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
35 u[1] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
36 z = u[3];
37 u[1] ^= (z >> 28) ^ (z >> 29) ^ (z >> 32) ^ (z >> 35);
38 u[0] ^= (z << 36) ^ (z << 35) ^ (z << 32) ^ (z << 29);
39 z = u[2] >> 35; /* z only has 29 significant bits */
40 u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
41 /* clear bits above 163 */
42 u[5] = u[4] = u[3] = 0;
43 u[2] ^= z << 35;
44 #else
45 if (MP_USED(r) < 11) {
46 MP_CHECKOK(s_mp_pad(r, 11));
47 }
48 u = MP_DIGITS(r);
49 MP_USED(r) = 11;
50
51 /* u[11] only has 6 significant bits */
52 z = u[10];
53 u[5] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
54 u[4] ^= (z << 29);
55 z = u[9];
56 u[5] ^= (z >> 28) ^ (z >> 29);
57 u[4] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
58 u[3] ^= (z << 29);
59 z = u[8];
60 u[4] ^= (z >> 28) ^ (z >> 29);
61 u[3] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
62 u[2] ^= (z << 29);
63 z = u[7];
64 u[3] ^= (z >> 28) ^ (z >> 29);
65 u[2] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
66 u[1] ^= (z << 29);
67 z = u[6];
68 u[2] ^= (z >> 28) ^ (z >> 29);
69 u[1] ^= (z << 4) ^ (z << 3) ^ z ^ (z >> 3);
70 u[0] ^= (z << 29);
71 z = u[5] >> 3; /* z only has 29 significant bits */
72 u[1] ^= (z >> 25) ^ (z >> 26);
73 u[0] ^= (z << 7) ^ (z << 6) ^ (z << 3) ^ z;
74 /* clear bits above 163 */
75 u[11] = u[10] = u[9] = u[8] = u[7] = u[6] = 0;
76 u[5] ^= z << 3;
77 #endif
78 s_mp_clamp(r);
79
80 CLEANUP:
81 return res;
82 }
83
84 /* Fast squaring for polynomials over a 163-bit curve. Assumes reduction
85 * polynomial with terms {163, 7, 6, 3, 0}. */
86 mp_err
87 ec_GF2m_163_sqr(const mp_int *a, mp_int *r, const GFMethod *meth)
88 {
89 mp_err res = MP_OKAY;
90 mp_digit *u, *v;
91
92 v = MP_DIGITS(a);
93
94 #ifdef ECL_SIXTY_FOUR_BIT
95 if (MP_USED(a) < 3) {
96 return mp_bsqrmod(a, meth->irr_arr, r);
97 }
98 if (MP_USED(r) < 6) {
99 MP_CHECKOK(s_mp_pad(r, 6));
100 }
101 MP_USED(r) = 6;
102 #else
103 if (MP_USED(a) < 6) {
104 return mp_bsqrmod(a, meth->irr_arr, r);
105 }
106 if (MP_USED(r) < 12) {
107 MP_CHECKOK(s_mp_pad(r, 12));
108 }
109 MP_USED(r) = 12;
110 #endif
111 u = MP_DIGITS(r);
112
113 #ifdef ECL_THIRTY_TWO_BIT
114 u[11] = gf2m_SQR1(v[5]);
115 u[10] = gf2m_SQR0(v[5]);
116 u[9] = gf2m_SQR1(v[4]);
117 u[8] = gf2m_SQR0(v[4]);
118 u[7] = gf2m_SQR1(v[3]);
119 u[6] = gf2m_SQR0(v[3]);
120 #endif
121 u[5] = gf2m_SQR1(v[2]);
122 u[4] = gf2m_SQR0(v[2]);
123 u[3] = gf2m_SQR1(v[1]);
124 u[2] = gf2m_SQR0(v[1]);
125 u[1] = gf2m_SQR1(v[0]);
126 u[0] = gf2m_SQR0(v[0]);
127 return ec_GF2m_163_mod(r, r, meth);
128
129 CLEANUP:
130 return res;
131 }
132
133 /* Fast multiplication for polynomials over a 163-bit curve. Assumes
134 * reduction polynomial with terms {163, 7, 6, 3, 0}. */
135 mp_err
136 ec_GF2m_163_mul(const mp_int *a, const mp_int *b, mp_int *r,
137 const GFMethod *meth)
138 {
139 mp_err res = MP_OKAY;
140 mp_digit a2 = 0, a1 = 0, a0, b2 = 0, b1 = 0, b0;
141
142 #ifdef ECL_THIRTY_TWO_BIT
143 mp_digit a5 = 0, a4 = 0, a3 = 0, b5 = 0, b4 = 0, b3 = 0;
144 mp_digit rm[6];
145 #endif
146
147 if (a == b) {
148 return ec_GF2m_163_sqr(a, r, meth);
149 } else {
150 switch (MP_USED(a)) {
151 #ifdef ECL_THIRTY_TWO_BIT
152 case 6:
153 a5 = MP_DIGIT(a, 5);
154 case 5:
155 a4 = MP_DIGIT(a, 4);
156 case 4:
157 a3 = MP_DIGIT(a, 3);
158 #endif
159 case 3:
160 a2 = MP_DIGIT(a, 2);
161 case 2:
162 a1 = MP_DIGIT(a, 1);
163 default:
164 a0 = MP_DIGIT(a, 0);
165 }
166 switch (MP_USED(b)) {
167 #ifdef ECL_THIRTY_TWO_BIT
168 case 6:
169 b5 = MP_DIGIT(b, 5);
170 case 5:
171 b4 = MP_DIGIT(b, 4);
172 case 4:
173 b3 = MP_DIGIT(b, 3);
174 #endif
175 case 3:
176 b2 = MP_DIGIT(b, 2);
177 case 2:
178 b1 = MP_DIGIT(b, 1);
179 default:
180 b0 = MP_DIGIT(b, 0);
181 }
182 #ifdef ECL_SIXTY_FOUR_BIT
183 MP_CHECKOK(s_mp_pad(r, 6));
184 s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
185 MP_USED(r) = 6;
186 s_mp_clamp(r);
187 #else
188 MP_CHECKOK(s_mp_pad(r, 12));
189 s_bmul_3x3(MP_DIGITS(r) + 6, a5, a4, a3, b5, b4, b3);
190 s_bmul_3x3(MP_DIGITS(r), a2, a1, a0, b2, b1, b0);
191 s_bmul_3x3(rm, a5 ^ a2, a4 ^ a1, a3 ^ a0, b5 ^ b2, b4 ^ b1,
192 b3 ^ b0);
193 rm[5] ^= MP_DIGIT(r, 5) ^ MP_DIGIT(r, 11);
194 rm[4] ^= MP_DIGIT(r, 4) ^ MP_DIGIT(r, 10);
195 rm[3] ^= MP_DIGIT(r, 3) ^ MP_DIGIT(r, 9);
196 rm[2] ^= MP_DIGIT(r, 2) ^ MP_DIGIT(r, 8);
197 rm[1] ^= MP_DIGIT(r, 1) ^ MP_DIGIT(r, 7);
198 rm[0] ^= MP_DIGIT(r, 0) ^ MP_DIGIT(r, 6);
199 MP_DIGIT(r, 8) ^= rm[5];
200 MP_DIGIT(r, 7) ^= rm[4];
201 MP_DIGIT(r, 6) ^= rm[3];
202 MP_DIGIT(r, 5) ^= rm[2];
203 MP_DIGIT(r, 4) ^= rm[1];
204 MP_DIGIT(r, 3) ^= rm[0];
205 MP_USED(r) = 12;
206 s_mp_clamp(r);
207 #endif
208 return ec_GF2m_163_mod(r, r, meth);
209 }
210
211 CLEANUP:
212 return res;
213 }
214
215 /* Wire in fast field arithmetic for 163-bit curves. */
216 mp_err
217 ec_group_set_gf2m163(ECGroup *group, ECCurveName name)
218 {
219 group->meth->field_mod = &ec_GF2m_163_mod;
220 group->meth->field_mul = &ec_GF2m_163_mul;
221 group->meth->field_sqr = &ec_GF2m_163_sqr;
222 return MP_OKAY;
223 }

mercurial