SecP521R1Field.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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 SecP521R1Field
  8. {
  9. // 2^521 - 1
  10. internal static readonly uint[] P = new uint[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  11. 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x1FF };
  12. private const int P16 = 0x1FF;
  13. public static void Add(uint[] x, uint[] y, uint[] z)
  14. {
  15. uint c = Nat.Add(16, x, y, z) + x[16] + y[16];
  16. if (c > P16 || (c == P16 && Nat.Eq(16, z, P)))
  17. {
  18. c += Nat.Inc(16, z);
  19. c &= P16;
  20. }
  21. z[16] = c;
  22. }
  23. public static void AddOne(uint[] x, uint[] z)
  24. {
  25. uint c = Nat.Inc(16, x, z) + x[16];
  26. if (c > P16 || (c == P16 && Nat.Eq(16, z, P)))
  27. {
  28. c += Nat.Inc(16, z);
  29. c &= P16;
  30. }
  31. z[16] = c;
  32. }
  33. public static uint[] FromBigInteger(BigInteger x)
  34. {
  35. uint[] z = Nat.FromBigInteger(521, x);
  36. if (Nat.Eq(17, z, P))
  37. {
  38. Nat.Zero(17, z);
  39. }
  40. return z;
  41. }
  42. public static void Half(uint[] x, uint[] z)
  43. {
  44. uint x16 = x[16];
  45. uint c = Nat.ShiftDownBit(16, x, x16, z);
  46. z[16] = (x16 >> 1) | (c >> 23);
  47. }
  48. public static void Multiply(uint[] x, uint[] y, uint[] z)
  49. {
  50. uint[] tt = Nat.Create(33);
  51. ImplMultiply(x, y, tt);
  52. Reduce(tt, z);
  53. }
  54. public static void Negate(uint[] x, uint[] z)
  55. {
  56. if (Nat.IsZero(17, x))
  57. {
  58. Nat.Zero(17, z);
  59. }
  60. else
  61. {
  62. Nat.Sub(17, P, x, z);
  63. }
  64. }
  65. public static void Reduce(uint[] xx, uint[] z)
  66. {
  67. Debug.Assert(xx[32] >> 18 == 0);
  68. uint xx32 = xx[32];
  69. uint c = Nat.ShiftDownBits(16, xx, 16, 9, xx32, z, 0) >> 23;
  70. c += xx32 >> 9;
  71. c += Nat.AddTo(16, xx, z);
  72. if (c > P16 || (c == P16 && Nat.Eq(16, z, P)))
  73. {
  74. c += Nat.Inc(16, z);
  75. c &= P16;
  76. }
  77. z[16] = c;
  78. }
  79. public static void Reduce23(uint[] z)
  80. {
  81. uint z16 = z[16];
  82. uint c = Nat.AddWordTo(16, z16 >> 9, z) + (z16 & P16);
  83. if (c > P16 || (c == P16 && Nat.Eq(16, z, P)))
  84. {
  85. c += Nat.Inc(16, z);
  86. c &= P16;
  87. }
  88. z[16] = c;
  89. }
  90. public static void Square(uint[] x, uint[] z)
  91. {
  92. uint[] tt = Nat.Create(33);
  93. ImplSquare(x, tt);
  94. Reduce(tt, z);
  95. }
  96. public static void SquareN(uint[] x, int n, uint[] z)
  97. {
  98. Debug.Assert(n > 0);
  99. uint[] tt = Nat.Create(33);
  100. ImplSquare(x, tt);
  101. Reduce(tt, z);
  102. while (--n > 0)
  103. {
  104. ImplSquare(z, tt);
  105. Reduce(tt, z);
  106. }
  107. }
  108. public static void Subtract(uint[] x, uint[] y, uint[] z)
  109. {
  110. int c = Nat.Sub(16, x, y, z) + (int)(x[16] - y[16]);
  111. if (c < 0)
  112. {
  113. c += Nat.Dec(16, z);
  114. c &= P16;
  115. }
  116. z[16] = (uint)c;
  117. }
  118. public static void Twice(uint[] x, uint[] z)
  119. {
  120. uint x16 = x[16];
  121. uint c = Nat.ShiftUpBit(16, x, x16 << 23, z) | (x16 << 1);
  122. z[16] = c & P16;
  123. }
  124. protected static void ImplMultiply(uint[] x, uint[] y, uint[] zz)
  125. {
  126. Nat512.Mul(x, y, zz);
  127. uint x16 = x[16], y16 = y[16];
  128. zz[32] = Nat.Mul31BothAdd(16, x16, y, y16, x, zz, 16) + (x16 * y16);
  129. }
  130. protected static void ImplSquare(uint[] x, uint[] zz)
  131. {
  132. Nat512.Square(x, zz);
  133. uint x16 = x[16];
  134. zz[32] = Nat.MulWordAddTo(16, x16 << 1, x, 0, zz, 16) + (x16 * x16);
  135. }
  136. }
  137. }
  138. #endif