Introduction to Rabin-Miller Vulnerary Test and RSA Algorithm

zhaozj2021-02-12  128

RSA algorithm

This algorithm has occurred in 1978, which is the first algorithm that can be used for data encryption and digital signatures. It is easy to understand and operate, and it is also very popular. The name of the algorithm is naming in the name of the inventor: Ron Rivest, Adishamir and Leonard Adleman. But RSA's security has not been able to obtain theoretical proof.

??? The security of RSA depends on the fact that the large number is difficult to decompose. The public key and private key are two functions of two bulk (more than 100 decocation). It is speculated that the difficulty of clearing the plain text from a key and ciphertext is equivalent to decomposing two largest accumulation.

??? The result of the key. Select two large numbers, p and q. Calculate: n = p * q then randomly select the encryption key E, require E and (P - 1) * (Q - 1) mutual. Finally, the decryption key D is calculated using the Euclid algorithm to satisfy E * D = 1 (MOD (P - 1) * (Q - 1)) where n and d are also mutual. The number E and N are the public key, and D is a private key. The two prime numbers p and q are no longer needed, should be discarded, don't let anyone know. When encrypting information m (binary representation), the m is first divided into a equal length data block M1, M2, ..., Mi, block length S, where 2 ^ s <= n, and s is as large as possible. The corresponding ciphertext is: Ci = Mi ^ e (MOD N) (a) decrypts as follows: Mi = Ci ^ D (MOD N) (B)

??? RSA can be used for digital signatures, the scheme is verified with (A) signature, (B). Considering the factors such as safety and M information when considering the factors of safety and M information, they are generally ash as a HASH operation. RSA security. The security of RSA depends on the large number of decomposition, but whether it is equivalent to the theoretical proof, because there is no proven to crack the RSA, there must be a large number of decomposition. Assume that there is an algorithm that does not have to decompose, it must be modified to become a large number of decomposition algorithms. At present, some of RSA's variety algorithms have been proven to be equivalent to large decomposition. Anyway, decomposition N is the most obvious attack method. Nowadays, people have decomposed more than 140 decimalities. Therefore, the modulus n must be selected, depending on the specific applicability.

??? Since all of them are calculated, the fastest cases of RSA are more slower than DES, whether it is software or hardware implementation. The speed has always been the defect of RSA. Generally, only a small amount of data encryption.

* /

#include

#include

#include

Unsing namespace std; // rsa algorithm required TypeDef struct? rsa_param_tag {??? unsigned __int64 ??? p, q; ?? // two prime numbers, do not participate in encryption decryption operation? ?? Unsigned __int64 ??? f ; ????? // f = (p-1) * (Q-1), do not participate in encryption decryption operation ??? Unsigned __int64 ??? n, e; ?? // 公, n = p * q, gcd (e, f) = 1 ??? unsigned __INT64 ??? D; ????? // Private spoon, E * D = 1 (MOD F), GCD (N, D) = 1 ?? • unsigned __int64 ??? s; ????? // block long, satisfying the largest S <= N, is log2 (n)} RSA_PARAM; // Small packet number const static long ???? ?? g_primetable [] = {??? 3, ??? 5, ??? 7, ??? 11, ??? 13, ??? 17, ??? 19, ???? 23,??? 29, ??? 31, ??? 37, ??? 41, ??? 43, ??? 47, ??? 53, ???? 59, ??? 61, ??? 67,??? 71, ??? 73, ??? 79, ??? 83, ??? 89, ??? 97}; const static long ?????? g_primoune / sizeof (g_primetable) / sizeof (long); Const Unsigned __INT64? Multiplier = 12747293821; const unsigned __INT64? adder = 1343545677842234541; // random number class ?????????????????? ?DNumber {/ * * / private: ??? Unsigned __int64 ??? randseed; / * * / public: ??? randnumber (unsigned __int64 s = 0); ??? Unsigned __INT64 ??? random (unsigned __int64 n);}; / * / randNumber :: RandNumber (unsigned __int64 s) {??? if (! s) ??? {??????? randsee D = (unsigned __INT64) Time (null); ???} ??? Else ??? {??????? randseed = S; ???}} / * * / unsigned __int64 randnumber :: random unsigned __int64 n) {??? randseed = multiplier * randseed adder; ??? Return Randseed% N;} Static RandNumber ?? g_rnd; / * Modular operation, return value x = a * b mod n * / inline unsigned __INT64 MULMOD (unsigned __int64 b, unsigned __int64 n) {??? return a * b% n;} / * model, return value x = base ^ POW MOD N * / unsigned __int64 Powmod (unsigned __int64 & base, unsigned __INT64 & POW, Unsigned __INT64 & n) {??? unsigned __INT64 ??? a = base, b = POW, C = 1; ??? While (b) ??? {??????? While (! (B &)

