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