Crypto++ 8.2 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 {
45 ECDSA<EC2N>::Signer t1;
46 ECDSA<EC2N>::Verifier t2(t1);
47 ECNR<ECP>::Signer t3;
48 ECNR<ECP>::Verifier t4(t3);
49 ECIES<ECP>::Encryptor t5;
50 ECIES<EC2N>::Decryptor t6;
51 ECDH<ECP>::Domain t7;
52 ECMQV<ECP>::Domain t8;
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
462 template <class EC> OID DL_GroupParameters_EC<EC>::GetNextRecommendedParametersOID(const OID &oid)
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>
535 void DL_GroupParameters_EC<EC>::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
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>
549 void DL_GroupParameters_EC<EC>::BERDecode(BufferedTransformation &bt)
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>
577 void DL_GroupParameters_EC<EC>::DEREncode(BufferedTransformation &bt) const
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>
595 Integer DL_GroupParameters_EC<EC>::GetCofactor() const
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>
608 Integer DL_GroupParameters_EC<EC>::ConvertElementToInteger(const Element &element) const
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>
684 OID DL_GroupParameters_EC<EC>::GetAlgorithmID() const
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>
710 void DL_PublicKey_EC<EC>::DEREncodePublicKey(BufferedTransformation &bt) const
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
725 BERGeneralDecoder dec(seq, OCTET_STRING);
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>
757 void DL_PrivateKey_EC<EC>::DEREncodePrivateKey(BufferedTransformation &bt) const
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>
781 void DL_PublicKey_ECGDSA<EC>::DEREncodePublicKey(BufferedTransformation &bt) const
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
796 BERGeneralDecoder dec(seq, OCTET_STRING);
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>
828 void DL_PrivateKey_ECGDSA<EC>::DEREncodePrivateKey(BufferedTransformation &bt) const
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
argnames.h
Standard names for retrieving values by name when working with NameValuePairs.
InvalidArgument
An invalid argument was detected.
Definition: cryptlib.h:202
DL_PublicKey_EC::DEREncodePublicKey
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition: eccrypto.cpp:710
EcRecommendedParameters
Definition: eccrypto.cpp:92
DL_FixedBasePrecomputation::Exponentiate
virtual Element Exponentiate(const DL_GroupPrecomputation< Element > &group, const Integer &exponent) const =0
Exponentiates an element.
DL_GroupParameters_EC::ValidateGroup
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
Check the group for errors.
Definition: eccrypto.cpp:614
DL_PublicKey_ECGDSA::DEREncodePublicKey
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition: eccrypto.cpp:781
misc.h
Utility functions for the Crypto++ library.
DL_GroupParameters_EC::AssignFrom
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: eccrypto.cpp:514
BufferedTransformation::Peek
virtual size_t Peek(byte &outByte) const
Peek a 8-bit byte.
Definition: cryptlib.cpp:551
DL_PrivateKey_ECGDSA::DEREncodePrivateKey
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: eccrypto.cpp:828
NameValuePairs::GetValueWithDefault
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
Definition: cryptlib.h:392
GF2NT
GF(2^n) with Trinomial Basis.
Definition: gf2n.h:332
INTEGER
ASN.1 Integer.
Definition: asn.h:34
ECP
Elliptic Curve over GF(p), where p is prime.
Definition: ecp.h:26
HexDecoder
Decode base 16 data back to bytes.
Definition: hex.h:34
PolynomialMod2::Encode
void Encode(byte *output, size_t outputLen) const
encode in big-endian format
Definition: gf2n.cpp:195
oids.h
ASN.1 object identifiers for algorthms and schemes.
smartptr.h
Classes for automatic resource management.
config.h
Library configuration file.
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1413
DL_GroupParameters_EC::GenerateRandom
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:535
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:1097
BERSequenceDecoder
BER Sequence Decoder.
Definition: asn.h:524
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1630
CONSTRUCTED
ASN.1 Constructed flag.
Definition: asn.h:94
StringSource
String-based implementation of the Source interface.
Definition: filters.h:1458
GF2NT233
GF(2^n) for b233 and k233.
Definition: gf2n.h:358
Integer::One
static const Integer &CRYPTOPP_API One()
Integer representing 1.
Definition: integer.cpp:4868
PolynomialMod2
Polynomial with Coefficients in GF(2)
Definition: gf2n.h:26
DL_GroupParameters_EC::GetCofactor
Integer GetCofactor() const
Retrieves the cofactor.
Definition: eccrypto.cpp:595
member_ptr
Pointer that overloads operator ->
Definition: smartptr.h:37
ec2n.h
Classes for Elliptic Curves over binary fields.
OCTET_STRING
ASN.1 Octet string.
Definition: asn.h:38
DL_GroupParameters_EC::GetVoidValue
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: eccrypto.cpp:497
DL_PublicKey_ECGDSA::BERDecodePublicKey
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition: eccrypto.cpp:770
MQV_Domain
MQV domain for performing authenticated key agreement.
Definition: mqv.h:28
NotImplemented
A method was called which was not implemented.
Definition: cryptlib.h:232
OIDLessThan
Definition: eccrypto.cpp:137
CONTEXT_SPECIFIC
ASN.1 Context specific class.
Definition: asn.h:98
hex.h
Classes for HexEncoder and HexDecoder.
Name::GroupOID
const char * GroupOID()
OID.
Definition: argnames.h:41
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:49
EC2N
Elliptic Curve over GF(2^n)
Definition: ec2n.h:26
pch.h
Precompiled header file.
EcRecommendedParameters< EC2N >
Definition: eccrypto.cpp:94
BERDecodeBitString
CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
Definition: asn.cpp:246
DL_PrivateKey_EC::DEREncodePrivateKey
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: eccrypto.cpp:757
Name::SubgroupGenerator
const char * SubgroupGenerator()
Integer, ECP::Point, or EC2N::Point.
Definition: argnames.h:39
Integer::IsEven
bool IsEven() const
Determines if the Integer is even parity.
Definition: integer.h:351
DL_PrivateKey_ECGDSA::BERDecodePrivateKey
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: eccrypto.cpp:789
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
DH_Domain
Diffie-Hellman domain.
Definition: dh.h:25
BERDecodeError
void BERDecodeError()
Raises a BERDecodeErr.
Definition: asn.h:104
asn.h
Classes and functions for working with ANS.1 objects.
DL_FixedBasePrecomputation
DL_FixedBasePrecomputation interface.
Definition: eprecomp.h:60
DL_GroupParameters_EC
Elliptic Curve Parameters.
Definition: eccrypto.h:39
NameValuePairs::GetRequiredParameter
void GetRequiredParameter(const char *className, const char *name, T &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:468
Integer::BitCount
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Definition: integer.cpp:3348
filters.h
Implementation of BufferedTransformation&#39;s attachment interface.
BERGeneralDecoder::MessageEnd
void MessageEnd()
Signals the end of messages to the object.
Definition: asn.cpp:553
GF2NPP
GF(2^n) with Pentanomial Basis.
Definition: gf2n.h:372
nbtheory.h
Classes and functions for number theoretic operations.
DERSequenceEncoder
DER Sequence Encoder.
Definition: asn.h:556
Name::Cofactor
const char * Cofactor()
Integer.
Definition: argnames.h:38
BufferedTransformation::MaxRetrievable
virtual lword MaxRetrievable() const
Provides the number of bytes ready for retrieval.
Definition: cryptlib.cpp:505
EcRecommendedParameters< ECP >
Definition: eccrypto.cpp:120
UnknownOID
Exception thrown when an unknown object identifier is encountered.
Definition: asn.h:107
PolynomialMod2::ByteCount
unsigned int ByteCount() const
number of significant bytes = ceiling(BitCount()/8)
Definition: gf2n.cpp:244
Integer::Decode
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED)
Decode from big-endian byte array.
Definition: integer.cpp:3357
integer.h
Multiple precision integer with arithmetic operations.
Integer::Zero
static const Integer &CRYPTOPP_API Zero()
Integer representing 0.
Definition: integer.cpp:4856
OBJECT_IDENTIFIER
ASN.1 Object identifier.
Definition: asn.h:42
VerifyPrime
CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level=1)
Verifies a number is probably prime.
Definition: nbtheory.cpp:247
DL_GroupParameters_EC::Initialize
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
Integer::BERDecode
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
Definition: integer.cpp:3440
eccrypto.h
Classes and functions for Elliptic Curves over prime and binary fields.
CryptoPP
Crypto++ library namespace.
NameValuePairs::GetValue
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:379
Name::Curve
const char * Curve()
ECP or EC2N.
Definition: argnames.h:40
Integer::SquareRoot
Integer SquareRoot() const
Extract square root.
Definition: integer.cpp:4363
BERGeneralDecoder
BER General Decoder.
Definition: asn.h:379
OID
Object Identifier.
Definition: asn.h:264
Name::SubgroupOrder
const char * SubgroupOrder()
Integer.
Definition: argnames.h:37
DL_PublicKey_EC::BERDecodePublicKey
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition: eccrypto.cpp:699
DiscreteLogWorkFactor
CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength)
Estimate work factor.
Definition: nbtheory.cpp:1045
SecBlock::size
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:831
DL_PrivateKey_EC::BERDecodePrivateKey
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: eccrypto.cpp:718
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:321
PK_FinalTemplate
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2187