os/security/crypto/weakcrypto/test/tasymmetric/cryptopp/exponentiate.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
/**
sl@0
    20
 @file
sl@0
    21
*/
sl@0
    22
sl@0
    23
#include "modarith.h"
sl@0
    24
#include "nbtheory.h"
sl@0
    25
#include <iostream.h>
sl@0
    26
sl@0
    27
USING_NAMESPACE(CryptoPP)
sl@0
    28
sl@0
    29
void CheckEPOCDecrypt(Integer& e, Integer& p, Integer& q, Integer& cipher, Integer& expectedPlaintext);
sl@0
    30
sl@0
    31
void TestRSASigning()
sl@0
    32
{
sl@0
    33
	const Integer m("AA36ABCE88ACFDFF55523C7FC4523F90EFA00DF3774A259F2E62B4C5D99CB5ADB300A0285E5301930E0C70FB6876939CE616CE624A11E0086D341EBCACA0A1F5h");
sl@0
    34
	const Integer d("0A033748626487695F5F30BC38B98B44C2CD2DFF434098CD20D8A138D090BF64797C3FA7A2CDCB3CD1E0BDBA2654B4F9DF8E8AE59D733D9F33B301624AFD1D51h");
sl@0
    35
	const Integer e(17);
sl@0
    36
sl@0
    37
//	Take EPOC padded plain text, sign and verify
sl@0
    38
	const Integer plain("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0054859B342C49EA2Ah");
sl@0
    39
	const Integer expectedSig("786C08484F59280886A19919BECA53711819B2D2DD82D702E2F6DE991DC89CB968C01B1315A742B5BE783A781B5B1286F46DAFE29DE675C64A3BA4781DEF8F19h");
sl@0
    40
	
sl@0
    41
//	Private Encrypt (Sign) signedText = (digest ^ d) mod m
sl@0
    42
	Integer cipher_privateEncrypt = a_exp_b_mod_c(plain, d, m);
sl@0
    43
	assert(cipher_privateEncrypt==expectedSig);
sl@0
    44
		
sl@0
    45
//	Public Decrypt (Decrypt) = (signedText ^ e) mod m
sl@0
    46
	Integer verified = a_exp_b_mod_c(cipher_privateEncrypt, e, m);
sl@0
    47
	assert(verified==plain);
sl@0
    48
		
sl@0
    49
//	Now reverse operations (as in previous bugged asymmetric) and check results...
sl@0
    50
//	Do a private decrypt for bad signing
sl@0
    51
	Integer badSign = a_exp_b_mod_c(plain, d, m);
sl@0
    52
	assert(badSign==expectedSig);
sl@0
    53
sl@0
    54
//	And verify (public encryption)
sl@0
    55
	Integer badVerify = a_exp_b_mod_c(badSign, e, m);
sl@0
    56
	assert(badVerify==plain);
sl@0
    57
sl@0
    58
}
sl@0
    59
sl@0
    60
