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