X448.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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.Math.EC.Rfc8032;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Rfc7748
  9. {
  10. public abstract class X448
  11. {
  12. public const int PointSize = 56;
  13. public const int ScalarSize = 56;
  14. private class F : X448Field {};
  15. private const uint C_A = 156326;
  16. private const uint C_A24 = (C_A + 2)/4;
  17. //private static readonly uint[] Sqrt156324 = { 0x0551B193U, 0x07A21E17U, 0x0E635AD3U, 0x00812ABBU, 0x025B3F99U, 0x01605224U,
  18. // 0x0AF8CB32U, 0x0D2E7D68U, 0x06BA50FDU, 0x08E55693U, 0x0CB08EB4U, 0x02ABEBC1U, 0x051BA0BBU, 0x02F8812EU, 0x0829B611U,
  19. // 0x0BA4D3A0U };
  20. public static bool CalculateAgreement(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff)
  21. {
  22. ScalarMult(k, kOff, u, uOff, r, rOff);
  23. return !Arrays.AreAllZeroes(r, rOff, PointSize);
  24. }
  25. private static uint Decode32(byte[] bs, int off)
  26. {
  27. uint n = bs[off];
  28. n |= (uint)bs[++off] << 8;
  29. n |= (uint)bs[++off] << 16;
  30. n |= (uint)bs[++off] << 24;
  31. return n;
  32. }
  33. private static void DecodeScalar(byte[] k, int kOff, uint[] n)
  34. {
  35. for (int i = 0; i < 14; ++i)
  36. {
  37. n[i] = Decode32(k, kOff + i * 4);
  38. }
  39. n[ 0] &= 0xFFFFFFFCU;
  40. n[13] |= 0x80000000U;
  41. }
  42. public static void GeneratePrivateKey(SecureRandom random, byte[] k)
  43. {
  44. random.NextBytes(k);
  45. k[0] &= 0xFC;
  46. k[ScalarSize - 1] |= 0x80;
  47. }
  48. public static void GeneratePublicKey(byte[] k, int kOff, byte[] r, int rOff)
  49. {
  50. ScalarMultBase(k, kOff, r, rOff);
  51. }
  52. private static void PointDouble(uint[] x, uint[] z)
  53. {
  54. uint[] a = F.Create();
  55. uint[] b = F.Create();
  56. //F.Apm(x, z, a, b);
  57. F.Add(x, z, a);
  58. F.Sub(x, z, b);
  59. F.Sqr(a, a);
  60. F.Sqr(b, b);
  61. F.Mul(a, b, x);
  62. F.Sub(a, b, a);
  63. F.Mul(a, C_A24, z);
  64. F.Add(z, b, z);
  65. F.Mul(z, a, z);
  66. }
  67. public static void Precompute()
  68. {
  69. Ed448.Precompute();
  70. }
  71. public static void ScalarMult(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff)
  72. {
  73. uint[] n = new uint[14]; DecodeScalar(k, kOff, n);
  74. uint[] x1 = F.Create(); F.Decode(u, uOff, x1);
  75. uint[] x2 = F.Create(); F.Copy(x1, 0, x2, 0);
  76. uint[] z2 = F.Create(); z2[0] = 1;
  77. uint[] x3 = F.Create(); x3[0] = 1;
  78. uint[] z3 = F.Create();
  79. uint[] t1 = F.Create();
  80. uint[] t2 = F.Create();
  81. Debug.Assert(n[13] >> 31 == 1U);
  82. int bit = 447, swap = 1;
  83. do
  84. {
  85. //F.Apm(x3, z3, t1, x3);
  86. F.Add(x3, z3, t1);
  87. F.Sub(x3, z3, x3);
  88. //F.Apm(x2, z2, z3, x2);
  89. F.Add(x2, z2, z3);
  90. F.Sub(x2, z2, x2);
  91. F.Mul(t1, x2, t1);
  92. F.Mul(x3, z3, x3);
  93. F.Sqr(z3, z3);
  94. F.Sqr(x2, x2);
  95. F.Sub(z3, x2, t2);
  96. F.Mul(t2, C_A24, z2);
  97. F.Add(z2, x2, z2);
  98. F.Mul(z2, t2, z2);
  99. F.Mul(x2, z3, x2);
  100. //F.Apm(t1, x3, x3, z3);
  101. F.Sub(t1, x3, z3);
  102. F.Add(t1, x3, x3);
  103. F.Sqr(x3, x3);
  104. F.Sqr(z3, z3);
  105. F.Mul(z3, x1, z3);
  106. --bit;
  107. int word = bit >> 5, shift = bit & 0x1F;
  108. int kt = (int)(n[word] >> shift) & 1;
  109. swap ^= kt;
  110. F.CSwap(swap, x2, x3);
  111. F.CSwap(swap, z2, z3);
  112. swap = kt;
  113. }
  114. while (bit >= 2);
  115. Debug.Assert(swap == 0);
  116. for (int i = 0; i < 2; ++i)
  117. {
  118. PointDouble(x2, z2);
  119. }
  120. F.Inv(z2, z2);
  121. F.Mul(x2, z2, x2);
  122. F.Normalize(x2);
  123. F.Encode(x2, r, rOff);
  124. }
  125. public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff)
  126. {
  127. uint[] x = F.Create();
  128. uint[] y = F.Create();
  129. Ed448.ScalarMultBaseXY(k, kOff, x, y);
  130. F.Inv(x, x);
  131. F.Mul(x, y, x);
  132. F.Sqr(x, x);
  133. F.Normalize(x);
  134. F.Encode(x, r, rOff);
  135. }
  136. }
  137. }
  138. #pragma warning restore
  139. #endif