Crypto++ 7.0 Free C++ class library of cryptographic schemes

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