Last active
April 1, 2021 15:37
-
-
Save thennequin/31750f2b0de2cf968500861f359980dd to your computer and use it in GitHub Desktop.
MonocypherExemple
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "monocypher.h" | |
#include "base64.h" | |
#include <stdlib.h> | |
void main() | |
{ | |
uint8_t pMasterPrivateKey[32]; | |
uint8_t pMasterPublicKey[32]; | |
uint8_t pSlavePrivateKey[32]; | |
uint8_t pSlavePublicKey[32]; | |
uint8_t pSignPrivateKey[32]; | |
uint8_t pSignPublicKey[32]; | |
//Generate random key | |
srand(time(0)); | |
for (int i = 0; i < 32; ++i) | |
{ | |
pSignPrivateKey[i] = (rand() + 26523) % 256; // 26523 is random and can be replaced | |
pMasterPrivateKey[i] = (rand() + 26523) % 256; // 26523 is random and can be replaced | |
pSlavePrivateKey[i] = (rand() + 26523) % 256; // 26523 is random and can be replaced | |
} | |
//Master public generation | |
crypto_key_exchange_public_key(pMasterPublicKey, pMasterPrivateKey); | |
// Display Master Private and Public key as Base64 | |
{ | |
char pMasterPrivateKeyBase64[32 * 2]; | |
b64_encode(pMasterPrivateKey, sizeof(pMasterPrivateKey), pMasterPrivateKeyBase64, sizeof(pMasterPrivateKeyBase64)); | |
char pMasterPublicKeyBase64[32 * 2]; | |
b64_encode(pMasterPublicKey, sizeof(pMasterPublicKey), pMasterPublicKeyBase64, sizeof(pMasterPublicKeyBase64)); | |
printf("Master Private: %s\n", pMasterPrivateKeyBase64); | |
printf("Master Public: %s\n", pMasterPublicKeyBase64); | |
} | |
// Slave public generation | |
crypto_key_exchange_public_key(pSlavePublicKey, pSlavePrivateKey); | |
// Display Slave Private and Public key as Base64 | |
{ | |
char pSlavePrivateKeyBase64[32 * 2]; | |
b64_encode(pSlavePrivateKey, sizeof(pSlavePrivateKey), pSlavePrivateKeyBase64, sizeof(pSlavePrivateKeyBase64)); | |
char pSlavePublicKeyBase64[32 * 2]; | |
b64_encode(pSlavePublicKey, sizeof(pSlavePublicKey), pSlavePublicKeyBase64, sizeof(pSlavePublicKeyBase64)); | |
printf("Slave Private: %s\n", pSlavePrivateKeyBase64); | |
printf("Slave Public: %s\n", pSlavePublicKeyBase64); | |
} | |
// Generate Shared key on Master | |
uint8_t pMasterSharedKey[32]; | |
crypto_key_exchange(pMasterSharedKey, pMasterPrivateKey, pSlavePublicKey); | |
// Generate Shared key on Slave | |
uint8_t pSlaveSharedKey[32]; | |
crypto_key_exchange(pSlaveSharedKey, pSlavePrivateKey, pMasterPublicKey); | |
// Display Master & Slave Shared key as Base64 | |
// They should be the same | |
{ | |
char pMasterSharedKeyBase64[32 * 2]; | |
b64_encode(pMasterSharedKey, sizeof(pMasterSharedKey), pMasterSharedKeyBase64, sizeof(pMasterSharedKeyBase64)); | |
char pSlaveSharedKeyBase64[32 * 2]; | |
b64_encode(pSlaveSharedKey, sizeof(pSlaveSharedKey), pSlaveSharedKeyBase64, sizeof(pSlaveSharedKeyBase64)); | |
printf("Master Shared: %s\n", pMasterSharedKeyBase64); | |
printf("Slave Shared: %s\n", pSlaveSharedKeyBase64); | |
} | |
char pPlain[32]; | |
char pCypher[32]; | |
char pNewPlain[32]; | |
char pNonce[24]; | |
memset(pNonce, 0, sizeof(pNonce)); //Should be unique | |
char pMac[16]; // Message authentication code | |
// Encrypt pPlain to pCypher using Master Shared key | |
strcpy(pPlain, "Super test"); | |
crypto_lock(pMac, pCypher, pMasterSharedKey, pNonce, pPlain, sizeof(pPlain)); | |
// Decrypt pCypher to pNewPlain using Slave Shared Key | |
printf("crypto_unlock %s\n", crypto_unlock(pNewPlain, pSlaveSharedKey, pNonce, pMac, pCypher, sizeof(pCypher)) == 0 ? "Ok" : "Fail"); | |
printf("Plain Text: %s\n", pPlain); | |
char pCyperBase64[32 * 2]; | |
b64_encode(pCypher, sizeof(pCypher), pCyperBase64, sizeof(pCyperBase64)); | |
printf("Cyper Base64: %s\n", pCyperBase64); | |
printf("Decypher text: %s\n", pNewPlain); | |
// Generate Sign Public key | |
crypto_sign_public_key(pSignPublicKey, pSignPrivateKey); | |
// Generate Signature of pPlain | |
uint8_t pSignature[64]; | |
crypto_sign(pSignature, pSignPrivateKey, pSignPublicKey, pPlain, sizeof(pPlain)); | |
// Check Signature of pPlain | |
printf("pPlain Signature Checked %s\n", crypto_check(pSignature, pSignPublicKey, pPlain, sizeof(pPlain)) == 0 ? "Ok" : "Fail"); | |
// Modify pPlain and recheck it whith signature | |
pPlain[0] = 's'; | |
// Check Signature of modified pPlain | |
printf("Modified pPlain Signature Checked %s\n", crypto_check(pSignature, pSignPublicKey, pPlain, sizeof(pPlain)) == 0 ? "Ok" : "Fail"); | |
// Benchmark | |
const size_t iAllocSize = 65535LL * 16384LL; | |
char* pAlloc1 = (char*)malloc(iAllocSize); | |
char* pAlloc2 = (char*)malloc(iAllocSize); | |
//Benchmark crypt | |
memset(pAlloc1, 64, iAllocSize); | |
{ | |
long iStartTicks = GetTickCount(); | |
crypto_lock(pMac, pAlloc2, pMasterSharedKey, pNonce, pAlloc1, iAllocSize); | |
long iEndTicks = GetTickCount(); | |
long iTicks = (iEndTicks - iStartTicks); | |
printf("crypto_lock Ticks %d => %f Mo/s\n", iTicks, (iAllocSize / (iTicks / 1000.0)) / (1024 * 1024)); | |
} | |
//Benchmark decrypt | |
memset(pAlloc1, 0, iAllocSize); | |
{ | |
long iStartTicks = GetTickCount(); | |
crypto_unlock(pAlloc1, pSlaveSharedKey, pNonce, pMac, pAlloc2, iAllocSize); | |
long iEndTicks = GetTickCount(); | |
long iTicks = (iEndTicks - iStartTicks); | |
printf("crypto_unlock Ticks %d => %f Mo/s\n", iTicks, (iAllocSize / (iTicks / 1000.0)) / (1024 * 1024)); | |
} | |
//Benchmark Signature | |
{ | |
long iStartTicks = GetTickCount(); | |
crypto_sign(pSignature, pSignPrivateKey, pSignPublicKey, pAlloc1, iAllocSize); | |
long iEndTicks = GetTickCount(); | |
long iTicks = (iEndTicks - iStartTicks); | |
printf("crypto_sign Ticks %d => %f Mo/s\n", iTicks, (iAllocSize / (iTicks / 1000.0)) / (1024 * 1024)); | |
} | |
//Benchmark Signature check | |
{ | |
long iStartTicks = GetTickCount(); | |
int iCheckRes = crypto_check(pSignature, pSignPublicKey, pAlloc1, iAllocSize); | |
long iEndTicks = GetTickCount(); | |
long iTicks = (iEndTicks - iStartTicks); | |
printf("Check %s\n", iCheckRes == 0 ? "Ok" : "Fail"); | |
printf("crypto_check Ticks %d => %f Mo/s\n", iTicks, (iAllocSize / (iTicks / 1000.0)) / (1024 * 1024)); | |
} | |
return 0; | |
} | |
/* | |
Results on Ryzen 9 3900X | |
Master Private: p8p7e5iX6GU+wXmZYWDr7+vUWf+1RC06lFRJSKMldqM= | |
Master Public: OBlDd2xc36jZ2zyXJbWjMhFC4XVmRSu5gilw427SkhY= | |
Slave Private: mWKYBUNYxWxnqZjB4vuP6CYdB4zWj3LHpVLYEW/xk20= | |
Slave Public: e4mmIx/7X37axhSO4UdRqmp6rekWUmAl3cJGuI3nhRk= | |
Master Shared: vIiNTZwHxOW3aYPsENTxRCZDDBhmeM0vVUe5m9VKWaU= | |
Slave Shared: vIiNTZwHxOW3aYPsENTxRCZDDBhmeM0vVUe5m9VKWaU= | |
crypto_unlock Ok | |
Plain Text: Super test | |
Cyper Base64: B1RyYnaWraPWCUP18td68ewKdHA/xfFrEQj2LYPP5wE= | |
Decypher text: Super test | |
pPlain Signature Checked Ok | |
Modified pPlain Signature Checked Fail | |
crypto_lock Ticks 3937 => 260.092551 Mo/s | |
crypto_unlock Ticks 3843 => 266.454430 Mo/s | |
crypto_sign Ticks 4282 => 239.136940 Mo/s | |
Check Ok | |
crypto_check Ticks 2140 => 478.497371 Mo/s | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "base64.h" | |
#include <stdlib.h> // malloc | |
const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
const int b64invs[] = { | |
62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, | |
59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, | |
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, | |
21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, | |
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, | |
43, 44, 45, 46, 47, 48, 49, 50, 51 | |
}; | |
size_t b64_encoded_size(size_t inlen) | |
{ | |
size_t ret; | |
ret = inlen; | |
if (inlen % 3 != 0) | |
ret += 3 - (inlen % 3); | |
ret /= 3; | |
ret *= 4; | |
return ret; | |
} | |
int b64_encode(const unsigned char *in, size_t len, unsigned char* out, size_t outLen) | |
{ | |
size_t elen; | |
size_t i; | |
size_t j; | |
size_t v; | |
if (in == NULL || len == 0) | |
return 0; | |
if (out == NULL || outLen == 0) | |
return 0; | |
elen = b64_encoded_size(len); | |
if (outLen < (elen + 1)) | |
return 0; | |
out[elen] = '\0'; | |
for (i = 0, j = 0; i < len; i += 3, j += 4) { | |
v = in[i]; | |
v = i + 1 < len ? v << 8 | in[i + 1] : v << 8; | |
v = i + 2 < len ? v << 8 | in[i + 2] : v << 8; | |
out[j] = b64chars[(v >> 18) & 0x3F]; | |
out[j + 1] = b64chars[(v >> 12) & 0x3F]; | |
if (i + 1 < len) { | |
out[j + 2] = b64chars[(v >> 6) & 0x3F]; | |
} | |
else { | |
out[j + 2] = '='; | |
} | |
if (i + 2 < len) { | |
out[j + 3] = b64chars[v & 0x3F]; | |
} | |
else { | |
out[j + 3] = '='; | |
} | |
} | |
return 1; | |
} | |
size_t b64_decoded_size(const char *in) | |
{ | |
size_t len; | |
size_t ret; | |
size_t i; | |
if (in == NULL) | |
return 0; | |
len = strlen(in); | |
ret = len / 4 * 3; | |
for (i = len; i-- > 0; ) { | |
if (in[i] == '=') { | |
ret--; | |
} | |
else { | |
break; | |
} | |
} | |
return ret; | |
} | |
int b64_isvalidchar(char c) | |
{ | |
if (c >= '0' && c <= '9') | |
return 1; | |
if (c >= 'A' && c <= 'Z') | |
return 1; | |
if (c >= 'a' && c <= 'z') | |
return 1; | |
if (c == '+' || c == '/' || c == '=') | |
return 1; | |
return 0; | |
} | |
int b64_decode(const char *in, unsigned char *out, size_t outlen) | |
{ | |
size_t len; | |
size_t i; | |
size_t j; | |
int v; | |
if (in == NULL || out == NULL) | |
return 0; | |
len = strlen(in); | |
if (outlen < b64_decoded_size(in) || len % 4 != 0) | |
return 0; | |
for (i = 0; i < len; i++) { | |
if (!b64_isvalidchar(in[i])) { | |
return 0; | |
} | |
} | |
for (i = 0, j = 0; i < len; i += 4, j += 3) { | |
v = b64invs[in[i] - 43]; | |
v = (v << 6) | b64invs[in[i + 1] - 43]; | |
v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 2] - 43]; | |
v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64invs[in[i + 3] - 43]; | |
out[j] = (v >> 16) & 0xFF; | |
if (in[i + 2] != '=') | |
out[j + 1] = (v >> 8) & 0xFF; | |
if (in[i + 3] != '=') | |
out[j + 2] = v & 0xFF; | |
} | |
return 1; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stddef.h> // size_t | |
size_t b64_encoded_size(size_t inlen); | |
int b64_encode(const unsigned char *in, size_t len, unsigned char* out, size_t outLen); | |
size_t b64_decoded_size(const char *in); | |
int b64_decode(const char *in, unsigned char *out, size_t outlen); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment