1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#include <iostream>
#include <string>
#include <algorithm>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <sstream>
#include <ctime>
#include <vector>
#include <windows.h>
#include <stdio.h>
#include "KaratsubaMultiplication.h"
using namespace std;
int gcd(int a, int h)
{
int temp;
while (1)
{
temp = a % h;
if (temp == 0)
return h;
a = h;
h = temp;
}
}
int getLength(long long value)
{
int counter = 0;
while (value != 0)
{
counter++;
value /= 10;
}
return counter;
}
long long multiply(long long x, long long y)
{
int xLength = getLength(x);
int yLength = getLength(y);
// the bigger of the two lengths
int N = (int)(fmax(xLength, yLength));
// if the max length is small it's faster to just flat out multiply the two nums
if (N < 10)
return x * y;
//max length divided and rounded up
N = (N / 2) + (N % 2);
long long multiplier = pow(10, N);
long long b = x / multiplier;
long long a = x - (b *multiplier);
long long d = y / multiplier;
long long c = y - (d *N);
long long z0 = multiply(a, c);
long long z1 = multiply(a + b, c + d);
long long z2 = multiply(b, d);
return z0 + ((z1 - z0 - z2) *multiplier) + (z2 *(long long)(pow(10, 2 *N)));
}
//Random number generating function
int random(int from, int to)
{
return rand() % (to - from + 1) + from;
}
//function to return random prime numbers
double randomprime()
{
static std::vector<double> primenumber;
int num, i, count;
int n = 50000;
for (num = 1; num <= n; num++)
{
count = 0;
for (i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
count++;
break;
}
}
if (count == 0 && num != 1)
primenumber.push_back(num);
}
int upto = primenumber.size();
// When you get here, the dictionary file has been read into the words vector.
int randomline = random(2, upto); // pick a random number 2 - dictionary size
return primenumber[randomline]; // return that word from the dictionary
}
//In order to calculate pow(a,b) % n to be used for RSA decryption,
//the best algorithm I came across is Primality Testing 1) which is as follows:
int modulo(int a, int b, int n)
{
long long x = 1, y = a;
while (b > 0)
{
if (b % 2 == 1)
{
x = (x *y) % n; // multiplying with base
}
y = (y *y) % n; // squaring the base
b /= 2;
}
return x % n;
}
int main()
{
srand(time(0));
double count;
for (int i = 0; i <= 200; i++)
{
//2 random prime numbers
double a = randomprime();
double b = randomprime();
double n = multiply(a, b);
double totient = multiply((a - 1), (b - 1));
double e = 2;
//for checking co-prime which satisfies e>1
while (e < totient)
{
count = gcd(e, totient);
if (count == 1)
break;
else
e++;
}
//here is that I can't code, I have to do a division with big numbers, is that the problem?
//k can be any arbitrary value
//double k = 2;
//prod_k_tot = multiply(k, totient);
//choosing d such that it satisfies d *e = 1 + k *totient
//d = (1 + prod_k_tot)/e;
cout << "a = " << a << " b = " << b << " n = " << n << " modulo = " << modulo(a, b, n) << " totient = " << totient << " e = " << e << endl;
}
}
| |