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.

145 lines
5.0 KiB

  1. // ecp.h - written and placed in the public domain by Wei Dai
  2. //! \file ecp.h
  3. //! \brief Classes for Elliptic Curves over prime fields
  4. #ifndef CRYPTOPP_ECP_H
  5. #define CRYPTOPP_ECP_H
  6. #include "cryptlib.h"
  7. #include "integer.h"
  8. #include "modarith.h"
  9. #include "eprecomp.h"
  10. #include "smartptr.h"
  11. #include "pubkey.h"
  12. NAMESPACE_BEGIN(CryptoPP)
  13. //! Elliptical Curve Point
  14. struct CRYPTOPP_DLL ECPPoint
  15. {
  16. ECPPoint() : identity(true) {}
  17. ECPPoint(const Integer &x, const Integer &y)
  18. : identity(false), x(x), y(y) {}
  19. bool operator==(const ECPPoint &t) const
  20. {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);}
  21. bool operator< (const ECPPoint &t) const
  22. {return identity ? !t.identity : (!t.identity && (x<t.x || (x==t.x && y<t.y)));}
  23. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  24. virtual ~ECPPoint() {}
  25. #endif
  26. bool identity;
  27. Integer x, y;
  28. };
  29. CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup<ECPPoint>;
  30. //! Elliptic Curve over GF(p), where p is prime
  31. class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint>
  32. {
  33. public:
  34. typedef ModularArithmetic Field;
  35. typedef Integer FieldElement;
  36. typedef ECPPoint Point;
  37. ECP() {}
  38. ECP(const ECP &ecp, bool convertToMontgomeryRepresentation = false);
  39. ECP(const Integer &modulus, const FieldElement &a, const FieldElement &b)
  40. : m_fieldPtr(new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {}
  41. // construct from BER encoded parameters
  42. // this constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters
  43. ECP(BufferedTransformation &bt);
  44. // encode the fields fieldID and curve of the sequence ECParameters
  45. void DEREncode(BufferedTransformation &bt) const;
  46. bool Equal(const Point &P, const Point &Q) const;
  47. const Point& Identity() const;
  48. const Point& Inverse(const Point &P) const;
  49. bool InversionIsFast() const {return true;}
  50. const Point& Add(const Point &P, const Point &Q) const;
  51. const Point& Double(const Point &P) const;
  52. Point ScalarMultiply(const Point &P, const Integer &k) const;
  53. Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const;
  54. void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const;
  55. Point Multiply(const Integer &k, const Point &P) const
  56. {return ScalarMultiply(P, k);}
  57. Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const
  58. {return CascadeScalarMultiply(P, k1, Q, k2);}
  59. bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const;
  60. bool VerifyPoint(const Point &P) const;
  61. unsigned int EncodedPointSize(bool compressed = false) const
  62. {return 1 + (compressed?1:2)*GetField().MaxElementByteLength();}
  63. // returns false if point is compressed and not valid (doesn't check if uncompressed)
  64. bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const;
  65. bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const;
  66. void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const;
  67. void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const;
  68. Point BERDecodePoint(BufferedTransformation &bt) const;
  69. void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const;
  70. Integer FieldSize() const {return GetField().GetModulus();}
  71. const Field & GetField() const {return *m_fieldPtr;}
  72. const FieldElement & GetA() const {return m_a;}
  73. const FieldElement & GetB() const {return m_b;}
  74. bool operator==(const ECP &rhs) const
  75. {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;}
  76. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  77. virtual ~ECP() {}
  78. #endif
  79. private:
  80. clonable_ptr<Field> m_fieldPtr;
  81. FieldElement m_a, m_b;
  82. mutable Point m_R;
  83. };
  84. CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<ECP::Point>;
  85. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation<ECP::Point>;
  86. template <class T> class EcPrecomputation;
  87. //! ECP precomputation
  88. template<> class EcPrecomputation<ECP> : public DL_GroupPrecomputation<ECP::Point>
  89. {
  90. public:
  91. typedef ECP EllipticCurve;
  92. // DL_GroupPrecomputation
  93. bool NeedConversions() const {return true;}
  94. Element ConvertIn(const Element &P) const
  95. {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));};
  96. Element ConvertOut(const Element &P) const
  97. {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));}
  98. const AbstractGroup<Element> & GetGroup() const {return *m_ec;}
  99. Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec->BERDecodePoint(bt);}
  100. void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec->DEREncodePoint(bt, v, false);}
  101. // non-inherited
  102. void SetCurve(const ECP &ec)
  103. {
  104. m_ec.reset(new ECP(ec, true));
  105. m_ecOriginal = ec;
  106. }
  107. const ECP & GetCurve() const {return *m_ecOriginal;}
  108. #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
  109. virtual ~EcPrecomputation() {}
  110. #endif
  111. private:
  112. value_ptr<ECP> m_ec, m_ecOriginal;
  113. };
  114. NAMESPACE_END
  115. #endif