Skip to content
Snippets Groups Projects
Commit 199a93c1 authored by Anian Bühler's avatar Anian Bühler
Browse files

added DidacticEnc Lib

parent c2063db2
No related branches found
No related tags found
1 merge request!1dev_prefereences to master
/**************************************************************************/
/*!
@file didacticEnc.cpp
@author anian buehler @ letsgoING.org
*/
/**************************************************************************/
#include "Arduino.h"
#include "DidacticEnc.h"
//**************************************************************************
//SYMETRIC
//**************************************************************************
DidacticEncSymetric::DidacticEncSymetric(){}
DidacticEncSymetric::~DidacticEncSymetric(){}
int DidacticEncSymetric::setKey(char* key){
if(strlen(key) == DE_LENGHT_KEY){
memcpy(_key, key, DE_LENGHT_KEY+1);
return DE_ERROR_NOERROR;
} else if(strlen(key) > DE_LENGHT_KEY){
return DE_ERROR_KEYLENGHT_LONG;
} else{
return DE_ERROR_KEYLENGHT_SHORT;
}
}
//Nachricht wird entschlüsselt und überschrieben
void DidacticEncSymetric::crypt(char* messageIn, int lengthMessage, char* messageOut, char* key, int lengthKey){
//ACHTUNG: bei gleichem Zeichen in Schlüssel und Nachricht wird die Nachricht unterbrochen
int keyCounter = 0;
int msgCounter = 0;
for (msgCounter = 0; msgCounter < lengthMessage; msgCounter++) {
keyCounter = msgCounter % lengthKey; //Zähler für key der nie größer wird als lengthKey (Restwert der Division durch Schlüssellänge)
messageOut[msgCounter] = messageIn[msgCounter] ^ key[keyCounter]; //XOR-Verknüpfung
}
messageOut[msgCounter + 1] = '\0'; //"EndOfString" an letzter Stelle
}
void DidacticEncSymetric::crypt(char* messageIn, char* messageOut, char* key){
crypt(messageIn, strlen(messageIn), messageOut, key, strlen(key) );
}
void DidacticEncSymetric::crypt(char* messageIn, char* messageOut){
crypt(messageIn, strlen(messageIn), messageOut, _key, strlen(_key));
}
//**************************************************************************
//ASYMETRIC
//**************************************************************************
DidacticEncAsymetric::DidacticEncAsymetric(){}
DidacticEncAsymetric::~DidacticEncAsymetric(){}
void DidacticEncAsymetric::generateRsaKeys(long p, long q, long& n, long& e, long& d) {
long x = 0;
long y = 0;
long m = 0;
n = p * q;
m = (p - 1) * (q - 1);
e = 3; //start value
while (gcd(e, m) > 1) {
e += 2;
}
if (egcd(e, m, x, y) == 1) {
if (x < 0) {
x += m;
}
d = x % m;
}
}
long DidacticEncAsymetric::cryptRsa(long key, long n, long message) {
return modPow(message, key, n);
}
long DidacticEncAsymetric::getPrime(){
return prime[random(0, MAX_NR_OF_PRIMES- MAX_PRIME_OFFSET)];
}
long DidacticEncAsymetric::getPrimeWithOffset(long basicPrime){
int index = 0;
while(prime[index] != basicPrime && index <= MAX_NR_OF_PRIMES- MAX_PRIME_OFFSET){
++index;
}
return prime[index + random(1,MAX_PRIME_OFFSET)];
}
void DidacticEncAsymetric::setRandomSeedPin(int analogPin){
if(analogPin <= A5 && analogPin >= A0){
_randomPin = analogPin;
}
}
void DidacticEncAsymetric::generateKeys(){
randomSeed(analogRead(_randomPin));
long firstPrime = getPrime();
long secondPrime = getPrimeWithOffset(firstPrime);
generateRsaKeys(firstPrime, secondPrime, _rsaModule, _publicKey, _privateKey);
}
long DidacticEncAsymetric::getPrivateKey(){
return _privateKey;
}
long DidacticEncAsymetric::getPublicKey(){
return _publicKey;
}
long DidacticEncAsymetric::getRsaModule(){
return _rsaModule;
}
int DidacticEncAsymetric::encrypt(char* plainText, int lengthplainText, char* cypherText, long key, long rsaModule){
for(int i = 0; i< lengthplainText; ++i){
long currentMessage = (long) plainText[i];
snprintf(&(cypherText[strlen(cypherText)]), MAX_LEN_CYPHERTEXT, "%ld", cryptRsa( key, rsaModule, currentMessage));
snprintf(&(cypherText[strlen(cypherText)]), MAX_LEN_CYPHERTEXT, DE_CYPHER_SEPARATOR);
}
return strlen(cypherText);
}
int DidacticEncAsymetric::encrypt(char* plainText, char* cypherText, long key, long rsaModule){
return encrypt(plainText, strlen(plainText), cypherText, key, rsaModule);
}
int DidacticEncAsymetric::decrypt(char* cypherText, char* plainText, long key, long rsaModule) {
char *currentNumber;
char *savePointer = cypherText;
int counter = 0;
while ((currentNumber = strtok_r(savePointer, DE_CYPHER_SEPARATOR, &savePointer)) != NULL) // Don't use \n here it fails
{
long number = atol(currentNumber);
plainText[counter] = cryptRsa( key, rsaModule, number);
++counter;
}
plainText[counter] = '\0';
return counter;
}
//***************
/**********************************************
* MATH FUNCTIONS FOR RSA
**********************************************/
// Basic Euclidean Algorithm for greatest common divider
long DidacticEncAsymetric::gcd (long a, long b) {
long r;
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
/*recursive version of gcd
long gcd(long a, long b)
{
if (a == 0)
return b;
return gcd(b%a, a);
} */
// extended euclidean algorithm: also finds coefficients x and y
long DidacticEncAsymetric::egcd (long a, long b, long& x, long& y){
if (a == 0)
{
x = 0;
y = 1;
return b;
}
long _x, _y;
long gcd = egcd(b % a, a, _x, _y);
x = _y - (b / a) * _x;
y = _x;
return gcd;
}
//modular exponentation (to keep values as small as possible)
long DidacticEncAsymetric::modPow(long base, long exponent, long modulus) {
if (modulus == 1) {
return 0;
}
long c = 1;
for (long i = 0; i < exponent; i++) {
c = c * base % modulus;
}
return c;
}
/**************************************************************************
@file didacticNet.h
@author anian buehler @ letsgoING
**************************************************************************/
#ifndef _DIDACTICENC_
#define _DIDACTICENC_
#include "Arduino.h"
class DidacticEncSymetric
{
#define DE_LENGHT_KEY 8
#define MAX_LEN_CYPHERTEXT DE_LENGHT_KEY*4
#define MAX_LEN_PLAINTEXT DE_LENGHT_KEY*4
#define DE_ERROR_NOERROR 1
#define DE_ERROR_KEYLENGHT_LONG -1
#define DE_ERROR_KEYLENGHT_SHORT -2
private:
char _bufferCyphertext[MAX_LEN_CYPHERTEXT +1] = {0};
char _bufferPlaintext[MAX_LEN_PLAINTEXT +1] = {0};
char _key[DE_LENGHT_KEY +1] = {'0','0','0','0','0','0','0','0','\0'};
public:
DidacticEncSymetric();
~DidacticEncSymetric();
int setKey(char*);
void crypt(char*, int, char*, char*, int);
void crypt(char*, char*, char*);
void crypt(char*, char*);
};
class DidacticEncAsymetric
{
#define MAX_NR_OF_PRIMES 48
#define MAX_PRIME_OFFSET 3
#define MAX_LEN_PLAINTEXT 20
#define MAX_LEN_CYPHERTEXT 250
#define DE_CYPHER_SEPARATOR ";"
private:
const int prime[MAX_NR_OF_PRIMES] = { 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73,
79, 83, 89, 97, 101, 103, 107, 109,
113, 127, 131, 137, 139, 149, 151, 157,
163, 167, 173, 179, 181, 191, 193, 197,
199, 211, 223, 227, 229, 233, 239, 241,
251};//, 257, 263, 269, 271, 277, 281};
char _bufferCyphertext[MAX_LEN_CYPHERTEXT +1] = {0};
long _privateKey = 0L;
long _publicKey = 0L;
long _rsaModule = 0L;
int _randomPin = A5;
void generateRsaKeys(long, long, long&, long&, long&);
long cryptRsa(long key, long rsaModul, long message);
long getPrimeWithOffset(long);
long getPrime();
//rsa math functions
long gcd (long, long); //basic euclidean algorithm
long egcd (long, long, long&, long&); //extended euclidean algorithm
long modPow(long, long, long); //modular exponentation
public:
DidacticEncAsymetric();
~DidacticEncAsymetric();
void generateKeys();
void setRandomSeedPin(int);
long getPrivateKey();
long getPublicKey();
long getRsaModule();
int encrypt(char*, int, char*, long, long);
int encrypt(char*, char*, long, long);
int decrypt(char*, char*, long, long);
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment