Crypto++
eccrypto.h
Go to the documentation of this file.
1 #ifndef CRYPTOPP_ECCRYPTO_H
2 #define CRYPTOPP_ECCRYPTO_H
3 
4 /*! \file
5 */
6 
7 #include "pubkey.h"
8 #include "integer.h"
9 #include "asn.h"
10 #include "hmac.h"
11 #include "sha.h"
12 #include "gfpcrypt.h"
13 #include "dh.h"
14 #include "mqv.h"
15 #include "ecp.h"
16 #include "ec2n.h"
17 
18 NAMESPACE_BEGIN(CryptoPP)
19 
20 //! Elliptic Curve Parameters
21 /*! This class corresponds to the ASN.1 sequence of the same name
22  in ANSI X9.62 (also SEC 1).
23 */
24 template <class EC>
26 {
28 
29 public:
30  typedef EC EllipticCurve;
31  typedef typename EllipticCurve::Point Point;
32  typedef Point Element;
34 
35  DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {}
36  DL_GroupParameters_EC(const OID &oid)
37  : m_compress(false), m_encodeAsOID(false) {Initialize(oid);}
38  DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
39  : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);}
41  : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);}
42 
43  void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero())
44  {
45  this->m_groupPrecomputation.SetCurve(ec);
46  this->SetSubgroupGenerator(G);
47  m_n = n;
48  m_k = k;
49  }
50  void Initialize(const OID &oid);
51 
52  // NameValuePairs
53  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
54  void AssignFrom(const NameValuePairs &source);
55 
56  // GeneratibleCryptoMaterial interface
57  //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values
58  /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */
59  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
60 
61  // DL_GroupParameters
62  const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
63  DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
64  const Integer & GetSubgroupOrder() const {return m_n;}
65  Integer GetCofactor() const;
66  bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
67  bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation<Element> *precomp) const;
68  bool FastSubgroupCheckAvailable() const {return false;}
69  void EncodeElement(bool reversible, const Element &element, byte *encoded) const
70  {
71  if (reversible)
72  GetCurve().EncodePoint(encoded, element, m_compress);
73  else
74  element.x.Encode(encoded, GetEncodedElementSize(false));
75  }
76  unsigned int GetEncodedElementSize(bool reversible) const
77  {
78  if (reversible)
79  return GetCurve().EncodedPointSize(m_compress);
80  else
81  return GetCurve().GetField().MaxElementByteLength();
82  }
83  Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const
84  {
85  Point result;
86  if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true)))
87  throw DL_BadElement();
88  if (checkForGroupMembership && !ValidateElement(1, result, NULL))
89  throw DL_BadElement();
90  return result;
91  }
92  Integer ConvertElementToInteger(const Element &element) const;
93  Integer GetMaxExponent() const {return GetSubgroupOrder()-1;}
94  bool IsIdentity(const Element &element) const {return element.identity;}
95  void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
96  static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";}
97 
98  // ASN1Key
99  OID GetAlgorithmID() const;
100 
101  // used by MQV
102  Element MultiplyElements(const Element &a, const Element &b) const;
103  Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
104 
105  // non-inherited
106 
107  // enumerate OIDs for recommended parameters, use OID() to get first one
108  static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid);
109 
110  void BERDecode(BufferedTransformation &bt);
111  void DEREncode(BufferedTransformation &bt) const;
112 
113  void SetPointCompression(bool compress) {m_compress = compress;}
114  bool GetPointCompression() const {return m_compress;}
115 
116  void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
117  bool GetEncodeAsOID() const {return m_encodeAsOID;}
118 
119  const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();}
120 
121  bool operator==(const ThisClass &rhs) const
122  {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);}
123 
124 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
125  const Point& GetBasePoint() const {return GetSubgroupGenerator();}
126  const Integer& GetBasePointOrder() const {return GetSubgroupOrder();}
127  void LoadRecommendedParameters(const OID &oid) {Initialize(oid);}
128 #endif
129 
130 protected:
131  unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();}
132  unsigned int ExponentLength() const {return m_n.ByteCount();}
133 
134  OID m_oid; // set if parameters loaded from a recommended curve
135  Integer m_n; // order of base point
136  bool m_compress, m_encodeAsOID;
137  mutable Integer m_k; // cofactor
138 };
139 
140 //! EC public key
141 template <class EC>
142 class DL_PublicKey_EC : public DL_PublicKeyImpl<DL_GroupParameters_EC<EC> >
143 {
144 public:
145  typedef typename EC::Point Element;
146 
147  void Initialize(const DL_GroupParameters_EC<EC> &params, const Element &Q)
148  {this->AccessGroupParameters() = params; this->SetPublicElement(Q);}
149  void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q)
150  {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPublicElement(Q);}
151 
152  // X509PublicKey
153  void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
155 };
156 
157 //! EC private key
158 template <class EC>
159 class DL_PrivateKey_EC : public DL_PrivateKeyImpl<DL_GroupParameters_EC<EC> >
160 {
161 public:
162  typedef typename EC::Point Element;
163 
164  void Initialize(const DL_GroupParameters_EC<EC> &params, const Integer &x)
165  {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);}
166  void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x)
167  {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);}
168  void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC<EC> &params)
169  {this->GenerateRandom(rng, params);}
170  void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n)
171  {this->GenerateRandom(rng, DL_GroupParameters_EC<EC>(ec, G, n));}
172 
173  // PKCS8PrivateKey
174  void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
176 };
177 
178 //! Elliptic Curve Diffie-Hellman, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECDH">ECDH</a>
179 template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
180 struct ECDH
181 {
182  typedef DH_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
183 };
184 
185 /// Elliptic Curve Menezes-Qu-Vanstone, AKA <a href="http://www.weidai.com/scan-mirror/ka.html#ECMQV">ECMQV</a>
186 template <class EC, class COFACTOR_OPTION = CPP_TYPENAME DL_GroupParameters_EC<EC>::DefaultCofactorOption>
187 struct ECMQV
188 {
189  typedef MQV_Domain<DL_GroupParameters_EC<EC>, COFACTOR_OPTION> Domain;
190 };
191 
192 //! EC keys
193 template <class EC>
195 {
198 };
199 
200 template <class EC, class H>
201 struct ECDSA;
202 
203 //! ECDSA keys
204 template <class EC>
206 {
209 };
210 
211 //! ECDSA algorithm
212 template <class EC>
213 class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
214 {
215 public:
216  static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
217 };
218 
219 //! ECNR algorithm
220 template <class EC>
221 class DL_Algorithm_ECNR : public DL_Algorithm_NR<typename EC::Point>
222 {
223 public:
224  static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";}
225 };
226 
227 //! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
228 template <class EC, class H>
229 struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
230 {
231 };
232 
233 //! ECNR
234 template <class EC, class H = SHA>
235 struct ECNR : public DL_SS<DL_Keys_EC<EC>, DL_Algorithm_ECNR<EC>, DL_SignatureMessageEncodingMethod_NR, H>
236 {
237 };
238 
239 //! Elliptic Curve Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#ECIES">ECIES</a>
240 /*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2.
241  The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best
242  efficiency and security. */
243 template <class EC, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = false>
244 struct ECIES
245  : public DL_ES<
246  DL_Keys_EC<EC>,
247  DL_KeyAgreementAlgorithm_DH<typename EC::Point, COFACTOR_OPTION>,
248  DL_KeyDerivationAlgorithm_P1363<typename EC::Point, DHAES_MODE, P1363_KDF2<SHA1> >,
249  DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
250  ECIES<EC> >
251 {
252  static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
253 };
254 
255 NAMESPACE_END
256 
257 #ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
258 #include "eccrypto.cpp"
259 #endif
260 
261 NAMESPACE_BEGIN(CryptoPP)
262 
263 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<ECP>;
264 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC<EC2N>;
265 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<ECP> >;
266 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl<DL_GroupParameters_EC<EC2N> >;
267 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<ECP>;
268 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC<EC2N>;
269 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
270 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
271 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
272 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
273 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
274 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
275 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
276 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
277 
278 NAMESPACE_END
279 
280 #endif
implements the SHA-256 standard
Definition: sha.h:20
Discrete Log Based Signature Scheme.
Definition: pubkey.h:1646
This file contains helper classes/functions for implementing public key algorithms.
ECDSA keys.
Definition: eccrypto.h:205
Elliptic Curve over GF(p), where p is prime.
Definition: ecp.h:30
ECDSA
Definition: eccrypto.h:201
EC keys.
Definition: eccrypto.h:194
EC public key.
Definition: eccrypto.h:142
interface for random number generators
Definition: cryptlib.h:668
EC private key.
Definition: eccrypto.h:159
Discrete Log Based Encryption Scheme.
Definition: pubkey.h:1665
interface for buffered transformations
Definition: cryptlib.h:770
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
_
Definition: mqv.h:13
Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV
Definition: eccrypto.h:187
multiple precision integer and basic arithmetics
Definition: integer.h:26
Elliptic Curve over GF(2^n)
Definition: ec2n.h:30
Elliptic Curve Integrated Encryption Scheme, AKA ECIES
Definition: eccrypto.h:244
ECNR algorithm.
Definition: eccrypto.h:221
Implementation of schemes based on DL over GF(p)
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
ECDSA algorithm.
Definition: eccrypto.h:213
to be thrown by DecodeElement and AgreeWithStaticPrivateKey
Definition: pubkey.h:513
,
Definition: dh.h:13
Elliptic Curve Diffie-Hellman, AKA ECDH
Definition: eccrypto.h:180
Elliptic Curve Parameters.
Definition: eccrypto.h:25
GDSA algorithm.
Definition: gfpcrypt.h:152
NR algorithm.
Definition: gfpcrypt.h:184
static const Integer & Zero()
avoid calling constructors for these frequently used integers
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Definition: pubkey.h:779
Object Identifier.
Definition: asn.h:82
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
ECNR.
Definition: eccrypto.h:235
interface for retrieving values given their names
Definition: cryptlib.h:224