void TestRSADecryptValues()
sl@0
    61
{
sl@0
    62
//	First test a good set
sl@0
    63
/*	<modulus>BBF82F090682CE9C2338AC2B9DA871F7368D07EED41043A440D6B6F07454F51FB8DFBAAF035C02AB61EA48CEEB6FCD4876ED520D60E1EC4619719D8A5B8B807FAFB8E0A3DFC737723EE6B4B7D93A2584EE6A649D060953748834B2454598394EE0AAB12D7B61A51F527A9A41F6C1687FE2537298CA2A8F5946F8E5FD091DBDCB</modulus>
sl@0
    64
	<P>EECFAE81B1B9B3C908810B10A1B5600199EB9F44AEF4FDA493B81A9E3D84F632124EF0236E5D1E3B7E28FAE7AA040A2D5B252176459D1F397541BA2A58FB6599</P>
sl@0
    65
	<Q>C97FB1F027F453F6341233EAAAD1D9353F6C42D08866B1D05A0F2035028B9D869840B41666B42E92EA0DA3B43204B5CFCE3352524D0416A5A441E700AF461503</Q>
sl@0
    66
	<dP>54494CA63EBA0337E4E24023FCD69A5AEB07DDDC0183A4D0AC9B54B051F2B13ED9490975EAB77414FF59C1F7692E9A2E202B38FC910A474174ADC93C1F67C981</dP>
sl@0
    67
	<dQ>471E0290FF0AF0750351B7F878864CA961ADBD3A8A7E991C5C0556A94C3146A7F9803F8F6F8AE342E931FD8AE47A220D1B99A495849807FE39F9245A9836DA3D</dQ>
sl@0
    68
	<qInv>B06C4FDABB6301198D265BDBAE9423B380F271F73453885093077FCD39E2119FC98632154F5883B167A967BF402B4E9E2E0F9656E698EA3666EDFB25798039F7</qInv>
sl@0
    69
	<plaintext>D436E99569FD32A7C8A05BBC90D32C49</plaintext>
sl@0
    70
	<ciphertext>4B9C35BC3CA99B3908EF91C91F4D661544B5462CB3079D7B7A610B90039602F080417B049B7F31BAF16A87B59986620EC1BBD791AD30774309C05F0AFA24B0BF1EA1FEAA3A8EFA2C24F5626B8A9C9A157C1018DA54D314E728E2DB75E84FB5E99082561D904139B95C4DA70A5AB6412527B97CEDA04C6FB00BE1E44537706FF2</ciphertext>
sl@0
    71
*/
sl@0
    72
	Integer e1 = Integer(17);
sl@0
    73
	Integer p1 = Integer("EECFAE81B1B9B3C908810B10A1B5600199EB9F44AEF4FDA493B81A9E3D84F632124EF0236E5D1E3B7E28FAE7AA040A2D5B252176459D1F397541BA2A58FB6599h");
sl@0
    74
	Integer q1 = Integer("C97FB1F027F453F6341233EAAAD1D9353F6C42D08866B1D05A0F2035028B9D869840B41666B42E92EA0DA3B43204B5CFCE3352524D0416A5A441E700AF461503h");
sl@0
    75
	Integer cipher1 = Integer("4B9C35BC3CA99B3908EF91C91F4D661544B5462CB3079D7B7A610B90039602F080417B049B7F31BAF16A87B59986620EC1BBD791AD30774309C05F0AFA24B0BF1EA1FEAA3A8EFA2C24F5626B8A9C9A157C1018DA54D314E728E2DB75E84FB5E99082561D904139B95C4DA70A5AB6412527B97CEDA04C6FB00BE1E44537706FF2h");
sl@0
    76
	Integer ePlaintext1 = Integer("D436E99569FD32A7C8A05BBC90D32C49h"); 
sl@0
    77
sl@0
    78
	CheckEPOCDecrypt(e1, p1, q1, cipher1, ePlaintext1); 
sl@0
    79
sl@0
    80
//	Now test a bad set
sl@0
    81
/*
sl@0
    82
	<input>123456789ABCDEF123456789ABCDEF</input>
sl@0
    83
	<P>ED49CE92ABF0509006E412AC7F28EEA7626107C3F2456FA18E6513153D6F6003</P>
sl@0
    84
	<Q>ED12B5B118CBA1154DC24AE05AAB1E3A33B5E47A3715861697498824E5BCA331</Q>
sl@0
    85
	----------- e -----------
sl@0
    86
01 00 01 
sl@0
    87
	 ----------- P -----------
sl@0
    88
ed 49 ce 92 ab f0 50 90 06 e4 12 ac 7f 28 ee a7 62 61 07 c3 f2 45 6f a1 8e 65 13 15 3d 6f 60 03 
sl@0
    89
	 ----------- Q -----------
sl@0
    90
ed 12 b5 b1 18 cb a1 15 4d c2 4a e0 5a ab 1e 3a 33 b5 e4 7a 37 15 86 16 97 49 88 24 e5 bc a3 31 
sl@0
    91
	 ----------- DP -----------
sl@0
    92
dc e0 33 15 7c 4e f9 ee d7 3b 3d d6 ab 97 22 6f 54 b8 15 4e 64 1a 16 4b 40 0c fd b2 6b b9 5c 99 
sl@0
    93
	 ----------- DQ -----------
sl@0
    94
27 65 a3 92 11 a7 cd 56 27 fc f0 ca 85 e6 c7 f8 2e 1d bd 21 5e 44 12 6b 70 aa c4 98 35 21 7b 11 
sl@0
    95
	 ----------- QInv -----------
sl@0
    96
76 2f 0a 8c fa 16 d8 a6 df 53 0b 1c fa 5f ff 4c 55 a4 4f 52 e1 b6 28 89 1f c9 c9 10 1c d9 73 2d 
sl@0
    97
	 ----------- N -----------
sl@0
    98
db be ab d7 a5 8e c2 a8 83 17 83 86 9a 2e 07 12 03 1a 5c 0f 87 a8 4b d3 fe 3c 21 91 df 49 4e 2b e4 fa 8d a8 65 e5 c8 c7 49 4d fa c5 5c 6a d2 fc e6 96 2e 3b de 1b 38 28 94 93 04 47 dd a7 49 93 
sl@0
    99
	 ----------- ciphertext -----------
sl@0
   100
69 3a 72 26 39 cc 70 9c 89 ac dc 24 8c 52 ef 01 dd f7 5a c3 8e bf f9 8d eb ed 25 5e 11 f0 d9 b1 43 de 14 97 d2 34 65 a6 2c 11 13 6e f8 c4 37 81 01 d5 8e 8d ea 0b 33 f2 9f e2 df 68 c4 c7 34 2c 
sl@0
   101
sl@0
   102
*/
sl@0
   103
//	Two primes: p, q
sl@0
   104
	Integer e2 = Integer(65537);
sl@0
   105
	Integer p2 = Integer("ED49CE92ABF0509006E412AC7F28EEA7626107C3F2456FA18E6513153D6F6003h");
sl@0
   106
	Integer q2 = Integer("ED12B5B118CBA1154DC24AE05AAB1E3A33B5E47A3715861697498824E5BCA331h");
sl@0
   107
	Integer cipher2 = Integer("693A722639CC709C89ACDC248C52EF01DDF75AC38EBFF98DEBED255E11F0D9B143DE1497D23465A62C11136EF8C4378101D58E8DEA0B33F29FE2DF68C4C7342Ch");
sl@0
   108
	Integer ePlaintext2 = Integer("123456789ABCDEF123456789ABCDEFh"); 
sl@0
   109
	
sl@0
   110
	CheckEPOCDecrypt(e2, p2, q2, cipher2, ePlaintext2);
sl@0
   111
sl@0
   112
/*
sl@0
   113
<modulus>EF6419DC54EC49B7D0524BA675727F6D895A66A9940F3C76B6220A5B9073357D70702C9FC2D6ECA41448356CE562F7FFAF1DA64BA947274BA0D372F5866B69CB</modulus>
sl@0
   114
<P>FB4F79F4E8C816B816A817120901AED45D0FD72F3DC4BA6946F790776E8A5845</P>
sl@0
   115
<Q>F3DBAF51B232E334964581AE27DE17BFF90A66AE84C2BE95574082880BFF82CF</Q>
sl@0
   116
<dP>63D8A1C5B22EBD080AC861D2228DEE9E251344155ADF2C88E34F3CB096D49459</dP>
sl@0
   117
<dQ>F145A87EC23B0B059AB08690132DF07DA61F9E5C894A4D5A610B989A9694658D</dQ>
sl@0
   118
<qInv>4B8869676360EDC92F0B02F0B93580A570686E7EA3C7D39A5E572AB79314CCBD</qInv>
sl@0
   119
<ciphertext>2EAEAE1F07AAD1D3A14C2178397DFECD91C92E963511BE5CDDE8BCA79B47ECEF68F8DD2F8240DE2E05E90E2A75FAA6495CE903DE413D332CFDD2DD83BC8244C5</ciphertext>
sl@0
   120
<plaintext>123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEF</plaintext>
sl@0
   121
*/
sl@0
   122
	Integer e3 = Integer(65537);
sl@0
   123
	Integer p3 = Integer("FB4F79F4E8C816B816A817120901AED45D0FD72F3DC4BA6946F790776E8A5845h");
sl@0
   124
	Integer q3 = Integer("F3DBAF51B232E334964581AE27DE17BFF90A66AE84C2BE95574082880BFF82CFh");
sl@0
   125
	Integer cipher3 = Integer("2EAEAE1F07AAD1D3A14C2178397DFECD91C92E963511BE5CDDE8BCA79B47ECEF68F8DD2F8240DE2E05E90E2A75FAA6495CE903DE413D332CFDD2DD83BC8244C5h");
sl@0
   126
	Integer ePlaintext3 = Integer("123456789ABCDEF123456789ABCDEF123456789ABCDEF123456789ABCDEFh");
sl@0
   127
sl@0
   128
	CheckEPOCDecrypt(e3, p3, q3, cipher3, ePlaintext3);
sl@0
   129
}
sl@0
   130
