Crypto++ 8.7
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
36extern const char ECCRYPTO_FNAME[] = __FILE__;
37#endif
38
39NAMESPACE_BEGIN(CryptoPP)
40
41#if 0
42#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
43static void ECDSA_TestInstantiations()
44{
53}
54#endif
55#endif
56
57ANONYMOUS_NAMESPACE_BEGIN
58inline 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
66inline Integer ConvertToInteger(const Integer &x)
67{
68 return x;
69}
70
71inline 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}
88ANONYMOUS_NAMESPACE_END
89
90// ******************************************************************
91
92template <class T> struct EcRecommendedParameters;
93
94template<> 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
120template<> 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
137struct 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
147static 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
283static 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
470template <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
496template <class EC>
497bool 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
513template <class EC>
514void 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
534template <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
548template <class EC>
550{
551 byte b;
552 if (!bt.Peek(b))
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
576template <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
594template <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
607template <class EC>
609{
610 return ConvertToInteger(element.x);
611}
612
613template <class EC>
614bool 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
639template <class EC>
640bool 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
665template <class EC>
666void 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
671template <class EC>
672typename 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
677template <class EC>
678typename 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
683template <class EC>
685{
686 return ASN1::id_ecPublicKey();
687}
688
689std::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
698template <class EC>
699void 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))
706 this->SetPublicElement(P);
707}
708
709template <class EC>
711{
712 this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression());
713}
714
715// ******************************************************************
716
717template <class EC>
718void 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())
728 Integer x;
729 x.Decode(dec, (size_t)dec.RemainingLength());
730 dec.MessageEnd();
731 if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
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())))
750 }
751 seq.MessageEnd();
752
753 this->SetPrivateExponent(x);
754}
755
756template <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
769template <class EC>
770void 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))
777 this->SetPublicElement(P);
778}
779
780template <class EC>
782{
783 this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression());
784}
785
786// ******************************************************************
787
788template <class EC>
789void 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())
799 Integer x;
800 x.Decode(dec, (size_t)dec.RemainingLength());
801 dec.MessageEnd();
802 if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0))
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())))
821 }
822 seq.MessageEnd();
823
824 this->SetPrivateExponent(x);
825}
826
827template <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
838NAMESPACE_END
839
840#endif
Standard names for retrieving values by name when working with NameValuePairs.
Classes and functions for working with ANS.1 objects.
std::ostream & operator<<(std::ostream &out, const OID &oid)
Print a OID value.
Definition: asn.h:939
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
@ 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:1652
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
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
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
static const Integer & Zero()
Integer representing 0.
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Integer SquareRoot() const
Extract square root.
static const Integer & One()
Integer representing 1.
bool IsEven() const
Determines if the Integer is even parity.
Definition: integer.h:353
An invalid argument was detected.
Definition: cryptlib.h:203
MQV domain for performing authenticated key agreement.
Definition: mqv.h:29
Interface for retrieving values given their names.
Definition: cryptlib.h:322
A method was called which was not implemented.
Definition: cryptlib.h:233
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:1435
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:62
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 * GroupOID()
OID.
Definition: argnames.h:41
const char * SubgroupGenerator()
Integer, ECP::Point, or EC2N::Point.
Definition: argnames.h:39
const char * Curve()
ECP or EC2N.
Definition: argnames.h:40
const char * Cofactor()
Integer.
Definition: argnames.h:38
const char * SubgroupOrder()
Integer.
Definition: argnames.h:37
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