Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:02

0001 // ecp.h - originally written and placed in the public domain by Wei Dai

0002 
0003 /// \file ecp.h

0004 /// \brief Classes for Elliptic Curves over prime fields

0005 
0006 #ifndef CRYPTOPP_ECP_H
0007 #define CRYPTOPP_ECP_H
0008 
0009 #include "cryptlib.h"
0010 #include "integer.h"
0011 #include "algebra.h"
0012 #include "modarith.h"
0013 #include "ecpoint.h"
0014 #include "eprecomp.h"
0015 #include "smartptr.h"
0016 #include "pubkey.h"
0017 
0018 #if CRYPTOPP_MSC_VERSION
0019 # pragma warning(push)
0020 # pragma warning(disable: 4231 4275)
0021 #endif
0022 
0023 NAMESPACE_BEGIN(CryptoPP)
0024 
0025 /// \brief Elliptic Curve over GF(p), where p is prime

0026 class CRYPTOPP_DLL ECP : public AbstractGroup<ECPPoint>, public EncodedPoint<ECPPoint>
0027 {
0028 public:
0029     typedef ModularArithmetic Field;
0030     typedef Integer FieldElement;
0031     typedef ECPPoint Point;
0032 
0033     virtual ~ECP() {}
0034 
0035     /// \brief Construct an ECP

0036     ECP() {}
0037 
0038     /// \brief Construct an ECP

0039     /// \param ecp the other ECP object

0040     /// \param convertToMontgomeryRepresentation flag indicating if the curve

0041     ///  should be converted to a MontgomeryRepresentation.

0042     /// \details Prior to Crypto++ 8.3 the default value for

0043     ///  convertToMontgomeryRepresentation was false. it was changed due to

0044     ///  two audit tools finding, "Signature-compatible with a copy constructor".

0045     /// \sa ModularArithmetic, MontgomeryRepresentation

0046     ECP(const ECP &ecp, bool convertToMontgomeryRepresentation);
0047 
0048     /// \brief Construct an ECP

0049     /// \param modulus the prime modulus

0050     /// \param a Field::Element

0051     /// \param b Field::Element

0052     ECP(const Integer &modulus, const FieldElement &a, const FieldElement &b)
0053         : m_fieldPtr(new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {}
0054 
0055     /// \brief Construct an ECP from BER encoded parameters

0056     /// \param bt BufferedTransformation derived object

0057     /// \details This constructor will decode and extract the fields

0058     ///  fieldID and curve of the sequence ECParameters

0059     ECP(BufferedTransformation &bt);
0060 
0061     /// \brief DER Encode

0062     /// \param bt BufferedTransformation derived object

0063     /// \details DEREncode encode the fields fieldID and curve of the sequence

0064     ///  ECParameters

0065     void DEREncode(BufferedTransformation &bt) const;
0066 
0067     /// \brief Compare two points

0068     /// \param P the first point

0069     /// \param Q the second point

0070     /// \return true if equal, false otherwise

0071     bool Equal(const Point &P, const Point &Q) const;
0072 
0073     const Point& Identity() const;
0074     const Point& Inverse(const Point &P) const;
0075     bool InversionIsFast() const {return true;}
0076     const Point& Add(const Point &P, const Point &Q) const;
0077     const Point& Double(const Point &P) const;
0078     Point ScalarMultiply(const Point &P, const Integer &k) const;
0079     Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const;
0080     void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const;
0081 
0082     Point Multiply(const Integer &k, const Point &P) const
0083         {return ScalarMultiply(P, k);}
0084     Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const
0085         {return CascadeScalarMultiply(P, k1, Q, k2);}
0086 
0087     bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const;
0088     bool VerifyPoint(const Point &P) const;
0089 
0090     unsigned int EncodedPointSize(bool compressed = false) const
0091         {return 1 + (compressed?1:2)*GetField().MaxElementByteLength();}
0092     // returns false if point is compressed and not valid (doesn't check if uncompressed)

0093     bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const;
0094     bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const;
0095     void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const;
0096     void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const;
0097 
0098     Point BERDecodePoint(BufferedTransformation &bt) const;
0099     void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const;
0100 
0101     Integer FieldSize() const {return GetField().GetModulus();}
0102     const Field & GetField() const {return *m_fieldPtr;}
0103     const FieldElement & GetA() const {return m_a;}
0104     const FieldElement & GetB() const {return m_b;}
0105 
0106     bool operator==(const ECP &rhs) const
0107         {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;}
0108 
0109 private:
0110     clonable_ptr<Field> m_fieldPtr;
0111     FieldElement m_a, m_b;
0112     mutable Point m_R;
0113 };
0114 
0115 CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl<ECP::Point>;
0116 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation<ECP::Point>;
0117 
0118 /// \brief Elliptic Curve precomputation

0119 /// \tparam EC elliptic curve field

0120 template <class EC> class EcPrecomputation;
0121 
0122 /// \brief ECP precomputation specialization

0123 /// \details Implementation of <tt>DL_GroupPrecomputation<ECP::Point></tt> with input and output

0124 ///   conversions for Montgomery modular multiplication.

0125 /// \sa DL_GroupPrecomputation, ModularArithmetic, MontgomeryRepresentation

0126 template<> class EcPrecomputation<ECP> : public DL_GroupPrecomputation<ECP::Point>
0127 {
0128 public:
0129     typedef ECP EllipticCurve;
0130 
0131     virtual ~EcPrecomputation() {}
0132 
0133     // DL_GroupPrecomputation

0134     bool NeedConversions() const {return true;}
0135     Element ConvertIn(const Element &P) const
0136         {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));};
0137     Element ConvertOut(const Element &P) const
0138         {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));}
0139     const AbstractGroup<Element> & GetGroup() const {return *m_ec;}
0140     Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec->BERDecodePoint(bt);}
0141     void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec->DEREncodePoint(bt, v, false);}
0142 
0143     /// \brief Set the elliptic curve

0144     /// \param ec ECP derived class

0145     /// \details SetCurve() is not inherited

0146     void SetCurve(const ECP &ec)
0147     {
0148         m_ec.reset(new ECP(ec, true));
0149         m_ecOriginal = ec;
0150     }
0151 
0152     /// \brief Get the elliptic curve

0153     /// \return ECP curve

0154     /// \details GetCurve() is not inherited

0155     const ECP & GetCurve() const {return *m_ecOriginal;}
0156 
0157 private:
0158     value_ptr<ECP> m_ec, m_ecOriginal;
0159 };
0160 
0161 NAMESPACE_END
0162 
0163 #if CRYPTOPP_MSC_VERSION
0164 # pragma warning(pop)
0165 #endif
0166 
0167 #endif