Team Fortress 2 Source Code as on 22/4/2020
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.

112 lines
3.1 KiB

  1. // xtrcrypt.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "asn.h"
  4. #include "integer.h"
  5. #include "xtrcrypt.h"
  6. #include "nbtheory.h"
  7. #include "modarith.h"
  8. #include "argnames.h"
  9. NAMESPACE_BEGIN(CryptoPP)
  10. XTR_DH::XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g)
  11. : m_p(p), m_q(q), m_g(g)
  12. {
  13. }
  14. XTR_DH::XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits)
  15. {
  16. XTR_FindPrimesAndGenerator(rng, m_p, m_q, m_g, pbits, qbits);
  17. }
  18. XTR_DH::XTR_DH(BufferedTransformation &bt)
  19. {
  20. BERSequenceDecoder seq(bt);
  21. m_p.BERDecode(seq);
  22. m_q.BERDecode(seq);
  23. m_g.c1.BERDecode(seq);
  24. m_g.c2.BERDecode(seq);
  25. seq.MessageEnd();
  26. }
  27. void XTR_DH::DEREncode(BufferedTransformation &bt) const
  28. {
  29. DERSequenceEncoder seq(bt);
  30. m_p.DEREncode(seq);
  31. m_q.DEREncode(seq);
  32. m_g.c1.DEREncode(seq);
  33. m_g.c2.DEREncode(seq);
  34. seq.MessageEnd();
  35. }
  36. bool XTR_DH::Validate(RandomNumberGenerator &rng, unsigned int level) const
  37. {
  38. bool pass = true;
  39. pass = pass && m_p > Integer::One() && m_p.IsOdd();
  40. pass = pass && m_q > Integer::One() && m_q.IsOdd();
  41. GFP2Element three = GFP2_ONB<ModularArithmetic>(m_p).ConvertIn(3);
  42. pass = pass && !(m_g.c1.IsNegative() || m_g.c2.IsNegative() || m_g.c1 >= m_p || m_g.c2 >= m_p || m_g == three);
  43. if (level >= 1)
  44. pass = pass && ((m_p.Squared()-m_p+1)%m_q).IsZero();
  45. if (level >= 2)
  46. {
  47. pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
  48. pass = pass && XTR_Exponentiate(m_g, (m_p.Squared()-m_p+1)/m_q, m_p) != three;
  49. pass = pass && XTR_Exponentiate(m_g, m_q, m_p) == three;
  50. }
  51. return pass;
  52. }
  53. bool XTR_DH::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
  54. {
  55. return GetValueHelper(this, name, valueType, pValue).Assignable()
  56. CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
  57. CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
  58. CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
  59. ;
  60. }
  61. void XTR_DH::AssignFrom(const NameValuePairs &source)
  62. {
  63. AssignFromHelper(this, source)
  64. CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
  65. CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
  66. CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupGenerator)
  67. ;
  68. }
  69. void XTR_DH::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
  70. {
  71. Integer x(rng, Integer::Zero(), m_q-1);
  72. x.Encode(privateKey, PrivateKeyLength());
  73. }
  74. void XTR_DH::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
  75. {
  76. CRYPTOPP_UNUSED(rng);
  77. Integer x(privateKey, PrivateKeyLength());
  78. GFP2Element y = XTR_Exponentiate(m_g, x, m_p);
  79. y.Encode(publicKey, PublicKeyLength());
  80. }
  81. bool XTR_DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const
  82. {
  83. GFP2Element w(otherPublicKey, PublicKeyLength());
  84. if (validateOtherPublicKey)
  85. {
  86. GFP2_ONB<ModularArithmetic> gfp2(m_p);
  87. GFP2Element three = gfp2.ConvertIn(3);
  88. if (w.c1.IsNegative() || w.c2.IsNegative() || w.c1 >= m_p || w.c2 >= m_p || w == three)
  89. return false;
  90. if (XTR_Exponentiate(w, m_q, m_p) != three)
  91. return false;
  92. }
  93. Integer s(privateKey, PrivateKeyLength());
  94. GFP2Element z = XTR_Exponentiate(w, s, m_p);
  95. z.Encode(agreedValue, AgreedValueLength());
  96. return true;
  97. }
  98. NAMESPACE_END