X25519.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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 X25519
  11. {
  12. public const int PointSize = 32;
  13. public const int ScalarSize = 32;
  14. private class F : X25519Field {};
  15. private const int C_A = 486662;
  16. private const int C_A24 = (C_A + 2)/4;
  17. //private static readonly int[] SqrtNeg486664 = { 0x03457E06, 0x03812ABF, 0x01A82CC6, 0x028A5BE8, 0x018B43A7,
  18. // 0x03FC4F7E, 0x02C23700, 0x006BBD27, 0x03A30500, 0x001E4DDB };
  19. public static bool CalculateAgreement(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff)
  20. {
  21. ScalarMult(k, kOff, u, uOff, r, rOff);
  22. return !Arrays.AreAllZeroes(r, rOff, PointSize);
  23. }
  24. private static uint Decode32(byte[] bs, int off)
  25. {
  26. uint n = bs[off];
  27. n |= (uint)bs[++off] << 8;
  28. n |= (uint)bs[++off] << 16;
  29. n |= (uint)bs[++off] << 24;
  30. return n;
  31. }
  32. private static void DecodeScalar(byte[] k, int kOff, uint[] n)
  33. {
  34. for (int i = 0; i < 8; ++i)
  35. {
  36. n[i] = Decode32(k, kOff + i * 4);
  37. }
  38. n[0] &= 0xFFFFFFF8U;
  39. n[7] &= 0x7FFFFFFFU;
  40. n[7] |= 0x40000000U;
  41. }
  42. public static void GeneratePrivateKey(SecureRandom random, byte[] k)
  43. {
  44. random.NextBytes(k);
  45. k[0] &= 0xF8;
  46. k[ScalarSize - 1] &= 0x7F;
  47. k[ScalarSize - 1] |= 0x40;
  48. }
  49. public static void GeneratePublicKey(byte[] k, int kOff, byte[] r, int rOff)
  50. {
  51. ScalarMultBase(k, kOff, r, rOff);
  52. }
  53. private static void PointDouble(int[] x, int[] z)
  54. {
  55. int[] a = F.Create();
  56. int[] b = F.Create();
  57. F.Apm(x, z, a, b);
  58. F.Sqr(a, a);
  59. F.Sqr(b, b);
  60. F.Mul(a, b, x);
  61. F.Sub(a, b, a);
  62. F.Mul(a, C_A24, z);
  63. F.Add(z, b, z);
  64. F.Mul(z, a, z);
  65. }
  66. public static void Precompute()
  67. {
  68. Ed25519.Precompute();
  69. }
  70. public static void ScalarMult(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff)
  71. {
  72. uint[] n = new uint[8]; DecodeScalar(k, kOff, n);
  73. int[] x1 = F.Create(); F.Decode(u, uOff, x1);
  74. int[] x2 = F.Create(); F.Copy(x1, 0, x2, 0);
  75. int[] z2 = F.Create(); z2[0] = 1;
  76. int[] x3 = F.Create(); x3[0] = 1;
  77. int[] z3 = F.Create();
  78. int[] t1 = F.Create();
  79. int[] t2 = F.Create();
  80. Debug.Assert(n[7] >> 30 == 1U);
  81. int bit = 254, swap = 1;
  82. do
  83. {
  84. F.Apm(x3, z3, t1, x3);
  85. F.Apm(x2, z2, z3, x2);
  86. F.Mul(t1, x2, t1);
  87. F.Mul(x3, z3, x3);
  88. F.Sqr(z3, z3);
  89. F.Sqr(x2, x2);
  90. F.Sub(z3, x2, t2);
  91. F.Mul(t2, C_A24, z2);
  92. F.Add(z2, x2, z2);
  93. F.Mul(z2, t2, z2);
  94. F.Mul(x2, z3, x2);
  95. F.Apm(t1, x3, x3, z3);
  96. F.Sqr(x3, x3);
  97. F.Sqr(z3, z3);
  98. F.Mul(z3, x1, z3);
  99. --bit;
  100. int word = bit >> 5, shift = bit & 0x1F;
  101. int kt = (int)(n[word] >> shift) & 1;
  102. swap ^= kt;
  103. F.CSwap(swap, x2, x3);
  104. F.CSwap(swap, z2, z3);
  105. swap = kt;
  106. }
  107. while (bit >= 3);
  108. Debug.Assert(swap == 0);
  109. for (int i = 0; i < 3; ++i)
  110. {
  111. PointDouble(x2, z2);
  112. }
  113. F.Inv(z2, z2);
  114. F.Mul(x2, z2, x2);
  115. F.Normalize(x2);
  116. F.Encode(x2, r, rOff);
  117. }
  118. public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff)
  119. {
  120. int[] y = F.Create();
  121. int[] z = F.Create();
  122. Ed25519.ScalarMultBaseYZ(k, kOff, y, z);
  123. F.Apm(z, y, y, z);
  124. F.Inv(z, z);
  125. F.Mul(y, z, y);
  126. F.Normalize(y);
  127. F.Encode(y, r, rOff);
  128. }
  129. }
  130. }
  131. #pragma warning restore
  132. #endif