1)) ???????? {???????????? b >> = 1; ???????????? // a = a * a% N;? ?? // The function appears to handle the integer of 64 bits, but since A * a has caused overflow in A> = 2 ^ 32, there is no 64-bit in the actual processing range ?????????? ? a = mulmod (a, a, n); ???????} ??????? b -; ??????? // c = a * c% n; ?? ????? // This will also overflow, if the 64-bit integer is removed to two 32-bit integers, I don't know if I can solve this problem. ??????? c = mulmod (a, c, n); ???} ??? Return C;} / * rabin-miller number test, return 1 by test, otherwise returns 0. n is the number of pendings to be measured. Note: It is not necessarily the number of prime numbers by testing. The probability of non-quantity is 1/4 * / long Rabinmillerknl (unsigned __int64 & n) {??? unsigned __INT64 ??? B, M, J, V, I;?? ? M = n - 1; ??? j = 0; ??? // 0, first calculate M, J, so that N-1 = m * 2 ^ j, where M is odd, J is a non-negative integer ?? ? While (! (m & 1)) ??? {??????? j; ??????? m >> = 1; ???} ??? // 1, random Take a B, 2 <= B ??? b = 2 g_rnd.random (n - 3); ??? // 2, calculate v = b ^ m mod n

??? v = POWMOD (B, M, N); ??? // 3, if v == 1, through test

??? f (v == 1)

??? {

??????? Return 1;

???} ??? // 4, order i = 1

??? i = 1; ??? // 5, if v = N-1, through test

??? while (v! = n - 1)

??? {

??????? // 6, if i == L, non-prime number, end

??????? if (i == j)

??????? {

??????????? return 0;

???????} ??????? // 7, v = V ^ 2 mod n, i = i 1

??????? v = POWMOD (V, 2, n);

??????? i; ??????? // 8, loop to 5

???} ??? Return 1;

} / *

Rabin-miller number test, cycle calling core loop

All returns 1, otherwise returns 0

* /

Long Rabinmiller (unsigned __int64 & n, long loop)

{

??? // First screened once, improve efficiency

??? for (long i = 0; i

??? {

??????? IF (n% g_primetable [i] == 0)

??????? {

??????????? return 0;

???????}

???} ??? // Call the Rabin-Miller test loop, make the non-quantity pass the probability of test to (1/4) ^ LOOP

??? for (long i = 0; i

??? {

??????? if (! rabinmillerknl (n))

??????? {

??????????? Return 0; ???????}

???} ??? Return 1;

} / *

Randomly generate a BITS bit (binary position), up to 32 digits

* /

Unsigned __int64 randomprime (char bits)

{

??? Unsigned __INT64 ??? base;

??? do

??? {

??????? base = (unsigned long) 1 << (bits - 1); ?? // guarantee the highest bit is 1

??????? base = g_rnd.random (base); ?????????????? // plus a random number

??????? base | = 1; ??? // guaranteed the lowest position 1, that is, the guarantee is an odd number

???} while (! Rabinmiller (Base, 30)); ??? // Test 30 times in Labin-Miller test

??? Return Base; ??? // All considered by the number

} / *

European miles to get the biggest convention

* /

Unsigned __int64 euclidgcd (unsigned __int64 & p, unsigned __INT64 & q)

{

??? unsigned __INT64 ??? a = p> q? p: q;

??? unsigned __INT64 ??? b = P

??? Unsigned __INT64 ??? t;

??? IF (p == q)

??? {

??????? Return P; ?? // two numbers, the largest number of conventions is itself

???}

??? ELSE

??? {

??????? while (b) ??? // Rossing, GCD (A, B) = GCD (B, A-QB)

??????? {

??????????? a = a% B;

??????????? t = a;

??????????? a = B;

??????????? b = t;

???????} ??????? Return A;

???}

} / *

Stein's maximum number of conventions

* /

Unsigned __int64 steingcd (unsigned __int64 & p, unsigned __int64 & q)

{

??? unsigned __INT64 ??? a = p> q? p: q;

??? unsigned __INT64 ??? b = P

??? Unsigned __INT64 ??? T, R = 1;

??? IF (p == q)

??? {

??????? Return P; ?????????? // two numbers, etc., the maximum number of conventions is itself

???}

??? ELSE

??? {

??????? while ((! (A & 1)) && (! (b & 1))))))

??????? {

??????????? r << = 1; ?????????? // a, b is even, GCD (A, B) = 2 * GCD (A / 2 , B / 2)

??????????? a >> = 1;

??????????? b >> = 1;

???????} ??????? IF (! (A & 1))

??????? {

??????????? t = a; ??????????? // If A is an even number, exchange A, B

??????????? a = B;

??????????? b = t;

???????} ??????? do

??????? {

??????????? while (! (b & 1)) ??????????? {

????????????????, = 1; ????? // b is an even number, a is an odd number, GCD (B, a) = GCD (B / 2, a)

???????????} ??????????? IF (B

??????????? {

??????????????? t = a; ??????? // If B is less than A, exchange A, B

??????????????? a = B;

??????????????? b = t;

???????????} ??????????? b = (b-a) >> 1; // b, A is odd, GCD (b, a) = GCD ((ba) / 2, a)

???????} while (b);

??????? Return R * a;

???}

} / *

