C RSA key generation program - c

I'm trying to hone my skills in C as well as get a better understanding of RSA, so I took it upon myself to try and make my own generator. I've generated both base prime numbers, p and q, calculated the value o = (p-1) * (q-1). These are working correctly. The next steps is where I'm having issues. I'm pretty close, but I can't seem to find the correct way to calculate the encryption and decryption factors of the 1 mod r value. Any help for generating this would be awesome. (or just write the code yourself and i can learn off that) Plus if there's any other issues let me know!
Here's my code:
#include<stdio.h>
#include<time.h>
#include"../hdr/test.h" //fake header just to satisfy my makefile
//Receives: number that was generated in main
//Returns: 1 for false, 0 for true
//Purpose: checks if the numbers is prime and returns 1 or 0
int isPrime(int number)
{
if (number <= 1)
return 0;
int i;
for (i=2; i<number; i++) {
if (number % i == 0)
return 0;
}
return 1;
}
/*Receives: an integer ((p-1) * (q-1))
Returns: integer (e)
Purpose: Generates the relatively prime number to ((p-1) * (q-1))*/
int gen_E(int o)
{
puts("Generating E...");
int e;
do {e = rand() % o;} while (GCD(e, o) != 1);
return e;
}
/*Receives: integer E and O from the main
Returns: newly calculated integer D
Purpose: Generates D for the private key*/
int gen_D(int e, int o)
{
puts("Generating D...");
int e = a;
int o = b;
int phin, d;
for (phin = 1; phin < o; phin ++)
for (d = 1; d < 998001; d ++)
if ((e * d) == (o * phin) + 1) return d;
}
/*Receives: integer E and O from main
Returns: greatest common divisor's remainder
Purpose: Calculate if the two numbers share a divisor.*/
int GCD(int e, int o)
{
int c;
while (e != 0) {
c = e; e = o%e; o = c;
}
return o;
}
int main()
{
puts("Generating Prime P...");
srand(time(NULL));
int p = rand() % 1000;
while (isPrime(p) != 1) {
p = rand() % 1000;
}
puts("Generating Prime Q...");
int q = rand() % 1000;
while (isPrime(q) != 1) {
q = rand() % 1000;
}
int n = p * q;
int o = (p - 1) * (q - 1);
int e = gen_E(o);
int d = gen_D(e, o);
printf("p: %d\nq: %d\nn: %d\no: %d\ne: %d\nd: %d\n", p, q, n, o, e, d);
printf("KU = {%d, %d}\n", e, n);
printf("KR = {%d, %d}\n", d, n);
}

You will need a function to compute GCD (greatest common divider) of two numbers. After that, choose random e such that GCD(e,o) == 1.
Of course in practice it's probably more complicated than that but for homework it's fine.

Related

Lucas Lehmer C implementation up to M31 without BIGINT

I started learning C yesterday and I've literally just learned the basic data types (char, int, float), while loops, operators and printing.
Before I learn anything more, I wanted to set myself a mathematical challenge as the above should be enough to do elementary arithmetic. These are the constraints I'm working within - I'm well aware there are other ways to do the problem, like I could create an array to store all of the values of the Lucas Lehmer sequence, or I could use BIGINT etc. But I'm trying to use just what I've learned so far.
It just so happens that the largest possible INT value in C is 2^31-1, which is also a Mersenne Prime, M31. So I'd like to write a function which tests all candidate Mersennes up to M31.
This was my initial stab at it:
#include <stdio.h>
#include <stdbool.h>
int main() {
int p = 3;
while (p < 32) {
int e = 0;
int Mp = 1;
while (e < p) {
Mp *= 2;
++e;
}
Mp -= 1;
printf("Testing p=%d: %d\n", p, Mp);
int i = 0;
int Si = 4;
while (i < (p - 2))
{
Si = (Si * Si - 2) % Mp;
++i;
}
if (Si == 0) {
printf("2^%d is prime: %d\n", p, Mp);
}
++p;
++p;
}
return 0;
}
This worked up to p = 13, at which point we get a problem in the generation of the Si numbers, in particular the squaring, which wraps round beyond the limit for a signed INT.
In order to handle the squaring in a way that doesn't involve getting a number bigger than 2^31-1 I turned multiplication into repeated addition:
int main() {
int p = 3;
while (p < 32) {
int e = 0;
int Mp = 1;
while (e < p) {
Mp *= 2;
++e;
}
Mp -= 1;
int i = 0;
int Si = 4;
while (i < (p - 2))
{
int newSi;
newSi = 0;
int multiplications = 0;
while (multiplications < Si) {
newSi = (newSi + Si) % Mp;
++multiplications;
}
Si = newSi - 2;
++i;
}
if (Si == 0) {
printf("2^%d is prime: %d\n", p, Mp);
}
++p;
++p;
}
return 0;
}
But this had a huge effect on the time complexity of the function. It also only detected up to 2^19-1 as prime. Switching all values to unsigned instead of int makes the algorithm work up to 2^31 - 1, as below, but I'm trying to avoid doing so as I'd really like to do this within the bounds of a signed integer, just to see if it's possible.
#include <stdio.h>
int main() {
unsigned p = 3;
while (p < 32) {
unsigned e = 0;
unsigned Mp = 1;
while (e < p) {
Mp *= 2;
++e;
}
Mp -= 1;
unsigned i = 0;
unsigned Si = 4;
while (i < (p - 2))
{
unsigned newSi;
newSi = 0;
unsigned multiplications = 0;
while (multiplications < Si) {
newSi = (newSi + Si) % Mp;
++multiplications;
}
Si = newSi - 2;
++i;
}
if (Si == 0) {
printf("2^%d is prime: %d\n", p, Mp);
}
++p;
++p;
}
return 0;
}
But this has had a huge effect on the time complexity of the function.
Can anyone advise if there's an efficient way to run this function with only the functionality I've learned to date? I'm very particular about this constraint on the functionality I can use - I could easily just follow the next few lessons and learn other features of C, but the challenge here is to do so using these elementary skills only. I have found other questions on StackOverflow relating to an implementation of LL testing, but none that ask about an efficient algorithm that just uses math operators, int, while and printf.

