SecP128R1Field.cs 6.0 KB

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