Skip to content

Instantly share code, notes, and snippets.

@harieamjari
Last active March 2, 2023 03:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harieamjari/64ca1303a16922abfcaa5295225ad4c1 to your computer and use it in GitHub Desktop.
Save harieamjari/64ca1303a16922abfcaa5295225ad4c1 to your computer and use it in GitHub Desktop.
RING-LWE block (8 bit) based cipher.
/* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or distribute
* this software, either in source code form or as a compiled binary,
* for any purpose, commercial or non-commercial, and by any means.
*
* In jurisdictions that recognize copyright laws, the author or authors of
* this software dedicate any and all copyright interest in the software to
* the public domain. We make this dedication for the benefit of the public
* at large and to the detriment of our heirs and successors. We intend
* this dedication to be an overt act of relinquishment in perpetuity of
* all present and future rights to this software under copyright law.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <string.h>
#include <inttypes.h>
#define M 256
#define P 2048
/* Possible 256 values from 0 to 255*/
#define V 256
//#define RING_DEBUG
#pragma pack(push, 4)
typedef struct vec3D_t vec3D_t;
struct vec3D_t {
int32_t x, y, z;
};
typedef struct pkey_t pkey_t;
struct pkey_t {
int32_t x, y, z, s;
};
#pragma pack(pop)
int32_t mod(int32_t a, int32_t b){
int32_t ret = 0;
if (a > 0) return a%b;
ret = a;
while (ret < 0)
ret += b;
return ret;
}
int32_t stepfunc(int32_t x) {
// if (x > ((P/V)-1))
// return 1;
// return 0;
return x / ((P / V) - 1);
}
pkey_t encrypt(int32_t msg, pkey_t *pkey, int32_t n) {
pkey_t ret;
/* randomly pick three vectors */
pkey_t v0 = pkey[rand() % n], v1 = pkey[rand() % n], v2 = pkey[rand() % n];
// pkey_t v0 = pkey[0], v1 = {0}, v2 = {0}, v3 = {0};
ret.x = (v0.x + v1.x + v2.x) % P;
ret.y = (v0.y + v1.y + v2.y) % P;
ret.z = (v0.z + v1.z + v2.z) % P;
ret.s = ((v0.s + v1.s + v2.s) + msg * ((P / V) - 1)) % P;
#ifdef RING_DEBUG
printf("encrypted %d as u=%d v=%d,%d,%d\n", msg, ret.s, ret.x, ret.y, ret.z);
#endif
return ret;
}
int32_t decrypt(pkey_t msg, vec3D_t skey) {
int32_t sol = (msg.x * skey.x + msg.y * skey.y + msg.z * skey.z) % P;
int32_t ret = stepfunc(mod(msg.s - sol, P));
#ifdef RING_DEBUG
printf("decrypted %d from u=%d v=%d,%d,%d, (uint8_t)%" PRIu8 "\n", ret, msg.s, msg.x, msg.y,
msg.z, (uint8_t)ret);
#endif
return ret;
};
void generate_keys(){
srand(time(NULL));
vec3D_t skey = (vec3D_t){rand()%P, rand()%P, rand()%P};
pkey_t *pkey = malloc(sizeof(pkey_t)*M);
assert(pkey!=NULL);
for (int32_t i = 0; i < M; i++){
pkey[i].x = rand()%P;
pkey[i].y = rand()%P;
pkey[i].z = rand()%P;
pkey[i].s = (pkey[i].x*skey.x + pkey[i].y*skey.y + pkey[i].z*skey.z);
pkey[i].s += rand()%3;
pkey[i].s %= P;
}
FILE *fskey = fopen("skey.key", "wb");
if (fskey == NULL){
perror("skey.key");
exit(1);
}
FILE *fpkey = fopen("pkey.key", "wb");
if (fpkey == NULL){
perror("pkey.key");
exit(1);
}
fwrite("SKEY", sizeof(char), 4, fskey);
fwrite(&skey, sizeof(vec3D_t), 1, fskey);
fwrite("PKEY", sizeof(char), 4, fpkey);
fwrite(&(int32_t){M}, sizeof(int32_t), 1, fpkey);
fwrite(pkey, sizeof(pkey_t), M, fpkey);
fclose(fpkey);
fclose(fskey);
}
void print_help(char *name){
printf("usage: %s g\n", name);
printf(" %s [e|d] [key] [input] [output]\n", name);
char *msg =
" operations:\n"
" e - encrypt file\n"
" d - decrypt file\n"
" g - generate keys\n";
puts(msg);
}
void encrypt_file(FILE *fpin, FILE *fpout, pkey_t *pkey, int32_t m){
/* encrypt bytes by bytes */
fwrite("ENC ", sizeof(char), 4, fpout);
int32_t msg = 0;
while ((msg = fgetc(fpin)) != EOF){
pkey_t encrypted = encrypt(msg, pkey, m);
fwrite(&encrypted, sizeof(pkey_t), 1, fpout);
}
printf("encrypted\n");
}
void decrypt_file(FILE *fpin, FILE *fpout, vec3D_t skey){
/* encrypt bytes by bytes */
int32_t msg = 0;
pkey_t encrypted = {0};
do {
fread(&encrypted, sizeof(pkey_t), 1, fpin);
if (feof(fpin))
break;
int32_t decrypted = decrypt(encrypted, skey);
// uint8_t cdec = (uint8_t)(void*)decrypted;
fwrite(&(uint8_t){(uint8_t)decrypted}, sizeof(uint8_t), 1, fpout);
} while (1);
printf("decrypted\n");
}
int main(int argc, char *argv[]){
switch (argc){
case 1:
print_help(argv[0]);
goto exit;
case 2:
if (argv[1][0] == 'g'){
generate_keys();
goto exit;
}
else {
print_help(argv[0]);
goto exit;
}
case 5:
switch (argv[1][0]){
case 'e':
{
FILE *fpkey = fopen(argv[2], "rb");
if (fpkey == NULL){
perror(argv[2]); exit(1);
}
char magic4[4];
fread(magic4, sizeof(char), 4, fpkey);
if (memcmp(magic4, "PKEY", 4)){
fprintf(stderr, "%s: Not a public key\n", argv[2]);
exit(1);
}
FILE *fpin = fopen(argv[3], "rb");
if (fpin == NULL){
perror(argv[3]); exit(1);
}
FILE *fpout = fopen(argv[4], "wb");
if (fpout == NULL){
perror(argv[4]); exit(1);
}
int32_t mvectors = 0;
fread(&mvectors, sizeof(int32_t), 1, fpkey);
pkey_t *pkey = malloc(sizeof(pkey_t)*mvectors);
assert(pkey!=NULL);
fread(pkey, sizeof(pkey_t), mvectors, fpkey);
fclose(fpkey);
encrypt_file(fpin, fpout, pkey, mvectors);
fclose(fpin); fclose(fpout);
free(pkey);
goto exit;
}
goto exit;
case 'd':
{
FILE *fskey = fopen(argv[2], "rb");
if (fskey == NULL){
perror(argv[2]); exit(1);
}
char smagic4[4];
fread(smagic4, sizeof(char), 4, fskey);
if (memcmp(smagic4, "SKEY", 4)){
fprintf(stderr, "%s: Not a secret key\n", argv[2]);
exit(1);
}
FILE *fpin = fopen(argv[3], "rb");
if (fpin == NULL){
perror(argv[3]); exit(1);
}
char emagic4[4];
fread(emagic4, sizeof(char), 4, fpin);
if (memcmp(emagic4, "ENC ", 4)){
fprintf(stderr, "%s: Not an encrypted file\n", argv[3]);
exit(1);
}
FILE *fpout = fopen(argv[4], "wb");
if (fpout == NULL){
perror(argv[4]); exit(1);
}
vec3D_t skey = {0};
fread(&skey, sizeof(vec3D_t), 1, fskey);
fclose(fskey);
decrypt_file(fpin, fpout, skey);
fclose(fpin); fclose(fpout);
goto exit;
}
goto exit;
default:
print_help(argv[0]);
goto exit;
}
default:
print_help(argv[0]);
goto exit;
}
exit:
return 0;
}
int test_main() {
srand(time(NULL));
vec3D_t skey = (vec3D_t){1091, 1203, 792};
pkey_t pkey[M] = {0};
printf("skey: %d %d %d\n", skey.x, skey.y, skey.z);
for (int i = 0; i < M; i++) {
pkey[i].x = rand() % P;
pkey[i].y = rand() % P;
pkey[i].z = rand() % P;
pkey[i].s =
((pkey[i].x * skey.x + pkey[i].y * skey.y + pkey[i].z * skey.z));
/* introduce cute noises */
pkey[i].s += ((rand() % 3));
pkey[i].s %= P;
printf("%dx %dy %dz = %d\n", pkey[i].x, pkey[i].y, pkey[i].z, pkey[i].s);
}
for (int i = 0; i < V; i++){
int32_t msg = i;
int32_t testv = decrypt(encrypt(msg, pkey, M), skey);
printf("-----------\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment