First commit
This commit is contained in:
commit
940e7beb01
59
RSA_arduino.ino
Normal file
59
RSA_arduino.ino
Normal file
@ -0,0 +1,59 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "rsa.h"
|
||||
#include "prng.h"
|
||||
#include "constantes.h"
|
||||
#include <LiquidCrystal.h>
|
||||
|
||||
|
||||
struct entropy_pool s_entropy;
|
||||
int sensorValue = 0;
|
||||
int switchState = 0;
|
||||
// e -> public key
|
||||
// d -> private key
|
||||
unsigned long n, e, d = 0;
|
||||
// LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
|
||||
LiquidCrystal lcd(11, 10, 5, 4, 3, 2);
|
||||
|
||||
void setup(){
|
||||
pinMode(BUTTON, INPUT);
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(LED_PIN, LOW);
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
lcd.begin(16, 2);
|
||||
lcd.clear();
|
||||
|
||||
// Generate our entropy pool
|
||||
init_entropy();
|
||||
|
||||
// Entropy pool if full, the switch on the red LED
|
||||
digitalWrite(LED_PIN, HIGH);
|
||||
}
|
||||
|
||||
void loop(){
|
||||
Serial.println("Start generation key");
|
||||
|
||||
while(1){
|
||||
switchState = digitalRead(BUTTON);
|
||||
|
||||
// If we push the button, we generate new keys
|
||||
if (switchState == HIGH){
|
||||
lcd.clear();
|
||||
// Now, we can generate our keys
|
||||
generateKeys(&e, &d, &n);
|
||||
|
||||
if (DEBUG){
|
||||
Serial.println("e: " + String(e));
|
||||
Serial.println("d: " + String(d));
|
||||
Serial.println("n: " + String(n));
|
||||
}
|
||||
lcd.setCursor(0, 0);
|
||||
lcd.print("e:" + String(e) + "," + String(n));
|
||||
lcd.setCursor(0, 1);
|
||||
lcd.print("d:" + String(d) + "," + String(n));
|
||||
}
|
||||
}
|
||||
}
|
9
constantes.h
Normal file
9
constantes.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef H_CONSTANTES
|
||||
#define H_CONSTANTES
|
||||
|
||||
#define BUTTON 12 // Button pin
|
||||
#define LED_PIN 13
|
||||
#define DEBUG 0
|
||||
#define SENSOR_PIN 0 // Pin A0
|
||||
|
||||
#endif
|
93
prng.cpp
Normal file
93
prng.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "prng.h"
|
||||
#include "constantes.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
/*
|
||||
* Fill the entropy structure with random data
|
||||
*/
|
||||
void init_entropy(){
|
||||
if (DEBUG)
|
||||
Serial.println("Generation entropy");
|
||||
|
||||
// Generate entropy
|
||||
int sensorValue = 0;
|
||||
while(s_entropy.pool_size < BUFSIZE){
|
||||
generateEntropy(s_entropy.position++);
|
||||
s_entropy.pool_size++;
|
||||
|
||||
// Add a delay for avoiding the same value
|
||||
delay(50);
|
||||
}
|
||||
if (DEBUG)
|
||||
Serial.println("End generation");
|
||||
}
|
||||
/*
|
||||
* Generate a random value from the analog input
|
||||
* Store the value in the entropy structure at the position specified in argument
|
||||
*/
|
||||
static void generateEntropy(int position){
|
||||
int sensorValue = 0;
|
||||
|
||||
while( sensorValue == 0){
|
||||
sensorValue = analogRead(SENSOR_PIN);
|
||||
|
||||
if (sensorValue != 0){
|
||||
if (DEBUG)
|
||||
Serial.println("Value: " + String(sensorValue));
|
||||
|
||||
if(sensorValue <= 10)
|
||||
sensorValue = sensorValue << 5;
|
||||
else if(sensorValue > 10 && sensorValue <= 100)
|
||||
sensorValue = sensorValue << 4;
|
||||
|
||||
s_entropy.buf[position] = sensorValue;
|
||||
Serial.println("Position: " + String(position));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For avoiding to reused the seed, we must generate a new one
|
||||
*/
|
||||
static unsigned long generateSeed(){
|
||||
unsigned long seed;
|
||||
int sensorValue = 0;
|
||||
if (DEBUG)
|
||||
Serial.println("Generate seed");
|
||||
|
||||
while (sensorValue == 0){
|
||||
sensorValue = analogRead(SENSOR_PIN);
|
||||
seed = sensorValue;
|
||||
|
||||
if (DEBUG)
|
||||
Serial.println("Seed: " + String(seed));
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
/*
|
||||
* Generate a random data from the entropy pool
|
||||
*/
|
||||
unsigned long prng(){
|
||||
unsigned long p = 0;
|
||||
unsigned long pos = generateSeed();
|
||||
|
||||
pos += ( (pos << 4));
|
||||
pos ^= ( (pos >> 11));
|
||||
pos |= (pos << (pos % 15));
|
||||
pos = pos % 201;
|
||||
|
||||
if (pos > BUFSIZE)
|
||||
pos = pos / 2;
|
||||
|
||||
p = s_entropy.buf[pos];
|
||||
|
||||
// Replace the old value
|
||||
generateEntropy(pos);
|
||||
|
||||
return p;
|
||||
}
|
98
prng.cpp_bck
Normal file
98
prng.cpp_bck
Normal file
@ -0,0 +1,98 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include "prng.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
#define MAX_ENTRIES_ENTROPY 100
|
||||
|
||||
void init_entropy(){
|
||||
struct entropy_pool s_pool;
|
||||
randomSeed(analogRead(0));
|
||||
while (s_entropy.pool_size < BUFSIZE){
|
||||
s_entropy.buf[s_entropy.pool_size++] = random(300);
|
||||
}
|
||||
}
|
||||
|
||||
// Define a range ???
|
||||
unsigned long prng(int seed){
|
||||
//int32_t p = 4242;
|
||||
unsigned long p = seed;
|
||||
|
||||
//p = 4242;
|
||||
//p ^= p << 3; // XOR
|
||||
// 1000010010010 -> 4242
|
||||
// 1000010010010000 -> 33936
|
||||
// 1001010000000010 -> 37890
|
||||
//printf("%d\n", p);
|
||||
|
||||
// For small value, increase the value ?
|
||||
p ^= (p << 1) | (p << 2);
|
||||
|
||||
// Generate number between 1000 and 5000 ???
|
||||
// Or to add X bits to have the key number, for instance 32 bits
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int prng2 () {
|
||||
double *pool_entropy = entropy_pool();
|
||||
int pos = 0;
|
||||
|
||||
entropy_cpu_clock(pool_entropy, 0, MAX_ENTRIES_ENTROPY);
|
||||
pos++;
|
||||
|
||||
for(int i = 0; i < MAX_ENTRIES_ENTROPY; i++){
|
||||
//printf("%f\n", pool_entropy[i]);
|
||||
}
|
||||
|
||||
// Get from pool
|
||||
// Generate an integer from 0 to 100 (with clock CPU) for instance
|
||||
// And to pick up to the pool
|
||||
|
||||
// Generate entropy with the network ?
|
||||
|
||||
free(pool_entropy);
|
||||
return(0);
|
||||
}
|
||||
double *entropy_pool(){
|
||||
double *pool_entropy = (double *)malloc(sizeof(double) * MAX_ENTRIES_ENTROPY);
|
||||
|
||||
if (pool_entropy == NULL){
|
||||
//printf("Failed to allocate variables\n");
|
||||
exit(-1);
|
||||
}
|
||||
return pool_entropy;
|
||||
}
|
||||
void entropy_cpu_clock(double *entropy, int pos, int max){
|
||||
clock_t start_t, end_t;
|
||||
double total_t;
|
||||
double res = 0;
|
||||
|
||||
start_t = clock();
|
||||
//printf("Starting of the program, start_t = %ld\n", start_t);
|
||||
|
||||
//printf("Going to scan a big loop, start_t = %ld\n", start_t);
|
||||
for(int i = 0; i < 10000000; i++) {
|
||||
}
|
||||
end_t = clock();
|
||||
//printf("End of the big loop, end_t = %ld\n", end_t);
|
||||
|
||||
total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
|
||||
//printf("Total time taken by CPU: %f\n", total_t );
|
||||
//printf("Exiting of the program...\n");
|
||||
|
||||
entropy[pos] = total_t;
|
||||
|
||||
// Test - generate an iteger from 0 to 100
|
||||
|
||||
// Multiply the 10 first entries
|
||||
for (int i = 0; i < 10; i++){
|
||||
res += entropy[0];
|
||||
}
|
||||
|
||||
//printf("Pos: %f\n", ceil(res * 100));
|
||||
}
|
31
prng.h
Normal file
31
prng.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef H_PRNG
|
||||
#define H_PRNG
|
||||
|
||||
#define BUFSIZE 128
|
||||
|
||||
struct entropy_pool{
|
||||
unsigned long buf[BUFSIZE];
|
||||
int pool_size;
|
||||
int position;
|
||||
int pool_count;
|
||||
};
|
||||
|
||||
extern struct entropy_pool s_entropy;
|
||||
|
||||
void init_entropy();
|
||||
static void generateEntropy(int);
|
||||
static unsigned long generateSeed();
|
||||
unsigned long prng();
|
||||
int prng2();
|
||||
double *entropy_pool();
|
||||
void entropy_cpu_clock(double *, int, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
28
prng.h_bck
Normal file
28
prng.h_bck
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef H_PRNG
|
||||
#define H_PRNG
|
||||
|
||||
#define BUFSIZE 128
|
||||
|
||||
struct entropy_pool{
|
||||
unsigned long buf[BUFSIZE];
|
||||
int pool_size;
|
||||
};
|
||||
|
||||
extern struct entropy_pool s_entropy;
|
||||
|
||||
void init_entropy();
|
||||
unsigned long prng(int);
|
||||
int prng2();
|
||||
static void readDevRandom(char *);
|
||||
double *entropy_pool();
|
||||
void entropy_cpu_clock(double *, int, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
108
rsa.c_bck
Normal file
108
rsa.c_bck
Normal file
@ -0,0 +1,108 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rsa.h"
|
||||
#include "prng.h"
|
||||
|
||||
void generateKeys(unsigned long *e, unsigned long *d, unsigned long *n){
|
||||
unsigned long p = prng(25);
|
||||
unsigned long q = prng(47);
|
||||
unsigned long phi = 0;
|
||||
|
||||
// Generate big numbers of p and q
|
||||
//generateBigNumber(&p);
|
||||
//generateBigNumber(&q);
|
||||
|
||||
// Check if p and q are prime numbers
|
||||
if (isPrimeNumber(p) != 0)
|
||||
prime_number_finder(&p);
|
||||
|
||||
if (isPrimeNumber(q) != 0)
|
||||
prime_number_finder(&q);
|
||||
|
||||
// Calculate n
|
||||
*n = p * q;
|
||||
|
||||
// We're going to calcule the Euler's totient
|
||||
// Our number are prime number, so, phi = (p - 1) * (q - 1)
|
||||
phi = (p - 1)*(q - 1);
|
||||
|
||||
/* We will calculate e for the public key */
|
||||
generatePublicKey(phi, e);
|
||||
|
||||
/* We will calcuate d for the private key */
|
||||
generatePrivateKey(d, phi, e);
|
||||
|
||||
/* For encrypting
|
||||
m = ( message ** e) % n
|
||||
exemple!: A -> 0x65
|
||||
(65 ** 4033) % 6938083 = 1140958
|
||||
For decrypting
|
||||
( m ** d) % n
|
||||
Exemple:
|
||||
(1140958 ** 830257) % 6938083 = 65
|
||||
*/
|
||||
}
|
||||
static void generateBigNumber(unsigned long *v){
|
||||
/*if (*v < 100)
|
||||
*v = *v << 6;
|
||||
else if (*v >= 100 || *v < 1000)
|
||||
*v = *v << 4;
|
||||
else
|
||||
*v = *v << 2;*/
|
||||
}
|
||||
/*
|
||||
* This function will identify all the divider of the variable a
|
||||
* with the Euclidean algorithm
|
||||
*/
|
||||
static int gcd(unsigned long a, unsigned long b){
|
||||
// Ou utiliser l'algorithme d'Euclide ?
|
||||
int done = 0;
|
||||
while (!done){
|
||||
if (b == 0)
|
||||
done = 1;
|
||||
else{
|
||||
int tmp = b;
|
||||
b = a % b;
|
||||
a = tmp;
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
/*
|
||||
* This function will check if te variable e is a prime number
|
||||
* is not, we increment the value to 1 and continue until is a prime number
|
||||
*/
|
||||
static void prime_number_finder(unsigned long *e){
|
||||
while(isPrimeNumber(*e) != 0)
|
||||
*e += 1;
|
||||
}
|
||||
static int isPrimeNumber(unsigned long x){
|
||||
for (int i = 2; i < x; i++){
|
||||
if (x % i == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static unsigned long generatePublicKey(unsigned long phi, unsigned long *e){
|
||||
// Generate e
|
||||
*e = prng(61);
|
||||
//generateBigNumber(e);
|
||||
|
||||
// Get the coprime with phi
|
||||
while ((gcd(phi, *e)) != 1)
|
||||
*e += 1;
|
||||
|
||||
return *e;
|
||||
}
|
||||
static unsigned long generatePrivateKey(unsigned long *d, unsigned long phi, unsigned long *e){
|
||||
// Calculate the modular inverse
|
||||
int i = 0;
|
||||
for (i = 0; i <= phi; i++){
|
||||
if ((i * (*e)) % phi == 1){
|
||||
*d = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//*d = *e;
|
||||
return *d;
|
||||
}
|
88
rsa.cpp
Normal file
88
rsa.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "rsa.h"
|
||||
#include "prng.h"
|
||||
|
||||
/*
|
||||
* We will generate the public and private RSA key
|
||||
*/
|
||||
void generateKeys(unsigned long *e, unsigned long *d, unsigned long *n){
|
||||
unsigned long p = prng();
|
||||
unsigned long q = prng();
|
||||
unsigned long phi = 0;
|
||||
|
||||
// Check if p and q are different
|
||||
if (p == q)
|
||||
q ^= q << 2;
|
||||
|
||||
// Check if p and q are prime numbers
|
||||
if (isPrimeNumber(p) != 0)
|
||||
prime_number_finder(&p);
|
||||
|
||||
if (isPrimeNumber(q) != 0)
|
||||
prime_number_finder(&q);
|
||||
|
||||
// Calculate n
|
||||
*n = p * q;
|
||||
|
||||
// We're going to calcule the Euler's totient
|
||||
phi = (p - 1)*(q - 1);
|
||||
|
||||
/* We will calculate e for the public key */
|
||||
generatePublicKey(phi, e);
|
||||
|
||||
/* We will calcuate d for the private key */
|
||||
generatePrivateKey(d, phi, e);
|
||||
}
|
||||
/*
|
||||
* This function will identify all the divider of the variable a
|
||||
* with the Euclidean algorithm
|
||||
*/
|
||||
static int gcd(unsigned long a, unsigned long b){
|
||||
if (b == 0)
|
||||
return a;
|
||||
return gcd(b, a%b);
|
||||
}
|
||||
/*
|
||||
* This function will check if te variable e is a prime number
|
||||
* is not, we increment the value to 1 and continue until is a prime number
|
||||
*/
|
||||
static void prime_number_finder(unsigned long *p){
|
||||
while(isPrimeNumber(*p) != 0)
|
||||
*p += 1;
|
||||
}
|
||||
/*
|
||||
* Check if the number specified is a prime number
|
||||
*/
|
||||
static int isPrimeNumber(unsigned long x){
|
||||
for (int i = 2; i < x; i++){
|
||||
if (x % i == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Generate the public key and need to be coprime with phi(n)
|
||||
*/
|
||||
static unsigned long generatePublicKey(unsigned long phi, unsigned long *e){
|
||||
// Generate e
|
||||
*e = prng();
|
||||
|
||||
while ((gcd(phi, *e)) != 1)
|
||||
*e += 1;
|
||||
|
||||
return *e;
|
||||
}
|
||||
/*
|
||||
* We generate tne private key with the modular inverse of phi(n)
|
||||
*/
|
||||
static unsigned long generatePrivateKey(unsigned long *d, unsigned long phi, unsigned long *e){
|
||||
for (int i = 0; i <= phi; i++){
|
||||
if ((i * (*e)) % phi == 1){
|
||||
*d = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return *d;
|
||||
}
|
22
rsa.h
Normal file
22
rsa.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef H_RSA
|
||||
#define H_RSA
|
||||
|
||||
#include <math.h>
|
||||
|
||||
void generateKeys(unsigned long *, unsigned long *, unsigned long *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static void prime_number_finder(unsigned long *);
|
||||
static int gcd(unsigned long, unsigned long);
|
||||
static int isPrimeNumber(unsigned long a);
|
||||
static unsigned long generatePublicKey(unsigned long, unsigned long *);
|
||||
static unsigned long generatePrivateKey(unsigned long *, unsigned long, unsigned long *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user