Known a, b, seeking X to meet A * x = 1 (MOD B)

Equivalent to solving a * x-b * y = 1 minimum integer solution

* /

Unsigned __int64 euclid (unsigned __int64 & a, unsigned __int64 & b)

{

??? Unsigned __INT64 ??? M, E, I, J, X, Y;

??? long ??????????????? xx, yy;

??? m = b;

??? e = a;

??? x = 0;

??? y = 1;

??? xx = 1;

??? yy = 1;

??? While (e)

??? {

??????? i = m / e;

??????? j = m% e;

??????? m = e;

??????? e = j;

??????? j = y;

??????? y * = i;

??????? IF (xx == yy)

??????? {

??????????? if (x> y)

??????????? {

???????????????? Y = x-y;

???????????}

??????????? ELSE

??????????? {

??????????????? y- = x;

??????????????? yy = 0;

???????????}

???????}

??????? ELSE

??????? {

??????????? y = x;

??????????? xx = 1 - xx;

??????????? yy = 1 - yy;

???????} ??????? x = j;

???} ??? IF (xx == 0)

??? {

??????? x = b - x;

???} ??? Return X;

} / *

Random generate an RSA encryption parameter

* /

RSA_Param RsagetParam (Void)

{

??? RSA_PARAM ?????????? rsa = {0};

??? Unsigned __INT64 ??? t;

??? RSA.P = randomprime (16); ????????? // randomly generate two prime numbers

??? RSA.Q = randomprime (16);

??? RSA.N = RSA.P * RSA.Q;

??? RSA.f = (RSA.P - 1) * (RSA.Q - 1);

??? do

??? {

??????? rsa.e = g_rnd.random (65536) ;? // less than 2 ^ 16,65536 = 2 ^ 16

??????? rsa.e | = 1; ??????????????????? // guaranteed the lowest position 1, that is, the guarantee is an odd number, because F is an even number , To be mutual, can only be odd ???} while (steingcd (rsa.e, rsa.f)! = 1); ??? rsa.d = Euclid (RSA.E, RSA.f);

??? RSA.s = 0;

??? t = rsa.n >> 1;

??? While (t)

??? {

??????? rsa.s ; ??????????????????????????????? = log2 (N)

??????? t >> = 1;

???} ??? Return RSA;

} / *

Labin Miller Test

* /

Void TestRM (Void)

{

??? unsigned long ?? k = 0;

??? cout << "- rabin-miller prime check./N" << endl;

??? for (unsigned __int64 i = 4197900001; i <4198000000; i = 2)

??? {

??????? IF (Rabinmiller (i, 30))

??????? {

??????????? k ;

??????????? cout << i << endl;

???????}

???} ??? cout << "Total:" << k << endl;

} / *

RSA encryption decryption

* /

Void TestRSA (Void)

{

??? Rsa_param ?????????? r;

??? char ???????????????? psrc [] = "abcdefghijklmnopqrstuvwxyz";

??? const unsigned long n = sizeof (psrc);

??? Unsigned char ?????? * q, PDEC [N];

??? unsigned __INT64 ??? penc [n];

??? r = rsagetparam ();

??? cout << "p =" << r.p << endl;

??? cout << "q =" << r.q << Endl;

??? cout << "f = (p-1) * (Q-1) =" << r.f << endl;

??? cout << "n = p * q =" << R.N << endl;

??? cout << "e =" << r.e << Endl;

??? Cout << "d =" << r.d << ENDL;

??? Cout << "s =" << r.s << endl;

??? cout << "Source:" << psrc << endl;

??? q = (unsigned char *) PSRC;

??? Cout << "eNCode:";

??? for (unsigned long i = 0; i

??? {

??????? penc [i] = potmod (q [i], r.e, r.n); ??????? cout << Hex << Penc [i] << "

???} ??? cout << endl;

??? cout << "decode:";

??? for (unsigned long i = 0; i

??? {

??????? PDEC [I] = POWMOD (Penc [I], R.D, R.N);

??????? cout << HEX << (unsigned long) PDEC [i] << "

???} ??? cout << endl;

??? Cout << (char *) PDEC << Endl;

} / * * /

Int main (void)

{

??? TestRSA ();

??? RETURN 0;

}

转载请注明原文地址:https://www.9cbs.com/read-7576.html

New Post(0)