Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
5.0 KiB

  1. #ifndef CRYPTOPP_MQV_H
  2. #define CRYPTOPP_MQV_H
  3. /** \file
  4. */
  5. #include "gfpcrypt.h"
  6. NAMESPACE_BEGIN(CryptoPP)
  7. //! _
  8. template <class GROUP_PARAMETERS, class COFACTOR_OPTION = CPP_TYPENAME GROUP_PARAMETERS::DefaultCofactorOption>
  9. class MQV_Domain : public AuthenticatedKeyAgreementDomain
  10. {
  11. public:
  12. typedef GROUP_PARAMETERS GroupParameters;
  13. typedef typename GroupParameters::Element Element;
  14. typedef MQV_Domain<GROUP_PARAMETERS, COFACTOR_OPTION> Domain;
  15. MQV_Domain() {}
  16. MQV_Domain(const GroupParameters &params)
  17. : m_groupParameters(params) {}
  18. MQV_Domain(BufferedTransformation &bt)
  19. {m_groupParameters.BERDecode(bt);}
  20. template <class T1, class T2>
  21. MQV_Domain(T1 v1, T2 v2)
  22. {m_groupParameters.Initialize(v1, v2);}
  23. template <class T1, class T2, class T3>
  24. MQV_Domain(T1 v1, T2 v2, T3 v3)
  25. {m_groupParameters.Initialize(v1, v2, v3);}
  26. template <class T1, class T2, class T3, class T4>
  27. MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4)
  28. {m_groupParameters.Initialize(v1, v2, v3, v4);}
  29. const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
  30. GroupParameters & AccessGroupParameters() {return m_groupParameters;}
  31. CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
  32. unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
  33. unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
  34. unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);}
  35. void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
  36. {
  37. Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
  38. x.Encode(privateKey, StaticPrivateKeyLength());
  39. }
  40. void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
  41. {
  42. const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
  43. Integer x(privateKey, StaticPrivateKeyLength());
  44. Element y = params.ExponentiateBase(x);
  45. params.EncodeElement(true, y, publicKey);
  46. }
  47. unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
  48. unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();}
  49. void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
  50. {
  51. const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
  52. Integer x(rng, Integer::One(), params.GetMaxExponent());
  53. x.Encode(privateKey, StaticPrivateKeyLength());
  54. Element y = params.ExponentiateBase(x);
  55. params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
  56. }
  57. void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
  58. {
  59. memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
  60. }
  61. bool Agree(byte *agreedValue,
  62. const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
  63. const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
  64. bool validateStaticOtherPublicKey=true) const
  65. {
  66. try
  67. {
  68. const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
  69. Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
  70. Element VV = params.DecodeElement(ephemeralOtherPublicKey, true);
  71. Integer s(staticPrivateKey, StaticPrivateKeyLength());
  72. Integer u(ephemeralPrivateKey, StaticPrivateKeyLength());
  73. Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false);
  74. const Integer &r = params.GetSubgroupOrder();
  75. Integer h2 = Integer::Power2((r.BitCount()+1)/2);
  76. Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r;
  77. Integer tt = h2 + params.ConvertElementToInteger(VV) % h2;
  78. if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION)
  79. {
  80. Element P = params.ExponentiateElement(WW, tt);
  81. P = m_groupParameters.MultiplyElements(P, VV);
  82. Element R[2];
  83. const Integer e2[2] = {r, e};
  84. params.SimultaneousExponentiate(R, P, e2, 2);
  85. if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1]))
  86. return false;
  87. params.EncodeElement(false, R[1], agreedValue);
  88. }
  89. else
  90. {
  91. const Integer &k = params.GetCofactor();
  92. if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION)
  93. e = ModularArithmetic(r).Divide(e, k);
  94. Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r));
  95. if (params.IsIdentity(P))
  96. return false;
  97. params.EncodeElement(false, P, agreedValue);
  98. }
  99. }
  100. catch (DL_BadElement &)
  101. {
  102. return false;
  103. }
  104. return true;
  105. }
  106. private:
  107. DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
  108. const DL_GroupParameters<Element> & GetAbstractGroupParameters() const {return m_groupParameters;}
  109. GroupParameters m_groupParameters;
  110. };
  111. //! Menezes-Qu-Vanstone in GF(p) with key validation, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#MQV">MQV</a>
  112. typedef MQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> MQV;
  113. NAMESPACE_END
  114. #endif