Type aliases for RSA related functionality
This commit is contained in:
parent
6b64e0c18b
commit
2bad1303dc
2 changed files with 36 additions and 39 deletions
56
rsa.c
56
rsa.c
|
@ -1,15 +1,11 @@
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
|
#include "funconfig.h"
|
||||||
#include "rand.h"
|
#include "rand.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define NULL ((void *)0)
|
u64 gcd(u64 a, u64 b) { return extended_euclid(a, b, NULL, NULL); }
|
||||||
|
|
||||||
uint64_t gcd(uint64_t a, uint64_t b) {
|
u64 extended_euclid(u64 a, u64 b, u64 *x, u64 *y) {
|
||||||
return extended_euclid(a, b, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int extended_euclid(int a, int b, int *x, int *y) {
|
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
if (x)
|
if (x)
|
||||||
*x = 1;
|
*x = 1;
|
||||||
|
@ -18,8 +14,8 @@ int extended_euclid(int a, int b, int *x, int *y) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
int x1, y1;
|
u64 x1, y1;
|
||||||
int gcd = extended_euclid(b, a % b, &x1, &y1);
|
u64 gcd = extended_euclid(b, a % b, &x1, &y1);
|
||||||
|
|
||||||
if (x)
|
if (x)
|
||||||
*x = y1;
|
*x = y1;
|
||||||
|
@ -29,7 +25,7 @@ int extended_euclid(int a, int b, int *x, int *y) {
|
||||||
return gcd;
|
return gcd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int totient(int n) {
|
u64 totient(u64 n) {
|
||||||
int result = n;
|
int result = n;
|
||||||
|
|
||||||
// Check for prime factors
|
// Check for prime factors
|
||||||
|
@ -51,13 +47,13 @@ int totient(int n) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t mulmod(uint64_t a, uint64_t b, uint64_t m) {
|
u64 mulmod(u64 a, u64 b, u64 m) {
|
||||||
uint64_t result = 0;
|
u64 result = 0;
|
||||||
a %= m;
|
a %= m;
|
||||||
|
|
||||||
while (b > 0) {
|
while (b > 0) {
|
||||||
if (b & 1) {
|
if (b & 1) {
|
||||||
result = (result + a) % m; // Avoid overflow
|
result = (result + a) % m;
|
||||||
}
|
}
|
||||||
a = (a * 2) % m; // Double a, keep within mod
|
a = (a * 2) % m; // Double a, keep within mod
|
||||||
b >>= 1;
|
b >>= 1;
|
||||||
|
@ -66,8 +62,8 @@ uint64_t mulmod(uint64_t a, uint64_t b, uint64_t m) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t modexp(uint64_t a, uint64_t b, uint64_t m) {
|
u64 modexp(u64 a, u64 b, u64 m) {
|
||||||
uint64_t result = 1;
|
u64 result = 1;
|
||||||
a %= m;
|
a %= m;
|
||||||
|
|
||||||
while (b > 0) {
|
while (b > 0) {
|
||||||
|
@ -81,14 +77,14 @@ uint64_t modexp(uint64_t a, uint64_t b, uint64_t m) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t gen_prime(uint64_t min, uint64_t max) {
|
u64 gen_prime(u64 min, u64 max) {
|
||||||
uint64_t cand = 0;
|
u64 cand = 0;
|
||||||
while (!miller_rabin(cand, 10)) cand = prand_range(min, max);
|
while (!miller_rabin(cand, 10)) cand = prand_range(min, max);
|
||||||
|
|
||||||
return cand;
|
return cand;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_prime(int n) {
|
bool is_prime(u64 n) {
|
||||||
if (n < 2)
|
if (n < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -100,26 +96,26 @@ bool is_prime(int n) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool miller_rabin(uint64_t n, uint64_t k) {
|
bool miller_rabin(u64 n, u64 k) {
|
||||||
if (n < 2)
|
if (n < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint64_t d = n - 1;
|
u64 d = n - 1;
|
||||||
uint64_t s = 0;
|
u64 s = 0;
|
||||||
|
|
||||||
while (d % 2 == 0) {
|
while (d % 2 == 0) {
|
||||||
d /= 2;
|
d /= 2;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint64_t i = 0; i < k; i++) {
|
for (u64 i = 0; i < k; i++) {
|
||||||
uint64_t a = prand_range(2, n - 2);
|
u64 a = prand_range(2, n - 2);
|
||||||
uint64_t x = modexp(a, d, n);
|
u64 x = modexp(a, d, n);
|
||||||
|
|
||||||
if (x == 1 || x == n - 1)
|
if (x == 1 || x == n - 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (uint64_t r = 1; r < s; r++) {
|
for (u64 r = 1; r < s; r++) {
|
||||||
x = modexp(x, 2, n);
|
x = modexp(x, 2, n);
|
||||||
if (x == n - 1)
|
if (x == n - 1)
|
||||||
break;
|
break;
|
||||||
|
@ -132,17 +128,17 @@ bool miller_rabin(uint64_t n, uint64_t k) {
|
||||||
return true; // Likely prime
|
return true; // Likely prime
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t mod_inverse(uint64_t a, uint64_t m) {
|
u64 mod_inverse(u64 a, u64 m) {
|
||||||
uint64_t m0 = m;
|
u64 m0 = m;
|
||||||
uint64_t y = 0, x = 1;
|
u64 y = 0, x = 1;
|
||||||
|
|
||||||
if (m == 1)
|
if (m == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while (a > 1) {
|
while (a > 1) {
|
||||||
// q is quotient
|
// q is quotient
|
||||||
uint64_t q = a / m;
|
u64 q = a / m;
|
||||||
uint64_t t = m;
|
u64 t = m;
|
||||||
|
|
||||||
// m is remainder now
|
// m is remainder now
|
||||||
m = a % m;
|
m = a % m;
|
||||||
|
|
19
rsa.h
19
rsa.h
|
@ -1,4 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "funconfig.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@
|
||||||
* @param b Second number
|
* @param b Second number
|
||||||
* @return The greatest common divider
|
* @return The greatest common divider
|
||||||
*/
|
*/
|
||||||
uint64_t gcd(uint64_t a, uint64_t b);
|
u64 gcd(u64 a, u64 b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes Euler's Totient function φ(n), which counts the number of
|
* @brief Computes Euler's Totient function φ(n), which counts the number of
|
||||||
|
@ -19,7 +20,7 @@ uint64_t gcd(uint64_t a, uint64_t b);
|
||||||
* @param n The input number.
|
* @param n The input number.
|
||||||
* @return The number of integers from 1 to n that are coprime to n.
|
* @return The number of integers from 1 to n that are coprime to n.
|
||||||
*/
|
*/
|
||||||
int totient(int n);
|
u64 totient(u64 n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes (a * b) % m safely without overflow.
|
* @brief Computes (a * b) % m safely without overflow.
|
||||||
|
@ -32,7 +33,7 @@ int totient(int n);
|
||||||
* @param m The modulus.
|
* @param m The modulus.
|
||||||
* @return (a * b) % m computed safely.
|
* @return (a * b) % m computed safely.
|
||||||
*/
|
*/
|
||||||
uint64_t mulmod(uint64_t a, uint64_t b, uint64_t m);
|
u64 mulmod(u64 a, u64 b, u64 m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Modular exponentiation (a^b) mod m
|
* @brief Modular exponentiation (a^b) mod m
|
||||||
|
@ -41,7 +42,7 @@ uint64_t mulmod(uint64_t a, uint64_t b, uint64_t m);
|
||||||
* @param b The exponent
|
* @param b The exponent
|
||||||
* @param m The modulus
|
* @param m The modulus
|
||||||
*/
|
*/
|
||||||
uint64_t modexp(uint64_t a, uint64_t b, uint64_t m);
|
u64 modexp(u64 a, u64 b, u64 m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes the modular inverse of a modulo m.
|
* @brief Computes the modular inverse of a modulo m.
|
||||||
|
@ -50,7 +51,7 @@ uint64_t modexp(uint64_t a, uint64_t b, uint64_t m);
|
||||||
* @param m The modulus.
|
* @param m The modulus.
|
||||||
* @return The modular inverse of a modulo m, or -1 if no inverse exists.
|
* @return The modular inverse of a modulo m, or -1 if no inverse exists.
|
||||||
*/
|
*/
|
||||||
uint64_t mod_inverse(uint64_t a, uint64_t m);
|
u64 mod_inverse(u64 a, u64 m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates a random prime number within the given range.
|
* @brief Generates a random prime number within the given range.
|
||||||
|
@ -59,7 +60,7 @@ uint64_t mod_inverse(uint64_t a, uint64_t m);
|
||||||
* @param max The upper bound (inclusive).
|
* @param max The upper bound (inclusive).
|
||||||
* @return A prime number in the range [min, max].
|
* @return A prime number in the range [min, max].
|
||||||
*/
|
*/
|
||||||
uint64_t gen_prime(uint64_t min, uint64_t max);
|
u64 gen_prime(u64 min, u64 max);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if a number is prime.
|
* @brief Checks if a number is prime.
|
||||||
|
@ -67,7 +68,7 @@ uint64_t gen_prime(uint64_t min, uint64_t max);
|
||||||
* @param n The number to check.
|
* @param n The number to check.
|
||||||
* @return true if n is prime, false otherwise.
|
* @return true if n is prime, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool is_prime(int n);
|
bool is_prime(u64 n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs the Miller-Rabin primality test to check if a number is
|
* @brief Performs the Miller-Rabin primality test to check if a number is
|
||||||
|
@ -77,7 +78,7 @@ bool is_prime(int n);
|
||||||
* @param k The number of rounds of testing to perform.
|
* @param k The number of rounds of testing to perform.
|
||||||
* @return true if n is probably prime, false if n is composite.
|
* @return true if n is probably prime, false if n is composite.
|
||||||
*/
|
*/
|
||||||
bool miller_rabin(uint64_t n, uint64_t k);
|
bool miller_rabin(u64 n, u64 k);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Computes the greatest common divisor (GCD) of two integers a and b
|
* @brief Computes the greatest common divisor (GCD) of two integers a and b
|
||||||
|
@ -92,4 +93,4 @@ bool miller_rabin(uint64_t n, uint64_t k);
|
||||||
* + by = gcd(a, b).
|
* + by = gcd(a, b).
|
||||||
* @return The greatest common divisor (gcd) of a and b.
|
* @return The greatest common divisor (gcd) of a and b.
|
||||||
*/
|
*/
|
||||||
int extended_euclid(int a, int b, int *x, int *y);
|
u64 extended_euclid(u64 a, u64 b, u64 *x, u64 *y);
|
||||||
|
|
Loading…
Add table
Reference in a new issue