123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- using System;
- using System.Diagnostics;
- using Org.BouncyCastle.Crypto.Utilities;
- using Org.BouncyCastle.Security;
- using Org.BouncyCastle.Utilities;
- namespace Org.BouncyCastle.Math.Raw
- {
- internal abstract class Mod
- {
- private static readonly SecureRandom RandomSource = new SecureRandom();
- public static void Invert(uint[] p, uint[] x, uint[] z)
- {
- int len = p.Length;
- if (Nat.IsZero(len, x))
- throw new ArgumentException("cannot be 0", "x");
- if (Nat.IsOne(len, x))
- {
- Array.Copy(x, 0, z, 0, len);
- return;
- }
- uint[] u = Nat.Copy(len, x);
- uint[] a = Nat.Create(len);
- a[0] = 1;
- int ac = 0;
- if ((u[0] & 1) == 0)
- {
- InversionStep(p, u, len, a, ref ac);
- }
- if (Nat.IsOne(len, u))
- {
- InversionResult(p, ac, a, z);
- return;
- }
- uint[] v = Nat.Copy(len, p);
- uint[] b = Nat.Create(len);
- int bc = 0;
- int uvLen = len;
- for (;;)
- {
- while (u[uvLen - 1] == 0 && v[uvLen - 1] == 0)
- {
- --uvLen;
- }
- if (Nat.Gte(len, u, v))
- {
- Nat.SubFrom(len, v, u);
- Debug.Assert((u[0] & 1) == 0);
- ac += Nat.SubFrom(len, b, a) - bc;
- InversionStep(p, u, uvLen, a, ref ac);
- if (Nat.IsOne(len, u))
- {
- InversionResult(p, ac, a, z);
- return;
- }
- }
- else
- {
- Nat.SubFrom(len, u, v);
- Debug.Assert((v[0] & 1) == 0);
- bc += Nat.SubFrom(len, a, b) - ac;
- InversionStep(p, v, uvLen, b, ref bc);
- if (Nat.IsOne(len, v))
- {
- InversionResult(p, bc, b, z);
- return;
- }
- }
- }
- }
- public static uint[] Random(uint[] p)
- {
- int len = p.Length;
- uint[] s = Nat.Create(len);
- uint m = p[len - 1];
- m |= m >> 1;
- m |= m >> 2;
- m |= m >> 4;
- m |= m >> 8;
- m |= m >> 16;
- do
- {
- byte[] bytes = new byte[len << 2];
- RandomSource.NextBytes(bytes);
- Pack.BE_To_UInt32(bytes, 0, s);
- s[len - 1] &= m;
- }
- while (Nat.Gte(len, s, p));
- return s;
- }
- public static void Add(uint[] p, uint[] x, uint[] y, uint[] z)
- {
- int len = p.Length;
- uint c = Nat.Add(len, x, y, z);
- if (c != 0)
- {
- Nat.SubFrom(len, p, z);
- }
- }
- public static void Subtract(uint[] p, uint[] x, uint[] y, uint[] z)
- {
- int len = p.Length;
- int c = Nat.Sub(len, x, y, z);
- if (c != 0)
- {
- Nat.AddTo(len, p, z);
- }
- }
- private static void InversionResult(uint[] p, int ac, uint[] a, uint[] z)
- {
- if (ac < 0)
- {
- Nat.Add(p.Length, a, p, z);
- }
- else
- {
- Array.Copy(a, 0, z, 0, p.Length);
- }
- }
- private static void InversionStep(uint[] p, uint[] u, int uLen, uint[] x, ref int xc)
- {
- int len = p.Length;
- int count = 0;
- while (u[0] == 0)
- {
- Nat.ShiftDownWord(uLen, u, 0);
- count += 32;
- }
- {
- int zeroes = GetTrailingZeroes(u[0]);
- if (zeroes > 0)
- {
- Nat.ShiftDownBits(uLen, u, zeroes, 0);
- count += zeroes;
- }
- }
- for (int i = 0; i < count; ++i)
- {
- if ((x[0] & 1) != 0)
- {
- if (xc < 0)
- {
- xc += (int)Nat.AddTo(len, p, x);
- }
- else
- {
- xc += Nat.SubFrom(len, p, x);
- }
- }
- Debug.Assert(xc == 0 || xc == -1);
- Nat.ShiftDownBit(len, x, (uint)xc);
- }
- }
- private static int GetTrailingZeroes(uint x)
- {
- Debug.Assert(x != 0);
- int count = 0;
- while ((x & 1) == 0)
- {
- x >>= 1;
- ++count;
- }
- return count;
- }
- }
- }
- #endif
|