RSA

来源:互联网 发布:淘宝童装营销词有哪些 编辑:程序博客网 时间:2024/04/28 17:54

前阵子写的,RSA的算法。

 

    /*
     * A wrapper of Rsa algorithm
     
*/
 
    
public class Rsa : _Rsa
    
{
        
private RsaPublicProvider publicProvider;
        
private RsaPrivateProvider privateProvider;

        
public Rsa(int e, int pq, int d)
            : 
base(e, pq, d) {
            
this.publicProvider = new RsaPublicProvider(this);
            
this.privateProvider = new RsaPrivateProvider(this);
        }


        
public RsaPublicProvider RsaPublicProvider get return this.publicProvider; } }
        
public RsaPrivateProvider RsaPrivateProvider get return this.privateProvider; } }
    }


    
/*
     * Rsa algorithm
     
*/
 
    
public class _Rsa
    
{
        
private int e;      // public key A
        private int pq;     // public key B
        private int d;      // private key

        
protected _Rsa(int e, int pq, int d) {
            
this.e = e;
            
this.pq = pq;
            
this.d = d;
        }


        
public int[] PublicKey {
            
get return new int[] { e, pq }; }
        }


        
public int[] PrivateKey {
            
get return new int[] { d, pq }; }
        }


        
/* Encryptino algorithm: 
         * encrypt(T) = (T^E) mod PQ 
*/

        
public int[] Encrypt(int[] text) {
            
int[] cipher = new int[text.Length];
            
for (int i = 0; i < cipher.Length; i++{
                cipher[i] 
= CalculateMod(text[i], e, pq);
            }


            
return cipher;
        }


        
public unsafe void Encrypt(int* text, int* cipher, int length) {
            
for (int i = 0; i < length; i++{
                cipher[i] 
= CalculateMod(text[i], e, pq);
            }

        }


        
/* Decryptino algorithm: 
         * decrypt(C) = (C^D) mod PQ 
*/

        
public int[] Decrypt(int[] cipher) {
            
int[] text = new int[cipher.Length];
            
for (int i = 0; i < text.Length; i++{
                text[i] 
= CalculateMod(cipher[i], d, pq);
            }


            
return text;
        }


        
public unsafe void Decrypt(int* cipher, int* text, int length) {
            
for (int i = 0; i < length; i++{
                text[i] 
= CalculateMod(cipher[i], d, pq);
            }

        }


        
/*
         * Calculate (a^b mod c)
         
*/

        
private unsafe int CalculateMod(int a, int b, int c) {
            
/* Compute base 2 expression of b
             * i.e., 2753 = 101011000001 base 2
             *            = 1 + 2^6 + 2^7 + 2^9 + 2^11
             *            = 1 + 64  + 128 + 512 + 2048
             
*/

            
int* b2 = stackalloc int[31];
            
for (int i = b, j = 0; i > 0; i = i >> 1, j++{
                b2[j] 
= i % 2;
            }


            
/*
             * Consider this table of powers of 855:
             *      855^1 = 855 (mod 3233)
             *      855^2 = 367 (mod 3233)
             *      855^4 = 367^2 (mod 3233) = 2136 (mod 3233)
             *      855^8 = 2136^2 (mod 3233) = 733 (mod 3233)
             *      855^16 = 733^2 (mod 3233) = 611 (mod 3233)
             *      855^32 = 611^2 (mod 3233) = 1526 (mod 3233)
             *      855^64 = 1526^2 (mod 3233) = 916 (mod 3233)
             *      855^128 = 916^2 (mod 3233) = 1709 (mod 3233)
             *      855^256 = 1709^2 (mod 3233) = 1282 (mod 3233)
             *      855^512 = 1282^2 (mod 3233) = 1160 (mod 3233)
             *      855^1024 = 1160^2 (mod 3233) = 672 (mod 3233)
             *      855^2048 = 672^2 (mod 3233) = 2197 (mod 3233)
             * 
             *  Given the above, we know this:
             *
             *      855^2753 (mod 3233)
             *      = 855^(1 + 64  + 128 + 512 + 2048) (mod 3233)
             *      = 855^1 * 855^64 * 855^128 * 855^512 * 855^2048 (mod 3233)
             *      = 855 * 916 * 1709 * 1160 * 2197 (mod 3233)
             *      = 794 * 1709 * 1160 * 2197 (mod 3233)
             *      = 2319 * 1160 * 2197 (mod 3233)
             *      = 184 * 2197 (mod 3233)
             *      = 123 (mod 3233)
             *      = 123
             * 
             *  Since int.MaxValue * int.MaxValue < long.MaxValue, there will not
             *  be aithmetic overflow there. Remove check for performance increment
             
*/

            
long mod = 1long temp = a % c;

            
unchecked {
                
for (long i = 0; i < 31; i++{
                    
if (b2[i] == 1{
                        mod 
= (mod * temp) % c;
                    }


                    temp 
= temp * temp % c;
                }

            }


            
return (int)mod;
        }

    }


    
public static class RsaFactory
    
{
        
public static Rsa GenerateRsaKeyPair(int minimalKeyStrength) {
            
int topNumber = 1 << minimalKeyStrength;
            
int[] primeNumbers = GeneratePrimeNumberList(topNumber);

            Random ran 
= new Random();

            
// Randomly select two distinct prime numbers p, q such that p*q > topNumber
            int p = 2, q = 2, pq = 4;
            
while ((p == q) || (pq = p * q) < topNumber) {
                p 
= primeNumbers[ran.Next(1, primeNumbers.Length - 1)];
                q 
= primeNumbers[ran.Next(1, primeNumbers.Length - 1)];
            }


            
// Use Euclidean algorithm to determine e
            int t = (p - 1* (q - 1);
            
int e = 0;

            
for (e = 3; e <= topNumber; e++{
                
if (GetGreatestCommonDivisor(t, e) == 1{
                    
break;
                }

            }


            
// Compute d such that d*e = 1 + k*t for some integer k
            int d = 1;
            
for (int k = 2; k < topNumber; k++{
                
int sum = 1 + k * t;
                
if (sum % e == 0{
                    d 
= sum / e;
                    
break;
                }

            }


            
return new Rsa(e, pq, d);
        }


        
public static int[] GeneratePrimeNumberList(int topNumber) {
            List
<int> primeNumbers = new List<int>();

            
for (int i = 2; i < topNumber; i++{
                
bool divisible = false;

                
foreach (int number in primeNumbers)
                    
if (i % number == 0{
                        divisible 
= true;
                    }


                
if (!divisible) {
                    primeNumbers.Add(i);
                }

            }


            
return primeNumbers.ToArray();
        }


        
public static bool IsPrime(int number) {
            
bool isPrime = true;
            
for (int i = 2; i <= Math.Sqrt(number) && isPrime; i++{
                isPrime 
= (number % i != 0);
            }


            
return isPrime;
        }


        
public static int GetGreatestCommonDivisor(int a, int b) {
            
while (b != 0{
                
if (a > b) {
                    a 
= a - b;
                }
 else {
                    b 
= b - a;
                }

            }


            
return a;
        }

    }

 

    public interface IRsaProvider
    
{
        
int[] Key get;}
        
byte[] Transform(byte[] input);
    }


    
public class RsaPrivateProvider : IRsaProvider, ICloneable
    
{
        
private Rsa rsa;

        
public RsaPrivateProvider(Rsa rsa) {
            
this.rsa = rsa;
        }


        
public int[] Key 
            
get return this.rsa.PrivateKey; } 
        }


        
public byte[] Transform(byte[] input) {
            
int[] input2 = Converter.ConvertBytesToInts(input);
            
int[] output = rsa.Encrypt(input2);

            
return Converter.ConvertIntsToBytes(output);
        }


        
public object Clone() {
            
return new RsaPrivateProvider(this.rsa);
        }

    }


    
public class RsaPublicProvider : IRsaProvider, ICloneable
    
{
        
private Rsa rsa;

        
public RsaPublicProvider(Rsa rsa) {
            
this.rsa = rsa;
        }


        
public int[] Key 
            
get return this.rsa.PublicKey; } 
        }


        
public byte[] Transform(byte[] input) {
            
int[] input2 = Converter.ConvertBytesToInts(input);
            
int[] output = rsa.Decrypt(input2);

            
return Converter.ConvertIntsToBytes(output);
        }


        
public object Clone() {
            
return new RsaPrivateProvider(this.rsa);
        }

    }


    
/* 
     * Convert byte array from and to an int array
     
*/
 
    
public static class Converter
    
{
        
public static int[] ConvertBytesToInts(byte[] bytes) {
            
int[] ints = new int[bytes.Length / 4];
            
for (int i = 0; i < ints.Length; i++{
                ints[i] 
= bytes[i * 4|
                          bytes[i 
* 4 + 1<< 8 |
                          bytes[i 
* 4 + 2<< 16 |
                          bytes[i 
* 4 + 3<< 24;
            }


            
return ints;
        }


        
public static byte[] ConvertIntsToBytes(int[] ints) {
            
byte[] bytes = new byte[ints.Length * 4];
            
for (int i = 0; i < ints.Length; i++{
                bytes[
4 * i] = (byte)ints[i];
                bytes[
4 * i + 1= (byte)(ints[i] >> 8);
                bytes[
4 * i + 2= (byte)(ints[i] >> 16);
                bytes[
4 * i + 3= (byte)(ints[i] >> 24);
            }


            
return bytes;
        }

   }
原创粉丝点击