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