Crypto++  5.6.3
Free C++ class library of cryptographic schemes
eccrypto.h
Go to the documentation of this file.
1 // eccrypto.h - written and placed in the public domain by Wei Dai
2 
3 //! \file eccrypto.h
4 //! \brief Classes and functions for Elliptic Curves over prime and binary fields
5 
6 #ifndef CRYPTOPP_ECCRYPTO_H
7 #define CRYPTOPP_ECCRYPTO_H
8 
9 #include "config.h"
10 #include "cryptlib.h"
11 #include "pubkey.h"
12 #include "integer.h"
13 #include "asn.h"
14 #include "hmac.h"
15 #include "sha.h"
16 #include "gfpcrypt.h"
17 #include "dh.h"
18 #include "mqv.h"
19 #include "ecp.h"
20 #include "ec2n.h"
21 
22 NAMESPACE_BEGIN(CryptoPP)
23 
24 //! Elliptic Curve Parameters
25 /*! This class corresponds to the ASN.1 sequence of the same name
26  in ANSI X9.62 (also SEC 1).
27 */
28 template <class EC>
30 {
32 
33 public:
34  typedef EC EllipticCurve;
35  typedef typename EllipticCurve::Point Point;
36  typedef Point Element;
38 
39  DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {}
40  DL_GroupParameters_EC(const OID &oid)
41  : m_compress(false), m_encodeAsOID(false) {Initialize(oid);}
42  DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
43  : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);}
45  : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);}
46 
47  void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
48  {
49  this->m_groupPrecomputation.SetCurve(ec);
50  this->SetSubgroupGenerator(G);
51  m_n = n;
52  m_k = k;
53  }
54  void Initialize(const OID &oid);
55 
56  // NameValuePairs
57  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
58  void AssignFrom(const NameValuePairs &source);
59 
60  // GeneratibleCryptoMaterial interface
61  //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values
62  /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */
63  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
64 
65  // DL_GroupParameters
66  const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
68  const Integer & GetSubgroupOrder() const {return m_n;}
69  Integer GetCofactor() const;
70  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
71  bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const;
72  bool FastSubgroupCheckAvailable() const {return false;}
73  void EncodeElement(bool reversible, const Element &element, byte *encoded) const
74  {
75  if (reversible)
76  GetCurve().EncodePoint(encoded, element, m_compress);
77  else
78  element.x.Encode(encoded, GetEncodedElementSize(false));
79  }
80  virtual unsigned int GetEncodedElementSize(bool reversible) const
81  {
82  if (reversible)
83  return GetCurve().EncodedPointSize(m_compress);
84  else
85  return GetCurve().GetField().MaxElementByteLength();
86  }
87  Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
88  {
89  Point result;
90  if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true)))
91  throw DL_BadElement();
92  if (checkForGroupMembership && !ValidateElement(1, result, NULL))
93  throw DL_BadElement();
94  return result;
95  }
96  Integer ConvertElementToInteger(const Element &element) const;
97  Integer GetMaxExponent() const {return GetSubgroupOrder()-1;}
98  bool IsIdentity(const Element &element) const {return element.identity;}
99  void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
100  static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";}
101 
102  // ASN1Key
103  OID GetAlgorithmID() const;
104 
105  // used by MQV
106  Element MultiplyElements(const Element &a, const Element &b) const;
107  Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
108 
109  // non-inherited
110 
111  // enumerate OIDs for recommended parameters, use OID() to get first one
112  static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid);
113 
114  void BERDecode(BufferedTransformation &bt);
115  void DEREncode(BufferedTransformation &bt) const;
116 
117  void SetPointCompression(bool compress) {m_compress = compress;}
118  bool GetPointCompression() const {return m_compress;}
119 
120  void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
121  bool GetEncodeAsOID() const {return m_encodeAsOID;}
122 
123  const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();}
124 
125  bool operator==(const ThisClass &rhs) const
126  {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);}
127 
128 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
129  const Point& GetBasePoint() const {return this->GetSubgroupGenerator();}
130  const Integer& GetBasePointOrder() const {return this->GetSubgroupOrder();}
131  void LoadRecommendedParameters(const OID &oid) {Initialize(oid);}
132 #endif
133 
134 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
135  virtual ~DL_GroupParameters_EC() {}
136 #endif
137 
138 protected:
139  unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();}
140  unsigned int ExponentLength() const {return m_n.ByteCount();}
141 
142  OID m_oid; // set if parameters loaded from a recommended curve
143  Integer m_n; // order of base point
144  mutable Integer m_k; // cofactor
145  mutable bool m_compress, m_encodeAsOID; // presentation details
146 };
147 
148 //! EC public key
149 template <class EC>
150 class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
151 {
152 public:
153  typedef typename EC::Point Element;
154 
155  void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
156  {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
157  void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
158  {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);}
159 
160  // X509PublicKey
161  void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
163 
164 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
165  virtual ~DL_PublicKey_EC() {}
166 #endif
167 };
168 
169 //! EC private key
170 template <class EC>
171 class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
172 {
173 public:
174  typedef typename EC::Point Element;
175 
176  void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
177  {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
178  void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
179  {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);}
180  void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
181  {this->GenerateRandom(rng, params);}
182  void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
183  {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
184 
185  // PKCS8PrivateKey
186  void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
188 
189 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
190  virtual ~DL_PrivateKey_EC() {}
191 #endif
192 };
193 
194 //! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a>
195 template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
196 struct ECDH
197 {
198  typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
199 
200 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
201  virtual ~ECDH() {}
202 #endif
203 };
204 
205 /// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a>
206 template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
207 struct ECMQV
208 {
209  typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
210 
211 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
212  virtual ~ECMQV() {}
213 #endif
214 };
215 
216 //! EC keys
217 template <class EC>
219 {
222 
223 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
224  virtual ~DL_Keys_EC() {}
225 #endif
226 };
227 
228 template <class EC, class H>
229 struct ECDSA;
230 
231 //! ECDSA keys
232 template <class EC>
234 {
237 
238 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
239  virtual ~DL_Keys_ECDSA() {}
240 #endif
241 };
242 
243 //! ECDSA algorithm
244 template <class EC>
245 class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
246 {
247 public:
248  static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
249 
250 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
251  virtual ~DL_Algorithm_ECDSA() {}
252 #endif
253 };
254 
255 //! ECNR algorithm
256 template <class EC>
257 class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
258 {
259 public:
260  static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";}
261 
262 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
263  virtual ~DL_Algorithm_ECNR() {}
264 #endif
265 };
266 
267 //! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
268 template <class EC, class H>
269 struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
270 {
271 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
272  virtual ~ECDSA() {}
273 #endif
274 };
275 
276 //! ECNR
277 template <class EC, class H = SHA>
278 struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H>
279 {
280 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
281  virtual ~ECNR() {}
282 #endif
283 };
284 
285 //! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a>
286 /*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2.
287  The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best
288  efficiency and security. */
289 template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false>
290 struct ECIES
291  : public DL_ES<
292  DL_Keys_EC<EC>,
293  DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
294  DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >,
295  DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
296  ECIES<EC> >
297 {
298  static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
299 
300 #ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
301  virtual ~ECIES() {}
302 #endif
303 
304 #if (CRYPTOPP_GCC_VERSION >= 40500) || (CRYPTOPP_CLANG_VERSION >= 20800)
305 } __attribute__((deprecated ("ECIES will be changing in the near future due to (1) an implementation bug and (2) an interop issue")));
306 #elif (CRYPTOPP_GCC_VERSION)
307 } __attribute__((deprecated));
308 #else
309 };
310 #endif
311 
312 NAMESPACE_END
313 
314 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
315 #include "eccrypto.cpp"
316 #endif
317 
318 NAMESPACE_BEGIN(CryptoPP)
319 
320 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>;
321 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>;
322 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >;
323 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >;
324 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>;
325 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>;
326 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
327 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
328 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
329 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
330 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
331 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
332 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
333 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
334 
335 NAMESPACE_END
336 
337 #endif
implements the SHA-256 standard
Definition: sha.h:32
This file contains helper classes/functions for implementing public key algorithms.
ECDSA keys.
Definition: eccrypto.h:233
Classes for Elliptic Curves over prime fields.
Elliptic Curve over GF(p), where p is prime.
Definition: ecp.h:42
ECDSA
Definition: eccrypto.h:229
Converts a typename to an enumerated value.
Definition: cryptlib.h:115
Abstract base classes that provide a uniform interface to this library.
EC keys.
Definition: eccrypto.h:218
EC public key.
Definition: eccrypto.h:150
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition: eccrypto.h:67
Library configuration file.
Interface for random number generators.
Definition: cryptlib.h:1176
EC private key.
Definition: eccrypto.h:171
Discrete Log Based Encryption Scheme.
Definition: pubkey.h:2123
Interface for buffered transformations.
Definition: cryptlib.h:1342
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: eccrypto.cpp:707
Discrete Log Based Signature Scheme.
Definition: pubkey.h:2104
Classes for Elliptic Curves over binary fields.
Classes for HMAC message authentication codes.
MQV domain for performing authenticated key agreement.
Definition: mqv.h:26
Classes for Diffie-Hellman key exchange.
Integer GetMaxExponent() const
Retrieves the maximum exponent for the group.
Definition: eccrypto.h:97
Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV
Definition: eccrypto.h:207
Multiple precision integer with arithmetic operations.
Definition: integer.h:31
Elliptic Curve over GF(2^n)
Definition: ec2n.h:44
Elliptic Curve Integrated Encryption Scheme, AKA ECIES
Definition: eccrypto.h:290
ECNR algorithm.
Definition: eccrypto.h:257
Implementation of schemes based on DL over GF(p)
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: eccrypto.cpp:660
ECDSA algorithm.
Definition: eccrypto.h:245
Exception thrown when an invalid group element is encountered.
Definition: pubkey.h:738
Diffie-Hellman domain.
Definition: dh.h:23
Elliptic Curve Diffie-Hellman, AKA ECDH
Definition: eccrypto.h:196
Classes and functions for working with ANS.1 objects.
Classes for SHA-1 and SHA-2 family of message digests.
Elliptic Curve Parameters.
Definition: eccrypto.h:29
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition: eccrypto.h:66
GDSA algorithm.
Definition: gfpcrypt.h:185
virtual unsigned int GetEncodedElementSize(bool reversible) const
Retrieves the encoded element's size.
Definition: eccrypto.h:80
Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
Decodes the element.
Definition: eccrypto.h:87
NR algorithm.
Definition: gfpcrypt.h:221
static const Integer & Zero()
Integer representing 0.
Definition: integer.cpp:2939
Crypto++ library namespace.
Base implmentation of Discrete Log (DL) group parameters.
Definition: pubkey.h:961
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Definition: pubkey.h:1153
Classes for Menezes–Qu–Vanstone (MQV) key agreement.
Object Identifier.
Definition: asn.h:91
const Integer & GetSubgroupOrder() const
Retrieves the subgroup order.
Definition: eccrypto.h:68
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: eccrypto.cpp:649
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: eccrypto.cpp:668
ECNR.
Definition: eccrypto.h:278
Interface for retrieving values given their names.
Definition: cryptlib.h:277