Data Encryption-asymmetric
Last Update:2018-12-07
Source: Internet
Author: User
# Include "RSA. HPP"
Class prime_factory
{
Unsigned NP;
Unsigned * pl;
Public:
Prime_factory ();
~ Prime_factory ();
Vlong find_prime (vlong & START );
};
// Prime factory implementation
Static int is_probable_prime (const vlong & P)
{
// Test Based on fermats Theorem A ** (p-1) = 1 mod p for prime p
// For 1000 bit numbers this can take quite a while
Const rep = 4;
Const unsigned any [rep] = {2, 3, 5, 7 };
For (unsigned I = 0; I <rep; I + = 1)
If (modexp (any [I], P-1, p )! = 1)
Return 0;
Return 1;
}
Prime_factory: prime_factory ()
{
NP = 0;
Unsigned Np = 200;
PL = new unsigned [NP];
// Initialise pl
Unsigned Ss = 8 * NP; // rough estimate to fill pl
Char * B = new char [ss + 1]; // one extra to stop search
For (unsigned I = 0; I <= SS; I + = 1) B [I] = 1;
Unsigned P = 2;
While (1)
{
// Skip Composites
While (B [p] = 0) P + = 1;
If (P = SS) break;
PL [NP] = P;
NP + = 1;
If (Np = NP) break;
// Cross off multiples
Unsigned c = p * 2;
While (C <SS)
{
B [c] = 0;
C + = P;
}
P + = 1;
}
Delete [] B;
}
Prime_factory ::~ Prime_factory ()
{
Delete [] pl;
}
Vlong prime_factory: find_prime (vlong & start)
{
Unsigned Ss = 1000; // shoshould be enough unless we are unlucky
Char * B = new char [ss]; // bitset of candidate primes
Unsigned tested = 0;
While (1)
{
Unsigned I;
For (I = 0; I <SS; I + = 1)
B [I] = 1;
For (I = 0; I <NP; I + = 1)
{
Unsigned P = pl [I];
Unsigned r = start % P; // not as fast as it shocould be-cocould do with special routine
If (r) r = P-r;
// Cross off multiples of P
While (r <SS)
{
B [R] = 0;
R + = P;
}
}
// Now test candidates
For (I = 0; I <SS; I + = 1)
{
If (B [I])
{
Tested + = 1;
If (is_probable_prime (start ))
Return start;
}
Start + = 1;
}
}
Delete [] B;
}
Static vlong from_str (const char * s)
{
Vlong x = 0;
While (* s)
{
X = x * 256 + (unsigned char) * s;
S + = 1;
}
Return X;
}
Void private_key: Create (const char * R1, const char * R2)
{
// Choose Primes
{
Prime_factory PF;
P = PF. find_prime (from_str (R1 ));
Q = PF. find_prime (from_str (R2 ));
If (P> q) {vlong TMP = P; P = Q; q = TMP ;}
}
// Calculate Public Key
{
M = p * q;
E = 50001; // must be odd since P-1 q-1 are even
While (gcd (p-1, e )! = 1 w.w.gcd (q-1, e )! = 1) e + = 2;
}
}
Vlong public_key: encrypt (const vlong & plain)
{
Return modexp (plain, E, M );
}
Vlong private_key: decrypt (const vlong & Cipher)
{
// Calculate values for encryption Ming decryption
// These cocould be cached, but the calculation is quite fast
Vlong d = modinv (E, (p-1) * (q-1 ));
Vlong u = modinv (p, q );
Vlong dp = D % (p-1 );
Vlong DQ = D % (q-1 );
// Apply Chinese Remainder Theorem
Vlong A = modexp (Cipher % P, DP, P );
Vlong B = modexp (Cipher % Q, DQ, q );
If (B <A) B + = Q;
Return A + p * (B-a) * u) % Q );
}