Skip to content

Instantly share code, notes, and snippets.

@Fighter19
Last active January 21, 2021 15:00
Show Gist options
  • Save Fighter19/d40e77c8fe572d2faf8542bb63885918 to your computer and use it in GitHub Desktop.
Save Fighter19/d40e77c8fe572d2faf8542bb63885918 to your computer and use it in GitHub Desktop.
Simple RSA implementation for encrypting 16-bit values
// Copyright 2021 Patrick Zacharias
// Do what you want with it, no guarantees given.
// Provided under MIT or BSD-2 license, if required by law.
#include <time.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>
// This doesn't implement real RSA, rather a simpler version with a much smaller keysize
// Only really used for very simple signings. Easily bruteforced. Do NOT use for sensitive information or similar.
struct rsa_public_key {
uint32_t modulus; // n
uint16_t pub_exp; // e
};
struct rsa_priv_key {
struct rsa_public_key pub_key;
uint16_t priv_exp; // d
uint16_t prime1; // p
uint16_t prime2; // q
};
int gcd(int a, int b) {
int gcd = 0;
while(b != 0){
gcd = a % b;
a = b;
b = gcd;
}
return a;
}
int main() {
uint16_t timestamp;
// Used for key generation
uint32_t phi;
uint32_t remainder;
timestamp = time(0) / 65536;
struct rsa_priv_key priv_key;
// Chose two prime numbers of your choice here, make them big enough, as they will influence modulus,
// thus the maximum size of the encryptable content
priv_key.prime1 = 0;
priv_key.prime2 = 0;
// These two must be calculated using the commented blocks below
priv_key.pub_key.pub_exp = 0;
priv_key.priv_exp = 0;
priv_key.pub_key.modulus = priv_key.prime1 * priv_key.prime2;
printf("Current time: %d\n", timestamp);
printf("Private key: %d\n", priv_key.priv_exp);
printf("Public key: %d\n", priv_key.pub_key.pub_exp);
printf("Modulus: %d\n", priv_key.pub_key.modulus);
phi = (priv_key.prime1-1) * (priv_key.prime2-1);
printf("Phi: %d\n", phi);
// Use this to get the value for e => when gcd(e,phi) = 1
/*
for (int i = 1; i < phi; i++) {
remainder = gcd(i, phi);
if (remainder == 1) {
printf("Found gcd: %d\n", i);
}
}
*/
// result is priv_exp
/*
for (int i = 1; i < phi; i++) {
remainder = (i*priv_key.priv_exp) % phi;
if (remainder == 1) {
printf("Found d: %d\n", i);
}
}
*/
// d is public_exp
printf("RSA Test\n");
printf("Test %llu\n", (long long unsigned int)priv_key.pub_key.pub_exp*(long long unsigned int)priv_key.priv_exp);
long long unsigned int result = 1;
// Instead of
#ifdef DO_TEST
long long unsigned int biggest_result = 0;
/* pow(timestamp, priv_key.pub_key.pub_exp*priv_key.priv_exp); */
for (long long unsigned int i = 0; i < priv_key.pub_key.pub_exp*priv_key.priv_exp; i++) {
result *= timestamp;
if (result > biggest_result)
biggest_result = result;
result = result % priv_key.pub_key.modulus;
}
uint64_t test1 = result % priv_key.pub_key.modulus;
uint64_t test2 = timestamp % priv_key.pub_key.modulus;
printf("big r: %llu\n", biggest_result);
printf("Test1: %lu\n", test1);
printf("Test2: %lu\n", test2);
#endif
uint64_t encrypted = 1;
for (long long unsigned int i = 0; i < priv_key.priv_exp; i++) {
encrypted *= timestamp;
encrypted = encrypted % priv_key.pub_key.modulus;
}
uint64_t decrypted = 1;
for (long long unsigned int i = 0; i < priv_key.pub_key.pub_exp; i++) {
decrypted *= encrypted;
decrypted = decrypted % priv_key.pub_key.modulus;
}
printf("Enc: %lu\n", encrypted);
printf("Dec: %lu\n", decrypted);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment