Crypto++  8.8
Free C++ class library of cryptographic schemes
eccrypto.cpp
1 // eccrypto.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #include "config.h"
6 
7 #if CRYPTOPP_MSC_VERSION
8 # pragma warning(push)
9 # pragma warning(disable: 4127 4189 4505)
10 #endif
11 
12 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
13 # pragma GCC diagnostic push
14 # pragma GCC diagnostic ignored "-Wunused-function"
15 #endif
16 
17 #ifndef CRYPTOPP_IMPORTS
18 
19 #include "eccrypto.h"
20 #include "integer.h"
21 #include "nbtheory.h"
22 #include "filters.h"
23 #include "argnames.h"
24 #include "smartptr.h"
25 #include "oids.h"
26 #include "asn.h"
27 #include "hex.h"
28 #include "ec2n.h"
29 #include "misc.h"
30 
31 #include <iostream>
32 #include <sstream>
33 
34 // Squash MS LNK4221 and libtool warnings
35 #ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
36 extern const char ECCRYPTO_FNAME[] = __FILE__;
37 #endif
38 
39 NAMESPACE_BEGIN(CryptoPP)
40 
41 #if 0
42 #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
43 static void ECDSA_TestInstantiations()
44 {
46  ECDSA<EC2N>::Verifier t2(t1);
48  ECNR<ECP>::Verifier t4(t3);
53 }
54 #endif
55 #endif
56 
57 ANONYMOUS_NAMESPACE_BEGIN
58 inline Integer ConvertToInteger(const PolynomialMod2 &x)
59 {
60  unsigned int l = x.ByteCount();
61  SecByteBlock temp(l);
62  x.Encode(temp, l);
63  return Integer(temp, l);
64 }
65 
66 inline Integer ConvertToInteger(const Integer &x)
67 {
68  return x;
69 }
70 
71 inline bool CheckMOVCondition(const Integer &q, const Integer &r)
72 {
73  // see "Updated standards for validating elliptic curves", http://eprint.iacr.org/2007/343
74  Integer t = 1;
75  unsigned int n = q.IsEven() ? 1 : q.BitCount(), m = r.BitCount();
76 
77  for (unsigned int i=n; DiscreteLogWorkFactor(i)<m/2; i+=n)
78  {
79  if (q.IsEven())
80  t = (t+t)%r;
81  else
82  t = (t*q)%r;
83  if (t == 1)
84  return false;
85  }
86  return true;
87 }
88 ANONYMOUS_NAMESPACE_END
89 
90 // ******************************************************************
91 
92 template <class T> struct EcRecommendedParameters;
93 
94 template<> struct EcRecommendedParameters<EC2N>
95 {
96  EcRecommendedParameters(const OID &oid, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h)
97  : oid(oid), a(a), b(b), g(g), n(n), h(h), t0(0), t1(0), t2(t2), t3(t3), t4(t4) {}
98  EcRecommendedParameters(const OID &oid, unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h)
99  : oid(oid), a(a), b(b), g(g), n(n), h(h), t0(t0), t1(t1), t2(t2), t3(t3), t4(t4) {}
100  EC2N *NewEC() const
101  {
102  StringSource ssA(a, true, new HexDecoder);
103  StringSource ssB(b, true, new HexDecoder);
104  if (t0 == 0)
105  {
106  if (t2 == 233 && t3 == 74 && t4 == 0)
107  return new EC2N(GF2NT233(233, 74, 0), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable()));
108  else
109  return new EC2N(GF2NT(t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable()));
110  }
111  else
112  return new EC2N(GF2NPP(t0, t1, t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable()));
113  };
114 
115  OID oid;
116  const char *a, *b, *g, *n;
117  unsigned int h, t0, t1, t2, t3, t4;
118 };
119 
120 template<> struct EcRecommendedParameters<ECP>
121 {
122  EcRecommendedParameters(const OID &oid, const char *p, const char *a, const char *b, const char *g, const char *n, unsigned int h)
123  : oid(oid), p(p), a(a), b(b), g(g), n(n), h(h) {}
124  ECP *NewEC() const
125  {
126  StringSource ssP(p, true, new HexDecoder);
127  StringSource ssA(a, true, new HexDecoder);
128  StringSource ssB(b, true, new HexDecoder);
129  return new ECP(Integer(ssP, (size_t)ssP.MaxRetrievable()), ECP::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), ECP::FieldElement(ssB, (size_t)ssB.MaxRetrievable()));
130  };
131 
132  OID oid;
133  const char *p, *a, *b, *g, *n;
134  unsigned int h;
135 };
136 
137 struct OIDLessThan
138 {
139  template <typename T>
140  inline bool operator()(const EcRecommendedParameters<T>& a, const OID& b) {return a.oid < b;}
141  template <typename T>
142  inline bool operator()(const OID& a, const EcRecommendedParameters<T>& b) {return a < b.oid;}
143  template <typename T>
144  inline bool operator()(const EcRecommendedParameters<T>& a, const EcRecommendedParameters<T>& b) {return a.oid < b.oid;}
145 };
146 
147 static void GetRecommendedParameters(const EcRecommendedParameters<EC2N> *&begin, const EcRecommendedParameters<EC2N> *&end)
148 {
149  // this array must be sorted by OID
150  static const EcRecommendedParameters<EC2N> rec[] = {
151  EcRecommendedParameters<EC2N>(ASN1::sect163k1(),
152  163, 7, 6, 3, 0,
153  "000000000000000000000000000000000000000001",
154  "000000000000000000000000000000000000000001",
155  "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9",
156  "04000000000000000000020108A2E0CC0D99F8A5EF",
157  2),
158  EcRecommendedParameters<EC2N>(ASN1::sect163r1(),
159  163, 7, 6, 3, 0,
160  "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2",
161  "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9",
162  "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883",
163  "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B",
164  2),
165  EcRecommendedParameters<EC2N>(ASN1::sect239k1(),
166  239, 158, 0,
167  "000000000000000000000000000000000000000000000000000000000000",
168  "000000000000000000000000000000000000000000000000000000000001",
169  "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA",
170  "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5",
171  4),
172  EcRecommendedParameters<EC2N>(ASN1::sect113r1(),
173  113, 9, 0,
174  "003088250CA6E7C7FE649CE85820F7",
175  "00E8BEE4D3E2260744188BE0E9C723",
176  "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886",
177  "0100000000000000D9CCEC8A39E56F",
178  2),
179  EcRecommendedParameters<EC2N>(ASN1::sect113r2(),
180  113, 9, 0,
181  "00689918DBEC7E5A0DD6DFC0AA55C7",
182  "0095E9A9EC9B297BD4BF36E059184F",
183  "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D",
184  "010000000000000108789B2496AF93",
185  2),
186  EcRecommendedParameters<EC2N>(ASN1::sect163r2(),
187  163, 7, 6, 3, 0,
188  "000000000000000000000000000000000000000001",
189  "020A601907B8C953CA1481EB10512F78744A3205FD",
190  "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",
191  "040000000000000000000292FE77E70C12A4234C33",
192  2),
193  EcRecommendedParameters<EC2N>(ASN1::sect283k1(),
194  283, 12, 7, 5, 0,
195  "000000000000000000000000000000000000000000000000000000000000000000000000",
196  "000000000000000000000000000000000000000000000000000000000000000000000001",
197  "040503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC245849283601CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",
198  "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",
199  4),
200  EcRecommendedParameters<EC2N>(ASN1::sect283r1(),
201  283, 12, 7, 5, 0,
202  "000000000000000000000000000000000000000000000000000000000000000000000001",
203  "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",
204  "0405F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B1205303676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",
205  "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",
206  2),
207  EcRecommendedParameters<EC2N>(ASN1::sect131r1(),
208  131, 8, 3, 2, 0,
209  "07A11B09A76B562144418FF3FF8C2570B8",
210  "0217C05610884B63B9C6C7291678F9D341",
211  "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150",
212  "0400000000000000023123953A9464B54D",
213  2),
214  EcRecommendedParameters<EC2N>(ASN1::sect131r2(),
215  131, 8, 3, 2, 0,
216  "03E5A88919D7CAFCBF415F07C2176573B2",
217  "04B8266A46C55657AC734CE38F018F2192",
218  "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F",
219  "0400000000000000016954A233049BA98F",
220  2),
221  EcRecommendedParameters<EC2N>(ASN1::sect193r1(),
222  193, 15, 0,
223  "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01",
224  "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814",
225  "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05",
226  "01000000000000000000000000C7F34A778F443ACC920EBA49",
227  2),
228  EcRecommendedParameters<EC2N>(ASN1::sect193r2(),
229  193, 15, 0,
230  "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B",
231  "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE",
232  "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C",
233  "010000000000000000000000015AAB561B005413CCD4EE99D5",
234  2),
235  EcRecommendedParameters<EC2N>(ASN1::sect233k1(),
236  233, 74, 0,
237  "000000000000000000000000000000000000000000000000000000000000",
238  "000000000000000000000000000000000000000000000000000000000001",
239  "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",
240  "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",
241  4),
242  EcRecommendedParameters<EC2N>(ASN1::sect233r1(),
243  233, 74, 0,
244  "000000000000000000000000000000000000000000000000000000000001",
245  "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",
246  "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",
247  "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",
248  2),
249  EcRecommendedParameters<EC2N>(ASN1::sect409k1(),
250  409, 87, 0,
251  "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
252  "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
253  "040060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE902374601E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",
254  "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",
255  4),
256  EcRecommendedParameters<EC2N>(ASN1::sect409r1(),
257  409, 87, 0,
258  "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
259  "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",
260  "04015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A70061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",
261  "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",
262  2),
263  EcRecommendedParameters<EC2N>(ASN1::sect571k1(),
264  571, 10, 5, 2, 0,
265  "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
266  "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
267  "04026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C89720349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",
268  "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",
269  4),
270  EcRecommendedParameters<EC2N>(ASN1::sect571r1(),
271  571, 10, 5, 2, 0,
272  "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
273  "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",
274  "040303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",
275  "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",
276  2),
277  };
278  begin = rec;
279  end = rec + sizeof(rec)/sizeof(rec[0]);
280 }
281 
282 // See https://www.cryptopp.com/wiki/SM2 for details on sm2p256v1 and sm2encrypt_recommendedParameters
283 static void GetRecommendedParameters(const EcRecommendedParameters<ECP> *&begin, const EcRecommendedParameters<ECP> *&end)
284 {
285  // this array must be sorted by OID
286  static const EcRecommendedParameters<ECP> rec[] = {
287  EcRecommendedParameters<ECP>(ASN1::sm2p256v1(),
288  "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF",
289  "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC",
290  "28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93",
291  "04" "32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7"
292  "BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0",
293  "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123",
294  1),
295  EcRecommendedParameters<ECP>(ASN1::sm2encrypt_recommendedParameters(),
296  "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF",
297  "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC",
298  "28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93",
299  "04" "32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7"
300  "BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0",
301  "FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123",
302  1),
303  EcRecommendedParameters<ECP>(ASN1::secp192r1(),
304  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
305  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
306  "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
307  "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
308  "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
309  1),
310  EcRecommendedParameters<ECP>(ASN1::secp256r1(),
311  "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
312  "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
313  "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
314  "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
315  "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
316  1),
317  EcRecommendedParameters<ECP>(ASN1::brainpoolP160r1(),
318  "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
319  "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
320  "1E589A8595423412134FAA2DBDEC95C8D8675E58",
321  "04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321",
322  "E95E4A5F737059DC60DF5991D45029409E60FC09",
323  1),
324  EcRecommendedParameters<ECP>(ASN1::brainpoolP192r1(),
325  "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
326  "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
327  "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
328  "04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
329  "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
330  1),
331  EcRecommendedParameters<ECP>(ASN1::brainpoolP224r1(),
332  "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
333  "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
334  "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
335  "040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
336  "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
337  1),
338  EcRecommendedParameters<ECP>(ASN1::brainpoolP256r1(),
339  "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
340  "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
341  "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
342  "048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
343  "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
344  1),
345  EcRecommendedParameters<ECP>(ASN1::brainpoolP320r1(),
346  "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
347  "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
348  "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
349  "0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
350  "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
351  1),
352  EcRecommendedParameters<ECP>(ASN1::brainpoolP384r1(),
353  "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
354  "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
355  "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
356  "041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
357  "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
358  1),
359  EcRecommendedParameters<ECP>(ASN1::brainpoolP512r1(),
360  "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
361  "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
362  "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
363  "0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
364  "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
365  1),
366  EcRecommendedParameters<ECP>(ASN1::secp112r1(),
367  "DB7C2ABF62E35E668076BEAD208B",
368  "DB7C2ABF62E35E668076BEAD2088",
369  "659EF8BA043916EEDE8911702B22",
370  "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500",
371  "DB7C2ABF62E35E7628DFAC6561C5",
372  1),
373  EcRecommendedParameters<ECP>(ASN1::secp112r2(),
374  "DB7C2ABF62E35E668076BEAD208B",
375  "6127C24C05F38A0AAAF65C0EF02C",
376  "51DEF1815DB5ED74FCC34C85D709",
377  "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97",
378  "36DF0AAFD8B8D7597CA10520D04B",
379  4),
380  EcRecommendedParameters<ECP>(ASN1::secp160r1(),
381  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
382  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
383  "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
384  "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32",
385  "0100000000000000000001F4C8F927AED3CA752257",
386  1),
387  EcRecommendedParameters<ECP>(ASN1::secp160k1(),
388  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
389  "0000000000000000000000000000000000000000",
390  "0000000000000000000000000000000000000007",
391  "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE",
392  "0100000000000000000001B8FA16DFAB9ACA16B6B3",
393  1),
394  EcRecommendedParameters<ECP>(ASN1::secp256k1(),
395  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
396  "0000000000000000000000000000000000000000000000000000000000000000",
397  "0000000000000000000000000000000000000000000000000000000000000007",
398  "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
399  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
400  1),
401  EcRecommendedParameters<ECP>(ASN1::secp128r1(),
402  "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
403  "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
404  "E87579C11079F43DD824993C2CEE5ED3",
405  "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83",
406  "FFFFFFFE0000000075A30D1B9038A115",
407  1),
408  EcRecommendedParameters<ECP>(ASN1::secp128r2(),
409  "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
410  "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
411  "5EEEFCA380D02919DC2C6558BB6D8A5D",
412  "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44",
413  "3FFFFFFF7FFFFFFFBE0024720613B5A3",
414  4),
415  EcRecommendedParameters<ECP>(ASN1::secp160r2(),
416  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
417  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
418  "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
419  "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
420  "0100000000000000000000351EE786A818F3A1A16B",
421  1),
422  EcRecommendedParameters<ECP>(ASN1::secp192k1(),
423  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
424  "000000000000000000000000000000000000000000000000",
425  "000000000000000000000000000000000000000000000003",
426  "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
427  "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
428  1),
429  EcRecommendedParameters<ECP>(ASN1::secp224k1(),
430  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
431  "00000000000000000000000000000000000000000000000000000000",
432  "00000000000000000000000000000000000000000000000000000005",
433  "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
434  "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
435  1),
436  EcRecommendedParameters<ECP>(ASN1::secp224r1(),
437  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
438  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
439  "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
440  "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
441  "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
442  1),
443  EcRecommendedParameters<ECP>(ASN1::secp384r1(),
444  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
445  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
446  "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
447  "04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
448  "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
449  1),
450  EcRecommendedParameters<ECP>(ASN1::secp521r1(),
451  "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
452  "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
453  "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
454  "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
455  "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
456  1),
457  };
458  begin = rec;
459  end = rec + sizeof(rec)/sizeof(rec[0]);
460 }
461 
463 {
464  const EcRecommendedParameters<EllipticCurve> *begin, *end;
465  GetRecommendedParameters(begin, end);
466  const EcRecommendedParameters<EllipticCurve> *it = std::upper_bound(begin, end, oid, OIDLessThan());
467  return (it == end ? OID() : it->oid);
468 }
469 
470 template <class EC> void DL_GroupParameters_EC<EC>::Initialize(const OID &oid)
471 {
472  const EcRecommendedParameters<EllipticCurve> *begin, *end;
473  GetRecommendedParameters(begin, end);
474  const EcRecommendedParameters<EllipticCurve> *it = std::lower_bound(begin, end, oid, OIDLessThan());
475  if (it == end || it->oid != oid)
476  throw UnknownOID();
477 
478  const EcRecommendedParameters<EllipticCurve> &param = *it;
479  m_oid = oid;
480  member_ptr<EllipticCurve> ec(param.NewEC());
481  this->m_groupPrecomputation.SetCurve(*ec);
482 
483  StringSource ssG(param.g, true, new HexDecoder);
484  Element G;
485  bool result = GetCurve().DecodePoint(G, ssG, (size_t)ssG.MaxRetrievable());
486  this->SetSubgroupGenerator(G);
487 
488  // TODO: this fails in practice. Should it throw?
489  CRYPTOPP_UNUSED(result); CRYPTOPP_ASSERT(result);
490 
491  StringSource ssN(param.n, true, new HexDecoder);
492  m_n.Decode(ssN, (size_t)ssN.MaxRetrievable());
493  m_k = param.h;
494 }
495 
496 template <class EC>
497 bool DL_GroupParameters_EC<EC>::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
498 {
499  if (strcmp(name, Name::GroupOID()) == 0)
500  {
501  if (m_oid.Empty())
502  return false;
503 
504  this->ThrowIfTypeMismatch(name, typeid(OID), valueType);
505  *reinterpret_cast<OID *>(pValue) = m_oid;
506  return true;
507  }
508  else
509  return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue).Assignable()
510  CRYPTOPP_GET_FUNCTION_ENTRY(Curve);
511 }
512 
513 template <class EC>
514 void DL_GroupParameters_EC<EC>::AssignFrom(const NameValuePairs &source)
515 {
516  OID oid;
517  if (source.GetValue(Name::GroupOID(), oid))
518  Initialize(oid);
519  else
520  {
521  EllipticCurve ec;
522  Point G;
523  Integer n;
524 
525  source.GetRequiredParameter("DL_GroupParameters_EC<EC>", Name::Curve(), ec);
526  source.GetRequiredParameter("DL_GroupParameters_EC<EC>", Name::SubgroupGenerator(), G);
527  source.GetRequiredParameter("DL_GroupParameters_EC<EC>", Name::SubgroupOrder(), n);
528  Integer k = source.GetValueWithDefault(Name::Cofactor(), Integer::Zero());
529 
530  Initialize(ec, G, n, k);
531  }
532 }
533 
534 template <class EC>
536 {
537  try
538  {
539  CRYPTOPP_UNUSED(rng);
540  AssignFrom(alg);
541  }
542  catch (InvalidArgument &)
543  {
544  throw NotImplemented("DL_GroupParameters_EC<EC>: curve generation is not implemented yet");
545  }
546 }
547 
548 template <class EC>
550 {
551  byte b;
552  if (!bt.Peek(b))
553  BERDecodeError();
554  if (b == OBJECT_IDENTIFIER)
555  Initialize(OID(bt));
556  else
557  {
558  BERSequenceDecoder seq(bt);
559  word32 version;
560  BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); // check version
561  EllipticCurve ec(seq);
562  Point G = ec.BERDecodePoint(seq);
563  Integer n(seq);
564  Integer k;
565  bool cofactorPresent = !seq.EndReached();
566  if (cofactorPresent)
567  k.BERDecode(seq);
568  else
569  k = Integer::Zero();
570  seq.MessageEnd();
571 
572  Initialize(ec, G, n, k);
573  }
574 }
575 
576 template <class EC>
578 {
579  if (m_encodeAsOID && !m_oid.Empty())
580  m_oid.DEREncode(bt);
581  else
582  {
583  DERSequenceEncoder seq(bt);
584  DEREncodeUnsigned<word32>(seq, 1); // version
585  GetCurve().DEREncode(seq);
586  GetCurve().DEREncodePoint(seq, this->GetSubgroupGenerator(), m_compress);
587  m_n.DEREncode(seq);
588  if (m_k.NotZero())
589  m_k.DEREncode(seq);
590  seq.MessageEnd();
591  }
592 }
593 
594 template <class EC>
596 {
597  if (!m_k)
598  {
599  Integer q = GetCurve().FieldSize();
600  Integer qSqrt = q.SquareRoot();
601  m_k = (q+2*qSqrt+1)/m_n;
602  }
603 
604  return m_k;
605 }
606 
607 template <class EC>
609 {
610  return ConvertToInteger(element.x);
611 }
612 
613 template <class EC>
614 bool DL_GroupParameters_EC<EC>::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
615 {
616  bool pass = GetCurve().ValidateParameters(rng, level);
617  CRYPTOPP_ASSERT(pass);
618 
619  Integer q = GetCurve().FieldSize();
620  pass = pass && m_n!=q;
621  CRYPTOPP_ASSERT(pass);
622 
623  if (level >= 2)
624  {
625  Integer qSqrt = q.SquareRoot();
626  pass = pass && m_n>4*qSqrt;
627  CRYPTOPP_ASSERT(pass);
628  pass = pass && VerifyPrime(rng, m_n, level-2);
629  CRYPTOPP_ASSERT(pass);
630  pass = pass && (m_k.IsZero() || m_k == (q+2*qSqrt+1)/m_n);
631  CRYPTOPP_ASSERT(pass);
632  pass = pass && CheckMOVCondition(q, m_n);
633  CRYPTOPP_ASSERT(pass);
634  }
635 
636  return pass;
637 }
638 
639 template <class EC>
640 bool DL_GroupParameters_EC<EC>::ValidateElement(unsigned int level, const Element &g, const DL_FixedBasePrecomputation<Element> *gpc) const
641 {
642  bool pass = !IsIdentity(g);
643  CRYPTOPP_ASSERT(pass);
644  pass = pass && GetCurve().VerifyPoint(g);
645  CRYPTOPP_ASSERT(pass);
646 
647  if (level >= 1)
648  {
649  if (gpc)
650  {
651  pass = pass && gpc->Exponentiate(this->GetGroupPrecomputation(), Integer::One()) == g;
652  CRYPTOPP_ASSERT(pass);
653  }
654  }
655  if (level >= 2 && pass)
656  {
657  const Integer &q = GetSubgroupOrder();
658  Element gq = gpc ? gpc->Exponentiate(this->GetGroupPrecomputation(), q) : this->ExponentiateElement(g, q);
659  pass = pass && IsIdentity(gq);
660  CRYPTOPP_ASSERT(pass);
661  }
662  return pass;
663 }
664 
665 template <class EC>
666 void DL_GroupParameters_EC<EC>::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
667 {
668  GetCurve().SimultaneousMultiply(results, base, exponents, exponentsCount);
669 }
670 
671 template <class EC>
672 typename DL_GroupParameters_EC<EC>::Element DL_GroupParameters_EC<EC>::MultiplyElements(const Element &a, const Element &b) const
673 {
674  return GetCurve().Add(a, b);
675 }
676 
677 template <class EC>
678 typename DL_GroupParameters_EC<EC>::Element DL_GroupParameters_EC<EC>::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
679 {
680  return GetCurve().CascadeMultiply(exponent1, element1, exponent2, element2);
681 }
682 
683 template <class EC>
685 {
686  return ASN1::id_ecPublicKey();
687 }
688 
689 std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj)
690 {
691  std::ostringstream oss;
692  oss << "(" << std::hex << obj.x << ", " << std::hex << obj.y << ")";
693  return os << oss.str();
694 }
695 
696 // ******************************************************************
697 
698 template <class EC>
699 void DL_PublicKey_EC<EC>::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
700 {
701  CRYPTOPP_UNUSED(parametersPresent);
702 
703  typename EC::Point P;
704  if (!this->GetGroupParameters().GetCurve().DecodePoint(P, bt, size))
705  BERDecodeError();
706  this->SetPublicElement(P);
707 }
708 
709 template <class EC>
711 {
712  this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression());
713 }
714 
715 // ******************************************************************
716 
717 template <class EC>
718 void DL_PrivateKey_EC<EC>::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
719 {
720  CRYPTOPP_UNUSED(size);
721  BERSequenceDecoder seq(bt);
722  word32 version;
723  BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); // check version
724 
726  if (!dec.IsDefiniteLength())
727  BERDecodeError();
728  Integer x;
729  x.Decode(dec, (size_t)dec.RemainingLength());
730  dec.MessageEnd();
731  if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
732  BERDecodeError();
733  if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
734  {
735  BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0);
736  this->AccessGroupParameters().BERDecode(parameters);
737  parameters.MessageEnd();
738  }
739  if (!seq.EndReached())
740  {
741  // skip over the public element
742  SecByteBlock subjectPublicKey;
743  unsigned int unusedBits;
744  BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
745  BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
746  publicKey.MessageEnd();
747  Element Q;
748  if (!(unusedBits == 0 && this->GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size())))
749  BERDecodeError();
750  }
751  seq.MessageEnd();
752 
753  this->SetPrivateExponent(x);
754 }
755 
756 template <class EC>
758 {
759  DERSequenceEncoder privateKey(bt);
760  DEREncodeUnsigned<word32>(privateKey, 1); // version
761  // SEC 1 ver 1.0 says privateKey (m_d) has the same length as order of the curve
762  // this will be changed to order of base point in a future version
763  this->GetPrivateExponent().DEREncodeAsOctetString(privateKey, this->GetGroupParameters().GetSubgroupOrder().ByteCount());
764  privateKey.MessageEnd();
765 }
766 
767 // ******************************************************************
768 
769 template <class EC>
770 void DL_PublicKey_ECGDSA<EC>::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
771 {
772  CRYPTOPP_UNUSED(parametersPresent);
773 
774  typename EC::Point P;
775  if (!this->GetGroupParameters().GetCurve().DecodePoint(P, bt, size))
776  BERDecodeError();
777  this->SetPublicElement(P);
778 }
779 
780 template <class EC>
782 {
783  this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression());
784 }
785 
786 // ******************************************************************
787 
788 template <class EC>
789 void DL_PrivateKey_ECGDSA<EC>::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
790 {
791  CRYPTOPP_UNUSED(size);
792  BERSequenceDecoder seq(bt);
793  word32 version;
794  BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); // check version
795 
797  if (!dec.IsDefiniteLength())
798  BERDecodeError();
799  Integer x;
800  x.Decode(dec, (size_t)dec.RemainingLength());
801  dec.MessageEnd();
802  if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
803  BERDecodeError();
804  if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
805  {
806  BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0);
807  this->AccessGroupParameters().BERDecode(parameters);
808  parameters.MessageEnd();
809  }
810  if (!seq.EndReached())
811  {
812  // skip over the public element
813  SecByteBlock subjectPublicKey;
814  unsigned int unusedBits;
815  BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1);
816  BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
817  publicKey.MessageEnd();
818  Element Q;
819  if (!(unusedBits == 0 && this->GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size())))
820  BERDecodeError();
821  }
822  seq.MessageEnd();
823 
824  this->SetPrivateExponent(x);
825 }
826 
827 template <class EC>
829 {
830  DERSequenceEncoder privateKey(bt);
831  DEREncodeUnsigned<word32>(privateKey, 1); // version
832  // SEC 1 ver 1.0 says privateKey (m_d) has the same length as order of the curve
833  // this will be changed to order of base point in a future version
834  this->GetPrivateExponent().DEREncodeAsOctetString(privateKey, this->GetGroupParameters().GetSubgroupOrder().ByteCount());
835  privateKey.MessageEnd();
836 }
837 
838 NAMESPACE_END
839 
840 #endif
Standard names for retrieving values by name when working with NameValuePairs.
Classes and functions for working with ANS.1 objects.
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
@ CONSTRUCTED
ASN.1 Constructed flag.
Definition: asn.h:94
@ CONTEXT_SPECIFIC
ASN.1 Context specific class.
Definition: asn.h:98
std::ostream & operator<<(std::ostream &out, const OID &oid)
Print a OID value.
Definition: asn.h:939
@ OCTET_STRING
ASN.1 Octet string.
Definition: asn.h:38
@ INTEGER
ASN.1 Integer.
Definition: asn.h:34
@ OBJECT_IDENTIFIER
ASN.1 Object identifier.
Definition: asn.h:42
void BERDecodeError()
Raises a BERDecodeErr.
Definition: asn.h:104
BER General Decoder.
Definition: asn.h:380
BER Sequence Decoder.
Definition: asn.h:525
Interface for buffered transformations.
Definition: cryptlib.h:1657
virtual size_t Peek(byte &outByte) const
Peek a 8-bit byte.
DER Sequence Encoder.
Definition: asn.h:557
Diffie-Hellman domain.
Definition: dh.h:26
DL_FixedBasePrecomputation interface.
Definition: eprecomp.h:61
virtual Element Exponentiate(const DL_GroupPrecomputation< Element > &group, const Integer &exponent) const =0
Exponentiates an element.
Elliptic Curve Parameters.
Definition: eccrypto.h:40
Integer GetCofactor() const
Retrieves the cofactor.
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
this implementation doesn't actually generate a curve, it just initializes the parameters with existi...
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
Check the group for errors.
void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k=Integer::Zero())
Initialize an EC GroupParameters using {EC,G,n,k}.
Definition: eccrypto.h:78
Elliptic Curve German DSA key for ISO/IEC 15946.
Definition: eccrypto.h:419
Elliptic Curve Discrete Log (DL) private key.
Definition: eccrypto.h:210
Elliptic Curve German DSA key for ISO/IEC 15946.
Definition: eccrypto.h:501
Elliptic Curve Discrete Log (DL) public key.
Definition: eccrypto.h:179
Elliptic Curve over GF(2^n)
Definition: ec2n.h:27
Elliptic Curve over GF(p), where p is prime.
Definition: ecp.h:27
GF(2^n) with Pentanomial Basis.
Definition: gf2n.h:373
GF(2^n) for b233 and k233.
Definition: gf2n.h:359
GF(2^n) with Trinomial Basis.
Definition: gf2n.h:333
Decode base 16 data back to bytes.
Definition: hex.h:35
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
static const Integer & One()
Integer representing 1.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
static const Integer & Zero()
Integer representing 0.
Integer SquareRoot() const
Extract square root.
bool IsEven() const
Determines if the Integer is even parity.
Definition: integer.h:353
An invalid argument was detected.
Definition: cryptlib.h:208
MQV domain for performing authenticated key agreement.
Definition: mqv.h:29
Interface for retrieving values given their names.
Definition: cryptlib.h:327
A method was called which was not implemented.
Definition: cryptlib.h:238
Object Identifier.
Definition: asn.h:265
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2198
Polynomial with Coefficients in GF(2)
Definition: gf2n.h:27
Interface for random number generators.
Definition: cryptlib.h:1440
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
SecBlock<byte> typedef.
Definition: secblock.h:1226
String-based implementation of the Source interface.
Definition: filters.h:1459
Exception thrown when an unknown object identifier is encountered.
Definition: asn.h:108
Pointer that overloads operator ->
Definition: smartptr.h:38
Library configuration file.
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
Classes for Elliptic Curves over binary fields.
Classes and functions for Elliptic Curves over prime and binary fields.
Implementation of BufferedTransformation's attachment interface.
Classes for HexEncoder and HexDecoder.
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
Crypto++ library namespace.
const char * SubgroupGenerator()
Integer, ECP::Point, or EC2N::Point.
Definition: argnames.h:39
const char * SubgroupOrder()
Integer.
Definition: argnames.h:37
const char * Curve()
ECP or EC2N.
Definition: argnames.h:40
const char * GroupOID()
OID.
Definition: argnames.h:41
const char * Cofactor()
Integer.
Definition: argnames.h:38
Classes and functions for number theoretic operations.
CRYPTOPP_DLL unsigned int DiscreteLogWorkFactor(unsigned int bitlength)
Estimate work factor.
CRYPTOPP_DLL bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level=1)
Verifies a number is probably prime.
ASN.1 object identifiers for algorithms and schemes.
Precompiled header file.
Classes for automatic resource management.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68