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