SecP128R1Field.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Diagnostics;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math.Raw;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Custom.Sec
  9. {
  10. internal class SecP128R1Field
  11. {
  12. // 2^128 - 2^97 - 1
  13. internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFD };
  14. private static readonly uint[] PExt = new uint[]{ 0x00000001, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFE,
  15. 0xFFFFFFFF, 0x00000003, 0xFFFFFFFC };
  16. private static readonly uint[] PExtInv = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFB,
  17. 0x00000001, 0x00000000, 0xFFFFFFFC, 0x00000003 };
  18. private const uint P3 = 0xFFFFFFFD;
  19. private const uint PExt7 = 0xFFFFFFFC;
  20. public static void Add(uint[] x, uint[] y, uint[] z)
  21. {
  22. uint c = Nat128.Add(x, y, z);
  23. if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P)))
  24. {
  25. AddPInvTo(z);
  26. }
  27. }
  28. public static void AddExt(uint[] xx, uint[] yy, uint[] zz)
  29. {
  30. uint c = Nat256.Add(xx, yy, zz);
  31. if (c != 0 || (zz[7] >= PExt7 && Nat256.Gte(zz, PExt)))
  32. {
  33. Nat.AddTo(PExtInv.Length, PExtInv, zz);
  34. }
  35. }
  36. public static void AddOne(uint[] x, uint[] z)
  37. {
  38. uint c = Nat.Inc(4, x, z);
  39. if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P)))
  40. {
  41. AddPInvTo(z);
  42. }
  43. }
  44. public static uint[] FromBigInteger(BigInteger x)
  45. {
  46. uint[] z = Nat.FromBigInteger(128, x);
  47. if (z[3] >= P3 && Nat128.Gte(z, P))
  48. {
  49. Nat128.SubFrom(P, z);
  50. }
  51. return z;
  52. }
  53. public static void Half(uint[] x, uint[] z)
  54. {
  55. if ((x[0] & 1) == 0)
  56. {
  57. Nat.ShiftDownBit(4, x, 0, z);
  58. }
  59. else
  60. {
  61. uint c = Nat128.Add(x, P, z);
  62. Nat.ShiftDownBit(4, z, c);
  63. }
  64. }
  65. public static void Inv(uint[] x, uint[] z)
  66. {
  67. Mod.CheckedModOddInverse(P, x, z);
  68. }
  69. public static int IsZero(uint[] x)
  70. {
  71. uint d = 0;
  72. for (int i = 0; i < 4; ++i)
  73. {
  74. d |= x[i];
  75. }
  76. d = (d >> 1) | (d & 1);
  77. return ((int)d - 1) >> 31;
  78. }
  79. public static void Multiply(uint[] x, uint[] y, uint[] z)
  80. {
  81. uint[] tt = Nat128.CreateExt();
  82. Nat128.Mul(x, y, tt);
  83. Reduce(tt, z);
  84. }
  85. public static void MultiplyAddToExt(uint[] x, uint[] y, uint[] zz)
  86. {
  87. uint c = Nat128.MulAddTo(x, y, zz);
  88. if (c != 0 || (zz[7] >= PExt7 && Nat256.Gte(zz, PExt)))
  89. {
  90. Nat.AddTo(PExtInv.Length, PExtInv, zz);
  91. }
  92. }
  93. public static void Negate(uint[] x, uint[] z)
  94. {
  95. if (0 != IsZero(x))
  96. {
  97. Nat128.Sub(P, P, z);
  98. }
  99. else
  100. {
  101. Nat128.Sub(P, x, z);
  102. }
  103. }
  104. public static void Random(SecureRandom r, uint[] z)
  105. {
  106. byte[] bb = new byte[4 * 4];
  107. do
  108. {
  109. r.NextBytes(bb);
  110. Pack.LE_To_UInt32(bb, 0, z, 0, 4);
  111. }
  112. while (0 == Nat.LessThan(4, z, P));
  113. }
  114. public static void RandomMult(SecureRandom r, uint[] z)
  115. {
  116. do
  117. {
  118. Random(r, z);
  119. }
  120. while (0 != IsZero(z));
  121. }
  122. public static void Reduce(uint[] xx, uint[] z)
  123. {
  124. ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3];
  125. ulong x4 = xx[4], x5 = xx[5], x6 = xx[6], x7 = xx[7];
  126. x3 += x7; x6 += (x7 << 1);
  127. x2 += x6; x5 += (x6 << 1);
  128. x1 += x5; x4 += (x5 << 1);
  129. x0 += x4; x3 += (x4 << 1);
  130. z[0] = (uint)x0; x1 += (x0 >> 32);
  131. z[1] = (uint)x1; x2 += (x1 >> 32);
  132. z[2] = (uint)x2; x3 += (x2 >> 32);
  133. z[3] = (uint)x3;
  134. Reduce32((uint)(x3 >> 32), z);
  135. }
  136. public static void Reduce32(uint x, uint[] z)
  137. {
  138. while (x != 0)
  139. {
  140. ulong c, x4 = x;
  141. c = (ulong)z[0] + x4;
  142. z[0] = (uint)c; c >>= 32;
  143. if (c != 0)
  144. {
  145. c += (ulong)z[1];
  146. z[1] = (uint)c; c >>= 32;
  147. c += (ulong)z[2];
  148. z[2] = (uint)c; c >>= 32;
  149. }
  150. c += (ulong)z[3] + (x4 << 1);
  151. z[3] = (uint)c; c >>= 32;
  152. Debug.Assert(c >= 0 && c <= 2);
  153. x = (uint)c;
  154. }
  155. if (z[3] >= P3 && Nat128.Gte(z, P))
  156. {
  157. AddPInvTo(z);
  158. }
  159. }
  160. public static void Square(uint[] x, uint[] z)
  161. {
  162. uint[] tt = Nat128.CreateExt();
  163. Nat128.Square(x, tt);
  164. Reduce(tt, z);
  165. }
  166. public static void SquareN(uint[] x, int n, uint[] z)
  167. {
  168. Debug.Assert(n > 0);
  169. uint[] tt = Nat128.CreateExt();
  170. Nat128.Square(x, tt);
  171. Reduce(tt, z);
  172. while (--n > 0)
  173. {
  174. Nat128.Square(z, tt);
  175. Reduce(tt, z);
  176. }
  177. }
  178. public static void Subtract(uint[] x, uint[] y, uint[] z)
  179. {
  180. int c = Nat128.Sub(x, y, z);
  181. if (c != 0)
  182. {
  183. SubPInvFrom(z);
  184. }
  185. }
  186. public static void SubtractExt(uint[] xx, uint[] yy, uint[] zz)
  187. {
  188. int c = Nat.Sub(10, xx, yy, zz);
  189. if (c != 0)
  190. {
  191. Nat.SubFrom(PExtInv.Length, PExtInv, zz);
  192. }
  193. }
  194. public static void Twice(uint[] x, uint[] z)
  195. {
  196. uint c = Nat.ShiftUpBit(4, x, 0, z);
  197. if (c != 0 || (z[3] >= P3 && Nat128.Gte(z, P)))
  198. {
  199. AddPInvTo(z);
  200. }
  201. }
  202. private static void AddPInvTo(uint[] z)
  203. {
  204. long c = (long)z[0] + 1;
  205. z[0] = (uint)c; c >>= 32;
  206. if (c != 0)
  207. {
  208. c += (long)z[1];
  209. z[1] = (uint)c; c >>= 32;
  210. c += (long)z[2];
  211. z[2] = (uint)c; c >>= 32;
  212. }
  213. c += (long)z[3] + 2;
  214. z[3] = (uint)c;
  215. }
  216. private static void SubPInvFrom(uint[] z)
  217. {
  218. long c = (long)z[0] - 1;
  219. z[0] = (uint)c; c >>= 32;
  220. if (c != 0)
  221. {
  222. c += (long)z[1];
  223. z[1] = (uint)c; c >>= 32;
  224. c += (long)z[2];
  225. z[2] = (uint)c; c >>= 32;
  226. }
  227. c += (long)z[3] - 2;
  228. z[3] = (uint)c;
  229. }
  230. }
  231. }
  232. #pragma warning restore
  233. #endif