This solution would not accept any floats

Currently on one of the cs50x problem sets 'Cash', which is a simple 'ask for how much change is owed, then calculate how many coins are required' task, so not here asking for a solution but, I don't understand why this won't work.
While it does ask for an input, when I type in a float such as 5.96, it simply hangs. No returns, no errors whatsoever. I have to force it shut. The other thing is the while loop doing the same when set to 0, which is the intended way of doing things in order to get the exact number of coins.
I know how inefficient this code is and there are simpler ways of doing things. I just wish to understand the whys in order to avoid making the same mistakes moving on. Thanks.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
// changes and other containers
int p = 1;
int n = 5;
int d = 10;
int q = 25;
int x = 0;
float c;
// get how much change is owed in float
do
{
c = get_float("Change owed: ");
}
while (c < 0);
// int conversion to avoid imprecision
int a = round(c * 100);
// 1 because 0 spits out an unknown error
while (a >= 1)
{
// if the converted amount is bigger than a quarter
if (a >= q)
{
// x = number of coins, a = amount left
x = a / q;
a = a % q;
}
else if (a >= d)
{
x = x + a / d;
a = a - a % d;
}
else if (a >= n)
{
x = x + a / n;
a = a - a % n;
}
else
{
x = x + a / p;
a = a - a % p;
}
}
printf("%i\n", x);
printf("%i\n", a);
}
Thanks to WhozCraig, I figured out that my logic was at fault.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
// changes and other containers
int p = 1;
int n = 5;
int d = 10;
int q = 25;
int x = 0;
float c;
// get how much change is owed in float
do
{
c = get_float("Change owed: ");
}
while (c < 0);
// int conversion to avoid imprecision
int a = round(c * 100);
// 1 because 0 spits out an unknown error
while (a >= 1)
{
// if the converted amount is bigger than a quarter
if (a >= q)
{
// x = number of coins, a = amount left
x = a / q;
a = a % q;
}
else if (a >= d)
{
x = x + a / d;
a = a % d;
}
else if (a >= n)
{
x = x + a / n;
a = a % n;
}
else
{
x = x + a / p;
a = a % p;
}
}
printf("%i\n", x);
printf("%i\n", a);
}

Feige Fiat Shamir Scheme not working

