1
by weidai
Initial revision |
1 |
// validat2.cpp - written and placed in the public domain by Wei Dai
|
2 |
||
3 |
#include "pch.h" |
|
4 |
||
5 |
#include "blumshub.h" |
|
6 |
#include "rsa.h" |
|
7 |
#include "md2.h" |
|
8 |
#include "elgamal.h" |
|
9 |
#include "nr.h" |
|
10 |
#include "dsa.h" |
|
11 |
#include "dh.h" |
|
12 |
#include "mqv.h" |
|
13 |
#include "luc.h" |
|
14 |
#include "xtrcrypt.h" |
|
15 |
#include "rabin.h" |
|
16 |
#include "rw.h" |
|
17 |
#include "eccrypto.h" |
|
18 |
#include "ecp.h" |
|
19 |
#include "ec2n.h" |
|
20 |
#include "asn.h" |
|
21 |
#include "rng.h" |
|
22 |
#include "files.h" |
|
23 |
#include "hex.h" |
|
24 |
#include "oids.h" |
|
25 |
#include "esign.h" |
|
26 |
#include "osrng.h" |
|
27 |
||
28 |
#include <iostream> |
|
29 |
#include <iomanip> |
|
30 |
||
31 |
#include "validate.h" |
|
32 |
||
33 |
USING_NAMESPACE(CryptoPP) |
|
34 |
USING_NAMESPACE(std) |
|
35 |
||
36 |
class FixedRNG : public RandomNumberGenerator |
|
37 |
{
|
|
38 |
public: |
|
39 |
FixedRNG(BufferedTransformation &source) : m_source(source) {} |
|
40 |
||
41 |
byte GenerateByte() |
|
42 |
{
|
|
43 |
byte b; |
|
44 |
m_source.Get(b); |
|
45 |
return b; |
|
46 |
}
|
|
47 |
||
48 |
private: |
|
49 |
BufferedTransformation &m_source; |
|
50 |
};
|
|
51 |
||
52 |
bool ValidateBBS() |
|
53 |
{
|
|
54 |
cout << "\nBlumBlumShub validation suite running...\n\n"; |
|
55 |
||
56 |
Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351"); |
|
57 |
Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231"); |
|
58 |
Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431"); |
|
59 |
BlumBlumShub bbs(p, q, seed); |
|
60 |
bool pass = true, fail; |
|
61 |
int j; |
|
62 |
||
63 |
const byte output1[] = { |
|
64 |
0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9, |
|
65 |
0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE}; |
|
66 |
const byte output2[] = { |
|
67 |
0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7, |
|
68 |
0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1}; |
|
69 |
||
70 |
byte buf[20]; |
|
71 |
||
72 |
bbs.GenerateBlock(buf, 20); |
|
73 |
fail = memcmp(output1, buf, 20) != 0; |
|
74 |
pass = pass && !fail; |
|
75 |
||
76 |
cout << (fail ? "FAILED " : "passed "); |
|
77 |
for (j=0;j<20;j++) |
|
78 |
cout << setw(2) << setfill('0') << hex << (int)buf[j]; |
|
79 |
cout << endl; |
|
80 |
||
81 |
bbs.Seek(10); |
|
82 |
bbs.GenerateBlock(buf, 10); |
|
83 |
fail = memcmp(output1+10, buf, 10) != 0; |
|
84 |
pass = pass && !fail; |
|
85 |
||
86 |
cout << (fail ? "FAILED " : "passed "); |
|
87 |
for (j=0;j<10;j++) |
|
88 |
cout << setw(2) << setfill('0') << hex << (int)buf[j]; |
|
89 |
cout << endl; |
|
90 |
||
91 |
bbs.Seek(1234567); |
|
92 |
bbs.GenerateBlock(buf, 20); |
|
93 |
fail = memcmp(output2, buf, 20) != 0; |
|
94 |
pass = pass && !fail; |
|
95 |
||
96 |
cout << (fail ? "FAILED " : "passed "); |
|
97 |
for (j=0;j<20;j++) |
|
98 |
cout << setw(2) << setfill('0') << hex << (int)buf[j]; |
|
99 |
cout << endl; |
|
100 |
||
101 |
return pass; |
|
102 |
}
|
|
103 |
||
104 |
bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false) |
|
105 |
{
|
|
106 |
bool pass = true, fail; |
|
107 |
||
108 |
fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); |
|
109 |
pass = pass && !fail; |
|
110 |
||
111 |
cout << (fail ? "FAILED " : "passed "); |
|
112 |
cout << "signature key validation\n"; |
|
113 |
||
114 |
const byte *message = (byte *)"test message"; |
|
115 |
const int messageLen = 12; |
|
116 |
||
27
by weidai
various changes for 5.1 |
117 |
SecByteBlock signature(priv.MaxSignatureLength()); |
118 |
unsigned int signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature); |
|
119 |
fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength); |
|
1
by weidai
Initial revision |
120 |
pass = pass && !fail; |
121 |
||
122 |
cout << (fail ? "FAILED " : "passed "); |
|
123 |
cout << "signature and verification\n"; |
|
124 |
||
27
by weidai
various changes for 5.1 |
125 |
++signature[0]; |
126 |
fail = pub.VerifyMessage(message, messageLen, signature, signatureLength); |
|
1
by weidai
Initial revision |
127 |
pass = pass && !fail; |
128 |
||
129 |
cout << (fail ? "FAILED " : "passed "); |
|
130 |
cout << "checking invalid signature" << endl; |
|
131 |
||
27
by weidai
various changes for 5.1 |
132 |
if (priv.MaxRecoverableLength() > 0) |
133 |
{
|
|
134 |
signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULL, 0, signature); |
|
135 |
SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength)); |
|
136 |
DecodingResult result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength); |
|
137 |
fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0); |
|
138 |
pass = pass && !fail; |
|
139 |
||
140 |
cout << (fail ? "FAILED " : "passed "); |
|
141 |
cout << "signature and verification with recovery" << endl; |
|
142 |
||
143 |
++signature[0]; |
|
144 |
result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength); |
|
145 |
fail = result.isValidCoding; |
|
146 |
pass = pass && !fail; |
|
147 |
||
148 |
cout << (fail ? "FAILED " : "passed "); |
|
149 |
cout << "recovery with invalid signature" << endl; |
|
150 |
}
|
|
151 |
||
1
by weidai
Initial revision |
152 |
return pass; |
153 |
}
|
|
154 |
||
155 |
bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false) |
|
156 |
{
|
|
157 |
bool pass = true, fail; |
|
158 |
||
159 |
fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); |
|
160 |
pass = pass && !fail; |
|
161 |
||
162 |
cout << (fail ? "FAILED " : "passed "); |
|
163 |
cout << "cryptosystem key validation\n"; |
|
164 |
||
165 |
const byte *message = (byte *)"test message"; |
|
166 |
const int messageLen = 12; |
|
167 |
SecByteBlock ciphertext(priv.CiphertextLength(messageLen)); |
|
168 |
SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size())); |
|
169 |
||
170 |
pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext); |
|
27
by weidai
various changes for 5.1 |
171 |
fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen); |
1
by weidai
Initial revision |
172 |
fail = fail || memcmp(message, plaintext, messageLen); |
173 |
pass = pass && !fail; |
|
174 |
||
175 |
cout << (fail ? "FAILED " : "passed "); |
|
176 |
cout << "encryption and decryption\n"; |
|
177 |
||
178 |
return pass; |
|
179 |
}
|
|
180 |
||
181 |
bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d) |
|
182 |
{
|
|
183 |
if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) |
|
184 |
cout << "passed simple key agreement domain parameters validation" << endl; |
|
185 |
else
|
|
186 |
{
|
|
187 |
cout << "FAILED simple key agreement domain parameters invalid" << endl; |
|
188 |
return false; |
|
189 |
}
|
|
190 |
||
191 |
SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength()); |
|
192 |
SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength()); |
|
193 |
SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); |
|
194 |
||
195 |
d.GenerateKeyPair(GlobalRNG(), priv1, pub1); |
|
196 |
d.GenerateKeyPair(GlobalRNG(), priv2, pub2); |
|
197 |
||
198 |
memset(val1.begin(), 0x10, val1.size()); |
|
199 |
memset(val2.begin(), 0x11, val2.size()); |
|
200 |
||
201 |
if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1))) |
|
202 |
{
|
|
203 |
cout << "FAILED simple key agreement failed" << endl; |
|
204 |
return false; |
|
205 |
}
|
|
206 |
||
207 |
if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) |
|
208 |
{
|
|
209 |
cout << "FAILED simple agreed values not equal" << endl; |
|
210 |
return false; |
|
211 |
}
|
|
212 |
||
213 |
cout << "passed simple key agreement" << endl; |
|
214 |
return true; |
|
215 |
}
|
|
216 |
||
217 |
bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d) |
|
218 |
{
|
|
219 |
if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) |
|
220 |
cout << "passed authenticated key agreement domain parameters validation" << endl; |
|
221 |
else
|
|
222 |
{
|
|
223 |
cout << "FAILED authenticated key agreement domain parameters invalid" << endl; |
|
224 |
return false; |
|
225 |
}
|
|
226 |
||
227 |
SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength()); |
|
228 |
SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength()); |
|
229 |
SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength()); |
|
230 |
SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength()); |
|
231 |
SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); |
|
232 |
||
233 |
d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1); |
|
234 |
d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2); |
|
235 |
d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1); |
|
236 |
d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2); |
|
237 |
||
238 |
memset(val1.begin(), 0x10, val1.size()); |
|
239 |
memset(val2.begin(), 0x11, val2.size()); |
|
240 |
||
241 |
if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1))) |
|
242 |
{
|
|
243 |
cout << "FAILED authenticated key agreement failed" << endl; |
|
244 |
return false; |
|
245 |
}
|
|
246 |
||
247 |
if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) |
|
248 |
{
|
|
249 |
cout << "FAILED authenticated agreed values not equal" << endl; |
|
250 |
return false; |
|
251 |
}
|
|
252 |
||
253 |
cout << "passed authenticated key agreement" << endl; |
|
254 |
return true; |
|
255 |
}
|
|
256 |
||
257 |
bool ValidateRSA() |
|
258 |
{
|
|
259 |
cout << "\nRSA validation suite running...\n\n"; |
|
260 |
||
261 |
byte out[100], outPlain[100]; |
|
262 |
bool pass = true, fail; |
|
263 |
||
264 |
{
|
|
265 |
char *plain = "Everyone gets Friday off."; |
|
266 |
byte *signature = (byte *) |
|
267 |
"\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84" |
|
268 |
"\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21" |
|
269 |
"\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b" |
|
270 |
"\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1"; |
|
271 |
||
272 |
FileSource keys("rsa512a.dat", true, new HexDecoder); |
|
273 |
RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys); |
|
274 |
RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv); |
|
275 |
||
27
by weidai
various changes for 5.1 |
276 |
unsigned int signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out); |
1
by weidai
Initial revision |
277 |
fail = memcmp(signature, out, 64) != 0; |
278 |
pass = pass && !fail; |
|
279 |
||
280 |
cout << (fail ? "FAILED " : "passed "); |
|
281 |
cout << "signature check against test vector\n"; |
|
282 |
||
27
by weidai
various changes for 5.1 |
283 |
fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); |
1
by weidai
Initial revision |
284 |
pass = pass && !fail; |
285 |
||
286 |
cout << (fail ? "FAILED " : "passed "); |
|
287 |
cout << "verification check against test vector\n"; |
|
288 |
||
289 |
out[10]++; |
|
27
by weidai
various changes for 5.1 |
290 |
fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); |
1
by weidai
Initial revision |
291 |
pass = pass && !fail; |
292 |
||
293 |
cout << (fail ? "FAILED " : "passed "); |
|
294 |
cout << "invalid signature verification\n"; |
|
295 |
}
|
|
296 |
{
|
|
297 |
FileSource keys("rsa1024.dat", true, new HexDecoder); |
|
298 |
RSAES_PKCS1v15_Decryptor rsaPriv(keys); |
|
299 |
RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv); |
|
300 |
||
301 |
pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass; |
|
302 |
}
|
|
303 |
{
|
|
304 |
byte *plain = (byte *) |
|
305 |
"\x54\x85\x9b\x34\x2c\x49\xea\x2a"; |
|
306 |
byte *encrypted = (byte *) |
|
307 |
"\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" |
|
308 |
"\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" |
|
309 |
"\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" |
|
310 |
"\x62\x51"; |
|
311 |
byte *oaepSeed = (byte *) |
|
312 |
"\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2" |
|
313 |
"\xf0\x6c\xb5\x8f"; |
|
314 |
ByteQueue bq; |
|
315 |
bq.Put(oaepSeed, 20); |
|
316 |
FixedRNG rng(bq); |
|
317 |
||
318 |
FileSource privFile("rsa400pv.dat", true, new HexDecoder); |
|
319 |
FileSource pubFile("rsa400pb.dat", true, new HexDecoder); |
|
320 |
RSAES_OAEP_SHA_Decryptor rsaPriv; |
|
321 |
rsaPriv.AccessKey().BERDecodeKey(privFile); |
|
322 |
RSAES_OAEP_SHA_Encryptor rsaPub(pubFile); |
|
323 |
||
324 |
memset(out, 0, 50); |
|
325 |
memset(outPlain, 0, 8); |
|
326 |
rsaPub.Encrypt(rng, plain, 8, out); |
|
27
by weidai
various changes for 5.1 |
327 |
DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain); |
1
by weidai
Initial revision |
328 |
fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8); |
329 |
pass = pass && !fail; |
|
330 |
||
331 |
cout << (fail ? "FAILED " : "passed "); |
|
332 |
cout << "PKCS 2.0 encryption and decryption\n"; |
|
333 |
}
|
|
334 |
||
335 |
return pass; |
|
336 |
}
|
|
337 |
||
338 |
bool ValidateDH() |
|
339 |
{
|
|
340 |
cout << "\nDH validation suite running...\n\n"; |
|
341 |
||
342 |
FileSource f("dh1024.dat", true, new HexDecoder()); |
|
343 |
DH dh(f); |
|
344 |
return SimpleKeyAgreementValidate(dh); |
|
345 |
}
|
|
346 |
||
347 |
bool ValidateMQV() |
|
348 |
{
|
|
349 |
cout << "\nMQV validation suite running...\n\n"; |
|
350 |
||
351 |
FileSource f("mqv1024.dat", true, new HexDecoder()); |
|
352 |
MQV mqv(f); |
|
353 |
return AuthenticatedKeyAgreementValidate(mqv); |
|
354 |
}
|
|
355 |
||
356 |
bool ValidateLUC_DH() |
|
357 |
{
|
|
358 |
cout << "\nLUC-DH validation suite running...\n\n"; |
|
359 |
||
360 |
FileSource f("lucd512.dat", true, new HexDecoder()); |
|
361 |
LUC_DH dh(f); |
|
362 |
return SimpleKeyAgreementValidate(dh); |
|
363 |
}
|
|
364 |
||
365 |
bool ValidateXTR_DH() |
|
366 |
{
|
|
367 |
cout << "\nXTR-DH validation suite running...\n\n"; |
|
368 |
||
369 |
FileSource f("xtrdh171.dat", true, new HexDecoder()); |
|
370 |
XTR_DH dh(f); |
|
371 |
return SimpleKeyAgreementValidate(dh); |
|
372 |
}
|
|
373 |
||
374 |
bool ValidateElGamal() |
|
375 |
{
|
|
376 |
cout << "\nElGamal validation suite running...\n\n"; |
|
377 |
bool pass = true; |
|
378 |
{
|
|
379 |
FileSource fc("elgc1024.dat", true, new HexDecoder); |
|
380 |
ElGamalDecryptor privC(fc); |
|
381 |
ElGamalEncryptor pubC(privC); |
|
382 |
privC.AccessKey().Precompute(); |
|
383 |
ByteQueue queue; |
|
384 |
privC.AccessKey().SavePrecomputation(queue); |
|
385 |
privC.AccessKey().LoadPrecomputation(queue); |
|
386 |
||
387 |
pass = CryptoSystemValidate(privC, pubC) && pass; |
|
388 |
}
|
|
389 |
return pass; |
|
390 |
}
|
|
391 |
||
392 |
bool ValidateDLIES() |
|
393 |
{
|
|
394 |
cout << "\nDLIES validation suite running...\n\n"; |
|
395 |
bool pass = true; |
|
396 |
{
|
|
397 |
FileSource fc("dlie1024.dat", true, new HexDecoder); |
|
398 |
DLIES<>::Decryptor privC(fc); |
|
399 |
DLIES<>::Encryptor pubC(privC); |
|
400 |
pass = CryptoSystemValidate(privC, pubC) && pass; |
|
401 |
}
|
|
402 |
{
|
|
403 |
cout << "Generating new encryption key..." << endl; |
|
404 |
DLIES<>::GroupParameters gp; |
|
405 |
gp.GenerateRandomWithKeySize(GlobalRNG(), 128); |
|
406 |
DLIES<>::Decryptor decryptor; |
|
407 |
decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp); |
|
408 |
DLIES<>::Encryptor encryptor(decryptor); |
|
409 |
||
410 |
pass = CryptoSystemValidate(decryptor, encryptor) && pass; |
|
411 |
}
|
|
412 |
return pass; |
|
413 |
}
|
|
414 |
||
415 |
bool ValidateNR() |
|
416 |
{
|
|
417 |
cout << "\nNR validation suite running...\n\n"; |
|
418 |
bool pass = true; |
|
419 |
{
|
|
420 |
FileSource f("nr2048.dat", true, new HexDecoder); |
|
421 |
NR<SHA>::Signer privS(f); |
|
422 |
privS.AccessKey().Precompute(); |
|
423 |
NR<SHA>::Verifier pubS(privS); |
|
424 |
||
425 |
pass = SignatureValidate(privS, pubS) && pass; |
|
426 |
}
|
|
427 |
{
|
|
428 |
cout << "Generating new signature key..." << endl; |
|
429 |
NR<SHA>::Signer privS(GlobalRNG(), 256); |
|
430 |
NR<SHA>::Verifier pubS(privS); |
|
431 |
||
432 |
pass = SignatureValidate(privS, pubS) && pass; |
|
433 |
}
|
|
434 |
return pass; |
|
435 |
}
|
|
436 |
||
437 |
bool ValidateDSA(bool thorough) |
|
438 |
{
|
|
439 |
cout << "\nDSA validation suite running...\n\n"; |
|
440 |
||
441 |
bool pass = true, fail; |
|
442 |
{
|
|
443 |
FileSource fs("dsa512.dat", true, new HexDecoder()); |
|
444 |
GDSA<SHA>::Signer priv(fs); |
|
445 |
priv.AccessKey().Precompute(16); |
|
446 |
GDSA<SHA>::Verifier pub(priv); |
|
447 |
||
448 |
byte seed[]={0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, |
|
449 |
0x1b, 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3}; |
|
450 |
Integer k("358dad57 1462710f 50e254cf 1a376b2b deaadfbfh"); |
|
451 |
Integer h("a9993e36 4706816a ba3e2571 7850c26c 9cd0d89dh"); |
|
452 |
byte sig[]={0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43, 0x5c, 0xb7, 0x18, |
|
453 |
0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3, 0x41, 0xc0, |
|
454 |
0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf, 0x24, 0x58, 0xf4, |
|
455 |
0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc, 0xd8, 0xc8}; |
|
456 |
Integer r(sig, 20); |
|
457 |
Integer s(sig+20, 20); |
|
458 |
||
459 |
Integer pGen, qGen, rOut, sOut; |
|
460 |
int c; |
|
461 |
||
462 |
fail = !DSA::GeneratePrimes(seed, 160, c, pGen, 512, qGen); |
|
463 |
fail = fail || (pGen != pub.GetKey().GetGroupParameters().GetModulus()) || (qGen != pub.GetKey().GetGroupParameters().GetSubgroupOrder()); |
|
464 |
pass = pass && !fail; |
|
465 |
||
466 |
cout << (fail ? "FAILED " : "passed "); |
|
467 |
cout << "prime generation test\n"; |
|
468 |
||
27
by weidai
various changes for 5.1 |
469 |
priv.RawSign(k, h, rOut, sOut); |
1
by weidai
Initial revision |
470 |
fail = (rOut != r) || (sOut != s); |
471 |
pass = pass && !fail; |
|
472 |
||
473 |
cout << (fail ? "FAILED " : "passed "); |
|
474 |
cout << "signature check against test vector\n"; |
|
475 |
||
27
by weidai
various changes for 5.1 |
476 |
fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig)); |
1
by weidai
Initial revision |
477 |
pass = pass && !fail; |
478 |
||
479 |
cout << (fail ? "FAILED " : "passed "); |
|
480 |
cout << "verification check against test vector\n"; |
|
481 |
||
27
by weidai
various changes for 5.1 |
482 |
fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig)); |
1
by weidai
Initial revision |
483 |
pass = pass && !fail; |
484 |
}
|
|
485 |
FileSource fs1("dsa1024.dat", true, new HexDecoder()); |
|
486 |
DSA::Signer priv(fs1); |
|
487 |
DSA::Verifier pub(priv); |
|
488 |
FileSource fs2("dsa1024b.dat", true, new HexDecoder()); |
|
489 |
DSA::Verifier pub1(fs2); |
|
490 |
assert(pub.GetKey() == pub1.GetKey()); |
|
491 |
pass = SignatureValidate(priv, pub, thorough) && pass; |
|
492 |
return pass; |
|
493 |
}
|
|
494 |
||
495 |
bool ValidateLUC() |
|
496 |
{
|
|
497 |
cout << "\nLUC validation suite running...\n\n"; |
|
498 |
bool pass=true; |
|
499 |
||
500 |
{
|
|
501 |
FileSource f("luc1024.dat", true, new HexDecoder); |
|
502 |
LUCSSA_PKCS1v15_SHA_Signer priv(f); |
|
503 |
LUCSSA_PKCS1v15_SHA_Verifier pub(priv); |
|
504 |
pass = SignatureValidate(priv, pub) && pass; |
|
505 |
}
|
|
506 |
{
|
|
507 |
LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512); |
|
508 |
LUCES_OAEP_SHA_Encryptor pub(priv); |
|
509 |
pass = CryptoSystemValidate(priv, pub) && pass; |
|
510 |
}
|
|
511 |
return pass; |
|
512 |
}
|
|
513 |
||
514 |
bool ValidateLUC_DL() |
|
515 |
{
|
|
516 |
cout << "\nLUC-HMP validation suite running...\n\n"; |
|
517 |
||
518 |
FileSource f("lucs512.dat", true, new HexDecoder); |
|
519 |
LUC_HMP<SHA>::Signer privS(f); |
|
520 |
LUC_HMP<SHA>::Verifier pubS(privS); |
|
521 |
bool pass = SignatureValidate(privS, pubS); |
|
522 |
||
523 |
cout << "\nLUC-IES validation suite running...\n\n"; |
|
524 |
||
525 |
FileSource fc("lucc512.dat", true, new HexDecoder); |
|
526 |
LUC_IES<>::Decryptor privC(fc); |
|
527 |
LUC_IES<>::Encryptor pubC(privC); |
|
528 |
pass = CryptoSystemValidate(privC, pubC) && pass; |
|
529 |
||
530 |
return pass; |
|
531 |
}
|
|
532 |
||
533 |
bool ValidateRabin() |
|
534 |
{
|
|
535 |
cout << "\nRabin validation suite running...\n\n"; |
|
536 |
bool pass=true; |
|
537 |
||
538 |
{
|
|
539 |
FileSource f("rabi1024.dat", true, new HexDecoder); |
|
27
by weidai
various changes for 5.1 |
540 |
RabinSS<PSSR, SHA>::Signer priv(f); |
541 |
RabinSS<PSSR, SHA>::Verifier pub(priv); |
|
1
by weidai
Initial revision |
542 |
pass = SignatureValidate(priv, pub) && pass; |
543 |
}
|
|
544 |
{
|
|
545 |
RabinES<OAEP<SHA> >::Decryptor priv(GlobalRNG(), 512); |
|
546 |
RabinES<OAEP<SHA> >::Encryptor pub(priv); |
|
547 |
pass = CryptoSystemValidate(priv, pub) && pass; |
|
548 |
}
|
|
549 |
return pass; |
|
550 |
}
|
|
551 |
||
552 |
bool ValidateRW() |
|
553 |
{
|
|
554 |
cout << "\nRW validation suite running...\n\n"; |
|
555 |
||
556 |
FileSource f("rw1024.dat", true, new HexDecoder); |
|
27
by weidai
various changes for 5.1 |
557 |
RWSS<PSSR, SHA>::Signer priv(f); |
558 |
RWSS<PSSR, SHA>::Verifier pub(priv); |
|
1
by weidai
Initial revision |
559 |
|
560 |
return SignatureValidate(priv, pub); |
|
561 |
}
|
|
562 |
||
563 |
/*
|
|
564 |
bool ValidateBlumGoldwasser()
|
|
565 |
{
|
|
566 |
cout << "\nBlumGoldwasser validation suite running...\n\n";
|
|
567 |
||
568 |
FileSource f("blum512.dat", true, new HexDecoder);
|
|
569 |
BlumGoldwasserPrivateKey priv(f);
|
|
570 |
BlumGoldwasserPublicKey pub(priv);
|
|
571 |
||
572 |
return CryptoSystemValidate(priv, pub);
|
|
573 |
}
|
|
574 |
*/
|
|
575 |
||
576 |
bool ValidateECP() |
|
577 |
{
|
|
578 |
cout << "\nECP validation suite running...\n\n"; |
|
579 |
||
580 |
ECIES<ECP>::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1()); |
|
581 |
ECIES<ECP>::Encryptor cpub(cpriv); |
|
582 |
ByteQueue bq; |
|
583 |
cpriv.GetKey().DEREncode(bq); |
|
584 |
cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); |
|
585 |
cpub.GetKey().DEREncode(bq); |
|
586 |
ECDSA<ECP, SHA>::Signer spriv(bq); |
|
587 |
ECDSA<ECP, SHA>::Verifier spub(bq); |
|
588 |
ECDH<ECP>::Domain ecdhc(ASN1::secp192r1()); |
|
589 |
ECMQV<ECP>::Domain ecmqvc(ASN1::secp192r1()); |
|
590 |
||
591 |
spriv.AccessKey().Precompute(); |
|
592 |
ByteQueue queue; |
|
593 |
spriv.AccessKey().SavePrecomputation(queue); |
|
594 |
spriv.AccessKey().LoadPrecomputation(queue); |
|
595 |
||
596 |
bool pass = SignatureValidate(spriv, spub); |
|
597 |
cpub.AccessKey().Precompute(); |
|
598 |
cpriv.AccessKey().Precompute(); |
|
599 |
pass = CryptoSystemValidate(cpriv, cpub) && pass; |
|
600 |
pass = SimpleKeyAgreementValidate(ecdhc) && pass; |
|
601 |
pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; |
|
602 |
||
603 |
cout << "Turning on point compression..." << endl; |
|
604 |
cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); |
|
605 |
cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); |
|
606 |
ecdhc.AccessGroupParameters().SetPointCompression(true); |
|
607 |
ecmqvc.AccessGroupParameters().SetPointCompression(true); |
|
608 |
pass = CryptoSystemValidate(cpriv, cpub) && pass; |
|
609 |
pass = SimpleKeyAgreementValidate(ecdhc) && pass; |
|
610 |
pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; |
|
611 |
||
612 |
cout << "Testing SEC 2 recommended curves..." << endl; |
|
613 |
OID oid; |
|
614 |
while (!(oid = DL_GroupParameters_EC<ECP>::GetNextRecommendedParametersOID(oid)).m_values.empty()) |
|
615 |
{
|
|
616 |
DL_GroupParameters_EC<ECP> params(oid); |
|
617 |
bool fail = !params.Validate(GlobalRNG(), 2); |
|
618 |
cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl; |
|
619 |
pass = pass && !fail; |
|
620 |
}
|
|
621 |
||
622 |
return pass; |
|
623 |
}
|
|
624 |
||
625 |
bool ValidateEC2N() |
|
626 |
{
|
|
627 |
cout << "\nEC2N validation suite running...\n\n"; |
|
628 |
||
629 |
ECIES<EC2N>::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1()); |
|
630 |
ECIES<EC2N>::Encryptor cpub(cpriv); |
|
631 |
ByteQueue bq; |
|
632 |
cpriv.DEREncode(bq); |
|
633 |
cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); |
|
634 |
cpub.DEREncode(bq); |
|
635 |
ECDSA<EC2N, SHA>::Signer spriv(bq); |
|
636 |
ECDSA<EC2N, SHA>::Verifier spub(bq); |
|
637 |
ECDH<EC2N>::Domain ecdhc(ASN1::sect193r1()); |
|
638 |
ECMQV<EC2N>::Domain ecmqvc(ASN1::sect193r1()); |
|
639 |
||
640 |
spriv.AccessKey().Precompute(); |
|
641 |
ByteQueue queue; |
|
642 |
spriv.AccessKey().SavePrecomputation(queue); |
|
643 |
spriv.AccessKey().LoadPrecomputation(queue); |
|
644 |
||
645 |
bool pass = SignatureValidate(spriv, spub); |
|
646 |
pass = CryptoSystemValidate(cpriv, cpub) && pass; |
|
647 |
pass = SimpleKeyAgreementValidate(ecdhc) && pass; |
|
648 |
pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; |
|
649 |
||
650 |
cout << "Turning on point compression..." << endl; |
|
651 |
cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); |
|
652 |
cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); |
|
653 |
ecdhc.AccessGroupParameters().SetPointCompression(true); |
|
654 |
ecmqvc.AccessGroupParameters().SetPointCompression(true); |
|
655 |
pass = CryptoSystemValidate(cpriv, cpub) && pass; |
|
656 |
pass = SimpleKeyAgreementValidate(ecdhc) && pass; |
|
657 |
pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; |
|
658 |
||
659 |
#if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis |
|
660 |
cout << "Testing SEC 2 recommended curves..." << endl;
|
|
661 |
OID oid;
|
|
662 |
while (!(oid = ECParameters<EC2N>::GetNextRecommendedParametersOID(oid)).m_values.empty())
|
|
663 |
{
|
|
664 |
ECParameters<EC2N> params(oid);
|
|
665 |
bool fail = !params.ValidateParameters(GlobalRNG());
|
|
666 |
cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl;
|
|
667 |
pass = pass && !fail;
|
|
668 |
}
|
|
669 |
#endif
|
|
670 |
||
671 |
return pass; |
|
672 |
}
|
|
673 |
||
674 |
bool ValidateECDSA() |
|
675 |
{
|
|
676 |
cout << "\nECDSA validation suite running...\n\n"; |
|
677 |
||
678 |
// from Sample Test Vectors for P1363
|
|
679 |
GF2NT gf2n(191, 9, 0); |
|
680 |
byte a[]="\x28\x66\x53\x7B\x67\x67\x52\x63\x6A\x68\xF5\x65\x54\xE1\x26\x40\x27\x6B\x64\x9E\xF7\x52\x62\x67"; |
|
681 |
byte b[]="\x2E\x45\xEF\x57\x1F\x00\x78\x6F\x67\xB0\x08\x1B\x94\x95\xA3\xD9\x54\x62\xF5\xDE\x0A\xA1\x85\xEC"; |
|
682 |
EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24)); |
|
683 |
||
684 |
EC2N::Point P; |
|
685 |
ec.DecodePoint(P, (byte *)"\x04\x36\xB3\xDA\xF8\xA2\x32\x06\xF9\xC4\xF2\x99\xD7\xB2\x1A\x9C\x36\x91\x37\xF2\xC8\x4A\xE1\xAA\x0D" |
|
686 |
"\x76\x5B\xE7\x34\x33\xB3\xF9\x5E\x33\x29\x32\xE7\x0E\xA2\x45\xCA\x24\x18\xEA\x0E\xF9\x80\x18\xFB", ec.EncodedPointSize()); |
|
687 |
Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H"); |
|
688 |
Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH"); |
|
689 |
EC2N::Point Q(ec.Multiply(d, P)); |
|
690 |
ECDSA<EC2N, SHA>::Signer priv(ec, P, n, d); |
|
691 |
ECDSA<EC2N, SHA>::Verifier pub(priv); |
|
692 |
||
693 |
Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH"); |
|
694 |
Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H"); |
|
695 |
byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30" |
|
696 |
"\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e"; |
|
697 |
Integer r(sig, 24); |
|
698 |
Integer s(sig+24, 24); |
|
699 |
||
700 |
Integer rOut, sOut; |
|
701 |
bool fail, pass=true; |
|
702 |
||
27
by weidai
various changes for 5.1 |
703 |
priv.RawSign(k, h, rOut, sOut); |
1
by weidai
Initial revision |
704 |
fail = (rOut != r) || (sOut != s); |
705 |
pass = pass && !fail; |
|
706 |
||
707 |
cout << (fail ? "FAILED " : "passed "); |
|
708 |
cout << "signature check against test vector\n"; |
|
709 |
||
27
by weidai
various changes for 5.1 |
710 |
fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig)); |
1
by weidai
Initial revision |
711 |
pass = pass && !fail; |
712 |
||
713 |
cout << (fail ? "FAILED " : "passed "); |
|
714 |
cout << "verification check against test vector\n"; |
|
715 |
||
27
by weidai
various changes for 5.1 |
716 |
fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig)); |
1
by weidai
Initial revision |
717 |
pass = pass && !fail; |
718 |
||
719 |
pass = SignatureValidate(priv, pub) && pass; |
|
720 |
||
721 |
return pass; |
|
722 |
}
|
|
723 |
||
724 |
bool ValidateESIGN() |
|
725 |
{
|
|
726 |
cout << "\nESIGN validation suite running...\n\n"; |
|
727 |
||
728 |
bool pass = true, fail; |
|
729 |
||
730 |
const char *plain = "test"; |
|
731 |
const byte *signature = (byte *) |
|
732 |
"\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37\xFE\xBC\x76\x3F\xF1\x84\xF6\x59" |
|
733 |
"\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6" |
|
734 |
"\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A" |
|
735 |
"\x74\x02\x37\x0E\xED\x0A\x06\xAD\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C" |
|
736 |
"\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28"; |
|
737 |
||
738 |
FileSource keys("esig1536.dat", true, new HexDecoder); |
|
739 |
ESIGN<SHA>::Signer signer(keys); |
|
740 |
ESIGN<SHA>::Verifier verifier(signer); |
|
741 |
||
742 |
fail = !SignatureValidate(signer, verifier); |
|
743 |
pass = pass && !fail; |
|
744 |
||
27
by weidai
various changes for 5.1 |
745 |
fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength()); |
1
by weidai
Initial revision |
746 |
pass = pass && !fail; |
747 |
||
748 |
cout << (fail ? "FAILED " : "passed "); |
|
749 |
cout << "verification check against test vector\n"; |
|
750 |
||
751 |
cout << "Generating signature key from seed..." << endl; |
|
752 |
InvertibleESIGNFunction priv; |
|
753 |
priv.GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512)); |
|
754 |
||
755 |
fail = !SignatureValidate(signer, verifier); |
|
756 |
pass = pass && !fail; |
|
757 |
||
758 |
return pass; |
|
759 |
}
|