Skip to content

Commit

Permalink
add chacha20 code
Browse files Browse the repository at this point in the history
  • Loading branch information
redthing1 committed Jul 15, 2023
1 parent 6a86f6c commit a7e6616
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 0 deletions.
108 changes: 108 additions & 0 deletions test/chacha20/cc20.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// https://github.com/shiffthq/chacha20/blob/master/src/chacha20.c

#include "cc20.h"

static inline void u32t8le(uint32_t v, uint8_t p[4]) {
p[0] = v & 0xff;
p[1] = (v >> 8) & 0xff;
p[2] = (v >> 16) & 0xff;
p[3] = (v >> 24) & 0xff;
}

static inline uint32_t u8t32le(uint8_t p[4]) {
uint32_t value = p[3];

value = (value << 8) | p[2];
value = (value << 8) | p[1];
value = (value << 8) | p[0];

return value;
}

static inline uint32_t rotl32(uint32_t x, int n) {
// https://blog.regehr.org/archives/1063
return x << n | (x >> (-n & 31));
}

// https://tools.ietf.org/html/rfc7539#section-2.1
static void chacha20_quarterround(uint32_t *x, int a, int b, int c, int d) {
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 16);
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 12);
x[a] += x[b]; x[d] = rotl32(x[d] ^ x[a], 8);
x[c] += x[d]; x[b] = rotl32(x[b] ^ x[c], 7);
}

static void chacha20_serialize(uint32_t in[16], uint8_t output[64]) {
int i;
for (i = 0; i < 16; i++) {
u32t8le(in[i], output + (i << 2));
}
}

static void chacha20_block(uint32_t in[16], uint8_t out[64], int num_rounds) {
int i;
uint32_t x[16];

// memcpy(x, in, sizeof(uint32_t) * 16);
memcpy(x, in, 4 * 16); // patch for IRRE chcc

for (i = num_rounds; i > 0; i -= 2) {
chacha20_quarterround(x, 0, 4, 8, 12);
chacha20_quarterround(x, 1, 5, 9, 13);
chacha20_quarterround(x, 2, 6, 10, 14);
chacha20_quarterround(x, 3, 7, 11, 15);
chacha20_quarterround(x, 0, 5, 10, 15);
chacha20_quarterround(x, 1, 6, 11, 12);
chacha20_quarterround(x, 2, 7, 8, 13);
chacha20_quarterround(x, 3, 4, 9, 14);
}

for (i = 0; i < 16; i++) {
x[i] += in[i];
}

chacha20_serialize(x, out);
}

// https://tools.ietf.org/html/rfc7539#section-2.3
static void chacha20_init_state(uint32_t s[16], uint8_t key[32], uint32_t counter, uint8_t nonce[12]) {
int i;

// refer: https://dxr.mozilla.org/mozilla-beta/source/security/nss/lib/freebl/chacha20.c
// convert magic number to string: "expand 32-byte k"
s[0] = 0x61707865;
s[1] = 0x3320646e;
s[2] = 0x79622d32;
s[3] = 0x6b206574;

for (i = 0; i < 8; i++) {
s[4 + i] = u8t32le(key + i * 4);
}

s[12] = counter;

for (i = 0; i < 3; i++) {
s[13 + i] = u8t32le(nonce + i * 4);
}
}

void ChaCha20XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *in, uint8_t *out, int inlen) {
int i, j;

uint32_t s[16];
uint8_t block[64];

chacha20_init_state(s, key, counter, nonce);

for (i = 0; i < inlen; i += 64) {
chacha20_block(s, block, 20);
s[12]++;

for (j = i; j < i + 64; j++) {
if (j >= inlen) {
break;
}
out[j] = in[j] ^ block[j - i];
}
}
}
7 changes: 7 additions & 0 deletions test/chacha20/cc20.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// https://github.com/shiffthq/chacha20/blob/master/src/chacha20.h
#ifndef __CHACHA20_H
#define __CHACHA20_H

void ChaCha20XOR(uint8_t key[32], uint32_t counter, uint8_t nonce[12], uint8_t *input, uint8_t *output, int inputlen);

#endif
104 changes: 104 additions & 0 deletions test/chacha20/test1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#ifdef DESKTOP
#include <stdio.h>
#include <stdint.h>
#endif

#include "../lib/corlib.h"
#include "cc20.h"

#define PLAINTEXT_LEN 114

bool compare_bytes(uint8_t *a, uint8_t *b, int len) {
for (int i = 0; i < len; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
}

int main(int argc, char **argv) {
int i;

uint8_t key[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b,
0x1c, 0x1d, 0x1e, 0x1f
};

uint8_t nonce[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00
};

uint8_t input[PLAINTEXT_LEN] = {
0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c,
0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73,
0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63,
0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f,
0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20,
0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73,
0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69,
0x74, 0x2e
};

uint8_t encrypt[PLAINTEXT_LEN];
uint8_t decrypt[PLAINTEXT_LEN];

ChaCha20XOR(key, 1, nonce, input, encrypt, PLAINTEXT_LEN);
ChaCha20XOR(key, 1, nonce, encrypt, decrypt, PLAINTEXT_LEN);

#ifdef DESKTOP
printf("\nkey:");
for (i = 0; i < 32; i++) {
if (!(i % 16)) {
printf("\n");
}
printf("%02x ", key[i]);
}

printf("\n\nnonce:\n");
for (i = 0; i < 12; i++) {
printf("%02x ", nonce[i]);
}

printf("\n\nplaintext:");
for (i = 0; i < PLAINTEXT_LEN; i++) {
if (!(i % 16)) {
printf("\n");
}
printf("%02x ", input[i]);
}

printf("\n\nencrypted:");
for (i = 0; i < PLAINTEXT_LEN; i++) {
if (!(i % 16)) {
printf("\n");
}
printf("%02x ", encrypt[i]);
}

printf("\n\ndecrypted:");
for (i = 0; i < PLAINTEXT_LEN; i++) {
if (!(i % 16)) {
printf("\n");
}
printf("%02x ", decrypt[i]);
}

printf("\n");
#endif

// check that the encryption and decryption worked
if (!compare_bytes(input, decrypt, PLAINTEXT_LEN)) {
return 1;
}

return 0;
}

#include "cc20.c"
4 changes: 4 additions & 0 deletions test/lib/corlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#define UINT (unsigned int)
#define VOID (void)

#define int8_t char
#define uint8_t unsigned char
#define int16_t short
#define uint16_t unsigned short
#define int32_t int
#define uint32_t unsigned int
#define int64_t long
Expand Down

0 comments on commit a7e6616

Please sign in to comment.