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