Mercurial > hg > ucis.core
comparison NaCl/crypto_sign/ed25519.cs @ 73:6aca18ee4ec6
NaCl: improved ed25519 implementation, added simple API for ed25519 and sha512
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sat, 02 Nov 2013 16:01:09 +0100 |
parents | 7e9d1cfcc562 |
children |
comparison
equal
deleted
inserted
replaced
72:b7d981ccd434 | 73:6aca18ee4ec6 |
---|---|
1 using System; | 1 using System; |
2 using System.Text; | 2 using System.Text; |
3 using UCIS.NaCl.crypto_hash; | |
3 | 4 |
4 namespace UCIS.NaCl.crypto_sign { | 5 namespace UCIS.NaCl.crypto_sign { |
5 public static class ed25519 { | 6 public static class ed25519 { |
6 public const int SECRETKEYBYTES = 64; | 7 public const int SECRETKEYBYTES = 64; |
7 public const int PUBLICKEYBYTES = 32; | 8 public const int PUBLICKEYBYTES = 32; |
8 public const int SEEDBYTES = 32; | 9 public const int SEEDBYTES = 32; |
9 public const int BYTES = 64; | 10 public const int BYTES = 64; |
10 | 11 |
11 unsafe struct fe { | 12 unsafe struct fe { |
12 fixed Int32 v[10]; | 13 Int32 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9; |
13 public int this[int index] { | |
14 get { fixed (Int32* vp = v) return vp[index]; } | |
15 set { fixed (Int32* vp = v) vp[index] = value; } | |
16 } | |
17 public override string ToString() { | 14 public override string ToString() { |
18 return String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}", this[0], this[1], this[2], this[3], this[4], this[5], this[6], this[7], this[8], this[9]); | 15 return String.Format("{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}", v0, v1, v2, v3, v4, v5, v6, v7, v8, v9); |
16 } | |
17 public fe(int offset, Int32[] data) { | |
18 v0 = data[offset + 0]; | |
19 v1 = data[offset + 1]; | |
20 v2 = data[offset + 2]; | |
21 v3 = data[offset + 3]; | |
22 v4 = data[offset + 4]; | |
23 v5 = data[offset + 5]; | |
24 v6 = data[offset + 6]; | |
25 v7 = data[offset + 7]; | |
26 v8 = data[offset + 8]; | |
27 v9 = data[offset + 9]; | |
28 } | |
29 public void set_zero() { | |
30 v0 = v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = 0; | |
31 } | |
32 public void set_one() { | |
33 v0 = 1; | |
34 v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = v9 = 0; | |
35 } | |
36 public void cmov(ref fe g, Int32 b) { | |
37 b = -b; | |
38 v0 ^= (v0 ^ g.v0) & b; | |
39 v1 ^= (v1 ^ g.v1) & b; | |
40 v2 ^= (v2 ^ g.v2) & b; | |
41 v3 ^= (v3 ^ g.v3) & b; | |
42 v4 ^= (v4 ^ g.v4) & b; | |
43 v5 ^= (v5 ^ g.v5) & b; | |
44 v6 ^= (v6 ^ g.v6) & b; | |
45 v7 ^= (v7 ^ g.v7) & b; | |
46 v8 ^= (v8 ^ g.v8) & b; | |
47 v9 ^= (v9 ^ g.v9) & b; | |
48 } | |
49 public void neg() { | |
50 v0 = -v0; | |
51 v1 = -v1; | |
52 v2 = -v2; | |
53 v3 = -v3; | |
54 v4 = -v4; | |
55 v5 = -v5; | |
56 v6 = -v6; | |
57 v7 = -v7; | |
58 v8 = -v8; | |
59 v9 = -v9; | |
60 } | |
61 public void add(ref fe g) { | |
62 v0 += g.v0; | |
63 v1 += g.v1; | |
64 v2 += g.v2; | |
65 v3 += g.v3; | |
66 v4 += g.v4; | |
67 v5 += g.v5; | |
68 v6 += g.v6; | |
69 v7 += g.v7; | |
70 v8 += g.v8; | |
71 v9 += g.v9; | |
72 } | |
73 public void sub(ref fe g) { | |
74 v0 -= g.v0; | |
75 v1 -= g.v1; | |
76 v2 -= g.v2; | |
77 v3 -= g.v3; | |
78 v4 -= g.v4; | |
79 v5 -= g.v5; | |
80 v6 -= g.v6; | |
81 v7 -= g.v7; | |
82 v8 -= g.v8; | |
83 v9 -= g.v9; | |
84 } | |
85 public void mul(ref fe g) { | |
86 Int32 f0 = v0; | |
87 Int32 f1 = v1; | |
88 Int32 f2 = v2; | |
89 Int32 f3 = v3; | |
90 Int32 f4 = v4; | |
91 Int32 f5 = v5; | |
92 Int32 f6 = v6; | |
93 Int32 f7 = v7; | |
94 Int32 f8 = v8; | |
95 Int32 f9 = v9; | |
96 Int32 g0 = g.v0; | |
97 Int32 g1 = g.v1; | |
98 Int32 g2 = g.v2; | |
99 Int32 g3 = g.v3; | |
100 Int32 g4 = g.v4; | |
101 Int32 g5 = g.v5; | |
102 Int32 g6 = g.v6; | |
103 Int32 g7 = g.v7; | |
104 Int32 g8 = g.v8; | |
105 Int32 g9 = g.v9; | |
106 Int32 g1_19 = 19 * g1; /* 1.959375*2^29 */ | |
107 Int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ | |
108 Int32 g3_19 = 19 * g3; | |
109 Int32 g4_19 = 19 * g4; | |
110 Int32 g5_19 = 19 * g5; | |
111 Int32 g6_19 = 19 * g6; | |
112 Int32 g7_19 = 19 * g7; | |
113 Int32 g8_19 = 19 * g8; | |
114 Int32 g9_19 = 19 * g9; | |
115 Int32 f1_2 = 2 * f1; | |
116 Int32 f3_2 = 2 * f3; | |
117 Int32 f5_2 = 2 * f5; | |
118 Int32 f7_2 = 2 * f7; | |
119 Int32 f9_2 = 2 * f9; | |
120 Int64 f0g0 = f0 * (Int64)g0; | |
121 Int64 f0g1 = f0 * (Int64)g1; | |
122 Int64 f0g2 = f0 * (Int64)g2; | |
123 Int64 f0g3 = f0 * (Int64)g3; | |
124 Int64 f0g4 = f0 * (Int64)g4; | |
125 Int64 f0g5 = f0 * (Int64)g5; | |
126 Int64 f0g6 = f0 * (Int64)g6; | |
127 Int64 f0g7 = f0 * (Int64)g7; | |
128 Int64 f0g8 = f0 * (Int64)g8; | |
129 Int64 f0g9 = f0 * (Int64)g9; | |
130 Int64 f1g0 = f1 * (Int64)g0; | |
131 Int64 f1g1_2 = f1_2 * (Int64)g1; | |
132 Int64 f1g2 = f1 * (Int64)g2; | |
133 Int64 f1g3_2 = f1_2 * (Int64)g3; | |
134 Int64 f1g4 = f1 * (Int64)g4; | |
135 Int64 f1g5_2 = f1_2 * (Int64)g5; | |
136 Int64 f1g6 = f1 * (Int64)g6; | |
137 Int64 f1g7_2 = f1_2 * (Int64)g7; | |
138 Int64 f1g8 = f1 * (Int64)g8; | |
139 Int64 f1g9_38 = f1_2 * (Int64)g9_19; | |
140 Int64 f2g0 = f2 * (Int64)g0; | |
141 Int64 f2g1 = f2 * (Int64)g1; | |
142 Int64 f2g2 = f2 * (Int64)g2; | |
143 Int64 f2g3 = f2 * (Int64)g3; | |
144 Int64 f2g4 = f2 * (Int64)g4; | |
145 Int64 f2g5 = f2 * (Int64)g5; | |
146 Int64 f2g6 = f2 * (Int64)g6; | |
147 Int64 f2g7 = f2 * (Int64)g7; | |
148 Int64 f2g8_19 = f2 * (Int64)g8_19; | |
149 Int64 f2g9_19 = f2 * (Int64)g9_19; | |
150 Int64 f3g0 = f3 * (Int64)g0; | |
151 Int64 f3g1_2 = f3_2 * (Int64)g1; | |
152 Int64 f3g2 = f3 * (Int64)g2; | |
153 Int64 f3g3_2 = f3_2 * (Int64)g3; | |
154 Int64 f3g4 = f3 * (Int64)g4; | |
155 Int64 f3g5_2 = f3_2 * (Int64)g5; | |
156 Int64 f3g6 = f3 * (Int64)g6; | |
157 Int64 f3g7_38 = f3_2 * (Int64)g7_19; | |
158 Int64 f3g8_19 = f3 * (Int64)g8_19; | |
159 Int64 f3g9_38 = f3_2 * (Int64)g9_19; | |
160 Int64 f4g0 = f4 * (Int64)g0; | |
161 Int64 f4g1 = f4 * (Int64)g1; | |
162 Int64 f4g2 = f4 * (Int64)g2; | |
163 Int64 f4g3 = f4 * (Int64)g3; | |
164 Int64 f4g4 = f4 * (Int64)g4; | |
165 Int64 f4g5 = f4 * (Int64)g5; | |
166 Int64 f4g6_19 = f4 * (Int64)g6_19; | |
167 Int64 f4g7_19 = f4 * (Int64)g7_19; | |
168 Int64 f4g8_19 = f4 * (Int64)g8_19; | |
169 Int64 f4g9_19 = f4 * (Int64)g9_19; | |
170 Int64 f5g0 = f5 * (Int64)g0; | |
171 Int64 f5g1_2 = f5_2 * (Int64)g1; | |
172 Int64 f5g2 = f5 * (Int64)g2; | |
173 Int64 f5g3_2 = f5_2 * (Int64)g3; | |
174 Int64 f5g4 = f5 * (Int64)g4; | |
175 Int64 f5g5_38 = f5_2 * (Int64)g5_19; | |
176 Int64 f5g6_19 = f5 * (Int64)g6_19; | |
177 Int64 f5g7_38 = f5_2 * (Int64)g7_19; | |
178 Int64 f5g8_19 = f5 * (Int64)g8_19; | |
179 Int64 f5g9_38 = f5_2 * (Int64)g9_19; | |
180 Int64 f6g0 = f6 * (Int64)g0; | |
181 Int64 f6g1 = f6 * (Int64)g1; | |
182 Int64 f6g2 = f6 * (Int64)g2; | |
183 Int64 f6g3 = f6 * (Int64)g3; | |
184 Int64 f6g4_19 = f6 * (Int64)g4_19; | |
185 Int64 f6g5_19 = f6 * (Int64)g5_19; | |
186 Int64 f6g6_19 = f6 * (Int64)g6_19; | |
187 Int64 f6g7_19 = f6 * (Int64)g7_19; | |
188 Int64 f6g8_19 = f6 * (Int64)g8_19; | |
189 Int64 f6g9_19 = f6 * (Int64)g9_19; | |
190 Int64 f7g0 = f7 * (Int64)g0; | |
191 Int64 f7g1_2 = f7_2 * (Int64)g1; | |
192 Int64 f7g2 = f7 * (Int64)g2; | |
193 Int64 f7g3_38 = f7_2 * (Int64)g3_19; | |
194 Int64 f7g4_19 = f7 * (Int64)g4_19; | |
195 Int64 f7g5_38 = f7_2 * (Int64)g5_19; | |
196 Int64 f7g6_19 = f7 * (Int64)g6_19; | |
197 Int64 f7g7_38 = f7_2 * (Int64)g7_19; | |
198 Int64 f7g8_19 = f7 * (Int64)g8_19; | |
199 Int64 f7g9_38 = f7_2 * (Int64)g9_19; | |
200 Int64 f8g0 = f8 * (Int64)g0; | |
201 Int64 f8g1 = f8 * (Int64)g1; | |
202 Int64 f8g2_19 = f8 * (Int64)g2_19; | |
203 Int64 f8g3_19 = f8 * (Int64)g3_19; | |
204 Int64 f8g4_19 = f8 * (Int64)g4_19; | |
205 Int64 f8g5_19 = f8 * (Int64)g5_19; | |
206 Int64 f8g6_19 = f8 * (Int64)g6_19; | |
207 Int64 f8g7_19 = f8 * (Int64)g7_19; | |
208 Int64 f8g8_19 = f8 * (Int64)g8_19; | |
209 Int64 f8g9_19 = f8 * (Int64)g9_19; | |
210 Int64 f9g0 = f9 * (Int64)g0; | |
211 Int64 f9g1_38 = f9_2 * (Int64)g1_19; | |
212 Int64 f9g2_19 = f9 * (Int64)g2_19; | |
213 Int64 f9g3_38 = f9_2 * (Int64)g3_19; | |
214 Int64 f9g4_19 = f9 * (Int64)g4_19; | |
215 Int64 f9g5_38 = f9_2 * (Int64)g5_19; | |
216 Int64 f9g6_19 = f9 * (Int64)g6_19; | |
217 Int64 f9g7_38 = f9_2 * (Int64)g7_19; | |
218 Int64 f9g8_19 = f9 * (Int64)g8_19; | |
219 Int64 f9g9_38 = f9_2 * (Int64)g9_19; | |
220 Int64 h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; | |
221 Int64 h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; | |
222 Int64 h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; | |
223 Int64 h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; | |
224 Int64 h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; | |
225 Int64 h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; | |
226 Int64 h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; | |
227 Int64 h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; | |
228 Int64 h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; | |
229 Int64 h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; | |
230 Int64 carry0; | |
231 Int64 carry1; | |
232 Int64 carry2; | |
233 Int64 carry3; | |
234 Int64 carry4; | |
235 Int64 carry5; | |
236 Int64 carry6; | |
237 Int64 carry7; | |
238 Int64 carry8; | |
239 Int64 carry9; | |
240 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
241 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
242 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
243 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
244 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
245 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
246 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
247 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
248 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
249 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
250 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
251 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
252 v0 = (Int32)h0; | |
253 v1 = (Int32)h1; | |
254 v2 = (Int32)h2; | |
255 v3 = (Int32)h3; | |
256 v4 = (Int32)h4; | |
257 v5 = (Int32)h5; | |
258 v6 = (Int32)h6; | |
259 v7 = (Int32)h7; | |
260 v8 = (Int32)h8; | |
261 v9 = (Int32)h9; | |
262 } | |
263 public void sq() { | |
264 Int32 f0 = v0; | |
265 Int32 f1 = v1; | |
266 Int32 f2 = v2; | |
267 Int32 f3 = v3; | |
268 Int32 f4 = v4; | |
269 Int32 f5 = v5; | |
270 Int32 f6 = v6; | |
271 Int32 f7 = v7; | |
272 Int32 f8 = v8; | |
273 Int32 f9 = v9; | |
274 Int32 f0_2 = 2 * f0; | |
275 Int32 f1_2 = 2 * f1; | |
276 Int32 f2_2 = 2 * f2; | |
277 Int32 f3_2 = 2 * f3; | |
278 Int32 f4_2 = 2 * f4; | |
279 Int32 f5_2 = 2 * f5; | |
280 Int32 f6_2 = 2 * f6; | |
281 Int32 f7_2 = 2 * f7; | |
282 Int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ | |
283 Int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ | |
284 Int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ | |
285 Int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ | |
286 Int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ | |
287 Int64 f0f0 = f0 * (Int64)f0; | |
288 Int64 f0f1_2 = f0_2 * (Int64)f1; | |
289 Int64 f0f2_2 = f0_2 * (Int64)f2; | |
290 Int64 f0f3_2 = f0_2 * (Int64)f3; | |
291 Int64 f0f4_2 = f0_2 * (Int64)f4; | |
292 Int64 f0f5_2 = f0_2 * (Int64)f5; | |
293 Int64 f0f6_2 = f0_2 * (Int64)f6; | |
294 Int64 f0f7_2 = f0_2 * (Int64)f7; | |
295 Int64 f0f8_2 = f0_2 * (Int64)f8; | |
296 Int64 f0f9_2 = f0_2 * (Int64)f9; | |
297 Int64 f1f1_2 = f1_2 * (Int64)f1; | |
298 Int64 f1f2_2 = f1_2 * (Int64)f2; | |
299 Int64 f1f3_4 = f1_2 * (Int64)f3_2; | |
300 Int64 f1f4_2 = f1_2 * (Int64)f4; | |
301 Int64 f1f5_4 = f1_2 * (Int64)f5_2; | |
302 Int64 f1f6_2 = f1_2 * (Int64)f6; | |
303 Int64 f1f7_4 = f1_2 * (Int64)f7_2; | |
304 Int64 f1f8_2 = f1_2 * (Int64)f8; | |
305 Int64 f1f9_76 = f1_2 * (Int64)f9_38; | |
306 Int64 f2f2 = f2 * (Int64)f2; | |
307 Int64 f2f3_2 = f2_2 * (Int64)f3; | |
308 Int64 f2f4_2 = f2_2 * (Int64)f4; | |
309 Int64 f2f5_2 = f2_2 * (Int64)f5; | |
310 Int64 f2f6_2 = f2_2 * (Int64)f6; | |
311 Int64 f2f7_2 = f2_2 * (Int64)f7; | |
312 Int64 f2f8_38 = f2_2 * (Int64)f8_19; | |
313 Int64 f2f9_38 = f2 * (Int64)f9_38; | |
314 Int64 f3f3_2 = f3_2 * (Int64)f3; | |
315 Int64 f3f4_2 = f3_2 * (Int64)f4; | |
316 Int64 f3f5_4 = f3_2 * (Int64)f5_2; | |
317 Int64 f3f6_2 = f3_2 * (Int64)f6; | |
318 Int64 f3f7_76 = f3_2 * (Int64)f7_38; | |
319 Int64 f3f8_38 = f3_2 * (Int64)f8_19; | |
320 Int64 f3f9_76 = f3_2 * (Int64)f9_38; | |
321 Int64 f4f4 = f4 * (Int64)f4; | |
322 Int64 f4f5_2 = f4_2 * (Int64)f5; | |
323 Int64 f4f6_38 = f4_2 * (Int64)f6_19; | |
324 Int64 f4f7_38 = f4 * (Int64)f7_38; | |
325 Int64 f4f8_38 = f4_2 * (Int64)f8_19; | |
326 Int64 f4f9_38 = f4 * (Int64)f9_38; | |
327 Int64 f5f5_38 = f5 * (Int64)f5_38; | |
328 Int64 f5f6_38 = f5_2 * (Int64)f6_19; | |
329 Int64 f5f7_76 = f5_2 * (Int64)f7_38; | |
330 Int64 f5f8_38 = f5_2 * (Int64)f8_19; | |
331 Int64 f5f9_76 = f5_2 * (Int64)f9_38; | |
332 Int64 f6f6_19 = f6 * (Int64)f6_19; | |
333 Int64 f6f7_38 = f6 * (Int64)f7_38; | |
334 Int64 f6f8_38 = f6_2 * (Int64)f8_19; | |
335 Int64 f6f9_38 = f6 * (Int64)f9_38; | |
336 Int64 f7f7_38 = f7 * (Int64)f7_38; | |
337 Int64 f7f8_38 = f7_2 * (Int64)f8_19; | |
338 Int64 f7f9_76 = f7_2 * (Int64)f9_38; | |
339 Int64 f8f8_19 = f8 * (Int64)f8_19; | |
340 Int64 f8f9_38 = f8 * (Int64)f9_38; | |
341 Int64 f9f9_38 = f9 * (Int64)f9_38; | |
342 Int64 h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; | |
343 Int64 h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; | |
344 Int64 h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; | |
345 Int64 h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; | |
346 Int64 h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; | |
347 Int64 h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; | |
348 Int64 h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; | |
349 Int64 h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; | |
350 Int64 h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; | |
351 Int64 h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; | |
352 Int64 carry0; | |
353 Int64 carry1; | |
354 Int64 carry2; | |
355 Int64 carry3; | |
356 Int64 carry4; | |
357 Int64 carry5; | |
358 Int64 carry6; | |
359 Int64 carry7; | |
360 Int64 carry8; | |
361 Int64 carry9; | |
362 | |
363 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
364 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
365 | |
366 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
367 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
368 | |
369 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
370 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
371 | |
372 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
373 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
374 | |
375 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
376 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
377 | |
378 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
379 | |
380 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
381 | |
382 v0 = (Int32)h0; | |
383 v1 = (Int32)h1; | |
384 v2 = (Int32)h2; | |
385 v3 = (Int32)h3; | |
386 v4 = (Int32)h4; | |
387 v5 = (Int32)h5; | |
388 v6 = (Int32)h6; | |
389 v7 = (Int32)h7; | |
390 v8 = (Int32)h8; | |
391 v9 = (Int32)h9; | |
392 } | |
393 public void sq2() { | |
394 Int32 f0 = v0; | |
395 Int32 f1 = v1; | |
396 Int32 f2 = v2; | |
397 Int32 f3 = v3; | |
398 Int32 f4 = v4; | |
399 Int32 f5 = v5; | |
400 Int32 f6 = v6; | |
401 Int32 f7 = v7; | |
402 Int32 f8 = v8; | |
403 Int32 f9 = v9; | |
404 Int32 f0_2 = 2 * f0; | |
405 Int32 f1_2 = 2 * f1; | |
406 Int32 f2_2 = 2 * f2; | |
407 Int32 f3_2 = 2 * f3; | |
408 Int32 f4_2 = 2 * f4; | |
409 Int32 f5_2 = 2 * f5; | |
410 Int32 f6_2 = 2 * f6; | |
411 Int32 f7_2 = 2 * f7; | |
412 Int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ | |
413 Int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ | |
414 Int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ | |
415 Int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ | |
416 Int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ | |
417 Int64 f0f0 = f0 * (Int64)f0; | |
418 Int64 f0f1_2 = f0_2 * (Int64)f1; | |
419 Int64 f0f2_2 = f0_2 * (Int64)f2; | |
420 Int64 f0f3_2 = f0_2 * (Int64)f3; | |
421 Int64 f0f4_2 = f0_2 * (Int64)f4; | |
422 Int64 f0f5_2 = f0_2 * (Int64)f5; | |
423 Int64 f0f6_2 = f0_2 * (Int64)f6; | |
424 Int64 f0f7_2 = f0_2 * (Int64)f7; | |
425 Int64 f0f8_2 = f0_2 * (Int64)f8; | |
426 Int64 f0f9_2 = f0_2 * (Int64)f9; | |
427 Int64 f1f1_2 = f1_2 * (Int64)f1; | |
428 Int64 f1f2_2 = f1_2 * (Int64)f2; | |
429 Int64 f1f3_4 = f1_2 * (Int64)f3_2; | |
430 Int64 f1f4_2 = f1_2 * (Int64)f4; | |
431 Int64 f1f5_4 = f1_2 * (Int64)f5_2; | |
432 Int64 f1f6_2 = f1_2 * (Int64)f6; | |
433 Int64 f1f7_4 = f1_2 * (Int64)f7_2; | |
434 Int64 f1f8_2 = f1_2 * (Int64)f8; | |
435 Int64 f1f9_76 = f1_2 * (Int64)f9_38; | |
436 Int64 f2f2 = f2 * (Int64)f2; | |
437 Int64 f2f3_2 = f2_2 * (Int64)f3; | |
438 Int64 f2f4_2 = f2_2 * (Int64)f4; | |
439 Int64 f2f5_2 = f2_2 * (Int64)f5; | |
440 Int64 f2f6_2 = f2_2 * (Int64)f6; | |
441 Int64 f2f7_2 = f2_2 * (Int64)f7; | |
442 Int64 f2f8_38 = f2_2 * (Int64)f8_19; | |
443 Int64 f2f9_38 = f2 * (Int64)f9_38; | |
444 Int64 f3f3_2 = f3_2 * (Int64)f3; | |
445 Int64 f3f4_2 = f3_2 * (Int64)f4; | |
446 Int64 f3f5_4 = f3_2 * (Int64)f5_2; | |
447 Int64 f3f6_2 = f3_2 * (Int64)f6; | |
448 Int64 f3f7_76 = f3_2 * (Int64)f7_38; | |
449 Int64 f3f8_38 = f3_2 * (Int64)f8_19; | |
450 Int64 f3f9_76 = f3_2 * (Int64)f9_38; | |
451 Int64 f4f4 = f4 * (Int64)f4; | |
452 Int64 f4f5_2 = f4_2 * (Int64)f5; | |
453 Int64 f4f6_38 = f4_2 * (Int64)f6_19; | |
454 Int64 f4f7_38 = f4 * (Int64)f7_38; | |
455 Int64 f4f8_38 = f4_2 * (Int64)f8_19; | |
456 Int64 f4f9_38 = f4 * (Int64)f9_38; | |
457 Int64 f5f5_38 = f5 * (Int64)f5_38; | |
458 Int64 f5f6_38 = f5_2 * (Int64)f6_19; | |
459 Int64 f5f7_76 = f5_2 * (Int64)f7_38; | |
460 Int64 f5f8_38 = f5_2 * (Int64)f8_19; | |
461 Int64 f5f9_76 = f5_2 * (Int64)f9_38; | |
462 Int64 f6f6_19 = f6 * (Int64)f6_19; | |
463 Int64 f6f7_38 = f6 * (Int64)f7_38; | |
464 Int64 f6f8_38 = f6_2 * (Int64)f8_19; | |
465 Int64 f6f9_38 = f6 * (Int64)f9_38; | |
466 Int64 f7f7_38 = f7 * (Int64)f7_38; | |
467 Int64 f7f8_38 = f7_2 * (Int64)f8_19; | |
468 Int64 f7f9_76 = f7_2 * (Int64)f9_38; | |
469 Int64 f8f8_19 = f8 * (Int64)f8_19; | |
470 Int64 f8f9_38 = f8 * (Int64)f9_38; | |
471 Int64 f9f9_38 = f9 * (Int64)f9_38; | |
472 Int64 h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; | |
473 Int64 h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; | |
474 Int64 h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; | |
475 Int64 h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; | |
476 Int64 h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; | |
477 Int64 h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; | |
478 Int64 h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; | |
479 Int64 h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; | |
480 Int64 h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; | |
481 Int64 h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; | |
482 Int64 carry0; | |
483 Int64 carry1; | |
484 Int64 carry2; | |
485 Int64 carry3; | |
486 Int64 carry4; | |
487 Int64 carry5; | |
488 Int64 carry6; | |
489 Int64 carry7; | |
490 Int64 carry8; | |
491 Int64 carry9; | |
492 | |
493 h0 += h0; | |
494 h1 += h1; | |
495 h2 += h2; | |
496 h3 += h3; | |
497 h4 += h4; | |
498 h5 += h5; | |
499 h6 += h6; | |
500 h7 += h7; | |
501 h8 += h8; | |
502 h9 += h9; | |
503 | |
504 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
505 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
506 | |
507 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
508 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
509 | |
510 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
511 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
512 | |
513 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
514 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
515 | |
516 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
517 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
518 | |
519 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
520 | |
521 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
522 | |
523 v0 = (Int32)h0; | |
524 v1 = (Int32)h1; | |
525 v2 = (Int32)h2; | |
526 v3 = (Int32)h3; | |
527 v4 = (Int32)h4; | |
528 v5 = (Int32)h5; | |
529 v6 = (Int32)h6; | |
530 v7 = (Int32)h7; | |
531 v8 = (Int32)h8; | |
532 v9 = (Int32)h9; | |
533 } | |
534 public void invert() { | |
535 fe t0 = this; | |
536 t0.sq(); | |
537 fe t1 = t0; | |
538 t1.sq(); | |
539 t1.sq(); | |
540 mul(ref t1); | |
541 t0.mul(ref this); | |
542 fe t2 = t0; | |
543 t2.sq(); | |
544 mul(ref t2); | |
545 t1 = this; | |
546 for (int i = 1; i < 6; i++) sq(); | |
547 mul(ref t1); | |
548 t1 = this; | |
549 for (int i = 1; i < 11; i++) sq(); | |
550 mul(ref t1); | |
551 t2 = this; | |
552 for (int i = 1; i < 21; i++) sq(); | |
553 mul(ref t2); | |
554 for (int i = 1; i < 11; ++i) sq(); | |
555 this.mul(ref t1); | |
556 t1 = this; | |
557 for (int i = 1; i < 51; i++) sq(); | |
558 mul(ref t1); | |
559 t2 = this; | |
560 for (int i = 1; i < 101; i++) sq(); | |
561 mul(ref t2); | |
562 for (int i = 1; i < 51; i++) sq(); | |
563 mul(ref t1); | |
564 for (int i = 1; i < 6; i++) sq(); | |
565 mul(ref t0); | |
566 } | |
567 public unsafe void tobytes(Byte* s) { | |
568 Int32 h0 = v0, h1 = v1, h2 = v2, h3 = v3, h4 = v4, h5 = v5, h6 = v6, h7 = v7, h8 = v8, h9 = v9; | |
569 Int32 q = (19 * h9 + (((Int32)1) << 24)) >> 25; | |
570 q = (h0 + q) >> 26; | |
571 q = (h1 + q) >> 25; | |
572 q = (h2 + q) >> 26; | |
573 q = (h3 + q) >> 25; | |
574 q = (h4 + q) >> 26; | |
575 q = (h5 + q) >> 25; | |
576 q = (h6 + q) >> 26; | |
577 q = (h7 + q) >> 25; | |
578 q = (h8 + q) >> 26; | |
579 q = (h9 + q) >> 25; | |
580 h0 += 19 * q; | |
581 Int32 carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; | |
582 Int32 carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; | |
583 Int32 carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; | |
584 Int32 carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; | |
585 Int32 carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; | |
586 Int32 carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; | |
587 Int32 carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; | |
588 Int32 carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; | |
589 Int32 carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; | |
590 Int32 carry9 = h9 >> 25; h9 -= carry9 << 25; | |
591 s[0] = (Byte)(h0 >> 0); | |
592 s[1] = (Byte)(h0 >> 8); | |
593 s[2] = (Byte)(h0 >> 16); | |
594 s[3] = (Byte)((h0 >> 24) | (h1 << 2)); | |
595 s[4] = (Byte)(h1 >> 6); | |
596 s[5] = (Byte)(h1 >> 14); | |
597 s[6] = (Byte)((h1 >> 22) | (h2 << 3)); | |
598 s[7] = (Byte)(h2 >> 5); | |
599 s[8] = (Byte)(h2 >> 13); | |
600 s[9] = (Byte)((h2 >> 21) | (h3 << 5)); | |
601 s[10] = (Byte)(h3 >> 3); | |
602 s[11] = (Byte)(h3 >> 11); | |
603 s[12] = (Byte)((h3 >> 19) | (h4 << 6)); | |
604 s[13] = (Byte)(h4 >> 2); | |
605 s[14] = (Byte)(h4 >> 10); | |
606 s[15] = (Byte)(h4 >> 18); | |
607 s[16] = (Byte)(h5 >> 0); | |
608 s[17] = (Byte)(h5 >> 8); | |
609 s[18] = (Byte)(h5 >> 16); | |
610 s[19] = (Byte)((h5 >> 24) | (h6 << 1)); | |
611 s[20] = (Byte)(h6 >> 7); | |
612 s[21] = (Byte)(h6 >> 15); | |
613 s[22] = (Byte)((h6 >> 23) | (h7 << 3)); | |
614 s[23] = (Byte)(h7 >> 5); | |
615 s[24] = (Byte)(h7 >> 13); | |
616 s[25] = (Byte)((h7 >> 21) | (h8 << 4)); | |
617 s[26] = (Byte)(h8 >> 4); | |
618 s[27] = (Byte)(h8 >> 12); | |
619 s[28] = (Byte)((h8 >> 20) | (h9 << 6)); | |
620 s[29] = (Byte)(h9 >> 2); | |
621 s[30] = (Byte)(h9 >> 10); | |
622 s[31] = (Byte)(h9 >> 18); | |
623 } | |
624 public int isnegative() { | |
625 Int32 h0 = v0, h9 = v9; | |
626 Int32 q = (19 * h9 + (1 << 24)) >> 25; | |
627 q = (h0 + q) >> 26; | |
628 q = (v1 + q) >> 25; | |
629 q = (v2 + q) >> 26; | |
630 q = (v3 + q) >> 25; | |
631 q = (v4 + q) >> 26; | |
632 q = (v5 + q) >> 25; | |
633 q = (v6 + q) >> 26; | |
634 q = (v7 + q) >> 25; | |
635 q = (v8 + q) >> 26; | |
636 q = (h9 + q) >> 25; | |
637 h0 += 19 * q; | |
638 h0 -= (h0 >> 26) << 26; | |
639 return (h0 >> 0) & 1; | |
640 } | |
641 public unsafe void frombytes(Byte* s) { | |
642 Int64 h0 = load_4(s); | |
643 Int64 h1 = load_3(s + 4) << 6; | |
644 Int64 h2 = load_3(s + 7) << 5; | |
645 Int64 h3 = load_3(s + 10) << 3; | |
646 Int64 h4 = load_3(s + 13) << 2; | |
647 Int64 h5 = load_4(s + 16); | |
648 Int64 h6 = load_3(s + 20) << 7; | |
649 Int64 h7 = load_3(s + 23) << 5; | |
650 Int64 h8 = load_3(s + 26) << 4; | |
651 Int64 h9 = (load_3(s + 29) & 8388607) << 2; | |
652 | |
653 Int64 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
654 Int64 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
655 Int64 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
656 Int64 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
657 Int64 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
658 | |
659 Int64 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
660 Int64 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
661 Int64 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
662 Int64 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
663 Int64 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
664 | |
665 v0 = (Int32)h0; | |
666 v1 = (Int32)h1; | |
667 v2 = (Int32)h2; | |
668 v3 = (Int32)h3; | |
669 v4 = (Int32)h4; | |
670 v5 = (Int32)h5; | |
671 v6 = (Int32)h6; | |
672 v7 = (Int32)h7; | |
673 v8 = (Int32)h8; | |
674 v9 = (Int32)h9; | |
675 } | |
676 public int isnonzero() { | |
677 Int32 h0 = v0, h1 = v1, h2 = v2, h3 = v3, h4 = v4, h5 = v5, h6 = v6, h7 = v7, h8 = v8, h9 = v9; | |
678 Int32 q = (19 * h9 + (((Int32)1) << 24)) >> 25; | |
679 q = (h0 + q) >> 26; | |
680 q = (h1 + q) >> 25; | |
681 q = (h2 + q) >> 26; | |
682 q = (h3 + q) >> 25; | |
683 q = (h4 + q) >> 26; | |
684 q = (h5 + q) >> 25; | |
685 q = (h6 + q) >> 26; | |
686 q = (h7 + q) >> 25; | |
687 q = (h8 + q) >> 26; | |
688 q = (h9 + q) >> 25; | |
689 h0 += 19 * q; | |
690 Int32 carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; | |
691 Int32 carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; | |
692 Int32 carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; | |
693 Int32 carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; | |
694 Int32 carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; | |
695 Int32 carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; | |
696 Int32 carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; | |
697 Int32 carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; | |
698 Int32 carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; | |
699 Int32 carry9 = h9 >> 25; h9 -= carry9 << 25; | |
700 Int32 b = h0 | h1 | h2 | h3 | h4 | h5 | h6 | h7 | h8 | h9; | |
701 b = (b | (b >> 8) | (b >> 16) | (b >> 24)) & 0xff; | |
702 return (1 & ((b - 1) >> 8)) - 1; | |
703 } | |
704 public void pow22523() { | |
705 fe t0 = this; | |
706 t0.sq(); | |
707 fe t1 = t0; | |
708 for (int i = 1; i < 3; i++) t1.sq(); | |
709 fe t2 = this; | |
710 mul(ref t1); | |
711 t0.mul(ref this); | |
712 t0.sq(); | |
713 mul(ref t0); | |
714 t0 = this; | |
715 for (int i = 1; i < 6; i++) sq(); | |
716 mul(ref t0); | |
717 t0 = this; | |
718 for (int i = 1; i < 11; i++) sq(); | |
719 mul(ref t0); | |
720 t1 = this; | |
721 for (int i = 1; i < 21; i++) sq(); | |
722 mul(ref t1); | |
723 for (int i = 1; i < 11; i++) sq(); | |
724 mul(ref t0); | |
725 t0 = this; | |
726 for (int i = 1; i < 51; i++) sq(); | |
727 mul(ref t0); | |
728 t1 = this; | |
729 for (int i = 1; i < 101; i++) sq(); | |
730 mul(ref t1); | |
731 for (int i = 1; i < 51; i++) sq(); | |
732 mul(ref t0); | |
733 for (int i = 1; i < 3; i++) sq(); | |
734 mul(ref t2); | |
19 } | 735 } |
20 } | 736 } |
21 struct ge_precomp { | 737 struct ge_precomp { |
22 public fe yplusx; | 738 public fe yplusx; |
23 public fe yminusx; | 739 public fe yminusx; |
24 public fe xy2d; | 740 public fe xy2d; |
25 public ge_precomp(Int32[] data, int offset) | 741 public ge_precomp(Int32[] data, int offset) |
26 : this() { | 742 : this() { |
27 yplusx = fe_unpack(offset + 0 * 10, data); | 743 yplusx = new fe(offset + 0 * 10, data); |
28 yminusx = fe_unpack(offset + 1 * 10, data); | 744 yminusx = new fe(offset + 1 * 10, data); |
29 xy2d = fe_unpack(offset + 2 * 10, data); | 745 xy2d = new fe(offset + 2 * 10, data); |
746 } | |
747 public void set_zero() { | |
748 yplusx.set_one(); | |
749 yminusx.set_one(); | |
750 xy2d.set_zero(); | |
751 } | |
752 public void cmov(ref ge_precomp u, Byte b) { | |
753 yplusx.cmov(ref u.yplusx, b); | |
754 yminusx.cmov(ref u.yminusx, b); | |
755 xy2d.cmov(ref u.xy2d, b); | |
30 } | 756 } |
31 } | 757 } |
32 struct ge_p1p1 { | 758 struct ge_p1p1 { |
33 public fe X; | 759 public fe X; |
34 public fe Y; | 760 public fe Y; |
37 } | 763 } |
38 struct ge_p2 { | 764 struct ge_p2 { |
39 public fe X; | 765 public fe X; |
40 public fe Y; | 766 public fe Y; |
41 public fe Z; | 767 public fe Z; |
768 public void set_zero() { | |
769 X.set_zero(); | |
770 Y.set_one(); | |
771 Z.set_one(); | |
772 } | |
42 } | 773 } |
43 struct ge_p3 { | 774 struct ge_p3 { |
44 public fe X; | 775 public fe X; |
45 public fe Y; | 776 public fe Y; |
46 public fe Z; | 777 public fe Z; |
47 public fe T; | 778 public fe T; |
48 } | 779 public void set_zero() { |
49 | 780 X.set_zero(); |
50 static fe fe_unpack(int offset, Int32[] data) { | 781 Y.set_one(); |
51 fe ret = new fe(); | 782 Z.set_one(); |
52 for (int i = 0; i < 10; i++) ret[i] = data[offset + i]; | 783 T.set_zero(); |
784 } | |
785 } | |
786 struct ge_cached { | |
787 public fe YplusX; | |
788 public fe YminusX; | |
789 public fe Z; | |
790 public fe T2d; | |
791 } | |
792 | |
793 static ge_precomp[] base_unpack(int n, Int32[] data) { | |
794 ge_precomp[] ret = new ge_precomp[n]; | |
795 for (int i = 0; i < n; i++) ret[i] = new ge_precomp(data, i * 3 * 10); | |
53 return ret; | 796 return ret; |
54 } | 797 } |
55 static ge_precomp[] base_unpack(int n, int offset, Int32[] data) { | 798 static ge_precomp[] basev = base_unpack(32 * 8, |
56 ge_precomp[] ret = new ge_precomp[n]; | |
57 for (int i = 0; i < n; i++) ret[i] = new ge_precomp(data, offset + i * 3 * 10); | |
58 return ret; | |
59 } | |
60 static ge_precomp[][] base_unpack_a(int a, int b, Int32[] data) { | |
61 ge_precomp[][] ret = new ge_precomp[a][]; | |
62 for (int i = 0; i < a; i++) ret[i] = base_unpack(b, i * b * 3 * 10, data); | |
63 return ret; | |
64 } | |
65 static ge_precomp[][] basev = base_unpack_a(32, 8, | |
66 new Int32[32 * 8 * 3 * 10] { | 799 new Int32[32 * 8 * 3 * 10] { |
67 #region base point data | 800 #region base point data |
68 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605, | 801 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605, |
69 -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378, | 802 -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378, |
70 -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546, | 803 -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546, |
834 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684, | 1567 29701166,-14373934,-10878120,9279288,-17568,13127210,21382910,11042292,25838796,4642684, |
835 -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476, | 1568 -20430234,14955537,-24126347,8124619,-5369288,-5990470,30468147,-13900640,18423289,4177476, |
836 #endregion | 1569 #endregion |
837 }); | 1570 }); |
838 | 1571 |
839 static void fe_0(out fe h) { | |
840 h = new fe(); | |
841 h[0] = 0; | |
842 h[1] = 0; | |
843 h[2] = 0; | |
844 h[3] = 0; | |
845 h[4] = 0; | |
846 h[5] = 0; | |
847 h[6] = 0; | |
848 h[7] = 0; | |
849 h[8] = 0; | |
850 h[9] = 0; | |
851 } | |
852 static void fe_1(out fe h) { | |
853 h = new fe(); | |
854 h[0] = 1; | |
855 h[1] = 0; | |
856 h[2] = 0; | |
857 h[3] = 0; | |
858 h[4] = 0; | |
859 h[5] = 0; | |
860 h[6] = 0; | |
861 h[7] = 0; | |
862 h[8] = 0; | |
863 h[9] = 0; | |
864 } | |
865 static void ge_p3_0(out ge_p3 h) { | |
866 fe_0(out h.X); | |
867 fe_1(out h.Y); | |
868 fe_1(out h.Z); | |
869 fe_0(out h.T); | |
870 } | |
871 static Byte negative(SByte b) { | 1572 static Byte negative(SByte b) { |
872 UInt64 x = (UInt64)(Int64)b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ | 1573 UInt64 x = (UInt64)(Int64)b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ |
873 x >>= 63; /* 1: yes; 0: no */ | 1574 x >>= 63; /* 1: yes; 0: no */ |
874 return (Byte)x; | 1575 return (Byte)x; |
875 } | 1576 } |
876 static void ge_precomp_0(out ge_precomp h) { | 1577 static Byte equal(Byte b, Byte c) { |
877 fe_1(out h.yplusx); | 1578 UInt32 y = (UInt32)(b ^ c); /* 0: yes; 1..255: no */ |
878 fe_1(out h.yminusx); | |
879 fe_0(out h.xy2d); | |
880 } | |
881 static void fe_cmov(ref fe f, ref fe g, Int32 b) { | |
882 Int32 f0 = f[0]; | |
883 Int32 f1 = f[1]; | |
884 Int32 f2 = f[2]; | |
885 Int32 f3 = f[3]; | |
886 Int32 f4 = f[4]; | |
887 Int32 f5 = f[5]; | |
888 Int32 f6 = f[6]; | |
889 Int32 f7 = f[7]; | |
890 Int32 f8 = f[8]; | |
891 Int32 f9 = f[9]; | |
892 Int32 g0 = g[0]; | |
893 Int32 g1 = g[1]; | |
894 Int32 g2 = g[2]; | |
895 Int32 g3 = g[3]; | |
896 Int32 g4 = g[4]; | |
897 Int32 g5 = g[5]; | |
898 Int32 g6 = g[6]; | |
899 Int32 g7 = g[7]; | |
900 Int32 g8 = g[8]; | |
901 Int32 g9 = g[9]; | |
902 Int32 x0 = f0 ^ g0; | |
903 Int32 x1 = f1 ^ g1; | |
904 Int32 x2 = f2 ^ g2; | |
905 Int32 x3 = f3 ^ g3; | |
906 Int32 x4 = f4 ^ g4; | |
907 Int32 x5 = f5 ^ g5; | |
908 Int32 x6 = f6 ^ g6; | |
909 Int32 x7 = f7 ^ g7; | |
910 Int32 x8 = f8 ^ g8; | |
911 Int32 x9 = f9 ^ g9; | |
912 b = -b; | |
913 x0 &= b; | |
914 x1 &= b; | |
915 x2 &= b; | |
916 x3 &= b; | |
917 x4 &= b; | |
918 x5 &= b; | |
919 x6 &= b; | |
920 x7 &= b; | |
921 x8 &= b; | |
922 x9 &= b; | |
923 f[0] = f0 ^ x0; | |
924 f[1] = f1 ^ x1; | |
925 f[2] = f2 ^ x2; | |
926 f[3] = f3 ^ x3; | |
927 f[4] = f4 ^ x4; | |
928 f[5] = f5 ^ x5; | |
929 f[6] = f6 ^ x6; | |
930 f[7] = f7 ^ x7; | |
931 f[8] = f8 ^ x8; | |
932 f[9] = f9 ^ x9; | |
933 } | |
934 static void cmov(ref ge_precomp t, ref ge_precomp u, Byte b) { | |
935 fe_cmov(ref t.yplusx, ref u.yplusx, b); | |
936 fe_cmov(ref t.yminusx, ref u.yminusx, b); | |
937 fe_cmov(ref t.xy2d, ref u.xy2d, b); | |
938 } | |
939 static Byte equal(Byte b, SByte c) { | |
940 Byte ub = (Byte)b; | |
941 Byte uc = (Byte)c; | |
942 Byte x = (Byte)(ub ^ uc); /* 0: yes; 1..255: no */ | |
943 UInt32 y = x; /* 0: yes; 1..255: no */ | |
944 y -= 1; /* 4294967295: yes; 0..254: no */ | 1579 y -= 1; /* 4294967295: yes; 0..254: no */ |
945 y >>= 31; /* 1: yes; 0: no */ | 1580 y >>= 31; /* 1: yes; 0: no */ |
946 return (Byte)y; | 1581 return (Byte)y; |
947 } | |
948 static void fe_copy(out fe h, ref fe f) { | |
949 Int32 f0 = f[0]; | |
950 Int32 f1 = f[1]; | |
951 Int32 f2 = f[2]; | |
952 Int32 f3 = f[3]; | |
953 Int32 f4 = f[4]; | |
954 Int32 f5 = f[5]; | |
955 Int32 f6 = f[6]; | |
956 Int32 f7 = f[7]; | |
957 Int32 f8 = f[8]; | |
958 Int32 f9 = f[9]; | |
959 h = new fe(); | |
960 h[0] = f0; | |
961 h[1] = f1; | |
962 h[2] = f2; | |
963 h[3] = f3; | |
964 h[4] = f4; | |
965 h[5] = f5; | |
966 h[6] = f6; | |
967 h[7] = f7; | |
968 h[8] = f8; | |
969 h[9] = f9; | |
970 } | |
971 static void fe_neg(out fe h, ref fe f) { | |
972 Int32 f0 = f[0]; | |
973 Int32 f1 = f[1]; | |
974 Int32 f2 = f[2]; | |
975 Int32 f3 = f[3]; | |
976 Int32 f4 = f[4]; | |
977 Int32 f5 = f[5]; | |
978 Int32 f6 = f[6]; | |
979 Int32 f7 = f[7]; | |
980 Int32 f8 = f[8]; | |
981 Int32 f9 = f[9]; | |
982 Int32 h0 = -f0; | |
983 Int32 h1 = -f1; | |
984 Int32 h2 = -f2; | |
985 Int32 h3 = -f3; | |
986 Int32 h4 = -f4; | |
987 Int32 h5 = -f5; | |
988 Int32 h6 = -f6; | |
989 Int32 h7 = -f7; | |
990 Int32 h8 = -f8; | |
991 Int32 h9 = -f9; | |
992 h = new fe(); | |
993 h[0] = h0; | |
994 h[1] = h1; | |
995 h[2] = h2; | |
996 h[3] = h3; | |
997 h[4] = h4; | |
998 h[5] = h5; | |
999 h[6] = h6; | |
1000 h[7] = h7; | |
1001 h[8] = h8; | |
1002 h[9] = h9; | |
1003 } | 1582 } |
1004 static void select(out ge_precomp t, int pos, SByte b) { | 1583 static void select(out ge_precomp t, int pos, SByte b) { |
1005 ge_precomp minust; | 1584 ge_precomp minust; |
1006 Byte bnegative = negative(b); | 1585 Byte bnegative = negative(b); |
1007 Byte babs = (Byte)(b - (((-bnegative) & b) << 1)); | 1586 Byte babs = (Byte)(b - (((-bnegative) & b) << 1)); |
1008 ge_precomp_0(out t); | 1587 t = new ge_precomp(); |
1009 cmov(ref t, ref basev[pos][0], equal(babs, 1)); | 1588 t.set_zero(); |
1010 cmov(ref t, ref basev[pos][1], equal(babs, 2)); | 1589 int basei = pos * 8; |
1011 cmov(ref t, ref basev[pos][2], equal(babs, 3)); | 1590 t.cmov(ref basev[basei + 0], equal(babs, 1)); |
1012 cmov(ref t, ref basev[pos][3], equal(babs, 4)); | 1591 t.cmov(ref basev[basei + 1], equal(babs, 2)); |
1013 cmov(ref t, ref basev[pos][4], equal(babs, 5)); | 1592 t.cmov(ref basev[basei + 2], equal(babs, 3)); |
1014 cmov(ref t, ref basev[pos][5], equal(babs, 6)); | 1593 t.cmov(ref basev[basei + 3], equal(babs, 4)); |
1015 cmov(ref t, ref basev[pos][6], equal(babs, 7)); | 1594 t.cmov(ref basev[basei + 4], equal(babs, 5)); |
1016 cmov(ref t, ref basev[pos][7], equal(babs, 8)); | 1595 t.cmov(ref basev[basei + 5], equal(babs, 6)); |
1017 fe_copy(out minust.yplusx, ref t.yminusx); | 1596 t.cmov(ref basev[basei + 6], equal(babs, 7)); |
1018 fe_copy(out minust.yminusx, ref t.yplusx); | 1597 t.cmov(ref basev[basei + 7], equal(babs, 8)); |
1019 fe_neg(out minust.xy2d, ref t.xy2d); | 1598 minust.yplusx = t.yminusx; |
1020 cmov(ref t, ref minust, bnegative); | 1599 minust.yminusx = t.yplusx; |
1600 minust.xy2d = t.xy2d; minust.xy2d.neg(); | |
1601 t.cmov(ref minust, bnegative); | |
1021 } | 1602 } |
1022 static void fe_add(out fe h, ref fe f, ref fe g) { | 1603 static void fe_add(out fe h, ref fe f, ref fe g) { |
1023 Int32 f0 = f[0]; | 1604 fe r = f; |
1024 Int32 f1 = f[1]; | 1605 r.add(ref g); |
1025 Int32 f2 = f[2]; | 1606 h = r; |
1026 Int32 f3 = f[3]; | |
1027 Int32 f4 = f[4]; | |
1028 Int32 f5 = f[5]; | |
1029 Int32 f6 = f[6]; | |
1030 Int32 f7 = f[7]; | |
1031 Int32 f8 = f[8]; | |
1032 Int32 f9 = f[9]; | |
1033 Int32 g0 = g[0]; | |
1034 Int32 g1 = g[1]; | |
1035 Int32 g2 = g[2]; | |
1036 Int32 g3 = g[3]; | |
1037 Int32 g4 = g[4]; | |
1038 Int32 g5 = g[5]; | |
1039 Int32 g6 = g[6]; | |
1040 Int32 g7 = g[7]; | |
1041 Int32 g8 = g[8]; | |
1042 Int32 g9 = g[9]; | |
1043 Int32 h0 = f0 + g0; | |
1044 Int32 h1 = f1 + g1; | |
1045 Int32 h2 = f2 + g2; | |
1046 Int32 h3 = f3 + g3; | |
1047 Int32 h4 = f4 + g4; | |
1048 Int32 h5 = f5 + g5; | |
1049 Int32 h6 = f6 + g6; | |
1050 Int32 h7 = f7 + g7; | |
1051 Int32 h8 = f8 + g8; | |
1052 Int32 h9 = f9 + g9; | |
1053 h = new fe(); | |
1054 h[0] = h0; | |
1055 h[1] = h1; | |
1056 h[2] = h2; | |
1057 h[3] = h3; | |
1058 h[4] = h4; | |
1059 h[5] = h5; | |
1060 h[6] = h6; | |
1061 h[7] = h7; | |
1062 h[8] = h8; | |
1063 h[9] = h9; | |
1064 } | 1607 } |
1065 static void fe_sub(out fe h, ref fe f, ref fe g) { | 1608 static void fe_sub(out fe h, ref fe f, ref fe g) { |
1066 Int32 f0 = f[0]; | 1609 fe r = f; |
1067 Int32 f1 = f[1]; | 1610 r.sub(ref g); |
1068 Int32 f2 = f[2]; | 1611 h = r; |
1069 Int32 f3 = f[3]; | |
1070 Int32 f4 = f[4]; | |
1071 Int32 f5 = f[5]; | |
1072 Int32 f6 = f[6]; | |
1073 Int32 f7 = f[7]; | |
1074 Int32 f8 = f[8]; | |
1075 Int32 f9 = f[9]; | |
1076 Int32 g0 = g[0]; | |
1077 Int32 g1 = g[1]; | |
1078 Int32 g2 = g[2]; | |
1079 Int32 g3 = g[3]; | |
1080 Int32 g4 = g[4]; | |
1081 Int32 g5 = g[5]; | |
1082 Int32 g6 = g[6]; | |
1083 Int32 g7 = g[7]; | |
1084 Int32 g8 = g[8]; | |
1085 Int32 g9 = g[9]; | |
1086 Int32 h0 = f0 - g0; | |
1087 Int32 h1 = f1 - g1; | |
1088 Int32 h2 = f2 - g2; | |
1089 Int32 h3 = f3 - g3; | |
1090 Int32 h4 = f4 - g4; | |
1091 Int32 h5 = f5 - g5; | |
1092 Int32 h6 = f6 - g6; | |
1093 Int32 h7 = f7 - g7; | |
1094 Int32 h8 = f8 - g8; | |
1095 Int32 h9 = f9 - g9; | |
1096 h = new fe(); | |
1097 h[0] = h0; | |
1098 h[1] = h1; | |
1099 h[2] = h2; | |
1100 h[3] = h3; | |
1101 h[4] = h4; | |
1102 h[5] = h5; | |
1103 h[6] = h6; | |
1104 h[7] = h7; | |
1105 h[8] = h8; | |
1106 h[9] = h9; | |
1107 } | 1612 } |
1108 static void fe_mul(out fe h, ref fe f, ref fe g) { | 1613 static void fe_mul(out fe h, ref fe f, ref fe g) { |
1109 Int32 f0 = f[0]; | 1614 fe r = f; |
1110 Int32 f1 = f[1]; | 1615 r.mul(ref g); |
1111 Int32 f2 = f[2]; | 1616 h = r; |
1112 Int32 f3 = f[3]; | |
1113 Int32 f4 = f[4]; | |
1114 Int32 f5 = f[5]; | |
1115 Int32 f6 = f[6]; | |
1116 Int32 f7 = f[7]; | |
1117 Int32 f8 = f[8]; | |
1118 Int32 f9 = f[9]; | |
1119 Int32 g0 = g[0]; | |
1120 Int32 g1 = g[1]; | |
1121 Int32 g2 = g[2]; | |
1122 Int32 g3 = g[3]; | |
1123 Int32 g4 = g[4]; | |
1124 Int32 g5 = g[5]; | |
1125 Int32 g6 = g[6]; | |
1126 Int32 g7 = g[7]; | |
1127 Int32 g8 = g[8]; | |
1128 Int32 g9 = g[9]; | |
1129 Int32 g1_19 = 19 * g1; /* 1.959375*2^29 */ | |
1130 Int32 g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ | |
1131 Int32 g3_19 = 19 * g3; | |
1132 Int32 g4_19 = 19 * g4; | |
1133 Int32 g5_19 = 19 * g5; | |
1134 Int32 g6_19 = 19 * g6; | |
1135 Int32 g7_19 = 19 * g7; | |
1136 Int32 g8_19 = 19 * g8; | |
1137 Int32 g9_19 = 19 * g9; | |
1138 Int32 f1_2 = 2 * f1; | |
1139 Int32 f3_2 = 2 * f3; | |
1140 Int32 f5_2 = 2 * f5; | |
1141 Int32 f7_2 = 2 * f7; | |
1142 Int32 f9_2 = 2 * f9; | |
1143 Int64 f0g0 = f0 * (Int64)g0; | |
1144 Int64 f0g1 = f0 * (Int64)g1; | |
1145 Int64 f0g2 = f0 * (Int64)g2; | |
1146 Int64 f0g3 = f0 * (Int64)g3; | |
1147 Int64 f0g4 = f0 * (Int64)g4; | |
1148 Int64 f0g5 = f0 * (Int64)g5; | |
1149 Int64 f0g6 = f0 * (Int64)g6; | |
1150 Int64 f0g7 = f0 * (Int64)g7; | |
1151 Int64 f0g8 = f0 * (Int64)g8; | |
1152 Int64 f0g9 = f0 * (Int64)g9; | |
1153 Int64 f1g0 = f1 * (Int64)g0; | |
1154 Int64 f1g1_2 = f1_2 * (Int64)g1; | |
1155 Int64 f1g2 = f1 * (Int64)g2; | |
1156 Int64 f1g3_2 = f1_2 * (Int64)g3; | |
1157 Int64 f1g4 = f1 * (Int64)g4; | |
1158 Int64 f1g5_2 = f1_2 * (Int64)g5; | |
1159 Int64 f1g6 = f1 * (Int64)g6; | |
1160 Int64 f1g7_2 = f1_2 * (Int64)g7; | |
1161 Int64 f1g8 = f1 * (Int64)g8; | |
1162 Int64 f1g9_38 = f1_2 * (Int64)g9_19; | |
1163 Int64 f2g0 = f2 * (Int64)g0; | |
1164 Int64 f2g1 = f2 * (Int64)g1; | |
1165 Int64 f2g2 = f2 * (Int64)g2; | |
1166 Int64 f2g3 = f2 * (Int64)g3; | |
1167 Int64 f2g4 = f2 * (Int64)g4; | |
1168 Int64 f2g5 = f2 * (Int64)g5; | |
1169 Int64 f2g6 = f2 * (Int64)g6; | |
1170 Int64 f2g7 = f2 * (Int64)g7; | |
1171 Int64 f2g8_19 = f2 * (Int64)g8_19; | |
1172 Int64 f2g9_19 = f2 * (Int64)g9_19; | |
1173 Int64 f3g0 = f3 * (Int64)g0; | |
1174 Int64 f3g1_2 = f3_2 * (Int64)g1; | |
1175 Int64 f3g2 = f3 * (Int64)g2; | |
1176 Int64 f3g3_2 = f3_2 * (Int64)g3; | |
1177 Int64 f3g4 = f3 * (Int64)g4; | |
1178 Int64 f3g5_2 = f3_2 * (Int64)g5; | |
1179 Int64 f3g6 = f3 * (Int64)g6; | |
1180 Int64 f3g7_38 = f3_2 * (Int64)g7_19; | |
1181 Int64 f3g8_19 = f3 * (Int64)g8_19; | |
1182 Int64 f3g9_38 = f3_2 * (Int64)g9_19; | |
1183 Int64 f4g0 = f4 * (Int64)g0; | |
1184 Int64 f4g1 = f4 * (Int64)g1; | |
1185 Int64 f4g2 = f4 * (Int64)g2; | |
1186 Int64 f4g3 = f4 * (Int64)g3; | |
1187 Int64 f4g4 = f4 * (Int64)g4; | |
1188 Int64 f4g5 = f4 * (Int64)g5; | |
1189 Int64 f4g6_19 = f4 * (Int64)g6_19; | |
1190 Int64 f4g7_19 = f4 * (Int64)g7_19; | |
1191 Int64 f4g8_19 = f4 * (Int64)g8_19; | |
1192 Int64 f4g9_19 = f4 * (Int64)g9_19; | |
1193 Int64 f5g0 = f5 * (Int64)g0; | |
1194 Int64 f5g1_2 = f5_2 * (Int64)g1; | |
1195 Int64 f5g2 = f5 * (Int64)g2; | |
1196 Int64 f5g3_2 = f5_2 * (Int64)g3; | |
1197 Int64 f5g4 = f5 * (Int64)g4; | |
1198 Int64 f5g5_38 = f5_2 * (Int64)g5_19; | |
1199 Int64 f5g6_19 = f5 * (Int64)g6_19; | |
1200 Int64 f5g7_38 = f5_2 * (Int64)g7_19; | |
1201 Int64 f5g8_19 = f5 * (Int64)g8_19; | |
1202 Int64 f5g9_38 = f5_2 * (Int64)g9_19; | |
1203 Int64 f6g0 = f6 * (Int64)g0; | |
1204 Int64 f6g1 = f6 * (Int64)g1; | |
1205 Int64 f6g2 = f6 * (Int64)g2; | |
1206 Int64 f6g3 = f6 * (Int64)g3; | |
1207 Int64 f6g4_19 = f6 * (Int64)g4_19; | |
1208 Int64 f6g5_19 = f6 * (Int64)g5_19; | |
1209 Int64 f6g6_19 = f6 * (Int64)g6_19; | |
1210 Int64 f6g7_19 = f6 * (Int64)g7_19; | |
1211 Int64 f6g8_19 = f6 * (Int64)g8_19; | |
1212 Int64 f6g9_19 = f6 * (Int64)g9_19; | |
1213 Int64 f7g0 = f7 * (Int64)g0; | |
1214 Int64 f7g1_2 = f7_2 * (Int64)g1; | |
1215 Int64 f7g2 = f7 * (Int64)g2; | |
1216 Int64 f7g3_38 = f7_2 * (Int64)g3_19; | |
1217 Int64 f7g4_19 = f7 * (Int64)g4_19; | |
1218 Int64 f7g5_38 = f7_2 * (Int64)g5_19; | |
1219 Int64 f7g6_19 = f7 * (Int64)g6_19; | |
1220 Int64 f7g7_38 = f7_2 * (Int64)g7_19; | |
1221 Int64 f7g8_19 = f7 * (Int64)g8_19; | |
1222 Int64 f7g9_38 = f7_2 * (Int64)g9_19; | |
1223 Int64 f8g0 = f8 * (Int64)g0; | |
1224 Int64 f8g1 = f8 * (Int64)g1; | |
1225 Int64 f8g2_19 = f8 * (Int64)g2_19; | |
1226 Int64 f8g3_19 = f8 * (Int64)g3_19; | |
1227 Int64 f8g4_19 = f8 * (Int64)g4_19; | |
1228 Int64 f8g5_19 = f8 * (Int64)g5_19; | |
1229 Int64 f8g6_19 = f8 * (Int64)g6_19; | |
1230 Int64 f8g7_19 = f8 * (Int64)g7_19; | |
1231 Int64 f8g8_19 = f8 * (Int64)g8_19; | |
1232 Int64 f8g9_19 = f8 * (Int64)g9_19; | |
1233 Int64 f9g0 = f9 * (Int64)g0; | |
1234 Int64 f9g1_38 = f9_2 * (Int64)g1_19; | |
1235 Int64 f9g2_19 = f9 * (Int64)g2_19; | |
1236 Int64 f9g3_38 = f9_2 * (Int64)g3_19; | |
1237 Int64 f9g4_19 = f9 * (Int64)g4_19; | |
1238 Int64 f9g5_38 = f9_2 * (Int64)g5_19; | |
1239 Int64 f9g6_19 = f9 * (Int64)g6_19; | |
1240 Int64 f9g7_38 = f9_2 * (Int64)g7_19; | |
1241 Int64 f9g8_19 = f9 * (Int64)g8_19; | |
1242 Int64 f9g9_38 = f9_2 * (Int64)g9_19; | |
1243 Int64 h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; | |
1244 Int64 h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + f7g4_19 + f8g3_19 + f9g2_19; | |
1245 Int64 h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + f7g5_38 + f8g4_19 + f9g3_38; | |
1246 Int64 h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + f7g6_19 + f8g5_19 + f9g4_19; | |
1247 Int64 h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + f7g7_38 + f8g6_19 + f9g5_38; | |
1248 Int64 h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + f8g7_19 + f9g6_19; | |
1249 Int64 h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + f7g9_38 + f8g8_19 + f9g7_38; | |
1250 Int64 h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + f8g9_19 + f9g8_19; | |
1251 Int64 h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + f8g0 + f9g9_38; | |
1252 Int64 h9 = f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; | |
1253 Int64 carry0; | |
1254 Int64 carry1; | |
1255 Int64 carry2; | |
1256 Int64 carry3; | |
1257 Int64 carry4; | |
1258 Int64 carry5; | |
1259 Int64 carry6; | |
1260 Int64 carry7; | |
1261 Int64 carry8; | |
1262 Int64 carry9; | |
1263 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1264 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1265 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
1266 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
1267 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
1268 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
1269 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
1270 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
1271 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1272 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
1273 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
1274 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1275 h = new fe(); | |
1276 h[0] = (Int32)h0; | |
1277 h[1] = (Int32)h1; | |
1278 h[2] = (Int32)h2; | |
1279 h[3] = (Int32)h3; | |
1280 h[4] = (Int32)h4; | |
1281 h[5] = (Int32)h5; | |
1282 h[6] = (Int32)h6; | |
1283 h[7] = (Int32)h7; | |
1284 h[8] = (Int32)h8; | |
1285 h[9] = (Int32)h9; | |
1286 } | 1617 } |
1287 static void ge_madd(out ge_p1p1 r, ref ge_p3 p, ref ge_precomp q) { | 1618 static void ge_madd(out ge_p1p1 r, ref ge_p3 p, ref ge_precomp q) { |
1288 fe t0; | 1619 fe t0; |
1289 fe_add(out r.X, ref p.Y, ref p.X); | 1620 fe_add(out r.X, ref p.Y, ref p.X); |
1290 fe_sub(out r.Y, ref p.Y, ref p.X); | 1621 fe_sub(out r.Y, ref p.Y, ref p.X); |
1302 fe_mul(out r.Y, ref p.Y, ref p.Z); | 1633 fe_mul(out r.Y, ref p.Y, ref p.Z); |
1303 fe_mul(out r.Z, ref p.Z, ref p.T); | 1634 fe_mul(out r.Z, ref p.Z, ref p.T); |
1304 fe_mul(out r.T, ref p.X, ref p.Y); | 1635 fe_mul(out r.T, ref p.X, ref p.Y); |
1305 } | 1636 } |
1306 static void ge_p3_to_p2(out ge_p2 r, ref ge_p3 p) { | 1637 static void ge_p3_to_p2(out ge_p2 r, ref ge_p3 p) { |
1307 fe_copy(out r.X, ref p.X); | 1638 r.X = p.X; |
1308 fe_copy(out r.Y, ref p.Y); | 1639 r.Y = p.Y; |
1309 fe_copy(out r.Z, ref p.Z); | 1640 r.Z = p.Z; |
1310 } | 1641 } |
1311 static void fe_sq(out fe h, ref fe f) { | 1642 static void fe_sq(out fe h, ref fe f) { |
1312 Int32 f0 = f[0]; | 1643 h = f; |
1313 Int32 f1 = f[1]; | 1644 h.sq(); |
1314 Int32 f2 = f[2]; | |
1315 Int32 f3 = f[3]; | |
1316 Int32 f4 = f[4]; | |
1317 Int32 f5 = f[5]; | |
1318 Int32 f6 = f[6]; | |
1319 Int32 f7 = f[7]; | |
1320 Int32 f8 = f[8]; | |
1321 Int32 f9 = f[9]; | |
1322 Int32 f0_2 = 2 * f0; | |
1323 Int32 f1_2 = 2 * f1; | |
1324 Int32 f2_2 = 2 * f2; | |
1325 Int32 f3_2 = 2 * f3; | |
1326 Int32 f4_2 = 2 * f4; | |
1327 Int32 f5_2 = 2 * f5; | |
1328 Int32 f6_2 = 2 * f6; | |
1329 Int32 f7_2 = 2 * f7; | |
1330 Int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ | |
1331 Int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ | |
1332 Int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ | |
1333 Int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ | |
1334 Int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ | |
1335 Int64 f0f0 = f0 * (Int64)f0; | |
1336 Int64 f0f1_2 = f0_2 * (Int64)f1; | |
1337 Int64 f0f2_2 = f0_2 * (Int64)f2; | |
1338 Int64 f0f3_2 = f0_2 * (Int64)f3; | |
1339 Int64 f0f4_2 = f0_2 * (Int64)f4; | |
1340 Int64 f0f5_2 = f0_2 * (Int64)f5; | |
1341 Int64 f0f6_2 = f0_2 * (Int64)f6; | |
1342 Int64 f0f7_2 = f0_2 * (Int64)f7; | |
1343 Int64 f0f8_2 = f0_2 * (Int64)f8; | |
1344 Int64 f0f9_2 = f0_2 * (Int64)f9; | |
1345 Int64 f1f1_2 = f1_2 * (Int64)f1; | |
1346 Int64 f1f2_2 = f1_2 * (Int64)f2; | |
1347 Int64 f1f3_4 = f1_2 * (Int64)f3_2; | |
1348 Int64 f1f4_2 = f1_2 * (Int64)f4; | |
1349 Int64 f1f5_4 = f1_2 * (Int64)f5_2; | |
1350 Int64 f1f6_2 = f1_2 * (Int64)f6; | |
1351 Int64 f1f7_4 = f1_2 * (Int64)f7_2; | |
1352 Int64 f1f8_2 = f1_2 * (Int64)f8; | |
1353 Int64 f1f9_76 = f1_2 * (Int64)f9_38; | |
1354 Int64 f2f2 = f2 * (Int64)f2; | |
1355 Int64 f2f3_2 = f2_2 * (Int64)f3; | |
1356 Int64 f2f4_2 = f2_2 * (Int64)f4; | |
1357 Int64 f2f5_2 = f2_2 * (Int64)f5; | |
1358 Int64 f2f6_2 = f2_2 * (Int64)f6; | |
1359 Int64 f2f7_2 = f2_2 * (Int64)f7; | |
1360 Int64 f2f8_38 = f2_2 * (Int64)f8_19; | |
1361 Int64 f2f9_38 = f2 * (Int64)f9_38; | |
1362 Int64 f3f3_2 = f3_2 * (Int64)f3; | |
1363 Int64 f3f4_2 = f3_2 * (Int64)f4; | |
1364 Int64 f3f5_4 = f3_2 * (Int64)f5_2; | |
1365 Int64 f3f6_2 = f3_2 * (Int64)f6; | |
1366 Int64 f3f7_76 = f3_2 * (Int64)f7_38; | |
1367 Int64 f3f8_38 = f3_2 * (Int64)f8_19; | |
1368 Int64 f3f9_76 = f3_2 * (Int64)f9_38; | |
1369 Int64 f4f4 = f4 * (Int64)f4; | |
1370 Int64 f4f5_2 = f4_2 * (Int64)f5; | |
1371 Int64 f4f6_38 = f4_2 * (Int64)f6_19; | |
1372 Int64 f4f7_38 = f4 * (Int64)f7_38; | |
1373 Int64 f4f8_38 = f4_2 * (Int64)f8_19; | |
1374 Int64 f4f9_38 = f4 * (Int64)f9_38; | |
1375 Int64 f5f5_38 = f5 * (Int64)f5_38; | |
1376 Int64 f5f6_38 = f5_2 * (Int64)f6_19; | |
1377 Int64 f5f7_76 = f5_2 * (Int64)f7_38; | |
1378 Int64 f5f8_38 = f5_2 * (Int64)f8_19; | |
1379 Int64 f5f9_76 = f5_2 * (Int64)f9_38; | |
1380 Int64 f6f6_19 = f6 * (Int64)f6_19; | |
1381 Int64 f6f7_38 = f6 * (Int64)f7_38; | |
1382 Int64 f6f8_38 = f6_2 * (Int64)f8_19; | |
1383 Int64 f6f9_38 = f6 * (Int64)f9_38; | |
1384 Int64 f7f7_38 = f7 * (Int64)f7_38; | |
1385 Int64 f7f8_38 = f7_2 * (Int64)f8_19; | |
1386 Int64 f7f9_76 = f7_2 * (Int64)f9_38; | |
1387 Int64 f8f8_19 = f8 * (Int64)f8_19; | |
1388 Int64 f8f9_38 = f8 * (Int64)f9_38; | |
1389 Int64 f9f9_38 = f9 * (Int64)f9_38; | |
1390 Int64 h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; | |
1391 Int64 h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; | |
1392 Int64 h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; | |
1393 Int64 h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; | |
1394 Int64 h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; | |
1395 Int64 h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; | |
1396 Int64 h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; | |
1397 Int64 h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; | |
1398 Int64 h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; | |
1399 Int64 h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; | |
1400 Int64 carry0; | |
1401 Int64 carry1; | |
1402 Int64 carry2; | |
1403 Int64 carry3; | |
1404 Int64 carry4; | |
1405 Int64 carry5; | |
1406 Int64 carry6; | |
1407 Int64 carry7; | |
1408 Int64 carry8; | |
1409 Int64 carry9; | |
1410 | |
1411 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1412 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1413 | |
1414 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
1415 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
1416 | |
1417 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
1418 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
1419 | |
1420 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
1421 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
1422 | |
1423 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1424 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
1425 | |
1426 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
1427 | |
1428 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1429 | |
1430 h = new fe(); | |
1431 h[0] = (Int32)h0; | |
1432 h[1] = (Int32)h1; | |
1433 h[2] = (Int32)h2; | |
1434 h[3] = (Int32)h3; | |
1435 h[4] = (Int32)h4; | |
1436 h[5] = (Int32)h5; | |
1437 h[6] = (Int32)h6; | |
1438 h[7] = (Int32)h7; | |
1439 h[8] = (Int32)h8; | |
1440 h[9] = (Int32)h9; | |
1441 } | |
1442 static void fe_sq2(out fe h, ref fe f) { | |
1443 Int32 f0 = f[0]; | |
1444 Int32 f1 = f[1]; | |
1445 Int32 f2 = f[2]; | |
1446 Int32 f3 = f[3]; | |
1447 Int32 f4 = f[4]; | |
1448 Int32 f5 = f[5]; | |
1449 Int32 f6 = f[6]; | |
1450 Int32 f7 = f[7]; | |
1451 Int32 f8 = f[8]; | |
1452 Int32 f9 = f[9]; | |
1453 Int32 f0_2 = 2 * f0; | |
1454 Int32 f1_2 = 2 * f1; | |
1455 Int32 f2_2 = 2 * f2; | |
1456 Int32 f3_2 = 2 * f3; | |
1457 Int32 f4_2 = 2 * f4; | |
1458 Int32 f5_2 = 2 * f5; | |
1459 Int32 f6_2 = 2 * f6; | |
1460 Int32 f7_2 = 2 * f7; | |
1461 Int32 f5_38 = 38 * f5; /* 1.959375*2^30 */ | |
1462 Int32 f6_19 = 19 * f6; /* 1.959375*2^30 */ | |
1463 Int32 f7_38 = 38 * f7; /* 1.959375*2^30 */ | |
1464 Int32 f8_19 = 19 * f8; /* 1.959375*2^30 */ | |
1465 Int32 f9_38 = 38 * f9; /* 1.959375*2^30 */ | |
1466 Int64 f0f0 = f0 * (Int64)f0; | |
1467 Int64 f0f1_2 = f0_2 * (Int64)f1; | |
1468 Int64 f0f2_2 = f0_2 * (Int64)f2; | |
1469 Int64 f0f3_2 = f0_2 * (Int64)f3; | |
1470 Int64 f0f4_2 = f0_2 * (Int64)f4; | |
1471 Int64 f0f5_2 = f0_2 * (Int64)f5; | |
1472 Int64 f0f6_2 = f0_2 * (Int64)f6; | |
1473 Int64 f0f7_2 = f0_2 * (Int64)f7; | |
1474 Int64 f0f8_2 = f0_2 * (Int64)f8; | |
1475 Int64 f0f9_2 = f0_2 * (Int64)f9; | |
1476 Int64 f1f1_2 = f1_2 * (Int64)f1; | |
1477 Int64 f1f2_2 = f1_2 * (Int64)f2; | |
1478 Int64 f1f3_4 = f1_2 * (Int64)f3_2; | |
1479 Int64 f1f4_2 = f1_2 * (Int64)f4; | |
1480 Int64 f1f5_4 = f1_2 * (Int64)f5_2; | |
1481 Int64 f1f6_2 = f1_2 * (Int64)f6; | |
1482 Int64 f1f7_4 = f1_2 * (Int64)f7_2; | |
1483 Int64 f1f8_2 = f1_2 * (Int64)f8; | |
1484 Int64 f1f9_76 = f1_2 * (Int64)f9_38; | |
1485 Int64 f2f2 = f2 * (Int64)f2; | |
1486 Int64 f2f3_2 = f2_2 * (Int64)f3; | |
1487 Int64 f2f4_2 = f2_2 * (Int64)f4; | |
1488 Int64 f2f5_2 = f2_2 * (Int64)f5; | |
1489 Int64 f2f6_2 = f2_2 * (Int64)f6; | |
1490 Int64 f2f7_2 = f2_2 * (Int64)f7; | |
1491 Int64 f2f8_38 = f2_2 * (Int64)f8_19; | |
1492 Int64 f2f9_38 = f2 * (Int64)f9_38; | |
1493 Int64 f3f3_2 = f3_2 * (Int64)f3; | |
1494 Int64 f3f4_2 = f3_2 * (Int64)f4; | |
1495 Int64 f3f5_4 = f3_2 * (Int64)f5_2; | |
1496 Int64 f3f6_2 = f3_2 * (Int64)f6; | |
1497 Int64 f3f7_76 = f3_2 * (Int64)f7_38; | |
1498 Int64 f3f8_38 = f3_2 * (Int64)f8_19; | |
1499 Int64 f3f9_76 = f3_2 * (Int64)f9_38; | |
1500 Int64 f4f4 = f4 * (Int64)f4; | |
1501 Int64 f4f5_2 = f4_2 * (Int64)f5; | |
1502 Int64 f4f6_38 = f4_2 * (Int64)f6_19; | |
1503 Int64 f4f7_38 = f4 * (Int64)f7_38; | |
1504 Int64 f4f8_38 = f4_2 * (Int64)f8_19; | |
1505 Int64 f4f9_38 = f4 * (Int64)f9_38; | |
1506 Int64 f5f5_38 = f5 * (Int64)f5_38; | |
1507 Int64 f5f6_38 = f5_2 * (Int64)f6_19; | |
1508 Int64 f5f7_76 = f5_2 * (Int64)f7_38; | |
1509 Int64 f5f8_38 = f5_2 * (Int64)f8_19; | |
1510 Int64 f5f9_76 = f5_2 * (Int64)f9_38; | |
1511 Int64 f6f6_19 = f6 * (Int64)f6_19; | |
1512 Int64 f6f7_38 = f6 * (Int64)f7_38; | |
1513 Int64 f6f8_38 = f6_2 * (Int64)f8_19; | |
1514 Int64 f6f9_38 = f6 * (Int64)f9_38; | |
1515 Int64 f7f7_38 = f7 * (Int64)f7_38; | |
1516 Int64 f7f8_38 = f7_2 * (Int64)f8_19; | |
1517 Int64 f7f9_76 = f7_2 * (Int64)f9_38; | |
1518 Int64 f8f8_19 = f8 * (Int64)f8_19; | |
1519 Int64 f8f9_38 = f8 * (Int64)f9_38; | |
1520 Int64 f9f9_38 = f9 * (Int64)f9_38; | |
1521 Int64 h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; | |
1522 Int64 h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; | |
1523 Int64 h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; | |
1524 Int64 h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; | |
1525 Int64 h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; | |
1526 Int64 h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; | |
1527 Int64 h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; | |
1528 Int64 h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; | |
1529 Int64 h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; | |
1530 Int64 h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; | |
1531 Int64 carry0; | |
1532 Int64 carry1; | |
1533 Int64 carry2; | |
1534 Int64 carry3; | |
1535 Int64 carry4; | |
1536 Int64 carry5; | |
1537 Int64 carry6; | |
1538 Int64 carry7; | |
1539 Int64 carry8; | |
1540 Int64 carry9; | |
1541 | |
1542 h0 += h0; | |
1543 h1 += h1; | |
1544 h2 += h2; | |
1545 h3 += h3; | |
1546 h4 += h4; | |
1547 h5 += h5; | |
1548 h6 += h6; | |
1549 h7 += h7; | |
1550 h8 += h8; | |
1551 h9 += h9; | |
1552 | |
1553 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1554 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1555 | |
1556 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
1557 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
1558 | |
1559 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
1560 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
1561 | |
1562 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
1563 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
1564 | |
1565 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1566 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
1567 | |
1568 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
1569 | |
1570 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1571 | |
1572 h = new fe(); | |
1573 h[0] = (Int32)h0; | |
1574 h[1] = (Int32)h1; | |
1575 h[2] = (Int32)h2; | |
1576 h[3] = (Int32)h3; | |
1577 h[4] = (Int32)h4; | |
1578 h[5] = (Int32)h5; | |
1579 h[6] = (Int32)h6; | |
1580 h[7] = (Int32)h7; | |
1581 h[8] = (Int32)h8; | |
1582 h[9] = (Int32)h9; | |
1583 } | 1645 } |
1584 static void ge_p2_dbl(out ge_p1p1 r, ref ge_p2 p) { | 1646 static void ge_p2_dbl(out ge_p1p1 r, ref ge_p2 p) { |
1585 fe t0; | 1647 r.X = p.X; r.X.sq(); |
1586 fe_sq(out r.X, ref p.X); | 1648 r.Z = p.Y; r.Z.sq(); |
1587 fe_sq(out r.Z, ref p.Y); | 1649 r.T = p.Z; r.T.sq2(); |
1588 fe_sq2(out r.T, ref p.Z); | 1650 r.Y = p.X; r.Y.add(ref p.Y); |
1589 fe_add(out r.Y, ref p.X, ref p.Y); | 1651 fe t0 = r.Y; t0.sq(); |
1590 fe_sq(out t0, ref r.Y); | 1652 r.Y = r.Z; r.Y.add(ref r.X); |
1591 fe_add(out r.Y, ref r.Z, ref r.X); | 1653 r.Z.sub(ref r.X); |
1592 fe_sub(out r.Z, ref r.Z, ref r.X); | 1654 r.X = t0; r.X.sub(ref r.Y); |
1593 fe_sub(out r.X, ref t0, ref r.Y); | 1655 r.T.sub(ref r.Z); |
1594 fe_sub(out r.T, ref r.T, ref r.Z); | |
1595 } | 1656 } |
1596 static void ge_p3_dbl(out ge_p1p1 r, ref ge_p3 p) { | 1657 static void ge_p3_dbl(out ge_p1p1 r, ref ge_p3 p) { |
1597 ge_p2 q; | 1658 ge_p2 q; |
1598 ge_p3_to_p2(out q, ref p); | 1659 ge_p3_to_p2(out q, ref p); |
1599 ge_p2_dbl(out r, ref q); | 1660 ge_p2_dbl(out r, ref q); |
1618 carry >>= 4; | 1679 carry >>= 4; |
1619 e[i] -= (sbyte)(carry << 4); | 1680 e[i] -= (sbyte)(carry << 4); |
1620 } | 1681 } |
1621 e[63] += carry; | 1682 e[63] += carry; |
1622 | 1683 |
1623 ge_p3_0(out h); | 1684 h = new ge_p3(); |
1685 h.set_zero(); | |
1624 ge_precomp t; | 1686 ge_precomp t; |
1625 ge_p1p1 r; | 1687 ge_p1p1 r; |
1626 for (int i = 1; i < 64; i += 2) { | 1688 for (int i = 1; i < 64; i += 2) { |
1627 select(out t, i / 2, e[i]); | 1689 select(out t, i / 2, e[i]); |
1628 ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r); | 1690 ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r); |
1637 for (int i = 0; i < 64; i += 2) { | 1699 for (int i = 0; i < 64; i += 2) { |
1638 select(out t, i / 2, e[i]); | 1700 select(out t, i / 2, e[i]); |
1639 ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r); | 1701 ge_madd(out r, ref h, ref t); ge_p1p1_to_p3(out h, ref r); |
1640 } | 1702 } |
1641 } | 1703 } |
1642 static void fe_invert(out fe outv, ref fe z) { | |
1643 fe t0; | |
1644 fe t1; | |
1645 fe t2; | |
1646 fe t3; | |
1647 fe_sq(out t0, ref z); for (int i = 1; i < 1; ++i) fe_sq(out t0, ref t0); | |
1648 fe_sq(out t1, ref t0); for (int i = 1; i < 2; ++i) fe_sq(out t1, ref t1); | |
1649 fe_mul(out t1, ref z, ref t1); | |
1650 fe_mul(out t0, ref t0, ref t1); | |
1651 fe_sq(out t2, ref t0); for (int i = 1; i < 1; ++i) fe_sq(out t2, ref t2); | |
1652 fe_mul(out t1, ref t1, ref t2); | |
1653 fe_sq(out t2, ref t1); for (int i = 1; i < 5; ++i) fe_sq(out t2, ref t2); | |
1654 fe_mul(out t1, ref t2, ref t1); | |
1655 fe_sq(out t2, ref t1); for (int i = 1; i < 10; ++i) fe_sq(out t2, ref t2); | |
1656 fe_mul(out t2, ref t2, ref t1); | |
1657 fe_sq(out t3, ref t2); for (int i = 1; i < 20; ++i) fe_sq(out t3, ref t3); | |
1658 fe_mul(out t2, ref t3, ref t2); | |
1659 fe_sq(out t2, ref t2); for (int i = 1; i < 10; ++i) fe_sq(out t2, ref t2); | |
1660 fe_mul(out t1, ref t2, ref t1); | |
1661 fe_sq(out t2, ref t1); for (int i = 1; i < 50; ++i) fe_sq(out t2, ref t2); | |
1662 fe_mul(out t2, ref t2, ref t1); | |
1663 fe_sq(out t3, ref t2); for (int i = 1; i < 100; ++i) fe_sq(out t3, ref t3); | |
1664 fe_mul(out t2, ref t3, ref t2); | |
1665 fe_sq(out t2, ref t2); for (int i = 1; i < 50; ++i) fe_sq(out t2, ref t2); | |
1666 fe_mul(out t1, ref t2, ref t1); | |
1667 fe_sq(out t1, ref t1); for (int i = 1; i < 5; ++i) fe_sq(out t1, ref t1); | |
1668 fe_mul(out outv, ref t1, ref t0); | |
1669 } | |
1670 static unsafe void fe_tobytes(Byte* s, ref fe h) { | |
1671 Int32 h0 = h[0]; | |
1672 Int32 h1 = h[1]; | |
1673 Int32 h2 = h[2]; | |
1674 Int32 h3 = h[3]; | |
1675 Int32 h4 = h[4]; | |
1676 Int32 h5 = h[5]; | |
1677 Int32 h6 = h[6]; | |
1678 Int32 h7 = h[7]; | |
1679 Int32 h8 = h[8]; | |
1680 Int32 h9 = h[9]; | |
1681 Int32 q; | |
1682 Int32 carry0; | |
1683 Int32 carry1; | |
1684 Int32 carry2; | |
1685 Int32 carry3; | |
1686 Int32 carry4; | |
1687 Int32 carry5; | |
1688 Int32 carry6; | |
1689 Int32 carry7; | |
1690 Int32 carry8; | |
1691 Int32 carry9; | |
1692 | |
1693 q = (19 * h9 + (((Int32)1) << 24)) >> 25; | |
1694 q = (h0 + q) >> 26; | |
1695 q = (h1 + q) >> 25; | |
1696 q = (h2 + q) >> 26; | |
1697 q = (h3 + q) >> 25; | |
1698 q = (h4 + q) >> 26; | |
1699 q = (h5 + q) >> 25; | |
1700 q = (h6 + q) >> 26; | |
1701 q = (h7 + q) >> 25; | |
1702 q = (h8 + q) >> 26; | |
1703 q = (h9 + q) >> 25; | |
1704 | |
1705 h0 += 19 * q; | |
1706 | |
1707 carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; | |
1708 carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; | |
1709 carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; | |
1710 carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; | |
1711 carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; | |
1712 carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; | |
1713 carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; | |
1714 carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; | |
1715 carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; | |
1716 carry9 = h9 >> 25; h9 -= carry9 << 25; | |
1717 /* h10 = carry9 */ | |
1718 | |
1719 s[0] = (Byte)(h0 >> 0); | |
1720 s[1] = (Byte)(h0 >> 8); | |
1721 s[2] = (Byte)(h0 >> 16); | |
1722 s[3] = (Byte)((h0 >> 24) | (h1 << 2)); | |
1723 s[4] = (Byte)(h1 >> 6); | |
1724 s[5] = (Byte)(h1 >> 14); | |
1725 s[6] = (Byte)((h1 >> 22) | (h2 << 3)); | |
1726 s[7] = (Byte)(h2 >> 5); | |
1727 s[8] = (Byte)(h2 >> 13); | |
1728 s[9] = (Byte)((h2 >> 21) | (h3 << 5)); | |
1729 s[10] = (Byte)(h3 >> 3); | |
1730 s[11] = (Byte)(h3 >> 11); | |
1731 s[12] = (Byte)((h3 >> 19) | (h4 << 6)); | |
1732 s[13] = (Byte)(h4 >> 2); | |
1733 s[14] = (Byte)(h4 >> 10); | |
1734 s[15] = (Byte)(h4 >> 18); | |
1735 s[16] = (Byte)(h5 >> 0); | |
1736 s[17] = (Byte)(h5 >> 8); | |
1737 s[18] = (Byte)(h5 >> 16); | |
1738 s[19] = (Byte)((h5 >> 24) | (h6 << 1)); | |
1739 s[20] = (Byte)(h6 >> 7); | |
1740 s[21] = (Byte)(h6 >> 15); | |
1741 s[22] = (Byte)((h6 >> 23) | (h7 << 3)); | |
1742 s[23] = (Byte)(h7 >> 5); | |
1743 s[24] = (Byte)(h7 >> 13); | |
1744 s[25] = (Byte)((h7 >> 21) | (h8 << 4)); | |
1745 s[26] = (Byte)(h8 >> 4); | |
1746 s[27] = (Byte)(h8 >> 12); | |
1747 s[28] = (Byte)((h8 >> 20) | (h9 << 6)); | |
1748 s[29] = (Byte)(h9 >> 2); | |
1749 s[30] = (Byte)(h9 >> 10); | |
1750 s[31] = (Byte)(h9 >> 18); | |
1751 } | |
1752 static unsafe int fe_isnegative(ref fe f) { | |
1753 Byte* s = stackalloc Byte[32]; | |
1754 fe_tobytes(s, ref f); | |
1755 return s[0] & 1; | |
1756 } | |
1757 static unsafe void ge_p3_tobytes(Byte* s, ref ge_p3 h) { | 1704 static unsafe void ge_p3_tobytes(Byte* s, ref ge_p3 h) { |
1758 fe recip; | 1705 fe recip = h.Z; recip.invert(); |
1759 fe x; | 1706 fe x = h.X; x.mul(ref recip); |
1760 fe y; | 1707 fe y = h.Y; y.mul(ref recip); |
1761 fe_invert(out recip, ref h.Z); | 1708 y.tobytes(s); |
1762 fe_mul(out x, ref h.X, ref recip); | 1709 s[31] ^= (Byte)(x.isnegative() << 7); |
1763 fe_mul(out y, ref h.Y, ref recip); | |
1764 fe_tobytes(s, ref y); | |
1765 s[31] ^= (Byte)(fe_isnegative(ref x) << 7); | |
1766 } | 1710 } |
1767 | 1711 |
1768 public static unsafe void crypto_sign_seed_keypair(out Byte[] pk, out Byte[] sk, Byte[] seed) { | 1712 public static unsafe void crypto_sign_seed_keypair(out Byte[] pk, out Byte[] sk, Byte[] seed) { |
1769 if (seed.Length < SEEDBYTES) throw new ArgumentException("seed.Length < SEEDBYTES"); | 1713 if (seed.Length < SEEDBYTES) throw new ArgumentException("seed.Length < SEEDBYTES"); |
1770 sk = new Byte[SECRETKEYBYTES]; | 1714 sk = new Byte[SECRETKEYBYTES]; |
1789 | 1733 |
1790 public static unsafe void crypto_sign_getpublickey(out Byte[] pk, Byte[] sk) { | 1734 public static unsafe void crypto_sign_getpublickey(out Byte[] pk, Byte[] sk) { |
1791 pk = UCIS.Util.ArrayUtil.Slice(sk, 32, 32); | 1735 pk = UCIS.Util.ArrayUtil.Slice(sk, 32, 32); |
1792 } | 1736 } |
1793 | 1737 |
1794 static unsafe Int64 load_3(Byte* inv) { | 1738 static unsafe UInt32 load_3(Byte* inv) { |
1795 UInt64 result; | 1739 return (UInt32)inv[0] | ((UInt32)inv[1] << 8) | ((UInt32)inv[2] << 16); |
1796 result = (UInt64)inv[0]; | 1740 } |
1797 result |= ((UInt64)inv[1]) << 8; | 1741 static unsafe UInt32 load_4(Byte* inv) { |
1798 result |= ((UInt64)inv[2]) << 16; | 1742 return (UInt32)inv[0] | ((UInt32)inv[1] << 8) | ((UInt32)inv[2] << 16) | ((UInt32)inv[3] << 24); |
1799 return (Int64)result; | |
1800 } | |
1801 static unsafe Int64 load_4(Byte* inv) { | |
1802 UInt64 result; | |
1803 result = (UInt64)inv[0]; | |
1804 result |= ((UInt64)inv[1]) << 8; | |
1805 result |= ((UInt64)inv[2]) << 16; | |
1806 result |= ((UInt64)inv[3]) << 24; | |
1807 return (Int64)result; | |
1808 } | 1743 } |
1809 static unsafe void sc_reduce(Byte* s) { | 1744 static unsafe void sc_reduce(Byte* s) { |
1810 Int64 s0 = 2097151 & load_3(s); | 1745 Int64 s0 = 2097151 & load_3(s); |
1811 Int64 s1 = 2097151 & (load_4(s + 2) >> 5); | 1746 Int64 s1 = 2097151 & (load_4(s + 2) >> 5); |
1812 Int64 s2 = 2097151 & (load_3(s + 5) >> 2); | 1747 Int64 s2 = 2097151 & (load_3(s + 5) >> 2); |
1829 Int64 s19 = 2097151 & (load_4(s + 49) >> 7); | 1764 Int64 s19 = 2097151 & (load_4(s + 49) >> 7); |
1830 Int64 s20 = 2097151 & (load_4(s + 52) >> 4); | 1765 Int64 s20 = 2097151 & (load_4(s + 52) >> 4); |
1831 Int64 s21 = 2097151 & (load_3(s + 55) >> 1); | 1766 Int64 s21 = 2097151 & (load_3(s + 55) >> 1); |
1832 Int64 s22 = 2097151 & (load_4(s + 57) >> 6); | 1767 Int64 s22 = 2097151 & (load_4(s + 57) >> 6); |
1833 Int64 s23 = (load_4(s + 60) >> 3); | 1768 Int64 s23 = (load_4(s + 60) >> 3); |
1834 Int64 carry0; | |
1835 Int64 carry1; | |
1836 Int64 carry2; | |
1837 Int64 carry3; | |
1838 Int64 carry4; | |
1839 Int64 carry5; | |
1840 Int64 carry6; | |
1841 Int64 carry7; | |
1842 Int64 carry8; | |
1843 Int64 carry9; | |
1844 Int64 carry10; | |
1845 Int64 carry11; | |
1846 Int64 carry12; | |
1847 Int64 carry13; | |
1848 Int64 carry14; | |
1849 Int64 carry15; | |
1850 Int64 carry16; | |
1851 | 1769 |
1852 s11 += s23 * 666643; | 1770 s11 += s23 * 666643; |
1853 s12 += s23 * 470296; | 1771 s12 += s23 * 470296; |
1854 s13 += s23 * 654183; | 1772 s13 += s23 * 654183; |
1855 s14 -= s23 * 997805; | 1773 s14 -= s23 * 997805; |
1862 s12 += s22 * 654183; | 1780 s12 += s22 * 654183; |
1863 s13 -= s22 * 997805; | 1781 s13 -= s22 * 997805; |
1864 s14 += s22 * 136657; | 1782 s14 += s22 * 136657; |
1865 s15 -= s22 * 683901; | 1783 s15 -= s22 * 683901; |
1866 | 1784 |
1867 | |
1868 s9 += s21 * 666643; | 1785 s9 += s21 * 666643; |
1869 s10 += s21 * 470296; | 1786 s10 += s21 * 470296; |
1870 s11 += s21 * 654183; | 1787 s11 += s21 * 654183; |
1871 s12 -= s21 * 997805; | 1788 s12 -= s21 * 997805; |
1872 s13 += s21 * 136657; | 1789 s13 += s21 * 136657; |
1873 s14 -= s21 * 683901; | 1790 s14 -= s21 * 683901; |
1874 | 1791 |
1875 | |
1876 s8 += s20 * 666643; | 1792 s8 += s20 * 666643; |
1877 s9 += s20 * 470296; | 1793 s9 += s20 * 470296; |
1878 s10 += s20 * 654183; | 1794 s10 += s20 * 654183; |
1879 s11 -= s20 * 997805; | 1795 s11 -= s20 * 997805; |
1880 s12 += s20 * 136657; | 1796 s12 += s20 * 136657; |
1881 s13 -= s20 * 683901; | 1797 s13 -= s20 * 683901; |
1882 | 1798 |
1883 | |
1884 s7 += s19 * 666643; | 1799 s7 += s19 * 666643; |
1885 s8 += s19 * 470296; | 1800 s8 += s19 * 470296; |
1886 s9 += s19 * 654183; | 1801 s9 += s19 * 654183; |
1887 s10 -= s19 * 997805; | 1802 s10 -= s19 * 997805; |
1888 s11 += s19 * 136657; | 1803 s11 += s19 * 136657; |
1893 s8 += s18 * 654183; | 1808 s8 += s18 * 654183; |
1894 s9 -= s18 * 997805; | 1809 s9 -= s18 * 997805; |
1895 s10 += s18 * 136657; | 1810 s10 += s18 * 136657; |
1896 s11 -= s18 * 683901; | 1811 s11 -= s18 * 683901; |
1897 | 1812 |
1898 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; | 1813 Int64 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; |
1899 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; | 1814 Int64 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; |
1900 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; | 1815 Int64 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; |
1901 carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; | 1816 Int64 carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; |
1902 carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; | 1817 Int64 carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; |
1903 carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; | 1818 Int64 carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; |
1904 | 1819 |
1905 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; | 1820 Int64 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; |
1906 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; | 1821 Int64 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; |
1907 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; | 1822 Int64 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; |
1908 carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; | 1823 Int64 carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; |
1909 carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; | 1824 Int64 carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; |
1910 | 1825 |
1911 s5 += s17 * 666643; | 1826 s5 += s17 * 666643; |
1912 s6 += s17 * 470296; | 1827 s6 += s17 * 470296; |
1913 s7 += s17 * 654183; | 1828 s7 += s17 * 654183; |
1914 s8 -= s17 * 997805; | 1829 s8 -= s17 * 997805; |
1949 s3 -= s12 * 997805; | 1864 s3 -= s12 * 997805; |
1950 s4 += s12 * 136657; | 1865 s4 += s12 * 136657; |
1951 s5 -= s12 * 683901; | 1866 s5 -= s12 * 683901; |
1952 s12 = 0; | 1867 s12 = 0; |
1953 | 1868 |
1954 carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; | 1869 Int64 carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; |
1955 carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; | 1870 Int64 carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; |
1956 carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; | 1871 Int64 carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; |
1957 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; | 1872 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; |
1958 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; | 1873 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; |
1959 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; | 1874 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; |
1960 | 1875 |
1961 carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; | 1876 Int64 carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; |
1962 carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; | 1877 Int64 carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; |
1963 carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; | 1878 Int64 carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; |
1964 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; | 1879 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; |
1965 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; | 1880 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; |
1966 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; | 1881 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; |
1967 | 1882 |
1968 s0 += s12 * 666643; | 1883 s0 += s12 * 666643; |
1990 s1 += s12 * 470296; | 1905 s1 += s12 * 470296; |
1991 s2 += s12 * 654183; | 1906 s2 += s12 * 654183; |
1992 s3 -= s12 * 997805; | 1907 s3 -= s12 * 997805; |
1993 s4 += s12 * 136657; | 1908 s4 += s12 * 136657; |
1994 s5 -= s12 * 683901; | 1909 s5 -= s12 * 683901; |
1995 | 1910 |
1996 | |
1997 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; | 1911 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; |
1998 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; | 1912 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; |
1999 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; | 1913 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; |
2000 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; | 1914 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; |
2001 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; | 1915 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; |
2074 Int64 c7 = 2097151 & (load_3(c + 18) >> 3); | 1988 Int64 c7 = 2097151 & (load_3(c + 18) >> 3); |
2075 Int64 c8 = 2097151 & load_3(c + 21); | 1989 Int64 c8 = 2097151 & load_3(c + 21); |
2076 Int64 c9 = 2097151 & (load_4(c + 23) >> 5); | 1990 Int64 c9 = 2097151 & (load_4(c + 23) >> 5); |
2077 Int64 c10 = 2097151 & (load_3(c + 26) >> 2); | 1991 Int64 c10 = 2097151 & (load_3(c + 26) >> 2); |
2078 Int64 c11 = (load_4(c + 28) >> 7); | 1992 Int64 c11 = (load_4(c + 28) >> 7); |
2079 Int64 s0; | 1993 |
2080 Int64 s1; | 1994 Int64 s0 = c0 + a0 * b0; |
2081 Int64 s2; | 1995 Int64 s1 = c1 + a0 * b1 + a1 * b0; |
2082 Int64 s3; | 1996 Int64 s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; |
2083 Int64 s4; | 1997 Int64 s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; |
2084 Int64 s5; | 1998 Int64 s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; |
2085 Int64 s6; | 1999 Int64 s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; |
2086 Int64 s7; | 2000 Int64 s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; |
2087 Int64 s8; | 2001 Int64 s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; |
2088 Int64 s9; | 2002 Int64 s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; |
2089 Int64 s10; | 2003 Int64 s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; |
2090 Int64 s11; | 2004 Int64 s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; |
2091 Int64 s12; | 2005 Int64 s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; |
2092 Int64 s13; | 2006 Int64 s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; |
2093 Int64 s14; | 2007 Int64 s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; |
2094 Int64 s15; | 2008 Int64 s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; |
2095 Int64 s16; | 2009 Int64 s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; |
2096 Int64 s17; | 2010 Int64 s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; |
2097 Int64 s18; | 2011 Int64 s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; |
2098 Int64 s19; | 2012 Int64 s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; |
2099 Int64 s20; | 2013 Int64 s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; |
2100 Int64 s21; | 2014 Int64 s20 = a9 * b11 + a10 * b10 + a11 * b9; |
2101 Int64 s22; | 2015 Int64 s21 = a10 * b11 + a11 * b10; |
2102 Int64 s23; | 2016 Int64 s22 = a11 * b11; |
2103 Int64 carry0; | 2017 Int64 s23 = 0; |
2104 Int64 carry1; | 2018 |
2105 Int64 carry2; | 2019 Int64 carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; |
2106 Int64 carry3; | 2020 Int64 carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; |
2107 Int64 carry4; | 2021 Int64 carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; |
2108 Int64 carry5; | 2022 Int64 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; |
2109 Int64 carry6; | 2023 Int64 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; |
2110 Int64 carry7; | 2024 Int64 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; |
2111 Int64 carry8; | 2025 Int64 carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; |
2112 Int64 carry9; | 2026 Int64 carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; |
2113 Int64 carry10; | 2027 Int64 carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; |
2114 Int64 carry11; | 2028 Int64 carry18 = (s18 + (1 << 20)) >> 21; s19 += carry18; s18 -= carry18 << 21; |
2115 Int64 carry12; | 2029 Int64 carry20 = (s20 + (1 << 20)) >> 21; s21 += carry20; s20 -= carry20 << 21; |
2116 Int64 carry13; | 2030 Int64 carry22 = (s22 + (1 << 20)) >> 21; s23 += carry22; s22 -= carry22 << 21; |
2117 Int64 carry14; | 2031 |
2118 Int64 carry15; | 2032 Int64 carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; |
2119 Int64 carry16; | 2033 Int64 carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; |
2120 Int64 carry17; | 2034 Int64 carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; |
2121 Int64 carry18; | 2035 Int64 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; |
2122 Int64 carry19; | 2036 Int64 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; |
2123 Int64 carry20; | 2037 Int64 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; |
2124 Int64 carry21; | 2038 Int64 carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; |
2125 Int64 carry22; | 2039 Int64 carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; |
2126 | 2040 Int64 carry17 = (s17 + (1 << 20)) >> 21; s18 += carry17; s17 -= carry17 << 21; |
2127 s0 = c0 + a0 * b0; | 2041 Int64 carry19 = (s19 + (1 << 20)) >> 21; s20 += carry19; s19 -= carry19 << 21; |
2128 s1 = c1 + a0 * b1 + a1 * b0; | 2042 Int64 carry21 = (s21 + (1 << 20)) >> 21; s22 += carry21; s21 -= carry21 << 21; |
2129 s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; | 2043 |
2130 s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; | 2044 s11 += s23 * 666643; |
2131 s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; | 2045 s12 += s23 * 470296; |
2132 s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; | 2046 s13 += s23 * 654183; |
2133 s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; | 2047 s14 -= s23 * 997805; |
2134 s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + a6 * b1 + a7 * b0; | 2048 s15 += s23 * 136657; |
2135 s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + a6 * b2 + a7 * b1 + a8 * b0; | 2049 s16 -= s23 * 683901; |
2136 s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; | 2050 |
2137 s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; | 2051 s10 += s22 * 666643; |
2138 s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; | 2052 s11 += s22 * 470296; |
2139 s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; | 2053 s12 += s22 * 654183; |
2140 s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; | 2054 s13 -= s22 * 997805; |
2141 s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + a10 * b4 + a11 * b3; | 2055 s14 += s22 * 136657; |
2142 s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + a11 * b4; | 2056 s15 -= s22 * 683901; |
2143 s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; | 2057 |
2144 s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; | 2058 s9 += s21 * 666643; |
2145 s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; | 2059 s10 += s21 * 470296; |
2146 s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; | 2060 s11 += s21 * 654183; |
2147 s20 = a9 * b11 + a10 * b10 + a11 * b9; | 2061 s12 -= s21 * 997805; |
2148 s21 = a10 * b11 + a11 * b10; | 2062 s13 += s21 * 136657; |
2149 s22 = a11 * b11; | 2063 s14 -= s21 * 683901; |
2150 s23 = 0; | 2064 |
2151 | 2065 s8 += s20 * 666643; |
2152 carry0 = (s0 + (1 << 20)) >> 21; s1 += carry0; s0 -= carry0 << 21; | 2066 s9 += s20 * 470296; |
2153 carry2 = (s2 + (1 << 20)) >> 21; s3 += carry2; s2 -= carry2 << 21; | 2067 s10 += s20 * 654183; |
2154 carry4 = (s4 + (1 << 20)) >> 21; s5 += carry4; s4 -= carry4 << 21; | 2068 s11 -= s20 * 997805; |
2069 s12 += s20 * 136657; | |
2070 s13 -= s20 * 683901; | |
2071 | |
2072 s7 += s19 * 666643; | |
2073 s8 += s19 * 470296; | |
2074 s9 += s19 * 654183; | |
2075 s10 -= s19 * 997805; | |
2076 s11 += s19 * 136657; | |
2077 s12 -= s19 * 683901; | |
2078 | |
2079 s6 += s18 * 666643; | |
2080 s7 += s18 * 470296; | |
2081 s8 += s18 * 654183; | |
2082 s9 -= s18 * 997805; | |
2083 s10 += s18 * 136657; | |
2084 s11 -= s18 * 683901; | |
2085 | |
2155 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; | 2086 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; |
2156 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; | 2087 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; |
2157 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; | 2088 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; |
2158 carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; | 2089 carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; |
2159 carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; | 2090 carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; |
2160 carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; | 2091 carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; |
2161 carry18 = (s18 + (1 << 20)) >> 21; s19 += carry18; s18 -= carry18 << 21; | |
2162 carry20 = (s20 + (1 << 20)) >> 21; s21 += carry20; s20 -= carry20 << 21; | |
2163 carry22 = (s22 + (1 << 20)) >> 21; s23 += carry22; s22 -= carry22 << 21; | |
2164 | |
2165 carry1 = (s1 + (1 << 20)) >> 21; s2 += carry1; s1 -= carry1 << 21; | |
2166 carry3 = (s3 + (1 << 20)) >> 21; s4 += carry3; s3 -= carry3 << 21; | |
2167 carry5 = (s5 + (1 << 20)) >> 21; s6 += carry5; s5 -= carry5 << 21; | |
2168 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; | |
2169 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; | |
2170 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; | |
2171 carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; | |
2172 carry15 = (s15 + (1 << 20)) >> 21; s16 += carry15; s15 -= carry15 << 21; | |
2173 carry17 = (s17 + (1 << 20)) >> 21; s18 += carry17; s17 -= carry17 << 21; | |
2174 carry19 = (s19 + (1 << 20)) >> 21; s20 += carry19; s19 -= carry19 << 21; | |
2175 carry21 = (s21 + (1 << 20)) >> 21; s22 += carry21; s21 -= carry21 << 21; | |
2176 | |
2177 s11 += s23 * 666643; | |
2178 s12 += s23 * 470296; | |
2179 s13 += s23 * 654183; | |
2180 s14 -= s23 * 997805; | |
2181 s15 += s23 * 136657; | |
2182 s16 -= s23 * 683901; | |
2183 | |
2184 | |
2185 s10 += s22 * 666643; | |
2186 s11 += s22 * 470296; | |
2187 s12 += s22 * 654183; | |
2188 s13 -= s22 * 997805; | |
2189 s14 += s22 * 136657; | |
2190 s15 -= s22 * 683901; | |
2191 | |
2192 | |
2193 s9 += s21 * 666643; | |
2194 s10 += s21 * 470296; | |
2195 s11 += s21 * 654183; | |
2196 s12 -= s21 * 997805; | |
2197 s13 += s21 * 136657; | |
2198 s14 -= s21 * 683901; | |
2199 | |
2200 | |
2201 s8 += s20 * 666643; | |
2202 s9 += s20 * 470296; | |
2203 s10 += s20 * 654183; | |
2204 s11 -= s20 * 997805; | |
2205 s12 += s20 * 136657; | |
2206 s13 -= s20 * 683901; | |
2207 | |
2208 | |
2209 s7 += s19 * 666643; | |
2210 s8 += s19 * 470296; | |
2211 s9 += s19 * 654183; | |
2212 s10 -= s19 * 997805; | |
2213 s11 += s19 * 136657; | |
2214 s12 -= s19 * 683901; | |
2215 | |
2216 | |
2217 s6 += s18 * 666643; | |
2218 s7 += s18 * 470296; | |
2219 s8 += s18 * 654183; | |
2220 s9 -= s18 * 997805; | |
2221 s10 += s18 * 136657; | |
2222 s11 -= s18 * 683901; | |
2223 | |
2224 | |
2225 carry6 = (s6 + (1 << 20)) >> 21; s7 += carry6; s6 -= carry6 << 21; | |
2226 carry8 = (s8 + (1 << 20)) >> 21; s9 += carry8; s8 -= carry8 << 21; | |
2227 carry10 = (s10 + (1 << 20)) >> 21; s11 += carry10; s10 -= carry10 << 21; | |
2228 carry12 = (s12 + (1 << 20)) >> 21; s13 += carry12; s12 -= carry12 << 21; | |
2229 carry14 = (s14 + (1 << 20)) >> 21; s15 += carry14; s14 -= carry14 << 21; | |
2230 carry16 = (s16 + (1 << 20)) >> 21; s17 += carry16; s16 -= carry16 << 21; | |
2231 | 2092 |
2232 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; | 2093 carry7 = (s7 + (1 << 20)) >> 21; s8 += carry7; s7 -= carry7 << 21; |
2233 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; | 2094 carry9 = (s9 + (1 << 20)) >> 21; s10 += carry9; s9 -= carry9 << 21; |
2234 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; | 2095 carry11 = (s11 + (1 << 20)) >> 21; s12 += carry11; s11 -= carry11 << 21; |
2235 carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; | 2096 carry13 = (s13 + (1 << 20)) >> 21; s14 += carry13; s13 -= carry13 << 21; |
2239 s6 += s17 * 470296; | 2100 s6 += s17 * 470296; |
2240 s7 += s17 * 654183; | 2101 s7 += s17 * 654183; |
2241 s8 -= s17 * 997805; | 2102 s8 -= s17 * 997805; |
2242 s9 += s17 * 136657; | 2103 s9 += s17 * 136657; |
2243 s10 -= s17 * 683901; | 2104 s10 -= s17 * 683901; |
2244 | 2105 |
2245 | |
2246 s4 += s16 * 666643; | 2106 s4 += s16 * 666643; |
2247 s5 += s16 * 470296; | 2107 s5 += s16 * 470296; |
2248 s6 += s16 * 654183; | 2108 s6 += s16 * 654183; |
2249 s7 -= s16 * 997805; | 2109 s7 -= s16 * 997805; |
2250 s8 += s16 * 136657; | 2110 s8 += s16 * 136657; |
2251 s9 -= s16 * 683901; | 2111 s9 -= s16 * 683901; |
2252 | 2112 |
2253 | |
2254 s3 += s15 * 666643; | 2113 s3 += s15 * 666643; |
2255 s4 += s15 * 470296; | 2114 s4 += s15 * 470296; |
2256 s5 += s15 * 654183; | 2115 s5 += s15 * 654183; |
2257 s6 -= s15 * 997805; | 2116 s6 -= s15 * 997805; |
2258 s7 += s15 * 136657; | 2117 s7 += s15 * 136657; |
2259 s8 -= s15 * 683901; | 2118 s8 -= s15 * 683901; |
2260 | 2119 |
2261 | |
2262 s2 += s14 * 666643; | 2120 s2 += s14 * 666643; |
2263 s3 += s14 * 470296; | 2121 s3 += s14 * 470296; |
2264 s4 += s14 * 654183; | 2122 s4 += s14 * 654183; |
2265 s5 -= s14 * 997805; | 2123 s5 -= s14 * 997805; |
2266 s6 += s14 * 136657; | 2124 s6 += s14 * 136657; |
2267 s7 -= s14 * 683901; | 2125 s7 -= s14 * 683901; |
2268 | 2126 |
2269 | |
2270 s1 += s13 * 666643; | 2127 s1 += s13 * 666643; |
2271 s2 += s13 * 470296; | 2128 s2 += s13 * 470296; |
2272 s3 += s13 * 654183; | 2129 s3 += s13 * 654183; |
2273 s4 -= s13 * 997805; | 2130 s4 -= s13 * 997805; |
2274 s5 += s13 * 136657; | 2131 s5 += s13 * 136657; |
2275 s6 -= s13 * 683901; | 2132 s6 -= s13 * 683901; |
2276 | 2133 |
2277 | |
2278 s0 += s12 * 666643; | 2134 s0 += s12 * 666643; |
2279 s1 += s12 * 470296; | 2135 s1 += s12 * 470296; |
2280 s2 += s12 * 654183; | 2136 s2 += s12 * 654183; |
2281 s3 -= s12 * 997805; | 2137 s3 -= s12 * 997805; |
2282 s4 += s12 * 136657; | 2138 s4 += s12 * 136657; |
2322 s1 += s12 * 470296; | 2178 s1 += s12 * 470296; |
2323 s2 += s12 * 654183; | 2179 s2 += s12 * 654183; |
2324 s3 -= s12 * 997805; | 2180 s3 -= s12 * 997805; |
2325 s4 += s12 * 136657; | 2181 s4 += s12 * 136657; |
2326 s5 -= s12 * 683901; | 2182 s5 -= s12 * 683901; |
2327 | 2183 |
2328 | |
2329 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; | 2184 carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; |
2330 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; | 2185 carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; |
2331 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; | 2186 carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; |
2332 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; | 2187 carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; |
2333 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; | 2188 carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; |
2369 s[28] = (Byte)((s10 >> 14) | (s11 << 7)); | 2224 s[28] = (Byte)((s10 >> 14) | (s11 << 7)); |
2370 s[29] = (Byte)(s11 >> 1); | 2225 s[29] = (Byte)(s11 >> 1); |
2371 s[30] = (Byte)(s11 >> 9); | 2226 s[30] = (Byte)(s11 >> 9); |
2372 s[31] = (Byte)(s11 >> 17); | 2227 s[31] = (Byte)(s11 >> 17); |
2373 } | 2228 } |
2374 public static unsafe void crypto_sign(Byte[] sm, int smoffset, out UInt64 smlen, Byte[] m, int moffset, UInt64 mlen, Byte[] sk) { | 2229 public static unsafe void crypto_sign(Byte[] sm, int smoffset, out int smlen, Byte[] m, int moffset, int mlen, Byte[] sk) { |
2375 if (smoffset + (int)mlen + 64 > sm.Length) throw new ArgumentException("signed message buffer is too small"); | 2230 if (smoffset + (int)mlen + 64 > sm.Length) throw new ArgumentException("signed message buffer is too small"); |
2376 if (moffset + (int)mlen > m.Length) throw new ArgumentException("message buffer is too small"); | 2231 if (moffset + (int)mlen > m.Length) throw new ArgumentException("message buffer is too small"); |
2377 if (64 > sk.Length) throw new ArgumentException("key buffer is too small"); | 2232 if (64 > sk.Length) throw new ArgumentException("key buffer is too small"); |
2378 fixed (Byte* smp = sm, mp = m, skp = sk) crypto_sign(smp + smoffset, out smlen, mp + moffset, mlen, skp); | 2233 fixed (Byte* smp = sm, mp = m, skp = sk) crypto_sign(smp + smoffset, out smlen, mp + moffset, mlen, skp); |
2379 } | 2234 } |
2380 public static unsafe void crypto_sign(Byte* sm, out UInt64 smlen, Byte* m, UInt64 mlen, Byte* sk) { | 2235 public static unsafe void crypto_sign(Byte* sm, out int smlen, Byte* m, int mlen, Byte* sk) { |
2236 smlen = mlen + 64; | |
2237 for (int i = 0; i < mlen; ++i) sm[64 + i] = m[i]; | |
2238 crypto_getsignature(sm, m, mlen, sk); | |
2239 } | |
2240 public static unsafe void crypto_getsignature(Byte* sig, Byte* m, int mlen, Byte* sk) { | |
2381 Byte* az = stackalloc Byte[64]; | 2241 Byte* az = stackalloc Byte[64]; |
2382 Byte* r = stackalloc Byte[64]; | 2242 sha512.crypto_hash(az, sk, 32); |
2383 Byte* hram = stackalloc Byte[64]; | |
2384 | |
2385 crypto_hash.sha512.crypto_hash(az, sk, 32); | |
2386 az[0] &= 248; | 2243 az[0] &= 248; |
2387 az[31] &= 63; | 2244 az[31] &= 63; |
2388 az[31] |= 64; | 2245 az[31] |= 64; |
2389 | 2246 |
2390 smlen = mlen + 64; | 2247 sha512.sha512state hashstate = new sha512.sha512state(); |
2391 for (UInt64 i = 0; i < mlen; ++i) sm[64 + i] = m[i]; | 2248 hashstate.init(); |
2392 for (UInt64 i = 0; i < 32; ++i) sm[32 + i] = az[32 + i]; | 2249 hashstate.process(az + 32, 32); |
2393 crypto_hash.sha512.crypto_hash(r, sm + 32, mlen + 32); | 2250 hashstate.process(m, (int)mlen); |
2394 for (UInt64 i = 0; i < 32; ++i) sm[32 + i] = sk[32 + i]; | 2251 Byte* r = stackalloc Byte[64]; |
2252 hashstate.finish(r); | |
2395 | 2253 |
2396 sc_reduce(r); | 2254 sc_reduce(r); |
2397 ge_p3 R; | 2255 ge_p3 R; |
2398 ge_scalarmult_base(out R, r); | 2256 ge_scalarmult_base(out R, r); |
2399 ge_p3_tobytes(sm, ref R); | 2257 ge_p3_tobytes(sig, ref R); |
2400 | 2258 |
2401 crypto_hash.sha512.crypto_hash(hram, sm, mlen + 64); | 2259 hashstate.init(); |
2260 hashstate.process(sig, 32); | |
2261 hashstate.process(sk + 32, 32); | |
2262 hashstate.process(m, (int)mlen); | |
2263 Byte* hram = stackalloc Byte[64]; | |
2264 hashstate.finish(hram); | |
2402 sc_reduce(hram); | 2265 sc_reduce(hram); |
2403 sc_muladd(sm + 32, hram, az, r); | 2266 sc_muladd(sig + 32, hram, az, r); |
2404 } | 2267 } |
2405 | 2268 |
2406 static unsafe void fe_frombytes(out fe h, Byte* s) { | 2269 static fe d = new fe(0, new Int32[10] { -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 }); |
2407 Int64 h0 = load_4(s); | 2270 static fe sqrtm1 = new fe(0, new Int32[10] { -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 }); |
2408 Int64 h1 = load_3(s + 4) << 6; | 2271 |
2409 Int64 h2 = load_3(s + 7) << 5; | |
2410 Int64 h3 = load_3(s + 10) << 3; | |
2411 Int64 h4 = load_3(s + 13) << 2; | |
2412 Int64 h5 = load_4(s + 16); | |
2413 Int64 h6 = load_3(s + 20) << 7; | |
2414 Int64 h7 = load_3(s + 23) << 5; | |
2415 Int64 h8 = load_3(s + 26) << 4; | |
2416 Int64 h9 = (load_3(s + 29) & 8388607) << 2; | |
2417 Int64 carry0; | |
2418 Int64 carry1; | |
2419 Int64 carry2; | |
2420 Int64 carry3; | |
2421 Int64 carry4; | |
2422 Int64 carry5; | |
2423 Int64 carry6; | |
2424 Int64 carry7; | |
2425 Int64 carry8; | |
2426 Int64 carry9; | |
2427 | |
2428 carry9 = (h9 + (Int64)(1 << 24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; | |
2429 carry1 = (h1 + (Int64)(1 << 24)) >> 25; h2 += carry1; h1 -= carry1 << 25; | |
2430 carry3 = (h3 + (Int64)(1 << 24)) >> 25; h4 += carry3; h3 -= carry3 << 25; | |
2431 carry5 = (h5 + (Int64)(1 << 24)) >> 25; h6 += carry5; h5 -= carry5 << 25; | |
2432 carry7 = (h7 + (Int64)(1 << 24)) >> 25; h8 += carry7; h7 -= carry7 << 25; | |
2433 | |
2434 carry0 = (h0 + (Int64)(1 << 25)) >> 26; h1 += carry0; h0 -= carry0 << 26; | |
2435 carry2 = (h2 + (Int64)(1 << 25)) >> 26; h3 += carry2; h2 -= carry2 << 26; | |
2436 carry4 = (h4 + (Int64)(1 << 25)) >> 26; h5 += carry4; h4 -= carry4 << 26; | |
2437 carry6 = (h6 + (Int64)(1 << 25)) >> 26; h7 += carry6; h6 -= carry6 << 26; | |
2438 carry8 = (h8 + (Int64)(1 << 25)) >> 26; h9 += carry8; h8 -= carry8 << 26; | |
2439 | |
2440 h = new fe(); | |
2441 h[0] = (Int32)h0; | |
2442 h[1] = (Int32)h1; | |
2443 h[2] = (Int32)h2; | |
2444 h[3] = (Int32)h3; | |
2445 h[4] = (Int32)h4; | |
2446 h[5] = (Int32)h5; | |
2447 h[6] = (Int32)h6; | |
2448 h[7] = (Int32)h7; | |
2449 h[8] = (Int32)h8; | |
2450 h[9] = (Int32)h9; | |
2451 } | |
2452 static Byte[] zero = new Byte[32]; | |
2453 static unsafe int fe_isnonzero(ref fe f) { | |
2454 Byte* s = stackalloc Byte[32]; | |
2455 fe_tobytes(s, ref f); | |
2456 fixed (Byte* zerop = zero) return crypto_verify._32.crypto_verify(s, zerop); | |
2457 } | |
2458 static fe d = fe_unpack(0, new Int32[10] { -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 }); | |
2459 static fe sqrtm1 = fe_unpack(0, new Int32[10] { -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 }); | |
2460 static void fe_pow22523(out fe outv, ref fe z) { | |
2461 fe t0; | |
2462 fe t1; | |
2463 fe t2; | |
2464 fe_sq(out t0, ref z); for (int i = 1; i < 1; ++i) fe_sq(out t0, ref t0); | |
2465 fe_sq(out t1, ref t0); for (int i = 1; i < 2; ++i) fe_sq(out t1, ref t1); | |
2466 fe_mul(out t1, ref z, ref t1); | |
2467 fe_mul(out t0, ref t0, ref t1); | |
2468 fe_sq(out t0, ref t0); for (int i = 1; i < 1; ++i) fe_sq(out t0, ref t0); | |
2469 fe_mul(out t0, ref t1, ref t0); | |
2470 fe_sq(out t1, ref t0); for (int i = 1; i < 5; ++i) fe_sq(out t1, ref t1); | |
2471 fe_mul(out t0, ref t1, ref t0); | |
2472 fe_sq(out t1, ref t0); for (int i = 1; i < 10; ++i) fe_sq(out t1, ref t1); | |
2473 fe_mul(out t1, ref t1, ref t0); | |
2474 fe_sq(out t2, ref t1); for (int i = 1; i < 20; ++i) fe_sq(out t2, ref t2); | |
2475 fe_mul(out t1, ref t2, ref t1); | |
2476 fe_sq(out t1, ref t1); for (int i = 1; i < 10; ++i) fe_sq(out t1, ref t1); | |
2477 fe_mul(out t0, ref t1, ref t0); | |
2478 fe_sq(out t1, ref t0); for (int i = 1; i < 50; ++i) fe_sq(out t1, ref t1); | |
2479 fe_mul(out t1, ref t1, ref t0); | |
2480 fe_sq(out t2, ref t1); for (int i = 1; i < 100; ++i) fe_sq(out t2, ref t2); | |
2481 fe_mul(out t1, ref t2, ref t1); | |
2482 fe_sq(out t1, ref t1); for (int i = 1; i < 50; ++i) fe_sq(out t1, ref t1); | |
2483 fe_mul(out t0, ref t1, ref t0); | |
2484 fe_sq(out t0, ref t0); for (int i = 1; i < 2; ++i) fe_sq(out t0, ref t0); | |
2485 fe_mul(out outv, ref t0, ref z); | |
2486 } | |
2487 static unsafe Boolean ge_frombytes_negate_vartime(out ge_p3 h, Byte* s) { | 2272 static unsafe Boolean ge_frombytes_negate_vartime(out ge_p3 h, Byte* s) { |
2488 fe u; | 2273 fe u; |
2489 fe v; | 2274 fe v; |
2490 fe v3; | 2275 fe v3; |
2491 fe vxx; | 2276 fe vxx; |
2492 fe check; | 2277 fe check; |
2493 | 2278 |
2494 fe_frombytes(out h.Y, s); | 2279 h = new ge_p3(); |
2495 fe_1(out h.Z); | 2280 |
2281 h.Y.frombytes(s); | |
2282 h.Z.set_one(); | |
2496 fe_sq(out u, ref h.Y); | 2283 fe_sq(out u, ref h.Y); |
2497 fe_mul(out v, ref u, ref d); | 2284 fe_mul(out v, ref u, ref d); |
2498 fe_sub(out u, ref u, ref h.Z); /* u = y^2-1 */ | 2285 u.sub(ref h.Z); /* u = y^2-1 */ |
2499 fe_add(out v, ref v, ref h.Z); /* v = dy^2+1 */ | 2286 v.add(ref h.Z); /* v = dy^2+1 */ |
2500 | 2287 |
2501 fe_sq(out v3, ref v); | 2288 fe_sq(out v3, ref v); |
2502 fe_mul(out v3, ref v3, ref v); /* v3 = v^3 */ | 2289 v3.mul(ref v); /* v3 = v^3 */ |
2503 fe_sq(out h.X, ref v3); | 2290 fe_sq(out h.X, ref v3); |
2504 fe_mul(out h.X, ref h.X, ref v); | 2291 h.X.mul(ref v); |
2505 fe_mul(out h.X, ref h.X, ref u); /* x = uv^7 */ | 2292 h.X.mul(ref u); /* x = uv^7 */ |
2506 | 2293 |
2507 fe_pow22523(out h.X, ref h.X); /* x = (uv^7)^((q-5)/8) */ | 2294 h.X.pow22523(); /* x = (uv^7)^((q-5)/8) */ |
2508 fe_mul(out h.X, ref h.X, ref v3); | 2295 h.X.mul(ref v3); |
2509 fe_mul(out h.X, ref h.X, ref u); /* x = uv^3(uv^7)^((q-5)/8) */ | 2296 h.X.mul(ref u); /* x = uv^3(uv^7)^((q-5)/8) */ |
2510 | 2297 |
2511 fe_sq(out vxx, ref h.X); | 2298 fe_sq(out vxx, ref h.X); |
2512 fe_mul(out vxx, ref vxx, ref v); | 2299 vxx.mul(ref v); |
2513 fe_sub(out check, ref vxx, ref u); /* vx^2-u */ | 2300 fe_sub(out check, ref vxx, ref u); /* vx^2-u */ |
2514 if (fe_isnonzero(ref check) != 0) { | 2301 if (check.isnonzero() != 0) { |
2515 fe_add(out check, ref vxx, ref u); /* vx^2+u */ | 2302 fe_add(out check, ref vxx, ref u); /* vx^2+u */ |
2516 if (fe_isnonzero(ref check) != 0) return false; | 2303 if (check.isnonzero() != 0) return false; |
2517 fe_mul(out h.X, ref h.X, ref sqrtm1); | 2304 h.X.mul(ref sqrtm1); |
2518 } | 2305 } |
2519 | 2306 |
2520 if (fe_isnegative(ref h.X) == (s[31] >> 7)) | 2307 if (h.X.isnegative() == (s[31] >> 7)) h.X.neg(); |
2521 fe_neg(out h.X, ref h.X); | |
2522 | 2308 |
2523 fe_mul(out h.T, ref h.X, ref h.Y); | 2309 fe_mul(out h.T, ref h.X, ref h.Y); |
2524 return true; | 2310 return true; |
2525 } | |
2526 struct ge_cached { | |
2527 public fe YplusX; | |
2528 public fe YminusX; | |
2529 public fe Z; | |
2530 public fe T2d; | |
2531 } | 2311 } |
2532 static unsafe void slide(SByte* r, Byte* a) { | 2312 static unsafe void slide(SByte* r, Byte* a) { |
2533 for (int i = 0; i < 256; ++i) r[i] = (SByte)(1 & (a[i >> 3] >> (i & 7))); | 2313 for (int i = 0; i < 256; ++i) r[i] = (SByte)(1 & (a[i >> 3] >> (i & 7))); |
2534 | 2314 |
2535 for (int i = 0; i < 256; ++i) | 2315 for (int i = 0; i < 256; ++i) |
2551 break; | 2331 break; |
2552 } | 2332 } |
2553 } | 2333 } |
2554 } | 2334 } |
2555 } | 2335 } |
2556 static ge_precomp[] Bi = base_unpack(8, 0, new Int32[8 * 3 * 10] { | 2336 static ge_precomp[] Bi = base_unpack(8, new Int32[8 * 3 * 10] { |
2557 #region Base number | 2337 #region Base number |
2558 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605, | 2338 25967493,-14356035,29566456,3660896,-12694345,4014787,27544626,-11754271,-6079156,2047605, |
2559 -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378, | 2339 -12545711,934262,-2722910,3049990,-727428,9406986,12720692,5043384,19500929,-15469378, |
2560 -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546, | 2340 -8738181,4489570,9688441,-14785194,10184609,-12363380,29287919,11864899,-24514362,-4438546, |
2561 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024, | 2341 15636291,-9688557,24204773,-7912398,616977,-16685262,27787600,-14772189,28944400,-1550024, |
2579 -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876, | 2359 -3151181,-5046075,9282714,6866145,-31907062,-863023,-18940575,15033784,25105118,-7894876, |
2580 -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619, | 2360 -24326370,15950226,-31801215,-14592823,-11662737,-5090925,1573892,-2625887,2198790,-15804619, |
2581 -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683, | 2361 -3099351,10324967,-2241613,7453183,-5446979,-2735503,-13812022,-16236442,-32461234,-12290683, |
2582 #endregion | 2362 #endregion |
2583 }); | 2363 }); |
2584 static fe d2 = fe_unpack(0, new Int32[10] { -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }); | 2364 static fe d2 = new fe(0, new Int32[10] { -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }); |
2585 static void ge_p3_to_cached(out ge_cached r, ref ge_p3 p) { | 2365 static void ge_p3_to_cached(out ge_cached r, ref ge_p3 p) { |
2586 fe_add(out r.YplusX, ref p.Y, ref p.X); | 2366 fe_add(out r.YplusX, ref p.Y, ref p.X); |
2587 fe_sub(out r.YminusX, ref p.Y, ref p.X); | 2367 fe_sub(out r.YminusX, ref p.Y, ref p.X); |
2588 fe_copy(out r.Z, ref p.Z); | 2368 r.Z = p.Z; |
2589 fe_mul(out r.T2d, ref p.T, ref d2); | 2369 fe_mul(out r.T2d, ref p.T, ref d2); |
2590 } | 2370 } |
2591 static void ge_add(out ge_p1p1 r, ref ge_p3 p, ref ge_cached q) { | 2371 static void ge_add(out ge_p1p1 r, ref ge_p3 p, ref ge_cached q) { |
2592 fe t0; | 2372 fe t0; |
2593 fe_add(out r.X, ref p.Y, ref p.X); | 2373 fe_add(out r.X, ref p.Y, ref p.X); |
2600 fe_sub(out r.X, ref r.Z, ref r.Y); | 2380 fe_sub(out r.X, ref r.Z, ref r.Y); |
2601 fe_add(out r.Y, ref r.Z, ref r.Y); | 2381 fe_add(out r.Y, ref r.Z, ref r.Y); |
2602 fe_add(out r.Z, ref t0, ref r.T); | 2382 fe_add(out r.Z, ref t0, ref r.T); |
2603 fe_sub(out r.T, ref t0, ref r.T); | 2383 fe_sub(out r.T, ref t0, ref r.T); |
2604 } | 2384 } |
2605 static void ge_p2_0(out ge_p2 h) { | |
2606 fe_0(out h.X); | |
2607 fe_1(out h.Y); | |
2608 fe_1(out h.Z); | |
2609 } | |
2610 static void ge_sub(out ge_p1p1 r, ref ge_p3 p, ref ge_cached q) { | 2385 static void ge_sub(out ge_p1p1 r, ref ge_p3 p, ref ge_cached q) { |
2611 fe t0; | 2386 fe t0; |
2612 fe_add(out r.X, ref p.Y, ref p.X); | 2387 fe_add(out r.X, ref p.Y, ref p.X); |
2613 fe_sub(out r.Y, ref p.Y, ref p.X); | 2388 fe_sub(out r.Y, ref p.Y, ref p.X); |
2614 fe_mul(out r.Z, ref r.X, ref q.YminusX); | 2389 fe_mul(out r.Z, ref r.X, ref q.YminusX); |
2639 SByte* bslide = stackalloc SByte[256]; | 2414 SByte* bslide = stackalloc SByte[256]; |
2640 ge_cached* Ai = stackalloc ge_cached[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ | 2415 ge_cached* Ai = stackalloc ge_cached[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ |
2641 ge_p1p1 t; | 2416 ge_p1p1 t; |
2642 ge_p3 u; | 2417 ge_p3 u; |
2643 ge_p3 A2; | 2418 ge_p3 A2; |
2644 int i; | |
2645 | 2419 |
2646 slide(aslide, a); | 2420 slide(aslide, a); |
2647 slide(bslide, b); | 2421 slide(bslide, b); |
2648 | 2422 |
2649 ge_p3_to_cached(out Ai[0], ref A); | 2423 ge_p3_to_cached(out Ai[0], ref A); |
2654 ge_add(out t, ref A2, ref Ai[3]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[4], ref u); | 2428 ge_add(out t, ref A2, ref Ai[3]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[4], ref u); |
2655 ge_add(out t, ref A2, ref Ai[4]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[5], ref u); | 2429 ge_add(out t, ref A2, ref Ai[4]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[5], ref u); |
2656 ge_add(out t, ref A2, ref Ai[5]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[6], ref u); | 2430 ge_add(out t, ref A2, ref Ai[5]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[6], ref u); |
2657 ge_add(out t, ref A2, ref Ai[6]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[7], ref u); | 2431 ge_add(out t, ref A2, ref Ai[6]); ge_p1p1_to_p3(out u, ref t); ge_p3_to_cached(out Ai[7], ref u); |
2658 | 2432 |
2659 ge_p2_0(out r); | 2433 r = new ge_p2(); r.set_zero(); |
2660 | 2434 |
2661 for (i = 255; i >= 0; --i) { | 2435 int i; |
2662 if ((aslide[i] != 0) || (bslide[i] != 0)) break; | 2436 for (i = 255; i >= 0 && aslide[i] == 0 && bslide[i] == 0; i--); |
2663 } | 2437 for (; i >= 0; i--) { |
2664 | |
2665 for (; i >= 0; --i) { | |
2666 ge_p2_dbl(out t, ref r); | 2438 ge_p2_dbl(out t, ref r); |
2667 | 2439 |
2668 if (aslide[i] > 0) { | 2440 if (aslide[i] > 0) { |
2669 ge_p1p1_to_p3(out u, ref t); | 2441 ge_p1p1_to_p3(out u, ref t); |
2670 ge_add(out t, ref u, ref Ai[aslide[i] / 2]); | 2442 ge_add(out t, ref u, ref Ai[aslide[i] / 2]); |
2683 | 2455 |
2684 ge_p1p1_to_p2(out r, ref t); | 2456 ge_p1p1_to_p2(out r, ref t); |
2685 } | 2457 } |
2686 } | 2458 } |
2687 static unsafe void ge_tobytes(Byte* s, ref ge_p2 h) { | 2459 static unsafe void ge_tobytes(Byte* s, ref ge_p2 h) { |
2688 fe recip; | 2460 fe recip = h.Z; recip.invert(); |
2689 fe x; | 2461 fe x = h.X; x.mul(ref recip); |
2690 fe y; | 2462 fe y = h.Y; y.mul(ref recip); |
2691 fe_invert(out recip, ref h.Z); | 2463 y.tobytes(s); |
2692 fe_mul(out x, ref h.X, ref recip); | 2464 s[31] ^= (Byte)(x.isnegative() << 7); |
2693 fe_mul(out y, ref h.Y, ref recip); | 2465 } |
2694 fe_tobytes(s, ref y); | 2466 public static unsafe Boolean crypto_sign_open(Byte[] m, int moffset, out int mlen, Byte[] sm, int smoffset, int smlen, Byte[] pk) { |
2695 s[31] ^= (Byte)(fe_isnegative(ref x) << 7); | |
2696 } | |
2697 public static unsafe Boolean crypto_sign_open(Byte[] m, int moffset, out UInt64 mlen, Byte[] sm, int smoffset, UInt64 smlen, Byte[] pk) { | |
2698 if (smoffset + (int)smlen > sm.Length) throw new ArgumentException("signed message buffer is too small"); | 2467 if (smoffset + (int)smlen > sm.Length) throw new ArgumentException("signed message buffer is too small"); |
2699 if (moffset + (int)smlen > m.Length) throw new ArgumentException("message buffer is too small"); | 2468 if (moffset + (int)smlen > m.Length) throw new ArgumentException("message buffer is too small"); |
2700 if (32 > pk.Length) throw new ArgumentException("key buffer is too small"); | 2469 if (32 > pk.Length) throw new ArgumentException("key buffer is too small"); |
2701 fixed (Byte* mp = m, smp = sm, pkp = pk) return crypto_sign_open(mp + moffset, out mlen, smp + smoffset, smlen, pkp); | 2470 fixed (Byte* mp = m, smp = sm, pkp = pk) return crypto_sign_open(mp + moffset, out mlen, smp + smoffset, smlen, pkp); |
2702 } | 2471 } |
2703 public static unsafe Boolean crypto_sign_open(Byte* m, out UInt64 mlen, Byte* sm, UInt64 smlen, Byte* pk) { | 2472 public static unsafe Boolean crypto_sign_open(Byte* m, out int mlen, Byte* sm, int smlen, Byte* pk) { |
2704 Byte* h = stackalloc Byte[64]; | 2473 mlen = 0; |
2705 Byte* checkr = stackalloc Byte[32]; | 2474 if (!crypto_sign_verify(sm, sm + 64, (int)smlen - 64, pk)) return false; |
2706 ge_p3 A; | 2475 for (int i = 0; i < smlen - 64; ++i) m[i] = sm[64 + i]; |
2707 ge_p2 R; | |
2708 | |
2709 mlen = unchecked((UInt64)(-1)); | |
2710 if (smlen < 64) return false; | |
2711 if ((sm[63] & 224) != 0) return false; | |
2712 if (!ge_frombytes_negate_vartime(out A, pk)) return false; | |
2713 | |
2714 for (UInt64 i = 0; i < smlen; ++i) m[i] = sm[i]; | |
2715 for (UInt64 i = 0; i < 32; ++i) m[32 + i] = pk[i]; | |
2716 crypto_hash.sha512.crypto_hash(h, m, smlen); | |
2717 sc_reduce(h); | |
2718 | |
2719 ge_double_scalarmult_vartime(out R, h, ref A, sm + 32); | |
2720 ge_tobytes(checkr, ref R); | |
2721 if (crypto_verify._32.crypto_verify(checkr, sm) != 0) { | |
2722 for (UInt64 i = 0; i < smlen; ++i) m[i] = 0; | |
2723 return false; | |
2724 } | |
2725 | |
2726 for (UInt64 i = 0; i < smlen - 64; ++i) m[i] = sm[64 + i]; | |
2727 for (UInt64 i = smlen - 64; i < smlen; ++i) m[i] = 0; | |
2728 mlen = smlen - 64; | 2476 mlen = smlen - 64; |
2729 return true; | 2477 return true; |
2730 } | 2478 } |
2479 public static unsafe Boolean crypto_sign_verify(Byte* sig, Byte* m, int mlen, Byte* pk) { | |
2480 if (mlen < 0) return false; | |
2481 if ((sig[63] & 224) != 0) return false; | |
2482 ge_p3 A; | |
2483 if (!ge_frombytes_negate_vartime(out A, pk)) return false; | |
2484 | |
2485 sha512.sha512state hashstate = new sha512.sha512state(); | |
2486 hashstate.init(); | |
2487 hashstate.process(sig, 32); | |
2488 hashstate.process(pk, 32); | |
2489 hashstate.process(m, mlen); | |
2490 Byte* h = stackalloc Byte[64]; | |
2491 hashstate.finish(h); | |
2492 sc_reduce(h); | |
2493 | |
2494 ge_p2 R; | |
2495 ge_double_scalarmult_vartime(out R, h, ref A, sig + 32); | |
2496 ge_tobytes(h, ref R); | |
2497 return crypto_verify._32.crypto_verify(h, sig) == 0; | |
2498 } | |
2731 } | 2499 } |
2732 } | 2500 } |