ecp.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // ecp.h - originally 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 "algebra.h"
  9. #include "modarith.h"
  10. #include "ecpoint.h"
  11. #include "eprecomp.h"
  12. #include "smartptr.h"
  13. #include "pubkey.h"
  14. #if CRYPTOPP_MSC_VERSION
  15. # pragma warning(push)
  16. # pragma warning(disable: 4231 4275)
  17. #endif
  18. NAMESPACE_BEGIN(CryptoPP)
  19. /// \brief Elliptic Curve over GF(p), where p is prime
  20. class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint>, public EncodedPoint<ECPPoint>
  21. {
  22. public:
  23. typedef ModularArithmetic Field;
  24. typedef Integer FieldElement;
  25. typedef ECPPoint Point;
  26. virtual ~ECP() {}
  27. /// \brief Construct an ECP
  28. ECP() {}
  29. /// \brief Construct an ECP
  30. /// \param ecp the other ECP object
  31. /// \param convertToMontgomeryRepresentation flag indicating if the curve
  32. /// should be converted to a MontgomeryRepresentation.
  33. /// \details Prior to Crypto++ 8.3 the default value for
  34. /// convertToMontgomeryRepresentation was false. it was changed due to
  35. /// two audit tools finding, "Signature-compatible with a copy constructor".
  36. /// \sa ModularArithmetic, MontgomeryRepresentation
  37. ECP(const ECP &ecp, bool convertToMontgomeryRepresentation);
  38. /// \brief Construct an ECP
  39. /// \param modulus the prime modulus
  40. /// \param a Field::Element
  41. /// \param b Field::Element
  42. ECP(const Integer &modulus, const FieldElement &a, const FieldElement &b)
  43. : m_fieldPtr(new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {}
  44. /// \brief Construct an ECP from BER encoded parameters
  45. /// \param bt BufferedTransformation derived object
  46. /// \details This constructor will decode and extract the fields
  47. /// fieldID and curve of the sequence ECParameters
  48. ECP(BufferedTransformation &bt);
  49. /// \brief DER Encode
  50. /// \param bt BufferedTransformation derived object
  51. /// \details DEREncode encode the fields fieldID and curve of the sequence
  52. /// ECParameters
  53. void DEREncode(BufferedTransformation &bt) const;
  54. /// \brief Compare two points
  55. /// \param P the first point
  56. /// \param Q the second point
  57. /// \return true if equal, false otherwise
  58. bool Equal(const Point &P, const Point &Q) const;
  59. const Point& Identity() const;
  60. const Point& Inverse(const Point &P) const;
  61. bool InversionIsFast() const {return true;}
  62. const Point& Add(const Point &P, const Point &Q) const;
  63. const Point& Double(const Point &P) const;
  64. Point ScalarMultiply(const Point &P, const Integer &k) const;
  65. Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const;
  66. void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const;
  67. Point Multiply(const Integer &k, const Point &P) const
  68. {return ScalarMultiply(P, k);}
  69. Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const
  70. {return CascadeScalarMultiply(P, k1, Q, k2);}
  71. bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const;
  72. bool VerifyPoint(const Point &P) const;
  73. unsigned int EncodedPointSize(bool compressed = false) const
  74. {return 1 + (compressed?1:2)*GetField().MaxElementByteLength();}
  75. // returns false if point is compressed and not valid (doesn't check if uncompressed)
  76. bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const;
  77. bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const;
  78. void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const;
  79. void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const;
  80. Point BERDecodePoint(BufferedTransformation &bt) const;
  81. void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const;
  82. Integer FieldSize() const {return GetField().GetModulus();}
  83. const Field & GetField() const {return *m_fieldPtr;}
  84. const FieldElement & GetA() const {return m_a;}
  85. const FieldElement & GetB() const {return m_b;}
  86. bool operator==(const ECP &rhs) const
  87. {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;}
  88. private:
  89. clonable_ptr<Field> m_fieldPtr;
  90. FieldElement m_a, m_b;
  91. mutable Point m_R;
  92. };
  93. CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<ECP::Point>;
  94. CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation<ECP::Point>;
  95. /// \brief Elliptic Curve precomputation
  96. /// \tparam EC elliptic curve field
  97. template <class EC> class EcPrecomputation;
  98. /// \brief ECP precomputation specialization
  99. /// \details Implementation of <tt>DL_GroupPrecomputation<ECP::Point></tt> with input and output
  100. /// conversions for Montgomery modular multiplication.
  101. /// \sa DL_GroupPrecomputation, ModularArithmetic, MontgomeryRepresentation
  102. template<> class EcPrecomputation<ECP> : public DL_GroupPrecomputation<ECP::Point>
  103. {
  104. public:
  105. typedef ECP EllipticCurve;
  106. virtual ~EcPrecomputation() {}
  107. // DL_GroupPrecomputation
  108. bool NeedConversions() const {return true;}
  109. Element ConvertIn(const Element &P) const
  110. {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));};
  111. Element ConvertOut(const Element &P) const
  112. {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));}
  113. const AbstractGroup<Element> & GetGroup() const {return *m_ec;}
  114. Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec->BERDecodePoint(bt);}
  115. void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec->DEREncodePoint(bt, v, false);}
  116. /// \brief Set the elliptic curve
  117. /// \param ec ECP derived class
  118. /// \details SetCurve() is not inherited
  119. void SetCurve(const ECP &ec)
  120. {
  121. m_ec.reset(new ECP(ec, true));
  122. m_ecOriginal = ec;
  123. }
  124. /// \brief Get the elliptic curve
  125. /// \return ECP curve
  126. /// \details GetCurve() is not inherited
  127. const ECP & GetCurve() const {return *m_ecOriginal;}
  128. private:
  129. value_ptr<ECP> m_ec, m_ecOriginal;
  130. };
  131. NAMESPACE_END
  132. #if CRYPTOPP_MSC_VERSION
  133. # pragma warning(pop)
  134. #endif
  135. #endif