I'm trying to implement the Feige Fiat Shamir Identification Scheme in C (Arduino) and it works, but only when e = 0. When e = 1 it doesn't work.
How can I make it work?
#include <Wire.h>
int getGCD(int a, int b)
{
int c;
while (a != 0)
{
c = a;
a = b % a;
b = c;
}
return b;
}
int getCoprime(int n)
{
int coprime;
do
{
coprime = random(1, n);
}
while (getGCD(n, coprime) != 1);
return coprime;
}
//Preparation
int n = 7 * 3;
int s = getCoprime(n);
int v = (s * s) % n;
void loop ()
{
e = random(0, 2);
r = random(1, n);
int y = (r * (int)pow(s, e)) % n;
int x = (r * r) % n;
int ysqmodn = y * y % n;
int test = (x * (int)pow(v, e)) % n;
if(ysqmodn == test)
{
Serial.print("The current ICC matches. \n");
}
else
{
Serial.print(String(e));
Serial.print("\n");
}
delay(500);
}
It does work when e==1. When e==0 the computation is trivial, since s and v fall out due to power of 0 always being 1. This is the code copied and altered only enough to get it to compile.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
int random (int low, int high) {
return low + rand() % (high - low);
}
int getGCD(int a, int b) {
int c;
while (a != 0)
{
c = a;
a = b % a;
b = c;
}
return b;
}
int getCoprime(int n) {
int coprime;
do
{
coprime = random(1, n);
}
while (getGCD(n, coprime) != 1);
return coprime;
}
int main(void) {
int e, x, y, r, n, s, v, test, ysqmodn;
srand((unsigned)time(NULL));
n = 7 * 3;
s = getCoprime(n);
v = (s * s) % n;
e = random(0, 2);
r = random(1, n);
printf("n=%d, s=%d, e=%d, r=%d\n", n,s,e,r);
y = (r * (int)pow(s, e)) % n;
x = (r * r) % n;
ysqmodn = y * y % n;
test = (x * (int)pow(v, e)) % n;
if(ysqmodn == test)
printf("The current ICC matches. \n");
else
printf("%d\n", e);
return 0;
}
Sample results:
n=21, s=2, e=1, r=2
The current ICC matches.
n=21, s=11, e=0, r=12
The current ICC matches.
n=21, s=8, e=1, r=14
The current ICC matches.
n=21, s=17, e=1, r=13
The current ICC matches.
n=21, s=1, e=0, r=9
The current ICC matches.
n=21, s=4, e=0, r=13
The current ICC matches.

floating point exception in c program

while running this code I am getting floating point exception pls explain why it is coming so.
#include <stdio.h>
int gcd(long int, int);
int main() {
int t, n, a, i;
long int abc;
scanf("%d", &t);
while (t--) {
abc = 1;
scanf("%d", &n);
abc = n * (n - 1);
for (i = n - 2; i > 1; i--) {
a = gcd(abc, i);
abc = ((abc * i) / a);
}
printf("%ld \n", abc);
}
return 0;
}
int gcd(long int a, int b) {
if (b == 0)
return a;
else {
return (b, a % b);
}
}
The else part in gcd function is bogus. You probably wanted to call gcd recursively and instead you are returning a % b. And as a result if a % b == 0 you divide by 0 on line 13.
The expression (b, a % b) is evaluated as two subexpressions separated by comma operator. The value of b is forgotten and the value of the whole expression becomes a % b.
The correct version:
int gcd(long int a, int b) {
if (b == 0)
return a;
else {
return gcd(b, a % b);
}
}
You should change a few things:
1) if(a == 0) instead of b==0 and return variable b
2) Use recursion gcd(b%a, a)
if (a == 0)
return b;
else {
return gcd(b%a, a);
}
And you can also use this short version
return a ? gcd(b%a,a) : b;
Proof:
We have m = n * (m div n) + m Mod n.
This equation is correct even if n = 1, because m div 1 = m and m mod 1 =0.
If n and m mod n it's multiple of d, also m is multiple of d, because n * (m div n) and m mod n / d.
On the other hand if m and n is multiple of e, to because m mod n = m -n * (m div n) is also multiple of e.

Howto compute the factorial of x

how to get the value of an integer x, indicated by x!, it is the product of the numbers 1 to x.
Example: 5! 1x2x3x4x5 = 120.
int a , b = 1, c = 1, d = 1;
printf("geheel getal x = ");
scanf("%d", &a);
printf("%d! = ", a);
for(b = 1; b <= a; b++)
{
printf("%d x ", c);
c++;
d = d*a;
}
printf(" = %d", d);
how to get the som of an integer x, indicated by x!, is the product of the numbers 1 to x.
Did you mean factorial of x ?
Change d = d*a; to d = d*b inside the loop
You can simply do:
for(b = 1; b <= a; b++) {
d *= b;
}
// d now has a!
This is the optimal implementation in size and speed:
int factorial(int x)
{
static const int f[13] = { 1, 1, 2, 6, 24, 120, /* ... */ };
if ((unsigned)x < (sizeof f/sizeof f[0])) return f[x];
else return INT_MAX+1; /* or your favorite undefined behavior */
}
Hint: x! (x factorial) does not fit in an int except for very very small values of x.
Try
d = d * b;
instead of
d = d * a
and it should work fine
You actually have a lot of redundant code there, that might be why you did not spot the error yourself.
To calculate the factorial, you only need the accumulator (d in the above code) and the input (a). Why?
My code is not good as other but it works for me:
#include <iostream>
using namespace std;
unsigned int fattoriale (int n){
if (n == 1){
return 1;
}
else {
return n * fattoriale(n-1);
}
}
int main() {
int tmp, num;
cin >> num;
tmp = fattoriale(num);
cout << "Stampo il fattoriale del numero inserito: " << tmp << endl;
}
int factorial(int x)
{
int f;
if (x == 0)
{
f = 1;
}
else if (x > 0)
{
f = x*factorial(x-1);
}
return f;
}
int main()
{
int n = 0;
cout << factorial(n);
return 0;
}

Resources