Crypto++ 8.9 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.
asn.h
Classes and functions for working with ANS.1 objects.
BERDecodeBitString
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
CONSTRUCTED
@ CONSTRUCTED
ASN.1 Constructed flag.
Definition: asn.h:94
CONTEXT_SPECIFIC
@ CONTEXT_SPECIFIC
ASN.1 Context specific class.
Definition: asn.h:98
operator<<
std::ostream & operator<<(std::ostream &out, const OID &oid)
Print a OID value.
OCTET_STRING
@ OCTET_STRING
ASN.1 Octet string.
Definition: asn.h:38
INTEGER
@ INTEGER
ASN.1 Integer.
Definition: asn.h:34
OBJECT_IDENTIFIER
@ OBJECT_IDENTIFIER
ASN.1 Object identifier.
Definition: asn.h:42
BERDecodeError
void BERDecodeError()
Raises a BERDecodeErr.
Definition: asn.h:104
BERGeneralDecoder
BER General Decoder.
Definition: asn.h:381
BERSequenceDecoder
BER Sequence Decoder.
Definition: asn.h:526
BufferedTransformation
Interface for buffered transformations.
Definition: cryptlib.h:1657
BufferedTransformation::Peek
virtual size_t Peek(byte &outByte) const
Peek a 8-bit byte.
DERSequenceEncoder
DER Sequence Encoder.
Definition: asn.h:558
DH_Domain
Diffie-Hellman domain.
Definition: dh.h:26
DL_FixedBasePrecomputation
DL_FixedBasePrecomputation interface.
Definition: eprecomp.h:61
DL_FixedBasePrecomputation::Exponentiate
virtual Element Exponentiate(const DL_GroupPrecomputation< Element > &group, const Integer &exponent) const =0
Exponentiates an element.
DL_GroupParameters_EC
Elliptic Curve Parameters.
Definition: eccrypto.h:40
DL_GroupParameters_EC::GetCofactor
Integer GetCofactor() const
Retrieves the cofactor.
DL_GroupParameters_EC::GenerateRandom
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
this implementation doesn't actually generate a curve, it just initializes the parameters with existi...
DL_GroupParameters_EC::GetVoidValue
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
DL_GroupParameters_EC::ValidateGroup
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
Check the group for errors.
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
DL_PrivateKey_ECGDSA
Elliptic Curve German DSA key for ISO/IEC 15946.
Definition: eccrypto.h:419
DL_PrivateKey_EC
Elliptic Curve Discrete Log (DL) private key.
Definition: eccrypto.h:210
DL_PublicKey_ECGDSA
Elliptic Curve German DSA key for ISO/IEC 15946.
Definition: eccrypto.h:501
DL_PublicKey_EC
Elliptic Curve Discrete Log (DL) public key.
Definition: eccrypto.h:179
EC2N
Elliptic Curve over GF(2^n)
Definition: ec2n.h:27
ECP
Elliptic Curve over GF(p), where p is prime.
Definition: ecp.h:27
GF2NPP
GF(2^n) with Pentanomial Basis.
Definition: gf2n.h:375
GF2NT233
GF(2^n) for b233 and k233.
Definition: gf2n.h:361
GF2NT
GF(2^n) with Trinomial Basis.
Definition: gf2n.h:335
HexDecoder
Decode base 16 data back to bytes.
Definition: hex.h:35
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:50
Integer::BERDecode
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
Integer::One
static const Integer & One()
Integer representing 1.
Integer::BitCount
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Integer::Zero
static const Integer & Zero()
Integer representing 0.
Integer::SquareRoot
Integer SquareRoot() const
Extract square root.
Integer::IsEven
bool IsEven() const
Determines if the Integer is even parity.
Definition: integer.h:353
InvalidArgument
An invalid argument was detected.
Definition: cryptlib.h:208
MQV_Domain
MQV domain for performing authenticated key agreement.
Definition: mqv.h:29
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:327
NotImplemented
A method was called which was not implemented.
Definition: cryptlib.h:238
OID
Object Identifier.
Definition: asn.h:265
PK_FinalTemplate
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:2198
PolynomialMod2
Polynomial with Coefficients in GF(2)
Definition: gf2n.h:27
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1440
SecBlock::size
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:1226
StringSource
String-based implementation of the Source interface.
Definition: filters.h:1459
UnknownOID
Exception thrown when an unknown object identifier is encountered.
Definition: asn.h:108
member_ptr
Pointer that overloads operator ->
Definition: smartptr.h:38
config.h
Library configuration file.
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
ec2n.h
Classes for Elliptic Curves over binary fields.
eccrypto.h
Classes and functions for Elliptic Curves over prime and binary fields.
filters.h
Implementation of BufferedTransformation's attachment interface.
hex.h
Classes for HexEncoder and HexDecoder.
integer.h
Multiple precision integer with arithmetic operations.
misc.h
Utility functions for the Crypto++ library.
CryptoPP
Crypto++ library namespace.
Name::SubgroupGenerator
const char * SubgroupGenerator()
Integer, ECP::Point, or EC2N::Point.
Definition: argnames.h:39
Name::SubgroupOrder
const char * SubgroupOrder()
Integer.
Definition: argnames.h:37
Name::Curve
const char * Curve()
ECP or EC2N.
Definition: argnames.h:40
Name::GroupOID
const char * GroupOID()
OID.
Definition: argnames.h:41
Name::Cofactor
const char * Cofactor()
Integer.
Definition: argnames.h:38
nbtheory.h
Classes and functions for number theoretic operations.
DiscreteLogWorkFactor
CRYPTOPP_DLL unsigned int DiscreteLogWorkFactor(unsigned int bitlength)
Estimate work factor.
VerifyPrime
CRYPTOPP_DLL bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level=1)
Verifies a number is probably prime.
oids.h
ASN.1 object identifiers for algorithms and schemes.
pch.h
Precompiled header file.
smartptr.h
Classes for automatic resource management.
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68