sl@0
   131
void CheckEPOCDecrypt(Integer& e, Integer& p, Integer& q, Integer& cipher, Integer& expectedPlaintext)
sl@0
   132
{
sl@0
   133
//////////////////////////////////
sl@0
   134
//	Key generation
sl@0
   135
//////////////////////////////////
sl@0
   136
sl@0
   137
//	calculate n = p * q 
sl@0
   138
	Integer n=p*q;
sl@0
   139
sl@0
   140
	Integer r1 = p;
sl@0
   141
    r1-=1;		//	r1 = p-1
sl@0
   142
    
sl@0
   143
	Integer r2=q;
sl@0
   144
    r2-=1;		//	r2 = q-1
sl@0
   145
    
sl@0
   146
	Integer r0=r1;
sl@0
   147
    r0*=r2;	//	r0 = (p-1)(q-1)
sl@0
   148
sl@0
   149
//	e * d = 1 mod ((p-1)(q-1)) 
sl@0
   150
//	d = e^(-1) mod ((p-1)(q-1))
sl@0
   151
//! calculate multiplicative inverse of *this mod n
sl@0
   152
//	Integer InverseMod(const Integer &n) const;
sl@0
   153
	Integer d = e;
sl@0
   154
	d = d.InverseMod(r0);
sl@0
   155
sl@0
   156
//	calculate dP = d mod (p-1) 
sl@0
   157
	Integer dP=d;
sl@0
   158
	dP%=r1;
sl@0
   159
sl@0
   160
//	calculate dQ = d mod (q-1) 
sl@0
   161
	Integer dQ=d;
sl@0
   162
	dQ%=r2;
sl@0
   163
sl@0
   164
//	calculate inverse of qInv = q^(-1)mod(p)
sl@0
   165
    Integer qInv=q;
sl@0
   166
	qInv = qInv.InverseMod(p);
sl@0
   167
sl@0
   168
sl@0
   169
//////////////////////////////////
sl@0
   170
//	Decryption
sl@0
   171
//////////////////////////////////
sl@0
   172
sl@0
   173
//	m1 = c^(dP) mod(p)
sl@0
   174
	Integer m1 = ModularExponentiation((cipher % p), dP, p);
sl@0
   175
	
sl@0
   176
//	m2 = c^(dQ) mod(Q)
sl@0
   177
	Integer m2 = ModularExponentiation((cipher % q), dQ, q);
sl@0
   178
sl@0
   179
//	Calculate CRT
sl@0
   180
//	h = (m1-m2) qInv mod(p)	
sl@0
   181
	Integer plainRes = m1 - m2;
sl@0
   182
	plainRes *= qInv;
sl@0
   183
	plainRes %= p;
sl@0
   184
sl@0
   185
//	output = m2 + q * plainRes	
sl@0
   186
	plainRes *= q;
sl@0
   187
	plainRes += m2;
sl@0
   188
sl@0
   189
//	assert(expectedPlaintext==plainRes);	//	Not true because ciphertext includes
sl@0
   190
}											//	padding and plaintext doesn't. Though
sl@0
   191
											//	it's possible to compare the first chunk
sl@0
   192
											//	of plainRes with expectedPlaintext
sl@0
   193
sl@0
   194
int main(int argc, char** argv)
sl@0
   195
{
sl@0
   196
//	TestRSASigning();
sl@0
   197
	TestRSADecryptValues();
sl@0
   198
	return 0;
sl@0
   199
}
sl@0
   200