Initial commit.
[BoarSSL] / Crypto / ModInt.cs
1 /*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 using System;
26
27 namespace Crypto {
28
29 /*
30 * Mutable container for a modular integer.
31 *
32 * Rules:
33 *
34 * - Each instance is initialised over a given modulus, or by
35 * duplicating an existing instance.
36 *
37 * - All operands for a given operation must share the same modulus,
38 * i.e. the instances must have been created with Dup() calls from
39 * a common ancestor.
40 *
41 * - Modulus must be odd and greater than 1.
42 */
43
44 public class ModInt {
45
46 /*
47 * Dedicated class for a modulus. It maintains some useful
48 * values that depend only on the modulus.
49 */
50 class ZMod {
51
52 /*
53 * val = modulus value, 31 bits per word, little-endian
54 * bitLen = modulus bit length (exact)
55 * n0i is such that n0i * val[0] == -1 mod 2^31
56 * R = 2^(31*val.Length) (modular)
57 * R2 = 2^(31*(val.Length*2)) (modular)
58 * Rx[i] = 2^(31*(val.Length+(2^i))) (modular)
59 */
60 internal uint[] val;
61 internal int bitLen;
62 internal uint n0i;
63 internal uint[] R;
64 internal uint[] R2;
65 internal uint[][] Rx;
66 internal byte[] vm2;
67
68 internal ZMod(byte[] bmod, int off, int len)
69 {
70 bitLen = BigInt.BitLength(bmod, off, len);
71 if (bitLen <= 1 || (bmod[off + len - 1] & 1) == 0) {
72 throw new CryptoException("invalid modulus");
73 }
74 int n = (bitLen + 30) / 31;
75 val = new uint[n];
76 DecodeBE(bmod, off, len, val);
77 uint x = val[0];
78 uint y = 2 - x;
79 y *= 2 - y * x;
80 y *= 2 - y * x;
81 y *= 2 - y * x;
82 y *= 2 - y * x;
83 n0i = (1 + ~y) & 0x7FFFFFFF;
84
85 /*
86 * Compute the Rx[] values.
87 */
88 int zk = 0;
89 while ((n >> zk) != 0) {
90 zk ++;
91 }
92 R = new uint[n];
93 R[n - 1] = 1;
94 for (int i = 0; i < 31; i ++) {
95 ModMul2(R, val);
96 }
97 Rx = new uint[zk][];
98 Rx[0] = new uint[n];
99 Array.Copy(R, 0, Rx[0], 0, n);
100 for (int i = 0; i < 31; i ++) {
101 ModMul2(Rx[0], val);
102 }
103 for (int k = 1; k < zk; k ++) {
104 Rx[k] = new uint[n];
105 MontyMul(Rx[k - 1], Rx[k - 1], Rx[k], val, n0i);
106 }
107
108 /*
109 * Compute R2 by multiplying the relevant Rx[]
110 * values.
111 */
112 R2 = null;
113 uint[] tt = new uint[n];
114 for (int k = 0; k < zk; k ++) {
115 if (((n >> k) & 1) == 0) {
116 continue;
117 }
118 if (R2 == null) {
119 R2 = new uint[n];
120 Array.Copy(Rx[k], 0, R2, 0, n);
121 } else {
122 MontyMul(Rx[k], R2, tt, val, n0i);
123 Array.Copy(tt, 0, R2, 0, n);
124 }
125 }
126
127 /*
128 * Compute N-2; used as an exponent for modular
129 * inversion. Since modulus N is odd and greater
130 * than 1, N-2 is necessarily positive.
131 */
132 vm2 = new byte[(bitLen + 7) >> 3];
133 int cc = 2;
134 for (int i = 0; i < vm2.Length; i ++) {
135 int b = bmod[off + len - 1 - i];
136 b -= cc;
137 vm2[vm2.Length - 1 - i] = (byte)b;
138 cc = (b >> 8) & 1;
139 }
140 }
141 }
142
143 ZMod mod;
144 uint[] val;
145 uint[] tmp1, tmp2;
146
147 /*
148 * Get the modulus bit length.
149 */
150 public int ModBitLength {
151 get {
152 return mod.bitLen;
153 }
154 }
155
156 /*
157 * Test whether this value is zero.
158 */
159 public bool IsZero {
160 get {
161 return IsZeroCT != 0;
162 }
163 }
164
165 public uint IsZeroCT {
166 get {
167 int z = (int)val[0];
168 for (int i = 1; i < val.Length; i ++) {
169 z |= (int)val[i];
170 }
171 return ~(uint)((z | -z) >> 31);
172 }
173 }
174
175 /*
176 * Test whether this value is one.
177 */
178 public bool IsOne {
179 get {
180 return IsOneCT != 0;
181 }
182 }
183
184 public uint IsOneCT {
185 get {
186 int z = (int)val[0] ^ 1;
187 for (int i = 1; i < val.Length; i ++) {
188 z |= (int)val[i];
189 }
190 return ~(uint)((z | -z) >> 31);
191 }
192 }
193
194 ModInt(ZMod m)
195 {
196 Init(m);
197 }
198
199 /*
200 * Create a new instance by decoding the provided modulus
201 * (unsigned big-endian). Value is zero.
202 */
203 public ModInt(byte[] modulus)
204 : this(modulus, 0, modulus.Length)
205 {
206 }
207
208 /*
209 * Create a new instance by decoding the provided modulus
210 * (unsigned big-endian). Value is zero.
211 */
212 public ModInt(byte[] modulus, int off, int len)
213 {
214 Init(new ZMod(modulus, off, len));
215 }
216
217 void Init(ZMod mod)
218 {
219 this.mod = mod;
220 int n = mod.val.Length;
221 val = new uint[n];
222 tmp1 = new uint[n];
223 tmp2 = new uint[n];
224 }
225
226 /*
227 * Duplicate this instance. The new instance uses the same
228 * modulus, and its value is initialized to the same value as
229 * this instance.
230 */
231 public ModInt Dup()
232 {
233 ModInt m = new ModInt(mod);
234 Array.Copy(val, 0, m.val, 0, val.Length);
235 return m;
236 }
237
238 /*
239 * Set the value in this instance to a copy of the value in
240 * the provided instance. The 'm' instance may use a different
241 * modulus, in which case the value may incur modular reduction.
242 */
243 public void Set(ModInt m)
244 {
245 /*
246 * If the instances use the same modulus array, then
247 * the value can simply be copied as is.
248 */
249 if (mod == m.mod) {
250 Array.Copy(m.val, 0, val, 0, val.Length);
251 return;
252 }
253 Reduce(m.val);
254 }
255
256 /*
257 * Set the value in this instance to a copy of the value in
258 * the provided instance, but do so only conditionally. If
259 * 'ctl' is -1, then the copy is done. If 'ctl' is 0, then the
260 * copy is NOT done. This instance and the source instance
261 * MUST use the same modulus.
262 */
263 public void CondCopy(ModInt m, uint ctl)
264 {
265 if (mod != m.mod) {
266 throw new CryptoException("Not same modulus");
267 }
268 for (int i = 0; i < val.Length; i ++) {
269 uint w = val[i];
270 val[i] = w ^ (ctl & (m.val[i] ^ w));
271 }
272 }
273
274 /*
275 * Set the value in this instance to a copy of either 'a'
276 * (if ctl is -1) or 'b' (if ctl is 0).
277 */
278 public void CopyMux(uint ctl, ModInt a, ModInt b)
279 {
280 if (mod != a.mod || mod != b.mod) {
281 throw new CryptoException("Not same modulus");
282 }
283 for (int i = 0; i < val.Length; i ++) {
284 uint aw = a.val[i];
285 uint bw = b.val[i];
286 val[i] = bw ^ (ctl & (aw ^ bw));
287 }
288 }
289
290 /*
291 * Set the value in this instance to the provided integer value
292 * (which MUST be nonnegative).
293 */
294 public void Set(int x)
295 {
296 val[0] = (uint)x;
297 for (int i = 1; i < val.Length; i ++) {
298 val[i] = 0;
299 }
300 }
301
302 /*
303 * Set this value to either 0 (if ctl is 0) or 1 (if ctl is -1),
304 * in Montgomery representation.
305 */
306 public void SetMonty(uint ctl)
307 {
308 for (int i = 0; i < val.Length; i ++) {
309 val[i] = ctl & mod.R[i];
310 }
311 }
312
313 /*
314 * Set this value by decoding the provided integer (big-endian
315 * unsigned encoding). If the source value does not fit (it is
316 * not lower than the modulus), then this method return 0, and
317 * this instance is set to 0. Otherwise, it returns -1.
318 */
319 public uint Decode(byte[] buf)
320 {
321 return Decode(buf, 0, buf.Length);
322 }
323
324 /*
325 * Set this value by decoding the provided integer (big-endian
326 * unsigned encoding). If the source value does not fit (it is
327 * not lower than the modulus), then this method return 0, and
328 * this instance is set to 0. Otherwise, it returns -1.
329 */
330 public uint Decode(byte[] buf, int off, int len)
331 {
332 /*
333 * Decode into val[]; if the truncation loses some
334 * non-zero bytes, then this returns 0.
335 */
336 uint x = DecodeBE(buf, off, len, val);
337
338 /*
339 * Compare with modulus. We want to get a 0 if the
340 * subtraction would not yield a carry, i.e. the
341 * source value is not lower than the modulus.
342 */
343 x &= Sub(val, mod.val, 0);
344
345 /*
346 * At that point, x is -1 if the value fits, 0
347 * otherwise.
348 */
349 for (int i = 0; i < val.Length; i ++) {
350 val[i] &= x;
351 }
352 return x;
353 }
354
355 /*
356 * Set this value by decoding the provided integer (big-endian
357 * unsigned encoding). The source value is reduced if necessary.
358 */
359 public void DecodeReduce(byte[] buf)
360 {
361 DecodeReduce(buf, 0, buf.Length);
362 }
363
364 /*
365 * Set this value by decoding the provided integer (big-endian
366 * unsigned encoding). The source value is reduced if necessary.
367 */
368 public void DecodeReduce(byte[] buf, int off, int len)
369 {
370 uint[] x = new uint[((len << 3) + 30) / 31];
371 DecodeBE(buf, off, len, x);
372 Reduce(x);
373 }
374
375 /*
376 * Set the value from the provided source array, with modular
377 * reduction.
378 */
379 void Reduce(uint[] b)
380 {
381 /*
382 * If the modulus uses only one word then we must use
383 * a special code path.
384 */
385 if (mod.val.Length == 1) {
386 ReduceSmallMod(b);
387 return;
388 }
389
390 /*
391 * Fast copy of words that do not incur modular
392 * reduction.
393 */
394 int aLen = mod.val.Length;
395 int bLen = b.Length;
396 int cLen = Math.Min(aLen - 1, bLen);
397 Array.Copy(b, bLen - cLen, val, 0, cLen);
398 for (int i = cLen; i < aLen; i ++) {
399 val[i] = 0;
400 }
401
402 /*
403 * Inject extra words. We use the pre-computed
404 * Rx[] values to do shifts.
405 */
406 for (int j = bLen - cLen; j > 0;) {
407 /*
408 * We can add power-of-2 words, but less
409 * than the modulus size. Note that the modulus
410 * uses at least two words, so this process works.
411 */
412 int k;
413 for (k = 0;; k ++) {
414 int nk = 1 << (k + 1);
415 if (nk >= aLen || nk > j) {
416 break;
417 }
418 }
419 int num = 1 << k;
420 MontyMul(val, mod.Rx[k], tmp1, mod.val, mod.n0i);
421 j -= num;
422 Array.Copy(b, j, tmp2, 0, num);
423 for (int i = num; i < tmp2.Length; i ++) {
424 tmp2[i] = 0;
425 }
426 ModAdd(tmp1, tmp2, val, mod.val, 0);
427 }
428 }
429
430 /*
431 * Modular reduction in case the modulus fits on a single
432 * word.
433 */
434 void ReduceSmallMod(uint[] b)
435 {
436 uint x = 0;
437 uint n = mod.val[0];
438 int nlen = mod.bitLen;
439 uint n0i = mod.n0i;
440 uint r2 = mod.R2[0];
441 for (int i = b.Length - 1; i >= 0; i --) {
442 /*
443 * Multiply x by R (Montgomery multiplication by R^2).
444 */
445 ulong z = (ulong)x * (ulong)r2;
446 uint u = ((uint)z * n0i) & 0x7FFFFFFF;
447 z += (ulong)u * (ulong)n;
448 x = (uint)(z >> 31);
449
450 /*
451 * Ensure x fits on 31 bits (it may be up to twice
452 * the modulus at that point). If x >= 2^31 then,
453 * necessarily, x is greater than the modulus, and
454 * the subtraction is sound; moreover, in that case,
455 * subtracting the modulus brings back x to less
456 * than the modulus, hence fitting on 31 bits.
457 */
458 x -= (uint)((int)x >> 31) & n;
459
460 /*
461 * Add the next word, then reduce. The addition
462 * does not overflow since both operands fit on
463 * 31 bits.
464 *
465 * Since the modulus could be much smaller than
466 * 31 bits, we need a full remainder operation here.
467 */
468 x += b[i];
469
470 /*
471 * Constant-time modular reduction.
472 * We first perform two subtraction of the
473 * shifted modulus to ensure that the high bit
474 * is cleared. This allows the loop to work
475 * properly.
476 */
477 x -= (uint)((int)x >> 31) & (n << (31 - nlen));
478 x -= (uint)((int)x >> 31) & (n << (31 - nlen));
479 for (int j = 31 - nlen; j >= 0; j --) {
480 x -= (n << j);
481 x += (uint)((int)x >> 31) & (n << j);
482 }
483 }
484 val[0] = x;
485 }
486
487 /*
488 * Encode into bytes. Big-endian unsigned encoding is used, the
489 * returned array having the minimal length to encode the modulus.
490 */
491 public byte[] Encode()
492 {
493 return Encode(false);
494 }
495
496 /*
497 * Encode into bytes. Big-endian encoding is used; if 'signed' is
498 * true, then signed encoding is used: returned value will have a
499 * leading bit set to 0. Returned array length is the minimal size
500 * for encoding the modulus (with a sign bit if using signed
501 * encoding).
502 */
503 public byte[] Encode(bool signed)
504 {
505 int x = mod.bitLen;
506 if (signed) {
507 x ++;
508 }
509 byte[] buf = new byte[(x + 7) >> 3];
510 Encode(buf, 0, buf.Length);
511 return buf;
512 }
513
514 /*
515 * Encode into bytes. The provided array is fully set; big-endian
516 * encoding is used, and extra leading bytes of value 0 are added
517 * if necessary. If the destination array is too small, then the
518 * value is silently truncated.
519 */
520 public void Encode(byte[] buf)
521 {
522 Encode(buf, 0, buf.Length);
523 }
524
525 /*
526 * Encode into bytes. The provided array chunk is fully set;
527 * big-endian encoding is used, and extra leading bytes of value
528 * 0 are added if necessary. If the destination array is too
529 * small, then the value is silently truncated.
530 */
531 public void Encode(byte[] buf, int off, int len)
532 {
533 EncodeBE(val, buf, off, len);
534 }
535
536 /*
537 * Get the least significant bit of the value (0 or 1).
538 */
539 public uint GetLSB()
540 {
541 return val[0] & (uint)1;
542 }
543
544 /*
545 * Add a small integer to this instance. The small integer
546 * 'x' MUST be lower than 2^31 and MUST be lower than the modulus.
547 */
548 public void Add(uint x)
549 {
550 tmp1[0] = x;
551 for (int i = 1; i < tmp1.Length; i ++) {
552 tmp1[i] = 0;
553 }
554 ModAdd(val, tmp1, val, mod.val, 0);
555 }
556
557 /*
558 * Add another value to this instance. The operand 'b' may
559 * be the same as this instance.
560 */
561 public void Add(ModInt b)
562 {
563 if (mod != b.mod) {
564 throw new CryptoException("Not same modulus");
565 }
566 ModAdd(val, b.val, val, mod.val, 0);
567 }
568
569 /*
570 * Subtract a small integer from this instance. The small integer
571 * 'x' MUST be lower than 2^31 and MUST be lower than the modulus.
572 */
573 public void Sub(uint x)
574 {
575 tmp1[0] = x;
576 for (int i = 1; i < tmp1.Length; i ++) {
577 tmp1[i] = 0;
578 }
579 ModSub(val, tmp1, val, mod.val);
580 }
581
582 /*
583 * Subtract another value from this instance. The operand 'b'
584 * may be the same as this instance.
585 */
586 public void Sub(ModInt b)
587 {
588 if (mod != b.mod) {
589 throw new CryptoException("Not same modulus");
590 }
591 ModSub(val, b.val, val, mod.val);
592 }
593
594 /*
595 * Negate this value.
596 */
597 public void Negate()
598 {
599 ModSub(null, val, val, mod.val);
600 }
601
602 /*
603 * Convert this instance to Montgomery representation.
604 */
605 public void ToMonty()
606 {
607 MontyMul(val, mod.R2, tmp1, mod.val, mod.n0i);
608 Array.Copy(tmp1, 0, val, 0, val.Length);
609 }
610
611 /*
612 * Convert this instance back from Montgomery representation to
613 * normal representation.
614 */
615 public void FromMonty()
616 {
617 tmp1[0] = 1;
618 for (int i = 1; i < tmp1.Length; i ++) {
619 tmp1[i] = 0;
620 }
621 MontyMul(val, tmp1, tmp2, mod.val, mod.n0i);
622 Array.Copy(tmp2, 0, val, 0, val.Length);
623 }
624
625 /*
626 * Compute a Montgomery multiplication with the provided
627 * value. The other operand may be this instance.
628 */
629 public void MontyMul(ModInt b)
630 {
631 if (mod != b.mod) {
632 throw new CryptoException("Not same modulus");
633 }
634 MontyMul(val, b.val, tmp1, mod.val, mod.n0i);
635 Array.Copy(tmp1, 0, val, 0, val.Length);
636 }
637
638 /*
639 * Montgomery-square this instance.
640 */
641 public void MontySquare()
642 {
643 MontyMul(val, val, tmp1, mod.val, mod.n0i);
644 Array.Copy(tmp1, 0, val, 0, val.Length);
645 }
646
647 /*
648 * Perform modular exponentiation. Exponent is in big-endian
649 * unsigned encoding.
650 */
651 public void Pow(byte[] exp)
652 {
653 Pow(exp, 0, exp.Length);
654 }
655
656 /*
657 * Perform modular exponentiation. Exponent is in big-endian
658 * unsigned encoding.
659 */
660 public void Pow(byte[] exp, int off, int len)
661 {
662 MontyMul(val, mod.R2, tmp1, mod.val, mod.n0i);
663 val[0] = 1;
664 for (int i = 1; i < val.Length; i ++) {
665 val[i] = 0;
666 }
667 for (int i = 0; i < len; i ++) {
668 int x = exp[off + len - 1 - i];
669 for (int j = 0; j < 8; j ++) {
670 MontyMul(val, tmp1, tmp2, mod.val, mod.n0i);
671 uint ctl = (uint)-((x >> j) & 1);
672 for (int k = 0; k < val.Length; k ++) {
673 val[k] = (tmp2[k] & ctl)
674 | (val[k] & ~ctl);
675 }
676 MontyMul(tmp1, tmp1, tmp2, mod.val, mod.n0i);
677 Array.Copy(tmp2, 0, tmp1, 0, tmp2.Length);
678 }
679 }
680 }
681
682 /*
683 * Compute modular inverse of this value. If this instance is
684 * zero, then it remains equal to zero. If the modulus is not
685 * prime, then this function computes wrong values.
686 */
687 public void Invert()
688 {
689 Pow(mod.vm2);
690 }
691
692 /*
693 * Compute the square root for this value. This method assumes
694 * that the modulus is prime, greater than or equal to 7, and
695 * equal to 3 modulo 4; if it is not, then the returned value
696 * and the contents of this instance are indeterminate.
697 *
698 * Returned value is -1 if the value was indeed a square, 0
699 * otherwise. In the latter case, array contents are the square
700 * root of the opposite of the original value.
701 */
702 public uint SqrtBlum()
703 {
704 /*
705 * We suppose that p = 3 mod 4; we raise to the power
706 * (p-3)/4, then do an extra multiplication to go to
707 * power (p+1)/4.
708 *
709 * Since we know the modulus bit length, we can do
710 * the exponentiation from the high bits downwards.
711 */
712 ToMonty();
713 Array.Copy(val, 0, tmp1, 0, val.Length);
714 int k = (mod.bitLen - 2) / 31;
715 int j = mod.bitLen - 2 - k * 31;
716 uint ew = mod.val[k];
717 for (int i = mod.bitLen - 2; i >= 2; i --) {
718 uint ctl = ~(uint)-((int)(ew >> j) & 1);
719 MontyMul(tmp1, tmp1, tmp2, mod.val, mod.n0i);
720 MontyMul(val, tmp2, tmp1, mod.val, mod.n0i);
721 for (int m = 0; m < tmp1.Length; m ++) {
722 uint w = tmp1[m];
723 tmp1[m] = w ^ (ctl & (w ^ tmp2[m]));
724 }
725 if (-- j < 0) {
726 j = 30;
727 ew = mod.val[-- k];
728 }
729 }
730
731 /*
732 * The extra multiplication. Square root is written in
733 * tmp2 (in Montgomery representation).
734 */
735 MontyMul(val, tmp1, tmp2, mod.val, mod.n0i);
736
737 /*
738 * Square it back in tmp1, to see if it indeed yields
739 * val.
740 */
741 MontyMul(tmp2, tmp2, tmp1, mod.val, mod.n0i);
742 int z = 0;
743 for (int i = 0; i < val.Length; i ++) {
744 z |= (int)(val[i] ^ tmp1[i]);
745 }
746 uint good = ~(uint)((z | -z) >> 31);
747
748 /*
749 * Convert back the result to normal representation.
750 */
751 Array.Copy(tmp2, 0, val, 0, val.Length);
752 FromMonty();
753 return good;
754 }
755
756 /*
757 * Conditionally swap this instance with the one provided in
758 * parameter. The swap is performed if ctl is -1, not performed
759 * if ctl is 0.
760 */
761 public void CondSwap(ModInt b, uint ctl)
762 {
763 if (mod != b.mod) {
764 throw new CryptoException("Not same modulus");
765 }
766 for (int i = 0; i < val.Length; i ++) {
767 uint x = val[i];
768 uint y = b.val[i];
769 uint m = ctl & (x ^ y);
770 val[i] = x ^ m;
771 b.val[i] = y ^ m;
772 }
773 }
774
775 /*
776 * Compare for equality this value with another. Comparison still
777 * works if the two values use distinct moduli.
778 */
779 public bool Eq(ModInt b)
780 {
781 return EqCT(b) != 0;
782 }
783
784 /*
785 * Compare for equality this value with another. Comparison still
786 * works if the two values use distinct moduli. Returned value is
787 * -1 on equality, 0 otherwise.
788 */
789 public uint EqCT(ModInt b)
790 {
791 uint z = 0;
792 if (b.val.Length > val.Length) {
793 for (int i = 0; i < val.Length; i ++) {
794 z |= val[i] ^ b.val[i];
795 }
796 for (int i = val.Length; i < b.val.Length; i ++) {
797 z |= b.val[i];
798 }
799 } else {
800 for (int i = 0; i < b.val.Length; i ++) {
801 z |= val[i] ^ b.val[i];
802 }
803 for (int i = b.val.Length; i < val.Length; i ++) {
804 z |= b.val[i];
805 }
806 }
807 int x = (int)z;
808 return ~(uint)((x | -x) >> 31);
809 }
810
811 /* ============================================================== */
812
813 /*
814 * Decode value (unsigned big-endian) into dst[] (little-endian,
815 * 31 bits per word). All words of dst[] are initialised.
816 * Returned value is -1 on success, 0 if some non-zero source
817 * bits had to be ignored.
818 */
819 static uint DecodeBE(byte[] buf, int off, int len, uint[] dst)
820 {
821 int i = 0;
822 uint acc = 0;
823 int accLen = 0;
824 off += len;
825 while (i < dst.Length) {
826 uint b;
827 if (len > 0) {
828 b = buf[-- off];
829 len --;
830 } else {
831 b = 0;
832 }
833 acc |= (b << accLen);
834 accLen += 8;
835 if (accLen >= 31) {
836 dst[i ++] = acc & 0x7FFFFFFF;
837 accLen -= 31;
838 acc = b >> (8 - accLen);
839 }
840 }
841 while (len -- > 0) {
842 acc |= buf[-- off];
843 }
844 int x = (int)acc;
845 return ~(uint)((x | -x) >> 31);
846 }
847
848 /*
849 * Encode an integer (array of words, little-endian, 31 bits per
850 * word) into big-endian encoding, with the provided length (in
851 * bytes).
852 */
853 static byte[] EncodeBE(uint[] x, int len)
854 {
855 byte[] val = new byte[len];
856 EncodeBE(x, val, 0, len);
857 return val;
858 }
859
860 /*
861 * Encode an integer (array of words, little-endian, 31 bits per
862 * word) into big-endian encoding, with the provided length (in
863 * bytes).
864 */
865 static void EncodeBE(uint[] x, byte[] val)
866 {
867 EncodeBE(x, val, 0, val.Length);
868 }
869
870 /*
871 * Encode an integer (array of words, little-endian, 31 bits per
872 * word) into big-endian encoding, with the provided length (in
873 * bytes).
874 */
875 static void EncodeBE(uint[] x, byte[] val, int off, int len)
876 {
877 uint acc = 0;
878 int accLen = 0;
879 int j = 0;
880 for (int i = len - 1; i >= 0; i --) {
881 uint b;
882 if (accLen < 8) {
883 uint z = (j < x.Length) ? x[j ++] : 0;
884 b = acc | (z << accLen);
885 acc = z >> (8 - accLen);
886 accLen += 23;
887 } else {
888 b = acc;
889 accLen -= 8;
890 acc >>= 8;
891 }
892 val[off + i] = (byte)b;
893 }
894 }
895
896 /*
897 * Subtract b from a; the carry is returned (-1 if carry, 0
898 * otherwise). The operation is done only if ctl is -1; if
899 * ctl is 0, then a[] is unmodified, but the carry is still
900 * computed and returned.
901 *
902 * The two operand arrays MUST have the same size.
903 */
904 static uint Sub(uint[] a, uint[] b, uint ctl)
905 {
906 int n = a.Length;
907 int cc = 0;
908 ctl >>= 1;
909 for (int i = 0; i < n; i ++) {
910 uint aw = a[i];
911 uint bw = b[i];
912 uint cw = (uint)cc + aw - bw;
913 cc = (int)cw >> 31;
914 a[i] = (aw & ~ctl) | (cw & ctl);
915 }
916 return (uint)cc;
917 }
918
919 /*
920 * Left-shift value by one bit; the extra bit (carry) is
921 * return as -1 or 0.
922 */
923 static uint LShift(uint[] a)
924 {
925 int n = a.Length;
926 uint cc = 0;
927 for (int i = 0; i < n; i ++) {
928 uint aw = a[i];
929 a[i] = (cc | (aw << 1)) & 0x7FFFFFFF;
930 cc = aw >> 30;
931 }
932 return (uint)-(int)cc;
933 }
934
935 /*
936 * Modular left-shift value by one bit. Value and modulus MUST
937 * have the same length. Value MUST be lower than modulus.
938 */
939 static void ModMul2(uint[] a, uint[] mod)
940 {
941 int n = a.Length;
942
943 /*
944 * First pass: compute 2*a-mod, but don't keep the
945 * result, only the final carry (0 or -1).
946 */
947 uint cc1 = 0;
948 int cc2 = 0;
949 for (int i = 0; i < n; i ++) {
950 uint aw = a[i];
951 uint aws = ((aw << 1) | cc1) & 0x7FFFFFFF;
952 cc1 = aw >> 30;
953 uint z = aws - mod[i] + (uint)cc2;
954 cc2 = (int)z >> 31;
955 }
956 cc2 += (int)cc1;
957
958 /*
959 * If cc2 is 0, then the subtraction yields no carry and
960 * must be done. Otherwise, cc2 is -1, and the subtraction
961 * must not be done.
962 */
963 uint ctl = ~(uint)cc2;
964 cc1 = 0;
965 cc2 = 0;
966 for (int i = 0; i < n; i ++) {
967 uint aw = a[i];
968 uint aws = ((aw << 1) | cc1) & 0x7FFFFFFF;
969 cc1 = aw >> 30;
970 uint z = aws - (mod[i] & ctl) + (uint)cc2;
971 cc2 = (int)z >> 31;
972 a[i] = z & 0x7FFFFFFF;
973 }
974 }
975
976 /*
977 * Modular addition.
978 *
979 * If 'hi' is zero, then this computes a+b-n if a+b >= n,
980 * a+b otherwise.
981 *
982 * If 'hi' is non-zero, then this computes 2^k+a+b-n, where
983 * k = n.Length*31.
984 *
985 * Result is written in d[]. The same array may be used in
986 * several operands.
987 */
988 static void ModAdd(uint[] a, uint[] b, uint[] d, uint[] n, uint hi)
989 {
990 /*
991 * Set ctl to -1 if hi is non-zero, 0 otherwise.
992 * 'ctl' computes whether the subtraction with n[]
993 * is needed in the second pass.
994 */
995 int x = (int)hi;
996 uint ctl = (uint)((x | -x) >> 31);
997
998 for (int pass = 0; pass < 2; pass ++) {
999 /*
1000 * cc1 is the carry for a+b (0 or 1)
1001 *
1002 * cc2 is the carry for the modulus
1003 * subtraction (0 or -1)
1004 */
1005 uint cc1 = 0;
1006 int cc2 = 0;
1007 for (int i = 0; i < n.Length; i ++) {
1008 uint aw = a[i];
1009 uint bw = b[i];
1010 uint nw = n[i];
1011 uint sw = aw + bw + cc1;
1012 cc1 = sw >> 31;
1013 sw &= 0x7FFFFFFF;
1014 uint dw = sw - nw + (uint)cc2;
1015 cc2 = (int)dw >> 31;
1016 if (pass == 1) {
1017 dw &= 0x7FFFFFFF;
1018 d[i] = (dw & ctl) | (sw & ~ctl);
1019 }
1020 }
1021
1022 /*
1023 * Compute aggregate subtraction carry. This should
1024 * not be 1 if the operands are correct (it would
1025 * mean that a+b-n overflows, so both a and b are
1026 * larger than n). If it is 0, then a+b-n >= 0,
1027 * so the subtraction must be done; otherwise, the
1028 * aggregate carry will be -1, and the subtraction
1029 * should not be done (unless forced by a non-zero
1030 * 'hi' value).
1031 */
1032 cc2 += (int)cc1;
1033 ctl |= ~(uint)(cc2 >> 31);
1034 }
1035 }
1036
1037 /*
1038 * Modular subtraction.
1039 *
1040 * This computes a-b, then adds n if the result is negative.
1041 * If a is null, then it is assumed to be all-zeros.
1042 *
1043 * Result is written in d[]. The same array may be used in
1044 * several operands.
1045 */
1046 static void ModSub(uint[] a, uint[] b, uint[] d, uint[] n)
1047 {
1048 uint ctl = 0;
1049 for (int pass = 0; pass < 2; pass ++) {
1050 /*
1051 * cc1 = carry for a-b (0 or -1)
1052 * cc2 = carry for modulus addition (0 or 1)
1053 */
1054 int cc1 = 0;
1055 uint cc2 = 0;
1056 for (int i = 0; i < n.Length; i ++) {
1057 uint aw = (a == null) ? 0 : a[i];
1058 uint bw = b[i];
1059 uint nw = n[i];
1060 uint sw = aw - bw + (uint)cc1;
1061 cc1 = (int)sw >> 31;
1062 sw &= 0x7FFFFFFF;
1063 uint dw = sw + nw + cc2;
1064 cc2 = dw >> 31;
1065 if (pass == 1) {
1066 dw &= 0x7FFFFFFF;
1067 d[i] = (dw & ctl) | (sw & ~ctl);
1068 }
1069 }
1070
1071 /*
1072 * Modulus addition must be done if and only if
1073 * a-b had a final carry.
1074 */
1075 ctl = (uint)cc1;
1076 }
1077 }
1078
1079 /*
1080 * Compute Montgomery multiplication of a[] by b[], result in
1081 * d[], with modulus n[]. All arrays must have the same length.
1082 * d[] must be distinct from a[], b[] and n[]. Modulus must be
1083 * odd. n0i must be such that n[0]*n0i = -1 mod 2^31. Values a[]
1084 * and b[] must be lower than n[] (so, in particular, a[] and
1085 * b[] cannot be the same array as n[]).
1086 */
1087 static void MontyMul(uint[] a, uint[] b, uint[] d, uint[] n, uint n0i)
1088 {
1089 int len = n.Length;
1090 for (int i = 0; i < len; i ++) {
1091 d[i] = 0;
1092 }
1093 ulong dh = 0;
1094 for (int i = 0; i < len; i ++) {
1095 uint ai = a[i];
1096 uint u = ((d[0] + ai * b[0]) * n0i) & 0x7FFFFFFF;
1097 ulong cc = 0;
1098 for (int j = 0; j < len; j ++) {
1099 ulong z = (ulong)d[j]
1100 + (ulong)ai * (ulong)b[j]
1101 + (ulong)u * (ulong)n[j] + cc;
1102 cc = z >> 31;
1103 if (j > 0) {
1104 d[j - 1] = (uint)z & 0x7FFFFFFF;
1105 } else {
1106 // DEBUG
1107 if (((uint)z & 0x7FFFFFFF) != 0) {
1108 throw new Exception("BAD!");
1109 }
1110 }
1111 }
1112 dh += cc;
1113 d[len - 1] = (uint)dh & 0x7FFFFFFF;
1114 dh >>= 31;
1115 }
1116 int x = (int)dh;
1117 uint ctl = (uint)((x | -x) >> 31);
1118 Sub(d, n, ctl | ~Sub(d, n, 0));
1119 }
1120 }
1121
1122 }