pi16cipher in asm :-)
This commit is contained in:
parent
d9352fc79f
commit
c5e0834acc
|
@ -63,6 +63,7 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
/* !warning the pointer will point one below the allocated area! */
|
||||
.macro stack_alloc size:req, reg1=r30, reg2=r31
|
||||
in r0, _SFR_IO_ADDR(SREG)
|
||||
in \reg1, _SFR_IO_ADDR(SPL)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Makefile for pi-cipher
|
||||
ALGO_NAME := PICIPHER_C
|
||||
|
||||
# comment out the following line for removement of noekeon from the build process
|
||||
AEAD_CIPHERS += $(ALGO_NAME)
|
||||
|
||||
$(ALGO_NAME)_DIR := pi-cipher/
|
||||
$(ALGO_NAME)_INCDIR := arcfour/
|
||||
$(ALGO_NAME)_OBJ := pi16cipher.o pi16cipher-asm.o pi32cipher.o pi64cipher.o
|
||||
$(ALGO_NAME)_TESTBIN := main-picipher-test.o arcfour-asm.o $(CLI_STD) performance_test.o
|
||||
$(ALGO_NAME)_NESSIE_TEST := test nessie
|
||||
$(ALGO_NAME)_PERFORMANCE_TEST := performance
|
||||
|
|
@ -0,0 +1,755 @@
|
|||
/* pi-cipher.c */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "pi-cipher.h"
|
||||
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if (PI_WORD_SIZE == 16)
|
||||
# define load_word_little(mem) load_u16_little(mem)
|
||||
# define store_word_little(mem, val) store_u16_little((mem), (val))
|
||||
# define PRI_xw "04"PRIx16
|
||||
|
||||
|
||||
static uint16_t load_u16_little(const void *mem)
|
||||
{
|
||||
uint16_t ret;
|
||||
const uint8_t *x = (const uint8_t *)mem;
|
||||
ret = x[0] << 0
|
||||
| x[1] << 8;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void store_u16_little(void *mem, uint16_t val)
|
||||
{
|
||||
uint8_t *x = (uint8_t *)mem;
|
||||
x[0] = val & 0xff; val >>= 8;
|
||||
x[1] = val & 0xff;
|
||||
}
|
||||
|
||||
#elif (PI_WORD_SIZE == 32)
|
||||
# define load_word_little(mem) load_u32_little(mem)
|
||||
# define store_word_little(mem, val) store_u32_little((mem), (val))
|
||||
# define PRI_xw "08"PRIx32
|
||||
|
||||
static uint32_t load_u32_little(const void *mem)
|
||||
{
|
||||
uint32_t ret;
|
||||
const uint8_t *x = (const uint8_t *)mem;
|
||||
ret = (uint32_t)x[0] << 0
|
||||
| (uint32_t)x[1] << 8
|
||||
| (uint32_t)x[2] << 16
|
||||
| (uint32_t)x[3] << 24;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void store_u32_little(void *mem, uint32_t val)
|
||||
{
|
||||
uint8_t *x = (uint8_t *)mem;
|
||||
x[0] = val & 0xff; val >>= 8;
|
||||
x[1] = val & 0xff; val >>= 8;
|
||||
x[2] = val & 0xff; val >>= 8;
|
||||
x[3] = val & 0xff;
|
||||
}
|
||||
|
||||
#elif (PI_WORD_SIZE == 64)
|
||||
# define load_word_little(mem) load_u64_little(mem)
|
||||
# define store_word_little(mem, val) store_u64_little((mem), (val))
|
||||
# define PRI_xw "016"PRIx64
|
||||
|
||||
static uint64_t load_u64_little(const void *mem)
|
||||
{
|
||||
uint64_t ret;
|
||||
const uint8_t *x = (const uint8_t *)mem;
|
||||
ret = (uint64_t)x[0] << 0
|
||||
| (uint64_t)x[1] << 8
|
||||
| (uint64_t)x[2] << 16
|
||||
| (uint64_t)x[3] << 24
|
||||
| (uint64_t)x[4] << 32
|
||||
| (uint64_t)x[5] << 40
|
||||
| (uint64_t)x[6] << 48
|
||||
| (uint64_t)x[7] << 56;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void store_u64_little(void *mem, uint64_t val)
|
||||
{
|
||||
uint8_t *x = (uint8_t *)mem;
|
||||
x[0] = val & 0xff; val >>= 8;
|
||||
x[1] = val & 0xff; val >>= 8;
|
||||
x[2] = val & 0xff; val >>= 8;
|
||||
x[3] = val & 0xff; val >>= 8;
|
||||
x[4] = val & 0xff; val >>= 8;
|
||||
x[5] = val & 0xff; val >>= 8;
|
||||
x[6] = val & 0xff; val >>= 8;
|
||||
x[7] = val & 0xff;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef word_t state_t[4][4];
|
||||
const char* PI_CIPHER_NAME_X = XSTR(PI_CIPHER_NAME);
|
||||
|
||||
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
size_t dbg_l;
|
||||
const uint8_t *dbg_x;
|
||||
uint8_t dump;
|
||||
|
||||
|
||||
static
|
||||
void hexdump_block(
|
||||
const void *data,
|
||||
size_t length,
|
||||
unsigned short indent,
|
||||
unsigned short width)
|
||||
{
|
||||
unsigned short column = 0;
|
||||
char f = 0;
|
||||
while (length--) {
|
||||
if (column == 0) {
|
||||
unsigned short i;
|
||||
if (f) {
|
||||
putchar('\n');
|
||||
} else {
|
||||
f = 1;
|
||||
}
|
||||
for (i = 0; i < indent; ++i) {
|
||||
putchar(' ');
|
||||
}
|
||||
column = width;
|
||||
}
|
||||
column -= 1;
|
||||
printf("%02x ", *((unsigned char *)data));
|
||||
data = (void *)((char *)data + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void dump_state(const word_t* a)
|
||||
{
|
||||
if (dump || 1) {
|
||||
printf("\tCIS:\n");
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n", a[ 0], a[ 1], a[ 2], a[ 3]);
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n", a[ 4], a[ 5], a[ 6], a[ 7]);
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n", a[ 8], a[ 9], a[10], a[11]);
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n\n", a[12], a[13], a[14], a[15]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define printf(...)
|
||||
#endif
|
||||
|
||||
|
||||
static word_t rotl(word_t x, uint8_t n)
|
||||
{
|
||||
return (x << n) | (x >> ((PI_WORD_SIZE) - n));
|
||||
}
|
||||
|
||||
static void phi(
|
||||
word_t dest[4],
|
||||
const word_t x[4],
|
||||
const word_t c[4],
|
||||
const uint8_t v[8],
|
||||
const uint8_t rot[4])
|
||||
{
|
||||
word_t sum = 0;
|
||||
uint8_t i;
|
||||
i = 4;
|
||||
do {
|
||||
--i;
|
||||
sum += x[i];
|
||||
} while (i);
|
||||
i = 4;
|
||||
do {
|
||||
--i;
|
||||
dest[i] = rotl(pgm_read_word(&c[i]) + sum - x[pgm_read_byte(&v[i])], pgm_read_byte(&rot[i]) );
|
||||
} while (i);
|
||||
sum = 0;
|
||||
i = 4;
|
||||
do {
|
||||
--i;
|
||||
sum ^= dest[i];
|
||||
} while (i);
|
||||
i = 4;
|
||||
do {
|
||||
--i;
|
||||
dest[i] ^= sum;
|
||||
} while (i);
|
||||
}
|
||||
|
||||
static const word_t mu_const[4] PROGMEM = PI_MU_CONST;
|
||||
|
||||
static const uint8_t mu_v_const[4] PROGMEM = PI_MU_V_CONST;
|
||||
|
||||
static const uint8_t mu_rot_const[4] PROGMEM = PI_MU_ROT_CONST;
|
||||
|
||||
static const word_t ny_const[4] PROGMEM = PI_NY_CONST;
|
||||
|
||||
static const uint8_t ny_v_const[4] PROGMEM = PI_NY_V_CONST;
|
||||
|
||||
static const uint8_t ny_rot_const[4] PROGMEM = PI_NY_ROT_CONST;
|
||||
|
||||
static const word_t pi_const[8][4] PROGMEM = PI_CONST;
|
||||
|
||||
static void mu(
|
||||
word_t dest[4],
|
||||
const word_t x[4])
|
||||
{
|
||||
word_t t[4];
|
||||
phi(t, x, mu_const, mu_v_const, mu_rot_const);
|
||||
dest[0] = t[2];
|
||||
dest[1] = t[3];
|
||||
dest[2] = t[0];
|
||||
dest[3] = t[1];
|
||||
}
|
||||
|
||||
static void ny(
|
||||
word_t dest[4],
|
||||
const word_t x[4])
|
||||
{
|
||||
phi(dest, x, ny_const, ny_v_const, ny_rot_const);
|
||||
}
|
||||
|
||||
static void sigma(
|
||||
word_t dest[4],
|
||||
const word_t x1[4],
|
||||
const word_t x2[4] )
|
||||
{
|
||||
dest[3] = x1[0] + x2[0];
|
||||
dest[0] = x1[1] + x2[1];
|
||||
dest[1] = x1[2] + x2[2];
|
||||
dest[2] = x1[3] + x2[3];
|
||||
}
|
||||
|
||||
static void ast(
|
||||
word_t dest[4],
|
||||
const word_t x[4],
|
||||
const word_t y[4] )
|
||||
{
|
||||
word_t a[4], b[4];
|
||||
mu(a, x);
|
||||
ny(b, y);
|
||||
sigma(dest, a, b);
|
||||
}
|
||||
|
||||
static void e1(
|
||||
word_t *dest,
|
||||
const word_t c[4],
|
||||
const word_t *i )
|
||||
{
|
||||
uint8_t n = PI_N - 1;
|
||||
{
|
||||
word_t t[4];
|
||||
memcpy_P(t, c, sizeof(word_t) * 4);
|
||||
ast(dest, t, i);
|
||||
}
|
||||
do {
|
||||
i = &i[4];
|
||||
ast(&dest[4], dest, i);
|
||||
dest = &dest[4];
|
||||
} while (--n);
|
||||
}
|
||||
|
||||
static void e2(
|
||||
word_t *dest,
|
||||
const word_t c[4],
|
||||
const word_t *i )
|
||||
{
|
||||
uint8_t n = PI_N - 1;
|
||||
{
|
||||
word_t t[4];
|
||||
memcpy_P(t, c, sizeof(word_t) * 4);
|
||||
ast(&dest[4 * n], &i[4 * n], t);
|
||||
}
|
||||
while (n--) {
|
||||
ast(&dest[4 * n], &i[4 * n], &dest[4 * (n + 1)]);
|
||||
}
|
||||
}
|
||||
|
||||
static void pi(
|
||||
word_t *a )
|
||||
{
|
||||
uint8_t r = PI_ROUNDS;
|
||||
word_t t[4 * 4];
|
||||
const word_t *c = (const word_t *)pi_const;
|
||||
do {
|
||||
e1(t, c, a);
|
||||
c = &c[4];
|
||||
e2(a, c, t);
|
||||
c = &c[4];
|
||||
} while (--r);
|
||||
}
|
||||
|
||||
static void add_tag(
|
||||
PI_CTX *ctx,
|
||||
state_t a )
|
||||
{
|
||||
uint8_t i;
|
||||
i = 3;
|
||||
do {
|
||||
ctx->tag[i + 0] += a[0][i];
|
||||
ctx->tag[i + 4] += a[2][i];
|
||||
} while(i--);
|
||||
}
|
||||
|
||||
static void ctr_trans(
|
||||
const PI_CTX *ctx,
|
||||
state_t a,
|
||||
unsigned long ctr )
|
||||
{
|
||||
uint64_t t;
|
||||
int i;
|
||||
if ((void *)ctx->cis != (void *)a) {
|
||||
memcpy(a, ctx->cis, sizeof(state_t));
|
||||
}
|
||||
t = ctx->ctr + ctr;
|
||||
for (i = 0; i * PI_WORD_SIZE < 64; ++i) {
|
||||
a[0][i] ^= (word_t)t;
|
||||
# if PI_WORD_SIZE < 64
|
||||
t >>= PI_WORD_SIZE;
|
||||
# endif
|
||||
}
|
||||
|
||||
pi((word_t*)a);
|
||||
}
|
||||
|
||||
static void inject_tag(
|
||||
state_t a,
|
||||
const word_t x[8] )
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
a[0][i] ^= x[i];
|
||||
}
|
||||
for (; i < 8; ++i) {
|
||||
a[2][i - 4] ^= x[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void extract_block(
|
||||
void *block,
|
||||
state_t a)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
store_word_little(&((word_t *)block)[i], a[0][i]);
|
||||
}
|
||||
for (; i < 8; ++i) {
|
||||
store_word_little(&((word_t *)block)[i], a[2][i - 4]);
|
||||
}
|
||||
}
|
||||
|
||||
static void inject_block(
|
||||
state_t a,
|
||||
const void *block )
|
||||
{
|
||||
word_t x;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
x = load_word_little(&((const word_t *)block)[i]);
|
||||
a[0][i] ^= x;
|
||||
}
|
||||
for (; i < 8; ++i) {
|
||||
x = load_word_little(&((const word_t *)block)[i]);
|
||||
a[2][i - 4] ^= x;
|
||||
}
|
||||
}
|
||||
|
||||
static void inject_last_block(
|
||||
state_t a,
|
||||
const void *block,
|
||||
size_t length_b )
|
||||
{
|
||||
uint8_t t[PI_RATE_BYTES];
|
||||
if (length_b >= PI_RATE_BITS) {
|
||||
/* error */
|
||||
printf("ERROR <%s %s %d>\n", __FILE__, __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
memset(t, 0, sizeof(t));
|
||||
memcpy(t, block, (length_b + 7) / 8);
|
||||
t[length_b / 8] |= 1 << (length_b & 7);
|
||||
inject_block(a, t);
|
||||
}
|
||||
|
||||
static void replace_block(
|
||||
state_t a,
|
||||
const void *block )
|
||||
{
|
||||
word_t x;
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i) {
|
||||
x = load_word_little(&((const word_t *)block)[i]);
|
||||
a[0][i] = x;
|
||||
}
|
||||
for (; i < 8; ++i) {
|
||||
x = load_word_little(&((const word_t *)block)[i]);
|
||||
a[2][i - 4] = x;
|
||||
}
|
||||
}
|
||||
|
||||
static void replace_last_block(
|
||||
state_t a,
|
||||
const void *block,
|
||||
size_t length_b )
|
||||
{
|
||||
uint8_t t[PI_RATE_BYTES];
|
||||
if (length_b >= PI_RATE_BITS) {
|
||||
/* error */
|
||||
printf("ERROR <%s %s %d>\n", __FILE__, __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
extract_block(t, a);
|
||||
memcpy(t, block, length_b / 8);
|
||||
if (length_b % 8 != 0) {
|
||||
t[length_b / 8] &= 0xff << (length_b % 8);
|
||||
t[length_b / 8] |= ((uint8_t *)block)[length_b / 8];
|
||||
}
|
||||
// t[length_b / 8] ^= 1 << (length_b % 8);
|
||||
replace_block(a, t);
|
||||
}
|
||||
|
||||
|
||||
int PI_INIT(
|
||||
PI_CTX *ctx,
|
||||
const void *key,
|
||||
size_t key_length_b,
|
||||
const void *pmn,
|
||||
size_t pmn_length_b)
|
||||
{
|
||||
int i;
|
||||
uint8_t setup_buf[PI_IS_BITS / 8];
|
||||
if ((key_length_b % 8 != 0) || (pmn_length_b % 8 != 0)) {
|
||||
return -1;
|
||||
}
|
||||
if (key_length_b / 8 + pmn_length_b / 8 + 1 >= PI_IS_BITS / 8) {
|
||||
return -1;
|
||||
}
|
||||
memset(ctx->tag, 0, sizeof(ctx->tag));
|
||||
memset(setup_buf, 0, sizeof(setup_buf));
|
||||
memcpy(setup_buf, key, key_length_b / 8);
|
||||
memcpy(&setup_buf[key_length_b / 8], pmn, pmn_length_b / 8);
|
||||
setup_buf[key_length_b / 8 + pmn_length_b / 8] = 1;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
ctx->cis[i / 4][i % 4] = load_word_little(&setup_buf[i * PI_WORD_SIZE / 8]);
|
||||
}
|
||||
pi((word_t*)ctx->cis);
|
||||
ctx->ctr = 0;
|
||||
for (i = 0; i * PI_WORD_SIZE < 64; ++i) {
|
||||
ctx->ctr |= (uint64_t)ctx->cis[1][i] << (i * PI_WORD_SIZE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PI_PROCESS_AD_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
const void *ad,
|
||||
unsigned long ad_num )
|
||||
{
|
||||
state_t a;
|
||||
ctr_trans(ctx, a, ad_num);
|
||||
inject_block(a, ad);
|
||||
pi((word_t*)a);
|
||||
add_tag(ctx, a);
|
||||
}
|
||||
|
||||
void PI_PROCESS_AD_LAST_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
const void *ad,
|
||||
size_t ad_length_b,
|
||||
unsigned long ad_num )
|
||||
{
|
||||
state_t a;
|
||||
while (ad_length_b >= PI_AD_BLOCK_LENGTH_BITS) {
|
||||
PI_PROCESS_AD_BLOCK(ctx, ad, ad_num);
|
||||
ad_num++;
|
||||
ad_length_b -= PI_AD_BLOCK_LENGTH_BITS;
|
||||
ad = &((uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
|
||||
ctr_trans(ctx, a, ad_num);
|
||||
inject_last_block(a, ad, ad_length_b);
|
||||
pi((word_t*)a);
|
||||
add_tag(ctx, a);
|
||||
ctx->ctr += ad_num;
|
||||
inject_tag(ctx->cis, ctx->tag);
|
||||
pi((word_t*)ctx->cis);
|
||||
}
|
||||
|
||||
void PI_ENCRYPT_SMN(
|
||||
PI_CTX *ctx,
|
||||
void *c0,
|
||||
const void *smn)
|
||||
{
|
||||
ctx->ctr++;
|
||||
ctr_trans(ctx, ctx->cis, 0);
|
||||
inject_block(ctx->cis, smn);
|
||||
if (c0) {
|
||||
extract_block(c0, ctx->cis);
|
||||
}
|
||||
pi((word_t*)ctx->cis);
|
||||
add_tag(ctx, ctx->cis);
|
||||
}
|
||||
|
||||
void PI_DECRYPT_SMN(
|
||||
PI_CTX *ctx,
|
||||
void *smn,
|
||||
const void *c0)
|
||||
{
|
||||
ctx->ctr++;
|
||||
ctr_trans(ctx, ctx->cis, 0);
|
||||
inject_block(ctx->cis, c0);
|
||||
if (smn) {
|
||||
extract_block(smn, ctx->cis);
|
||||
}
|
||||
replace_block(ctx->cis, c0);
|
||||
pi((word_t*)ctx->cis);
|
||||
add_tag(ctx, ctx->cis);
|
||||
}
|
||||
|
||||
void PI_ENCRYPT_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num )
|
||||
{
|
||||
state_t a;
|
||||
ctr_trans(ctx, a, num);
|
||||
inject_block(a, src);
|
||||
if (dest) {
|
||||
extract_block(dest, a);
|
||||
}
|
||||
pi((word_t*)a);
|
||||
add_tag(ctx, a);
|
||||
}
|
||||
|
||||
void PI_ENCRYPT_LAST_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num )
|
||||
{
|
||||
state_t a;
|
||||
while (length_b >= PI_PT_BLOCK_LENGTH_BITS) {
|
||||
PI_ENCRYPT_BLOCK(ctx, dest, src, num);
|
||||
num++;
|
||||
length_b -= PI_PT_BLOCK_LENGTH_BITS;
|
||||
src = &((uint8_t*)src)[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
if (dest) {
|
||||
dest = &((uint8_t*)dest)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
}
|
||||
ctr_trans(ctx, a, num);
|
||||
inject_last_block(a, src, length_b);
|
||||
if (dest) {
|
||||
uint8_t tmp[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
extract_block(tmp, a);
|
||||
memcpy(dest, tmp, (length_b + 7) / 8);
|
||||
}
|
||||
pi((word_t*)a);
|
||||
add_tag(ctx, a);
|
||||
}
|
||||
|
||||
void PI_EXTRACT_TAG(
|
||||
PI_CTX *ctx,
|
||||
void *dest )
|
||||
{
|
||||
uint8_t buf[8 * PI_WORD_SIZE / 8];
|
||||
int i;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
store_word_little(&buf[i * PI_WORD_SIZE / 8], ctx->tag[i]);
|
||||
}
|
||||
memcpy(dest, buf, PI_TAG_BYTES);
|
||||
}
|
||||
|
||||
void PI_DECRYPT_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num )
|
||||
{
|
||||
state_t a;
|
||||
ctr_trans(ctx, a, num);
|
||||
inject_block(a, src);
|
||||
if (dest) {
|
||||
extract_block(dest, a);
|
||||
}
|
||||
replace_block(a, src);
|
||||
pi((word_t*)a);
|
||||
add_tag(ctx, a);
|
||||
}
|
||||
|
||||
#define GET_BIT(buf, addr) ((((uint8_t*)(buf))[(addr) / 8] >> (addr & 7)) & 1)
|
||||
|
||||
void PI_DECRYPT_LAST_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_B,
|
||||
unsigned long num )
|
||||
{
|
||||
state_t a;
|
||||
ctr_trans(ctx, a, num);
|
||||
inject_last_block(a, src, length_B * 8);
|
||||
if (dest) {
|
||||
uint8_t tmp[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
extract_block(tmp, a);
|
||||
memcpy(dest, tmp, length_B);
|
||||
}
|
||||
replace_last_block(a, src, length_B * 8);
|
||||
pi((word_t*)a);
|
||||
add_tag(ctx, a);
|
||||
}
|
||||
|
||||
void PI_ENCRYPT_SIMPLE(
|
||||
void *cipher,
|
||||
size_t *cipher_len_B,
|
||||
const void *msg,
|
||||
size_t msg_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_secret,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
)
|
||||
{
|
||||
unsigned i;
|
||||
PI_CTX ctx;
|
||||
if (PI_INIT(&ctx, key, key_len_B * 8, nonce_public, nonce_public_len_B * 8)) {
|
||||
printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
i = 1;
|
||||
while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) {
|
||||
PI_PROCESS_AD_BLOCK(&ctx, ad, i++);
|
||||
ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES;
|
||||
ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B * 8, i);
|
||||
*cipher_len_B = 0;
|
||||
if (nonce_secret) {
|
||||
PI_ENCRYPT_SMN(&ctx, cipher, nonce_secret);
|
||||
*cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES;
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
i = 1;
|
||||
while (msg_len_B >= PI_PT_BLOCK_LENGTH_BYTES) {
|
||||
PI_ENCRYPT_BLOCK(&ctx, cipher, msg, i++);
|
||||
msg = &((const uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
*cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES;
|
||||
msg_len_B -= PI_PT_BLOCK_LENGTH_BYTES;
|
||||
}
|
||||
PI_ENCRYPT_LAST_BLOCK(&ctx, cipher, msg, msg_len_B * 8, i);
|
||||
cipher = &((uint8_t*)cipher)[msg_len_B];
|
||||
*cipher_len_B += msg_len_B + PI_TAG_BYTES;
|
||||
PI_EXTRACT_TAG(&ctx, cipher);
|
||||
}
|
||||
|
||||
int PI_DECRYPT_SIMPLE(
|
||||
void *msg,
|
||||
size_t *msg_len_B,
|
||||
void *nonce_secret,
|
||||
const void *cipher,
|
||||
size_t cipher_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
)
|
||||
{
|
||||
unsigned i;
|
||||
PI_CTX ctx;
|
||||
|
||||
unsigned long clen = cipher_len_B, alen = ad_len_B;
|
||||
uint8_t bck_c[clen], bck_ad[alen];
|
||||
memcpy(bck_c, cipher, clen);
|
||||
memcpy(bck_ad, ad, alen);
|
||||
|
||||
uint8_t tmp_tag[PI_TAG_BYTES];
|
||||
if (nonce_secret && (cipher_len_B < PI_CT_BLOCK_LENGTH_BYTES + PI_TAG_BYTES)) {
|
||||
return -3;
|
||||
}
|
||||
if (PI_INIT(&ctx, key, key_len_B * 8, nonce_public, nonce_public_len_B * 8)) {
|
||||
printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__);
|
||||
return -2;
|
||||
}
|
||||
i = 1;
|
||||
while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) {
|
||||
PI_PROCESS_AD_BLOCK(&ctx, ad, i++);
|
||||
ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES;
|
||||
ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B * 8, i);
|
||||
*msg_len_B = 0;
|
||||
if (nonce_secret) {
|
||||
PI_DECRYPT_SMN(&ctx, nonce_secret, cipher);
|
||||
cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES;
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
i = 1;
|
||||
while (cipher_len_B - PI_TAG_BYTES >= PI_PT_BLOCK_LENGTH_BYTES) {
|
||||
PI_DECRYPT_BLOCK(&ctx, msg, cipher, i++);
|
||||
msg = &((uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES;
|
||||
*msg_len_B += PI_PT_BLOCK_LENGTH_BYTES;
|
||||
}
|
||||
PI_DECRYPT_LAST_BLOCK(&ctx, msg, cipher, cipher_len_B - PI_TAG_BYTES, i);
|
||||
*msg_len_B += cipher_len_B - PI_TAG_BYTES;
|
||||
cipher = &((uint8_t*)cipher)[cipher_len_B - PI_TAG_BYTES];
|
||||
PI_EXTRACT_TAG(&ctx, tmp_tag);
|
||||
if (memcmp(tmp_tag, cipher, PI_TAG_BYTES)) {
|
||||
#if DEBUG
|
||||
printf("DBG: verification failed: clen = %lu; alen = %lu\n", clen, alen);
|
||||
printf("Key:\n");
|
||||
hexdump_block(key, key_len_B, 4, 16);
|
||||
printf("\nNonce:\n");
|
||||
hexdump_block(nonce_public, nonce_public_len_B, 4, 16);
|
||||
printf("\nAD:\n");
|
||||
hexdump_block(bck_ad, alen, 4, 16);
|
||||
printf("\nCiphertext:\n");
|
||||
hexdump_block(bck_c, clen, 4, 16);
|
||||
printf("\nShould-Tag:\n");
|
||||
hexdump_block(cipher, PI_TAG_BYTES, 4, 16);
|
||||
printf("\nIS-Tag:\n");
|
||||
hexdump_block(tmp_tag, PI_TAG_BYTES, 4, 16);
|
||||
puts("");
|
||||
#endif /* DEBUG */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/* pi-cipher.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2015 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PI_CIPHER_H_
|
||||
#define PI_CIPHER_H_
|
||||
|
||||
/* please define PI_SIZE acoording to the primitive to implement (pi16cipher, pi32cipher or pi64cipher) */
|
||||
/* # define PI_SIZE 16 */
|
||||
|
||||
#ifdef SUPERCOP
|
||||
#include "ecrypt-portable.h"
|
||||
typedef u8 uint8_t;
|
||||
typedef u16 uint16_t;
|
||||
typedef u32 uint32_t;
|
||||
typedef u64 uint64_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#if PI_SIZE == 16
|
||||
#include "pi16_parameter.h"
|
||||
#elif PI_SIZE == 32
|
||||
#include "pi32_parameter.h"
|
||||
#elif PI_SIZE == 64
|
||||
#include "pi64_parameter.h"
|
||||
#else
|
||||
#error please define PI_SIZE
|
||||
#endif
|
||||
|
||||
#define PI_N 4
|
||||
|
||||
#define PI_IS_BITS (4 * PI_N * PI_WORD_SIZE)
|
||||
#define PI_IS_BYTES PI_IS_BITS / 8
|
||||
|
||||
#define PI_RATE_BITS (PI_IS_BITS / 2)
|
||||
#define PI_CAPACITY_BITS PI_BITS - PI_RATE_BITS
|
||||
|
||||
#define PI_RATE_BYTES (PI_RATE_BITS / 8)
|
||||
#define PI_CAPACITY_BYTES (PI_CAPACITY_BITS / 8)
|
||||
|
||||
#define PI_SMN_LENGTH_BITS PI_RATE_BITS
|
||||
#define PI_SMN_LENGTH_BYTES (PI_RATE_BITS / 8)
|
||||
|
||||
#define PI_AD_BLOCK_LENGTH_BITS PI_RATE_BITS
|
||||
#define PI_AD_BLOCK_LENGTH_BYTES (PI_AD_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI_PT_BLOCK_LENGTH_BITS PI_RATE_BITS
|
||||
#define PI_PT_BLOCK_LENGTH_BYTES (PI_PT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI_CT_BLOCK_LENGTH_BITS PI_RATE_BITS
|
||||
#define PI_CT_BLOCK_LENGTH_BYTES (PI_CT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI_ROUNDS 3
|
||||
|
||||
#define PI_MU_V_CONST { 3, 2, 1, 0 }
|
||||
#define PI_NY_V_CONST { 1, 0, 3, 2 }
|
||||
|
||||
|
||||
#define XSTR(x) STR(x)
|
||||
#define STR(x) #x
|
||||
|
||||
#define CTX_NAME(x) pi ## x ## _ctx_t
|
||||
#define INIT_NAME(x) pi ## x ## _init
|
||||
#define PROCESS_AD_BLOCK_NAME(x) pi ## x ## _process_ad_block
|
||||
#define PROCESS_AD_LAST_BLOCK_NAME(x) pi ## x ## _process_ad_last_block
|
||||
#define ENCRYPT_SMN_NAME(x) pi ## x ## _encrypt_smn
|
||||
#define DECRYPT_SMN_NAME(x) pi ## x ## _decrypt_smn
|
||||
#define ENCRYPT_BLOCK_NAME(x) pi ## x ## _encrypt_block
|
||||
#define ENCRYPT_LAST_BLOCK_NAME(x) pi ## x ## _encrypt_last_block
|
||||
#define EXTRACT_TAG_NAME(x) pi ## x ## _extract_tag
|
||||
#define DECRYPT_BLOCK_NAME(x) pi ## x ## _decrypt_block
|
||||
#define DECRYPT_LAST_BLOCK_NAME(x) pi ## x ## _decrypt_last_block
|
||||
#define ENCRYPT_SIMPLE_NAME(x) pi ## x ## _encrypt_simple
|
||||
#define DECRYPT_SIMPLE_NAME(x) pi ## x ## _decrypt_simple
|
||||
#define CIPHER_NAME(x) pi ## x ## cipher
|
||||
#define CIPHER_NAME_X(x) pi ## x ## _cipher_name
|
||||
|
||||
#define NAME(f,x) f(x)
|
||||
|
||||
#define PI_CTX NAME(CTX_NAME, PI_WORD_SIZE)
|
||||
#define PI_INIT NAME(INIT_NAME, PI_WORD_SIZE)
|
||||
#define PI_PROCESS_AD_BLOCK NAME(PROCESS_AD_BLOCK_NAME, PI_WORD_SIZE)
|
||||
#define PI_PROCESS_AD_LAST_BLOCK NAME(PROCESS_AD_LAST_BLOCK_NAME, PI_WORD_SIZE)
|
||||
#define PI_ENCRYPT_SMN NAME(ENCRYPT_SMN_NAME, PI_WORD_SIZE)
|
||||
#define PI_DECRYPT_SMN NAME(DECRYPT_SMN_NAME, PI_WORD_SIZE)
|
||||
#define PI_ENCRYPT_BLOCK NAME(ENCRYPT_BLOCK_NAME, PI_WORD_SIZE)
|
||||
#define PI_ENCRYPT_LAST_BLOCK NAME(ENCRYPT_LAST_BLOCK_NAME, PI_WORD_SIZE)
|
||||
#define PI_EXTRACT_TAG NAME(EXTRACT_TAG_NAME, PI_WORD_SIZE)
|
||||
#define PI_DECRYPT_BLOCK NAME(DECRYPT_BLOCK_NAME, PI_WORD_SIZE)
|
||||
#define PI_DECRYPT_LAST_BLOCK NAME(DECRYPT_LAST_BLOCK_NAME, PI_WORD_SIZE)
|
||||
#define PI_ENCRYPT_SIMPLE NAME(ENCRYPT_SIMPLE_NAME, PI_WORD_SIZE)
|
||||
#define PI_DECRYPT_SIMPLE NAME(DECRYPT_SIMPLE_NAME, PI_WORD_SIZE)
|
||||
#define PI_CIPHER_NAME NAME(CIPHER_NAME, PI_WORD_SIZE)
|
||||
#define PI_CIPHER_NAME_X NAME(CIPHER_NAME_X, PI_WORD_SIZE)
|
||||
|
||||
|
||||
|
||||
extern const char* PI_CIPHER_NAME_X;
|
||||
|
||||
typedef struct {
|
||||
word_t cis[4][4];
|
||||
word_t tag[8];
|
||||
uint64_t ctr;
|
||||
} PI_CTX;
|
||||
|
||||
int PI_INIT(
|
||||
PI_CTX *ctx,
|
||||
const void *key,
|
||||
size_t key_length_b,
|
||||
const void *pmn,
|
||||
size_t pmn_length_b);
|
||||
|
||||
void PI_PROCESS_AD_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
const void *ad,
|
||||
unsigned long ad_num );
|
||||
|
||||
void PI_PROCESS_AD_LAST_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
const void *ad,
|
||||
size_t ad_length_b,
|
||||
unsigned long ad_num );
|
||||
|
||||
void PI_ENCRYPT_SMN(
|
||||
PI_CTX *ctx,
|
||||
void *c0,
|
||||
const void *smn);
|
||||
|
||||
void PI_DECRYPT_SMN(
|
||||
PI_CTX *ctx,
|
||||
void *smn,
|
||||
const void *c0);
|
||||
|
||||
void PI_ENCRYPT_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void PI_ENCRYPT_LAST_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void PI_EXTRACT_TAG(
|
||||
PI_CTX *ctx,
|
||||
void *dest );
|
||||
|
||||
void PI_DECRYPT_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void PI_DECRYPT_LAST_BLOCK(
|
||||
PI_CTX *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void PI_ENCRYPT_SIMPLE(
|
||||
void *cipher,
|
||||
size_t *cipher_len_B,
|
||||
const void *msg,
|
||||
size_t msg_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_secret,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
int PI_DECRYPT_SIMPLE(
|
||||
void *msg,
|
||||
size_t *msg_len_B,
|
||||
void *nonce_secret,
|
||||
const void *cipher,
|
||||
size_t cipher_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
#endif /* PI_CIPHER_H_ */
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* pi16_parameter.h
|
||||
*
|
||||
* Created on: 07.09.2015
|
||||
* Author: bg
|
||||
*/
|
||||
|
||||
#ifndef PI16_PARAMETER_H_
|
||||
#define PI16_PARAMETER_H_
|
||||
|
||||
typedef uint16_t word_t;
|
||||
|
||||
#define PI_WORD_SIZE 16
|
||||
|
||||
#define PI_TAG_BITS 128
|
||||
#define PI_TAG_BYTES (PI_TAG_BITS / 8)
|
||||
|
||||
|
||||
#endif /* PI16_PARAMETER_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,325 @@
|
|||
/* pi16cipher.c */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define PI_SIZE 16
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "pi-cipher.h"
|
||||
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if (PI_WORD_SIZE == 16)
|
||||
# define load_word_little(mem) load_u16_little(mem)
|
||||
# define store_word_little(mem, val) store_u16_little((mem), (val))
|
||||
# define PRI_xw "04"PRIx16
|
||||
|
||||
|
||||
#elif (PI_WORD_SIZE == 32)
|
||||
# define load_word_little(mem) load_u32_little(mem)
|
||||
# define store_word_little(mem, val) store_u32_little((mem), (val))
|
||||
# define PRI_xw "08"PRIx32
|
||||
|
||||
static uint32_t load_u32_little(const void *mem)
|
||||
{
|
||||
uint32_t ret;
|
||||
const uint8_t *x = (const uint8_t *)mem;
|
||||
ret = (uint32_t)x[0] << 0
|
||||
| (uint32_t)x[1] << 8
|
||||
| (uint32_t)x[2] << 16
|
||||
| (uint32_t)x[3] << 24;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void store_u32_little(void *mem, uint32_t val)
|
||||
{
|
||||
uint8_t *x = (uint8_t *)mem;
|
||||
x[0] = val & 0xff; val >>= 8;
|
||||
x[1] = val & 0xff; val >>= 8;
|
||||
x[2] = val & 0xff; val >>= 8;
|
||||
x[3] = val & 0xff;
|
||||
}
|
||||
|
||||
#elif (PI_WORD_SIZE == 64)
|
||||
# define load_word_little(mem) load_u64_little(mem)
|
||||
# define store_word_little(mem, val) store_u64_little((mem), (val))
|
||||
# define PRI_xw "016"PRIx64
|
||||
|
||||
static uint64_t load_u64_little(const void *mem)
|
||||
{
|
||||
uint64_t ret;
|
||||
const uint8_t *x = (const uint8_t *)mem;
|
||||
ret = (uint64_t)x[0] << 0
|
||||
| (uint64_t)x[1] << 8
|
||||
| (uint64_t)x[2] << 16
|
||||
| (uint64_t)x[3] << 24
|
||||
| (uint64_t)x[4] << 32
|
||||
| (uint64_t)x[5] << 40
|
||||
| (uint64_t)x[6] << 48
|
||||
| (uint64_t)x[7] << 56;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void store_u64_little(void *mem, uint64_t val)
|
||||
{
|
||||
uint8_t *x = (uint8_t *)mem;
|
||||
x[0] = val & 0xff; val >>= 8;
|
||||
x[1] = val & 0xff; val >>= 8;
|
||||
x[2] = val & 0xff; val >>= 8;
|
||||
x[3] = val & 0xff; val >>= 8;
|
||||
x[4] = val & 0xff; val >>= 8;
|
||||
x[5] = val & 0xff; val >>= 8;
|
||||
x[6] = val & 0xff; val >>= 8;
|
||||
x[7] = val & 0xff;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef word_t state_t[4][4];
|
||||
const char* PI_CIPHER_NAME_X = XSTR(PI_CIPHER_NAME);
|
||||
|
||||
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
size_t dbg_l;
|
||||
const uint8_t *dbg_x;
|
||||
uint8_t dump;
|
||||
|
||||
|
||||
static
|
||||
void hexdump_block(
|
||||
const void *data,
|
||||
size_t length,
|
||||
unsigned short indent,
|
||||
unsigned short width)
|
||||
{
|
||||
unsigned short column = 0;
|
||||
char f = 0;
|
||||
while (length--) {
|
||||
if (column == 0) {
|
||||
unsigned short i;
|
||||
if (f) {
|
||||
putchar('\n');
|
||||
} else {
|
||||
f = 1;
|
||||
}
|
||||
for (i = 0; i < indent; ++i) {
|
||||
putchar(' ');
|
||||
}
|
||||
column = width;
|
||||
}
|
||||
column -= 1;
|
||||
printf("%02x ", *((unsigned char *)data));
|
||||
data = (void *)((char *)data + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void dump_state(const word_t* a)
|
||||
{
|
||||
if (dump || 1) {
|
||||
printf("\tCIS:\n");
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n", a[ 0], a[ 1], a[ 2], a[ 3]);
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n", a[ 4], a[ 5], a[ 6], a[ 7]);
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n", a[ 8], a[ 9], a[10], a[11]);
|
||||
printf("\t%"PRI_xw" %"PRI_xw" %"PRI_xw" %"PRI_xw"\n\n", a[12], a[13], a[14], a[15]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define printf(...)
|
||||
#endif
|
||||
|
||||
void pi(
|
||||
word_t *a );
|
||||
|
||||
void add_tag(
|
||||
PI_CTX *ctx,
|
||||
state_t a );
|
||||
|
||||
void ctr_trans(
|
||||
const PI_CTX *ctx,
|
||||
state_t a,
|
||||
uint32_t ctr );
|
||||
|
||||
void inject_tag(
|
||||
state_t a,
|
||||
const word_t x[8] );
|
||||
|
||||
|
||||
void extract_block(
|
||||
void *block,
|
||||
state_t a);
|
||||
|
||||
void inject_block(
|
||||
state_t a,
|
||||
const void *block );
|
||||
|
||||
void inject_last_block(
|
||||
state_t a,
|
||||
const void *block,
|
||||
size_t length_B );
|
||||
|
||||
void replace_block(
|
||||
state_t a,
|
||||
const void *block );
|
||||
|
||||
void replace_last_block(
|
||||
state_t a,
|
||||
const void *block,
|
||||
size_t length_B );
|
||||
/*
|
||||
void PI_ENCRYPT_SIMPLE(
|
||||
void *cipher,
|
||||
size_t *cipher_len_B,
|
||||
void *tag,
|
||||
size_t *tag_length_B,
|
||||
const void *msg,
|
||||
size_t msg_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_secret,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
)
|
||||
{
|
||||
unsigned i;
|
||||
PI_CTX ctx;
|
||||
if (PI_INIT(&ctx, key, key_len_B, nonce_public, nonce_public_len_B)) {
|
||||
printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__);
|
||||
return;
|
||||
}
|
||||
i = 1;
|
||||
while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) {
|
||||
PI_PROCESS_AD_BLOCK(&ctx, ad, i++);
|
||||
ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES;
|
||||
ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B, i);
|
||||
*cipher_len_B = 0;
|
||||
if (nonce_secret) {
|
||||
PI_ENCRYPT_SMN(&ctx, cipher, nonce_secret);
|
||||
*cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES;
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
i = 1;
|
||||
/ *
|
||||
while (msg_len_B >= PI_PT_BLOCK_LENGTH_BYTES) {
|
||||
PI_ENCRYPT_BLOCK(&ctx, cipher, msg, i++);
|
||||
msg = &((const uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
*cipher_len_B += PI_CT_BLOCK_LENGTH_BYTES;
|
||||
msg_len_B -= PI_PT_BLOCK_LENGTH_BYTES;
|
||||
}
|
||||
* /
|
||||
PI_ENCRYPT_LAST_BLOCK(&ctx, cipher, msg, msg_len_B, i);
|
||||
*cipher_len_B += msg_len_B;
|
||||
PI_EXTRACT_TAG(&ctx, tag);
|
||||
if (tag_length_B) {
|
||||
*tag_length_B = PI_TAG_BYTES;
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
int PI_DECRYPT_SIMPLE(
|
||||
void *msg,
|
||||
size_t *msg_len_B,
|
||||
void *nonce_secret,
|
||||
const void *cipher,
|
||||
size_t cipher_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
)
|
||||
{
|
||||
unsigned i;
|
||||
PI_CTX ctx;
|
||||
|
||||
unsigned long clen = cipher_len_B, alen = ad_len_B;
|
||||
uint8_t bck_c[clen], bck_ad[alen];
|
||||
memcpy(bck_c, cipher, clen);
|
||||
memcpy(bck_ad, ad, alen);
|
||||
|
||||
uint8_t tmp_tag[PI_TAG_BYTES];
|
||||
if (nonce_secret && (cipher_len_B < PI_CT_BLOCK_LENGTH_BYTES + PI_TAG_BYTES)) {
|
||||
return -3;
|
||||
}
|
||||
if (PI_INIT(&ctx, key, key_len_B, nonce_public, nonce_public_len_B)) {
|
||||
printf("ERROR! <%s %s %d>\n", __FILE__, __func__, __LINE__);
|
||||
return -2;
|
||||
}
|
||||
i = 1;
|
||||
while (ad_len_B >= PI_AD_BLOCK_LENGTH_BYTES) {
|
||||
PI_PROCESS_AD_BLOCK(&ctx, ad, i++);
|
||||
ad_len_B -= PI_AD_BLOCK_LENGTH_BYTES;
|
||||
ad = &((const uint8_t*)ad)[PI_AD_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
PI_PROCESS_AD_LAST_BLOCK(&ctx, ad, ad_len_B, i);
|
||||
*msg_len_B = 0;
|
||||
if (nonce_secret) {
|
||||
PI_DECRYPT_SMN(&ctx, nonce_secret, cipher);
|
||||
cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES;
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
}
|
||||
i = 1;
|
||||
while (cipher_len_B - PI_TAG_BYTES >= PI_PT_BLOCK_LENGTH_BYTES) {
|
||||
PI_DECRYPT_BLOCK(&ctx, msg, cipher, i++);
|
||||
msg = &((uint8_t*)msg)[PI_PT_BLOCK_LENGTH_BYTES];
|
||||
cipher = &((uint8_t*)cipher)[PI_CT_BLOCK_LENGTH_BYTES];
|
||||
cipher_len_B -= PI_CT_BLOCK_LENGTH_BYTES;
|
||||
*msg_len_B += PI_PT_BLOCK_LENGTH_BYTES;
|
||||
}
|
||||
PI_DECRYPT_LAST_BLOCK(&ctx, msg, cipher, cipher_len_B - PI_TAG_BYTES, i);
|
||||
*msg_len_B += cipher_len_B - PI_TAG_BYTES;
|
||||
cipher = &((uint8_t*)cipher)[cipher_len_B - PI_TAG_BYTES];
|
||||
PI_EXTRACT_TAG(&ctx, tmp_tag);
|
||||
if (memcmp(tmp_tag, cipher, PI_TAG_BYTES)) {
|
||||
#if DEBUG
|
||||
printf("DBG: verification failed: clen = %lu; alen = %lu\n", clen, alen);
|
||||
printf("Key:\n");
|
||||
hexdump_block(key, key_len_B, 4, 16);
|
||||
printf("\nNonce:\n");
|
||||
hexdump_block(nonce_public, nonce_public_len_B, 4, 16);
|
||||
printf("\nAD:\n");
|
||||
hexdump_block(bck_ad, alen, 4, 16);
|
||||
printf("\nCiphertext:\n");
|
||||
hexdump_block(bck_c, clen, 4, 16);
|
||||
printf("\nShould-Tag:\n");
|
||||
hexdump_block(cipher, PI_TAG_BYTES, 4, 16);
|
||||
printf("\nIS-Tag:\n");
|
||||
hexdump_block(tmp_tag, PI_TAG_BYTES, 4, 16);
|
||||
puts("");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,146 @@
|
|||
/* pi16cipher.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2015 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PI16CIPHER_H_
|
||||
#define PI16CIPHER_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define PI16_WORD_SIZE 16
|
||||
#define PI16_N 4
|
||||
|
||||
#define PI16_IS_BITS (4 * PI16_N * PI16_WORD_SIZE)
|
||||
|
||||
#define PI16_RATE_BITS (PI16_IS_BITS / 2)
|
||||
#define PI16_CAPACITY_BITS PI16_BITS - PI16_RATE_BITS
|
||||
|
||||
#define PI16_RATE_BYTES (PI16_RATE_BITS / 8)
|
||||
#define PI16_CAPACITY_BYTES (PI16_CAPACITY_BITS / 8)
|
||||
|
||||
#define PI16_SMN_LENGTH_BITS PI16_RATE_BITS
|
||||
#define PI16_SMN_LENGTH_BYTES (PI16_RATE_BITS / 8)
|
||||
|
||||
#define PI16_AD_BLOCK_LENGTH_BITS PI16_RATE_BITS
|
||||
#define PI16_AD_BLOCK_LENGTH_BYTES (PI16_AD_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI16_PT_BLOCK_LENGTH_BITS PI16_RATE_BITS
|
||||
#define PI16_PT_BLOCK_LENGTH_BYTES (PI16_PT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI16_CT_BLOCK_LENGTH_BITS PI16_RATE_BITS
|
||||
#define PI16_CT_BLOCK_LENGTH_BYTES (PI16_CT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI16_ROUNDS 3
|
||||
|
||||
extern const char* pi16_cipher_name;
|
||||
|
||||
typedef struct {
|
||||
uint16_t cis[4][4];
|
||||
uint16_t tag[8];
|
||||
uint64_t ctr;
|
||||
} pi16_ctx_t;
|
||||
|
||||
int pi16_init(
|
||||
pi16_ctx_t *ctx,
|
||||
const void *key,
|
||||
size_t key_length_b,
|
||||
const void *pmn,
|
||||
size_t pmn_length_b);
|
||||
|
||||
void pi16_process_ad_block(
|
||||
pi16_ctx_t *ctx,
|
||||
const void *ad,
|
||||
unsigned long ad_num );
|
||||
|
||||
void pi16_process_ad_last_block(
|
||||
pi16_ctx_t *ctx,
|
||||
const void *ad,
|
||||
size_t ad_length_b,
|
||||
unsigned long ad_num );
|
||||
|
||||
void pi16_encrypt_smn(
|
||||
pi16_ctx_t *ctx,
|
||||
void *c0,
|
||||
const void *smn);
|
||||
|
||||
void pi16_decrypt_smn(
|
||||
pi16_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi16_encrypt_block(
|
||||
pi16_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi16_encrypt_last_block(
|
||||
pi16_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void pi16_extract_tag(
|
||||
pi16_ctx_t *ctx,
|
||||
void *dest );
|
||||
|
||||
void pi16_decrypt_block(
|
||||
pi16_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi16_decrypt_last_block(
|
||||
pi16_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void pi16_encrypt_simple(
|
||||
void *cipher,
|
||||
size_t *cipher_len_B,
|
||||
const void *msg,
|
||||
size_t msg_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_secret,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
int pi16_decrypt_simple(
|
||||
void *msg,
|
||||
size_t *msg_len_B,
|
||||
void *nonce_secret,
|
||||
const void *cipher,
|
||||
size_t cipher_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
#endif /* PI16CIPHER_H_ */
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* pi32_parameter.h
|
||||
*
|
||||
* Created on: 2015-09-11
|
||||
* Author: bg
|
||||
*/
|
||||
|
||||
#ifndef PI32_PARAMETER_H_
|
||||
#define PI32_PARAMETER_H_
|
||||
|
||||
typedef uint32_t word_t;
|
||||
|
||||
#define PI_WORD_SIZE 32
|
||||
|
||||
#define PI_TAG_BITS 256
|
||||
#define PI_TAG_BYTES (PI_TAG_BITS / 8)
|
||||
|
||||
|
||||
/*mu-transformation*/ \
|
||||
#define PI_MU_CONST { \
|
||||
0xF0E8E4E2, \
|
||||
0xE1D8D4D2, \
|
||||
0xD1CCCAC9, \
|
||||
0xC6C5C3B8 \
|
||||
}
|
||||
|
||||
/*nu-transformation*/ \
|
||||
#define PI_NY_CONST { \
|
||||
0xB4B2B1AC, \
|
||||
0xAAA9A6A5, \
|
||||
0xA39C9A99, \
|
||||
0x9695938E \
|
||||
}
|
||||
|
||||
|
||||
/* FIXME */
|
||||
#if 0
|
||||
#define PI_MU_CONST { \
|
||||
0x8D8B8778, \
|
||||
0x7472716C, \
|
||||
0x6A696665, \
|
||||
0x635C5A59 \
|
||||
}
|
||||
|
||||
#define PI_NY_CONST { \
|
||||
0x5655534E, \
|
||||
0x4D4B473C, \
|
||||
0x3A393635, \
|
||||
0x332E2D2B \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PI_MU_ROT_CONST { 5, 11, 17, 23 }
|
||||
|
||||
#define PI_NY_ROT_CONST { 3, 10, 19, 29 }
|
||||
|
||||
#define PI_CONST { \
|
||||
{ 0x8D8B8778, 0x7472716C, 0x6A696665, 0x635C5A59 }, \
|
||||
{ 0x5655534E, 0x4D4B473C, 0x3A393635, 0x332E2D2B }, \
|
||||
{ 0x271E1D1B, 0x170FF0E8, 0xE4E2E1D8, 0xD4D2D1CC }, \
|
||||
{ 0xCAC9C6C5, 0xC3B8B4B2, 0xB1ACAAA9, 0xA6A5A39C }, \
|
||||
{ 0x9A999695, 0x938E8D8B, 0x87787472, 0x716C6A69 }, \
|
||||
{ 0x6665635C, 0x5A595655, 0x534E4D4B, 0x473C3A39 } \
|
||||
}
|
||||
|
||||
|
||||
#endif /* PI32_PARAMETER_H_ */
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
#define PI_SIZE 32
|
||||
#include "pi-cipher.c"
|
|
@ -0,0 +1,146 @@
|
|||
/* pi32cipher.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2015 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PI32CIPHER_H_
|
||||
#define PI32CIPHER_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define PI32_WORD_SIZE 32
|
||||
#define PI32_N 4
|
||||
|
||||
#define PI32_IS_BITS (4 * PI32_N * PI32_WORD_SIZE)
|
||||
|
||||
#define PI32_RATE_BITS (PI32_IS_BITS / 2)
|
||||
#define PI32_CAPACITY_BITS PI32_BITS - PI32_RATE_BITS
|
||||
|
||||
#define PI32_RATE_BYTES (PI32_RATE_BITS / 8)
|
||||
#define PI32_CAPACITY_BYTES (PI32_CAPACITY_BITS / 8)
|
||||
|
||||
#define PI32_SMN_LENGTH_BITS PI32_RATE_BITS
|
||||
#define PI32_SMN_LENGTH_BYTES (PI32_RATE_BITS / 8)
|
||||
|
||||
#define PI32_AD_BLOCK_LENGTH_BITS PI32_RATE_BITS
|
||||
#define PI32_AD_BLOCK_LENGTH_BYTES (PI32_AD_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI32_PT_BLOCK_LENGTH_BITS PI32_RATE_BITS
|
||||
#define PI32_PT_BLOCK_LENGTH_BYTES (PI32_PT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI32_CT_BLOCK_LENGTH_BITS PI32_RATE_BITS
|
||||
#define PI32_CT_BLOCK_LENGTH_BYTES (PI32_CT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI32_ROUNDS 3
|
||||
|
||||
extern const char* pi32_cipher_name;
|
||||
|
||||
typedef struct {
|
||||
uint32_t cis[4][4];
|
||||
uint32_t tag[8];
|
||||
uint64_t ctr;
|
||||
} pi32_ctx_t;
|
||||
|
||||
int pi32_init(
|
||||
pi32_ctx_t *ctx,
|
||||
const void *key,
|
||||
size_t key_length_b,
|
||||
const void *pmn,
|
||||
size_t pmn_length_b);
|
||||
|
||||
void pi32_process_ad_block(
|
||||
pi32_ctx_t *ctx,
|
||||
const void *ad,
|
||||
unsigned long ad_num );
|
||||
|
||||
void pi32_process_last_ad_block(
|
||||
pi32_ctx_t *ctx,
|
||||
const void *ad,
|
||||
size_t ad_length_b,
|
||||
unsigned long ad_num );
|
||||
|
||||
void pi32_process_smn(
|
||||
pi32_ctx_t *ctx,
|
||||
void *c0,
|
||||
const void *smn);
|
||||
|
||||
void pi32_decrypt_smn(
|
||||
pi32_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi32_encrypt_block(
|
||||
pi32_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi32_encrypt_last_block(
|
||||
pi32_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void pi32_extract_tag(
|
||||
pi32_ctx_t *ctx,
|
||||
void *dest );
|
||||
|
||||
void pi32_decrypt_block(
|
||||
pi32_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi32_decrypt_last_block(
|
||||
pi32_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void pi32_encrypt_simple(
|
||||
void *cipher,
|
||||
size_t *cipher_len_B,
|
||||
const void *msg,
|
||||
size_t msg_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_secret,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
int pi32_decrypt_simple(
|
||||
void *msg,
|
||||
size_t *msg_len_B,
|
||||
void *nonce_secret,
|
||||
const void *cipher,
|
||||
size_t cipher_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
#endif /* PI32CIPHER_H_ */
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* pi64_parameter.h
|
||||
*
|
||||
* Created on: 2015-09-12
|
||||
* Author: bg
|
||||
*/
|
||||
|
||||
#ifndef PI64_PARAMETER_H_
|
||||
#define PI64_PARAMETER_H_
|
||||
|
||||
typedef uint64_t word_t;
|
||||
|
||||
#define PI_WORD_SIZE 64
|
||||
|
||||
#define PI_TAG_BITS 512
|
||||
#define PI_TAG_BYTES (PI_TAG_BITS / 8)
|
||||
|
||||
#define PI_MU_CONST { \
|
||||
0xF0E8E4E2E1D8D4D2, \
|
||||
0xD1CCCAC9C6C5C3B8, \
|
||||
0xB4B2B1ACAAA9A6A5, \
|
||||
0xA39C9A999695938E \
|
||||
}
|
||||
|
||||
#define PI_MU_ROT_CONST { 7, 19, 31, 53 }
|
||||
|
||||
#define PI_NY_CONST { \
|
||||
0x8D8B87787472716C, \
|
||||
0x6A696665635C5A59, \
|
||||
0x5655534E4D4B473C, \
|
||||
0x3A393635332E2D2B \
|
||||
}
|
||||
|
||||
#define PI_NY_ROT_CONST { 11, 23, 37, 59 }
|
||||
|
||||
#define PI_CONST { \
|
||||
{ 0x271E1D1B170FF0E8, 0xE4E2E1D8D4D2D1CC, 0xCAC9C6C5C3B8B4B2, 0xB1ACAAA9A6A5A39C }, \
|
||||
{ 0x9A999695938E8D8B, 0x87787472716C6A69, 0x6665635C5A595655, 0x534E4D4B473C3A39 }, \
|
||||
{ 0x3635332E2D2B271E, 0x1D1B170FF0E8E4E2, 0xE1D8D4D2D1CCCAC9, 0xC6C5C3B8B4B2B1AC }, \
|
||||
{ 0xAAA9A6A5A39C9A99, 0x9695938E8D8B8778, 0x7472716C6A696665, 0x635C5A595655534E }, \
|
||||
{ 0x4D4B473C3A393635, 0x332E2D2B271E1D1B, 0x170FF0E8E4E2E1D8, 0xD4D2D1CCCAC9C6C5 }, \
|
||||
{ 0xC3B8B4B2B1ACAAA9, 0xA6A5A39C9A999695, 0x938E8D8B87787472, 0x716C6A696665635C } \
|
||||
}
|
||||
|
||||
|
||||
#endif /* PI64_PARAMETER_H_ */
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
#define PI_SIZE 64
|
||||
#include "pi-cipher.c"
|
|
@ -0,0 +1,146 @@
|
|||
/* pi64cipher.h */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2015 Daniel Otte (daniel.otte@rub.de)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PI64CIPHER_H_
|
||||
#define PI64CIPHER_H_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define PI64_WORD_SIZE 64
|
||||
#define PI64_N 4
|
||||
|
||||
#define PI64_IS_BITS (4 * PI64_N * PI64_WORD_SIZE)
|
||||
|
||||
#define PI64_RATE_BITS (PI64_IS_BITS / 2)
|
||||
#define PI64_CAPACITY_BITS PI64_BITS - PI64_RATE_BITS
|
||||
|
||||
#define PI64_RATE_BYTES (PI64_RATE_BITS / 8)
|
||||
#define PI64_CAPACITY_BYTES (PI64_CAPACITY_BITS / 8)
|
||||
|
||||
#define PI64_SMN_LENGTH_BITS PI64_RATE_BITS
|
||||
#define PI64_SMN_LENGTH_BYTES (PI64_RATE_BITS / 8)
|
||||
|
||||
#define PI64_AD_BLOCK_LENGTH_BITS PI64_RATE_BITS
|
||||
#define PI64_AD_BLOCK_LENGTH_BYTES (PI64_AD_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI64_PT_BLOCK_LENGTH_BITS PI64_RATE_BITS
|
||||
#define PI64_PT_BLOCK_LENGTH_BYTES (PI64_PT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI64_CT_BLOCK_LENGTH_BITS PI64_RATE_BITS
|
||||
#define PI64_CT_BLOCK_LENGTH_BYTES (PI64_CT_BLOCK_LENGTH_BITS / 8)
|
||||
|
||||
#define PI64_ROUNDS 3
|
||||
|
||||
extern const char* pi64_cipher_name;
|
||||
|
||||
typedef struct {
|
||||
uint64_t cis[4][4];
|
||||
uint64_t tag[8];
|
||||
uint64_t ctr;
|
||||
} pi64_ctx_t;
|
||||
|
||||
int pi64_init(
|
||||
pi64_ctx_t *ctx,
|
||||
const void *key,
|
||||
size_t key_length_b,
|
||||
const void *pmn,
|
||||
size_t pmn_length_b);
|
||||
|
||||
void pi64_process_ad_block(
|
||||
pi64_ctx_t *ctx,
|
||||
const void *ad,
|
||||
unsigned long ad_num );
|
||||
|
||||
void pi64_process_last_ad_block(
|
||||
pi64_ctx_t *ctx,
|
||||
const void *ad,
|
||||
size_t ad_length_b,
|
||||
unsigned long ad_num );
|
||||
|
||||
void pi64_process_smn(
|
||||
pi64_ctx_t *ctx,
|
||||
void *c0,
|
||||
const void *smn);
|
||||
|
||||
void pi64_decrypt_smn(
|
||||
pi64_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi64_encrypt_block(
|
||||
pi64_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi64_encrypt_last_block(
|
||||
pi64_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void pi64_extract_tag(
|
||||
pi64_ctx_t *ctx,
|
||||
void *dest );
|
||||
|
||||
void pi64_decrypt_block(
|
||||
pi64_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
unsigned long num );
|
||||
|
||||
void pi64_decrypt_last_block(
|
||||
pi64_ctx_t *ctx,
|
||||
void *dest,
|
||||
const void *src,
|
||||
size_t length_b,
|
||||
unsigned long num );
|
||||
|
||||
void pi64_encrypt_simple(
|
||||
void *cipher,
|
||||
size_t *cipher_len_B,
|
||||
const void *msg,
|
||||
size_t msg_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_secret,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
int pi64_decrypt_simple(
|
||||
void *msg,
|
||||
size_t *msg_len_B,
|
||||
void *nonce_secret,
|
||||
const void *cipher,
|
||||
size_t cipher_len_B,
|
||||
const void *ad,
|
||||
size_t ad_len_B,
|
||||
const void *nonce_public,
|
||||
size_t nonce_public_len_B,
|
||||
const void *key,
|
||||
size_t key_len_B
|
||||
);
|
||||
|
||||
#endif /* PI64CIPHER_H_ */
|
|
@ -0,0 +1,318 @@
|
|||
/* main-picipher-test.c */
|
||||
/*
|
||||
This file is part of the AVR-Crypto-Lib.
|
||||
Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "main-test-common.h"
|
||||
|
||||
#include <pi16cipher.h>
|
||||
#include <pi32cipher.h>
|
||||
#include <pi64cipher.h>
|
||||
|
||||
#include <arcfour.h>
|
||||
#include "performance_test.h"
|
||||
|
||||
char *algo_name = "pi16cipher";
|
||||
|
||||
/*****************************************************************************
|
||||
* additional validation-functions *
|
||||
*****************************************************************************/
|
||||
|
||||
#define DUMP_LEN(x, s) do { \
|
||||
printf("%s", "\n\n" #x ":"); \
|
||||
cli_hexdump_block((x), (s), 4, 16); \
|
||||
uart0_flush(); \
|
||||
} while (0)
|
||||
|
||||
#define DUMP(x) DUMP_LEN((x), (sizeof(x)))
|
||||
|
||||
arcfour_ctx_t prng;
|
||||
|
||||
static
|
||||
void fill_random(void *buf, size_t length) {
|
||||
while (length--) {
|
||||
*(uint8_t *)buf = arcfour_gen(&prng);
|
||||
buf = (uint8_t *)buf + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void testrun_performance_pi16cipher(void){
|
||||
pi16_ctx_t ctx;
|
||||
uint32_t t;
|
||||
const uint8_t key[16] = { 15, 14, 13, 12 , 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
uint8_t msg[19] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
|
||||
const uint8_t ad[17] = { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 };
|
||||
uint8_t nsec[16] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
const uint8_t npub[4] = { 10, 11, 12, 13 };
|
||||
uint8_t crypt[16 + 19 + 16];
|
||||
uint8_t *tag = &crypt[16 + 19];
|
||||
// size_t crypt_len, tag_len, msg_len = sizeof(msg);
|
||||
// int v;
|
||||
|
||||
calibrateTimer();
|
||||
print_overhead();
|
||||
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_init(&ctx, key, sizeof(key), npub, sizeof(npub));
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tinit time (16 + 4) : %10"PRIu32"\n"), t);
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_process_ad_block(&ctx, ad, 1);
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tprocess ad(16) : %10"PRIu32"\n"), t);
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_process_ad_last_block(&ctx, &ad[16], 1, 2);
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tprocess last ad(1) : %10"PRIu32"\n"), t);
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_encrypt_smn(&ctx, crypt, nsec);
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tprocess smn(16) : %10"PRIu32"\n"), t);
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_encrypt_block(&ctx, &crypt[16], msg, 1);
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tprocess encrypt block(16) : %10"PRIu32"\n"), t);
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_encrypt_last_block(&ctx, &crypt[32], &msg[16], 3, 2);
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tprocess encrypt last block(3): %10"PRIu32"\n"), t);
|
||||
uart0_flush();
|
||||
startTimer(1);
|
||||
pi16_extract_tag(&ctx, tag);
|
||||
t = stopTimer();
|
||||
printf_P(PSTR("\tprocess extract tag(16) : %10"PRIu32"\n"), t);
|
||||
}
|
||||
|
||||
void testrun_pi16(void)
|
||||
{
|
||||
const uint8_t key[16] = { 15, 14, 13, 12 , 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
uint8_t msg[19] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
|
||||
const uint8_t ad[17] = { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 };
|
||||
uint8_t nsec[16] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
|
||||
const uint8_t npub[4] = { 10, 11, 12, 13 };
|
||||
uint8_t crypt[16 + 19 + 16];
|
||||
size_t crypt_len, msg_len = sizeof(msg);
|
||||
int v;
|
||||
// printf("crypt = %p, crypt_len = %d, tag = %p, tag_len = %d\n", crypt, crypt_len, tag, tag_len);
|
||||
pi16_encrypt_simple(crypt, &crypt_len, msg, sizeof(msg), ad, sizeof(ad), nsec, npub, sizeof(npub), key, sizeof(key));
|
||||
// printf("crypt = %p, crypt_len = %d, tag = %p, tag_len = %d\n", crypt, crypt_len, tag, tag_len);
|
||||
DUMP(key);
|
||||
DUMP(msg);
|
||||
DUMP(ad);
|
||||
DUMP(nsec);
|
||||
DUMP(npub);
|
||||
DUMP_LEN(crypt, crypt_len);
|
||||
puts("");
|
||||
crypt[0] ^= 0;
|
||||
v = pi16_decrypt_simple(msg, &msg_len, nsec, crypt, crypt_len, ad, sizeof(ad), npub, sizeof(npub), key, sizeof(key));
|
||||
DUMP(key);
|
||||
DUMP(msg);
|
||||
DUMP(ad);
|
||||
DUMP(nsec);
|
||||
DUMP(npub);
|
||||
DUMP_LEN(crypt, crypt_len);
|
||||
printf("\nverification: >> %s (%d) <<\n", v ? "FAILED!" : "ok", v);
|
||||
puts("");
|
||||
}
|
||||
|
||||
void testrun_pi32(void)
|
||||
{
|
||||
const uint8_t key[16] = { 0 };
|
||||
const uint8_t msg[1] = { 0xf };
|
||||
const uint8_t ad[1] = { 0 };
|
||||
const uint8_t nsec[PI32_SMN_LENGTH_BYTES] = { 0 };
|
||||
const uint8_t npub[16] = { 0 };
|
||||
uint8_t crypt[sizeof(nsec) + sizeof(msg) + 32];
|
||||
uint16_t crypt_len;
|
||||
pi32_encrypt_simple(crypt, &crypt_len, msg, sizeof(msg), ad, sizeof(ad), nsec, npub, sizeof(npub), key, sizeof(key));
|
||||
DUMP(key);
|
||||
DUMP(msg);
|
||||
DUMP(ad);
|
||||
DUMP(nsec);
|
||||
DUMP(npub);
|
||||
DUMP(crypt);
|
||||
}
|
||||
|
||||
void testrun_pi64(void)
|
||||
{
|
||||
const uint8_t key[16] = { 0 };
|
||||
const uint8_t msg[1] = { 0xf };
|
||||
const uint8_t ad[1] = { 0 };
|
||||
const uint8_t nsec[PI64_SMN_LENGTH_BYTES] = { 0 };
|
||||
const uint8_t npub[16] = { 0 };
|
||||
uint8_t crypt[sizeof(nsec) + sizeof(msg) + 64];
|
||||
uint16_t crypt_len;
|
||||
pi64_encrypt_simple(crypt, &crypt_len, msg, sizeof(msg), ad, sizeof(ad), nsec, npub, sizeof(npub), key, sizeof(key));
|
||||
DUMP(key);
|
||||
DUMP(msg);
|
||||
DUMP(ad);
|
||||
DUMP(nsec);
|
||||
DUMP(npub);
|
||||
DUMP(crypt);
|
||||
}
|
||||
|
||||
void testrun(void) {
|
||||
testrun_pi16();
|
||||
testrun_pi32();
|
||||
testrun_pi64();
|
||||
}
|
||||
|
||||
static
|
||||
void print_item(const char *label, const void* data, size_t length) {
|
||||
printf("%s (%u) = ", label, length);
|
||||
while (length--) {
|
||||
printf("%02X", *(uint8_t*)data);
|
||||
data = (uint8_t*)data + 1;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void generate_single_testvector(
|
||||
const uint8_t *m, size_t mlen,
|
||||
const uint8_t *ad, size_t adlen,
|
||||
const uint8_t *nsec,
|
||||
const uint8_t *npub, size_t npub_len,
|
||||
const uint8_t *key, size_t key_len,
|
||||
void(*encrypt)(void*, size_t*, const void*, size_t, const void*, size_t, const void*, const void*, size_t, const void*, size_t),
|
||||
int(*decrypt)(void*, size_t*, void*, const void*, size_t, const void*, size_t, const void*, size_t, const void*, size_t),
|
||||
size_t block_length
|
||||
) {
|
||||
uint8_t c[block_length + mlen + block_length];
|
||||
uint8_t m_check[mlen];
|
||||
uint8_t nsec_check[block_length];
|
||||
size_t clen, mlen_check;
|
||||
int v;
|
||||
|
||||
print_item("KEY", key, key_len);
|
||||
print_item("NPUB", npub, npub_len);
|
||||
print_item("NSEC", nsec, block_length);
|
||||
print_item("MSG", m, mlen);
|
||||
print_item("AD", ad, adlen);
|
||||
|
||||
fflush(stdout);
|
||||
encrypt(c, &clen, m, mlen, ad, adlen, nsec, npub, npub_len, key, key_len);
|
||||
|
||||
print_item("CIPHER", c, clen);
|
||||
fflush(stdout);
|
||||
|
||||
v = decrypt(m_check, &mlen_check, nsec_check, c, clen, ad, adlen, npub, npub_len, key, key_len);
|
||||
|
||||
if (v) {
|
||||
printf("!verification failed (%d)\n", v);
|
||||
}
|
||||
|
||||
if (mlen != mlen_check || memcmp(m, m_check, mlen)) {
|
||||
print_item("!ERROR MSG", m_check, mlen_check);
|
||||
}
|
||||
if (memcmp(nsec, nsec_check, block_length)) {
|
||||
print_item("!ERROR MSG", m_check, mlen_check);
|
||||
}
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void generate_testvectors(
|
||||
size_t key_len, size_t npub_len,
|
||||
void(*encrypt)(void*, size_t*, const void*, size_t, const void*, size_t, const void*, const void*, size_t, const void*, size_t),
|
||||
int(*decrypt)(void*, size_t*, void*, const void*, size_t, const void*, size_t, const void*, size_t, const void*, size_t),
|
||||
size_t block_length, const char *cipher_name) {
|
||||
size_t ad_len, msg_len, i, c = 1;
|
||||
uint8_t ad[3 * block_length / 2];
|
||||
uint8_t msg[3 * block_length / 2];
|
||||
uint8_t key[key_len];
|
||||
uint8_t npub[npub_len];
|
||||
uint8_t nsec[block_length];
|
||||
{
|
||||
char seed[64];
|
||||
snprintf(seed, sizeof(seed), "%s%03uv2 (%u byte nonce)", cipher_name, key_len * 8, npub_len);
|
||||
arcfour_init(seed, strlen(seed) * 8, &prng);
|
||||
}
|
||||
for (msg_len = 0; msg_len <= sizeof(msg); ++msg_len) {
|
||||
for (ad_len = 0; ad_len <= sizeof(ad); ++ad_len) {
|
||||
printf("[msg_len = %u]\n", msg_len);
|
||||
printf("[ad_len = %u]\n\n", ad_len);
|
||||
for (i = 0; i < 8; ++i) {
|
||||
printf("[vector #%u (%u)]\n", c, i + 1);
|
||||
++c;
|
||||
fill_random(key, sizeof(key));
|
||||
fill_random(npub, sizeof(npub));
|
||||
fill_random(nsec, sizeof(nsec));
|
||||
fill_random(ad, ad_len);
|
||||
fill_random(msg, msg_len);
|
||||
generate_single_testvector(msg, msg_len, ad, ad_len, nsec, npub, npub_len, key, key_len, encrypt, decrypt, block_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tv16(void) {
|
||||
puts("\n=====\n");
|
||||
printf("# Testvectors for %s\n", pi16_cipher_name);
|
||||
printf("# key size: %u bits\n", 128);
|
||||
printf("# nonce size: %u bits\n\n", 32);
|
||||
generate_testvectors(16, 4, pi16_encrypt_simple, pi16_decrypt_simple, PI16_PT_BLOCK_LENGTH_BYTES, pi16_cipher_name);
|
||||
puts("\n=====\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* main *
|
||||
*****************************************************************************/
|
||||
|
||||
const char nessie_str[] PROGMEM = "nessie";
|
||||
const char test_str[] PROGMEM = "test";
|
||||
const char tv16_str[] PROGMEM = "tv16";
|
||||
const char test16_str[] PROGMEM = "test16";
|
||||
const char test32_str[] PROGMEM = "test32";
|
||||
const char test64_str[] PROGMEM = "test64";
|
||||
const char ftest_str[] PROGMEM = "ftest";
|
||||
const char gtest_str[] PROGMEM = "gtest";
|
||||
const char performance_str[] PROGMEM = "performance";
|
||||
const char echo_str[] PROGMEM = "echo";
|
||||
|
||||
const cmdlist_entry_t cmdlist[] PROGMEM = {
|
||||
// { nessie_str, NULL, NULL },
|
||||
{ test_str, NULL, testrun},
|
||||
{ tv16_str, NULL, tv16},
|
||||
{ test16_str, NULL, testrun_pi16},
|
||||
{ test32_str, NULL, testrun_pi32},
|
||||
{ test64_str, NULL, testrun_pi64},
|
||||
// { ftest_str, NULL, testrun_f32},
|
||||
// { gtest_str, NULL, testrun_g32},
|
||||
{ performance_str, NULL, testrun_performance_pi16cipher},
|
||||
{ echo_str, (void*)1, (void_fpt)echo_ctrl},
|
||||
{ NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
main_setup();
|
||||
|
||||
for(;;){
|
||||
welcome_msg(algo_name);
|
||||
cmd_interface(cmdlist);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue