| //#include <stdint.h> |
| #include "ecc.h" |
| #include "ecies-chacha20.h" |
| #include <sys/types.h> |
| #include "chacha20_simple.h" |
| #include <unistd.h> |
| #include <fcntl.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <errno.h> |
| #include <string.h> |
| |
| #define CHACHA20_BLOCK_BYTES 64 |
| #define CHACHA20_NONCE_SIZE 8 |
| |
| ECIES_byte_t ChaCha20_nonce[CHACHA20_NONCE_SIZE] = { 1, 1, 1, 1, 1, 1, 1, 1 }; |
| const ECIES_size_t ChaCha20_nonce_size = CHACHA20_NONCE_SIZE; |
| |
| static void debug_print_bytes(const ECIES_byte_t *a, size_t len) { |
| unsigned int i; |
| for(i=0; i<len; i++) fprintf(stderr, "0x%hhx, ", a[i]); |
| fputc('\n', stderr); |
| } |
| |
| static void ChaCha20_init_ctx(chacha20_ctx *ctx, const uint8_t *key) { |
| //uint8_t nonce[8]; |
| /* |
| int fd = open("/dev/urandom", O_RDONLY); |
| if(fd == -1) { |
| perror("/dev/urandom"); |
| exit(1); |
| } |
| int count = 0; |
| do { |
| int s = read(fd, nonce + count, sizeof nonce - count); |
| if(s < 0) { |
| if(errno == EINTR) continue; |
| perror("/dev/urandom"); |
| exit(1); |
| } |
| if(!s) { |
| fprintf(stderr, "panic? /dev/urandom EOF??\n"); |
| exit(1); |
| } |
| count += s; |
| } while(count < sizeof nonce); |
| close(fd); |
| */ |
| //memset(nonce, 1, sizeof nonce); |
| //fprintf(stderr, "ChaCha20_nonce[0] = 0x%hhx\n", ChaCha20_nonce[0]); |
| chacha20_setup(ctx, key, CHACHA20_KEY_BYTES, ChaCha20_nonce); |
| } |
| |
| unsigned int ChaCha20_key_bytes() { |
| return CHACHA20_KEY_BYTES; |
| } |
| |
| void ChaCha20_ctr_crypt(ECIES_byte_t *data, ECIES_size_t size, const ECIES_byte_t *key) { |
| fprintf(stderr, "function: ChaCha20_ctr_crypt(%p, %u, %p)\n", data, size, key); |
| chacha20_ctx ctx; |
| ChaCha20_init_ctx(&ctx, key); |
| /* |
| uint32_t ctr = 0; |
| int i; |
| ECIES_byte_t buffer[CHACHA20_BLOCK_BYTES]; |
| while(size) { |
| //for(i = CHACHA20_BLOCK_BYTES / sizeof ctr - 1; i >= 0; i--) INT2CHARS(buffer + sizeof ctr * i, 0); |
| for(i = CHACHA20_BLOCK_BYTES - sizeof ctr; i >= 0; i -= sizeof ctr) INT2CHARS(buffer + i, ctr++); |
| chacha20_encrypt(&ctx, buffer, buffer, sizeof buffer); |
| ECIES_size_t len = MIN(sizeof buffer, size); |
| for(i = 0; i < len; i++) *data++ ^= buffer[i]; |
| size -= len; |
| } |
| */ |
| // ChaCha20 is already a counter mode cipher |
| chacha20_encrypt(&ctx, data, data, size); |
| } |
| |
| void ChaCha20_cbc_mac(ECIES_byte_t *mac, const ECIES_byte_t *data, ECIES_size_t size, const ECIES_byte_t *key) { |
| fprintf(stderr, "function: ChaCha20_cbc_mac(%p, %p, %u, %p)\n", mac, data, size, key); |
| chacha20_ctx ctx; |
| unsigned int i; |
| ChaCha20_init_ctx(&ctx, key); |
| // sizeof size == 4 |
| //INT2CHARS(mac, size); |
| INT2CHARS(mac, 0); |
| INT2CHARS(mac + 4, size); |
| chacha20_encrypt(&ctx, mac, mac, ECIES_CHUNK_OVERHEAD); |
| while(size) { |
| //ECIES_size_t blen = MIN(CHACHA20_BLOCK_BYTES, size); |
| ECIES_size_t blen = MIN(ECIES_CHUNK_OVERHEAD, size); |
| for(i = 0; i < blen; i++) mac[i] ^= *data++; |
| //chacha20_encrypt(&ctx, mac, mac, CHACHA20_BLOCK_BYTES); |
| chacha20_encrypt(&ctx, mac, mac, ECIES_CHUNK_OVERHEAD); |
| size -= blen; |
| } |
| } |
| |
| void ChaCha20_davies_meyer(ECIES_byte_t *out, const ECIES_byte_t *in, int ilen) { |
| fprintf(stderr, "function: ChaCha20_davies_meyer(%p, %p, %d)\n", out, in, ilen); |
| debug_print_bytes(ChaCha20_nonce, 8); |
| unsigned int i; |
| ECIES_byte_t buffer[CHACHA20_KEY_BYTES / 2]; |
| chacha20_ctx ctx; |
| memset(out, 0, CHACHA20_KEY_BYTES / 2); |
| while(ilen--) { |
| ChaCha20_init_ctx(&ctx, in); |
| memcpy(buffer, out, sizeof buffer); |
| chacha20_encrypt(&ctx, buffer, buffer, sizeof buffer); |
| debug_print_bytes(buffer, sizeof buffer); |
| for(i = 0; i < sizeof buffer; i++) out[i] ^= buffer[i]; |
| in += CHACHA20_KEY_BYTES; |
| } |
| } |