adding salsa20

This commit is contained in:
bg 2011-07-19 22:37:41 +02:00
parent b11f6230a4
commit f075eca3b7
7 changed files with 5331 additions and 0 deletions

13
mkfiles/salsa20_c.mk Normal file
View File

@ -0,0 +1,13 @@
# Makefile for Salsa20
ALGO_NAME := SALSA20_C
# comment out the following line for removement of Salsa20 from the build process
STREAM_CIPHERS += $(ALGO_NAME)
$(ALGO_NAME)_DIR := salsa20/
$(ALGO_NAME)_OBJ := salsa20.o
$(ALGO_NAME)_INCDIR := memxor/ scal/
$(ALGO_NAME)_TEST_BIN := main-salsa20-test.o $(CLI_STD) $(SCAL_STD) scal_salsa20.o
$(ALGO_NAME)_NESSIE_TEST := "nessie"
$(ALGO_NAME)_PERFORMANCE_TEST := "performance"

142
salsa20/salsa20.c Normal file
View File

@ -0,0 +1,142 @@
/* salsa20.c */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2006-2011 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/>.
*/
#include <stdint.h>
#include <string.h>
#include "salsa20.h"
#define ROTL32(a,n) (((a)<<(n))|((a)>>(32-(n))))
static
void quaterround(uint32_t* a, uint32_t* b, uint32_t* c, uint32_t* d){
*b ^= ROTL32(*a + *d, 7);
*c ^= ROTL32(*b + *a, 9);
*d ^= ROTL32(*c + *b, 13);
*a ^= ROTL32(*d + *c, 18);
}
static
void rowround(uint32_t* a){
quaterround(a+ 0, a+ 1, a+ 2, a+ 3);
quaterround(a+ 5, a+ 6, a+ 7, a+ 4);
quaterround(a+10, a+11, a+ 8, a+ 9);
quaterround(a+15, a+12, a+13, a+14);
}
static
void columnround(uint32_t* a){
quaterround(a+ 0, a+ 4, a+ 8, a+12);
quaterround(a+ 5, a+ 9, a+13, a+ 1);
quaterround(a+10, a+14, a+ 2, a+ 6);
quaterround(a+15, a+ 3, a+ 7, a+11);
}
static
void doubleround(uint32_t* a){
columnround(a);
rowround(a);
}
void salsa20_hash(uint32_t* a){
uint8_t i;
uint32_t b[16];
memcpy(b, a, 64);
for(i=0; i<10; ++i){
doubleround(a);
}
for(i=0; i<16; ++i){
a[i] += b[i];
}
}
uint8_t sigma[] = {'e','x','p','a','n','d',' ','3','2','-','b','y','t','e',' ','k'};
uint8_t theta[] = {'e','x','p','a','n','d',' ','1','6','-','b','y','t','e',' ','k'};
void salsa_k32(uint32_t* dest, const uint32_t* k, const uint32_t* n){
memcpy(dest+ 0, sigma+ 0, 4);
memcpy(dest+ 4, k+ 0, 16);
memcpy(dest+20, sigma+ 4, 4);
memcpy(dest+24, n+ 0, 16);
memcpy(dest+40, sigma+ 8, 4);
memcpy(dest+44, k+16, 16);
memcpy(dest+60, sigma+12, 4);
salsa20_hash(dest);
}
void salsa_k16(uint32_t* dest, const uint32_t* k, const uint32_t* n){
memcpy(dest+ 0, theta+ 0, 4);
memcpy(dest+ 4, k+ 0, 16);
memcpy(dest+20, theta+ 4, 4);
memcpy(dest+24, n+ 0, 16);
memcpy(dest+40, theta+ 8, 4);
memcpy(dest+44, k+ 0, 16);
memcpy(dest+60, theta+12, 4);
salsa20_hash(dest);
}
void salsa20_genBlock256(void* dest, const void* k, const void* iv, uint64_t i){
uint32_t n[4];
memcpy(n, iv, 8);
memcpy(n+8, &i, 8);
salsa_k32((uint32_t*)dest, (uint32_t*)k, n);
}
void salsa20_genBlock128(void* dest, const void* k, const void* iv, uint64_t i){
uint32_t n[4];
memcpy(n, iv, 8);
memcpy(n+8, &i, 8);
salsa_k16((uint32_t*)dest, (uint32_t*)k, n);
}
void salsa20_init(void* key, uint16_t keylength_b, void* iv, salsa20_ctx_t* ctx){
if(keylength_b==256){
memcpy((ctx->a+ 0), sigma+ 0, 4);
memcpy((ctx->a+20), sigma+ 4, 4);
memcpy((ctx->a+40), sigma+ 8, 4);
memcpy((ctx->a+44), (uint8_t*)key+16, 16);
memcpy((ctx->a+60), sigma+12, 4);
}else{
memcpy((ctx->a+ 0), theta+ 0, 4);
memcpy((ctx->a+20), theta+ 4, 4);
memcpy((ctx->a+40), theta+ 8, 4);
memcpy((ctx->a+44), (uint8_t*)key+ 0, 16);
memcpy((ctx->a+60), theta+12, 4);
}
memcpy((ctx->a+ 4), key, 16);
memset((ctx->a+24), 0, 16);
if(iv){
memcpy((ctx->a+24), iv, 8);
}
ctx->buffer_idx=64;
}
uint8_t salsa20_gen(salsa20_ctx_t* ctx){
if(ctx->buffer_idx==64){
memcpy(ctx->buffer, ctx->a, 64);
salsa20_hash((uint32_t*)(ctx->buffer));
*((uint64_t*)(ctx->a+32)) += 1;
ctx->buffer_idx = 0;
}
return ctx->buffer[ctx->buffer_idx++];
}

40
salsa20/salsa20.h Normal file
View File

@ -0,0 +1,40 @@
/* salsa20.h */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2011 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 SALSA20_H_
#define SALSA20_H_
#include <stdint.h>
typedef struct{
uint8_t a[64];
uint8_t buffer[64];
uint8_t buffer_idx;
} salsa20_ctx_t;
void salsa20_hash(uint32_t* a);
void salsa_k32(uint32_t* dest, const uint32_t* k, const uint32_t* n);
void salsa_k16(uint32_t* dest, const uint32_t* k, const uint32_t* n);
void salsa20_genBlock256(void* dest, const void* k, const void* iv, uint64_t i);
void salsa20_genBlock128(void* dest, const void* k, const void* iv, uint64_t i);
void salsa20_init(void* key, uint16_t keylength_b, void* iv, salsa20_ctx_t* ctx);
uint8_t salsa20_gen(salsa20_ctx_t* ctx);
#endif /* SALSA20_H_ */

55
scal/scal_salsa20.c Normal file
View File

@ -0,0 +1,55 @@
/* scal_salsa20.c */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2011 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/>.
*/
#include <stdlib.h>
#include <stdint.h>
#include "streamcipher_descriptor.h"
#include "keysize_descriptor.h"
#include "salsa20.h"
const char salsa20_str[] = "Salsa20";
const uint8_t salsa20_keysize_desc[] = {
KS_TYPE_LIST, 2, KS_INT(128), KS_INT(256),
KS_TYPE_TERMINATOR };
const uint8_t salsa20_ivsize_desc[] = {
KS_TYPE_LIST, 1, KS_INT(64),
KS_TYPE_TERMINATOR };
const scdesc_t salsa20_desc = {
SCDESC_TYPE_STREAMCIPHER, /* abstraction layer type designator */
SC_INIT_TYPE_4|SC_GEN_TYPE_1, /* flags*/
salsa20_str, /* name string pointer */
sizeof(salsa20_ctx_t), /* size of context */
8, /* blocksize */
{(void_fpt)salsa20_init}, /* init function pointer */
{(void_fpt)salsa20_gen}, /* key stream generator function pointer */
{(void_fpt)NULL}, /* key stream generator for random access function pointer */
(sc_free_fpt)NULL, /* free function pointer */
salsa20_keysize_desc, /* key size descriptor pointer */
salsa20_ivsize_desc /* iv size descriptor pointer */
};

27
scal/scal_salsa20.h Normal file
View File

@ -0,0 +1,27 @@
/* scal_salsa20.h */
/*
This file is part of the AVR-Crypto-Lib.
Copyright (C) 2011 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 SCAL_SALSA20_H_
#define SCAL_SALSA20_H_
#include "streamcipher_descriptor.h"
extern const scdesc_t salsa20_desc;
#endif /* SCAL_SALSA20_H_ */

View File

@ -0,0 +1,280 @@
/* main-salsa20-test.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2011 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/>.
*/
#include "main-test-common.h"
#include "performance_test.h"
#include "salsa20.h"
#include "scal_salsa20.h"
#include "scal-basic.h"
#include "scal-nessie.h"
char* algo_name = "Salsa20";
/*****************************************************************************
* additional validation-functions *
*****************************************************************************/
void nessie_first(void){
salsa20_ctx_t ctx;
uint8_t key[16];
memset(key, 0, 16);
key[0] = 0x80;
cli_putstr("\r\n testing with key: ");
cli_hexdump(key, 16);
salsa20_init(key, 128, NULL, &ctx);
cli_putstr("\r\n internal state: ");
cli_hexdump_block(ctx.a, 64, 4, 16);
salsa20_gen(&ctx);
cli_putstr("\r\n internal state: ");
cli_hexdump_block(ctx.a, 64, 4, 16);
cli_putstr("\r\n data: ");
cli_hexdump_block(ctx.buffer, 64, 4, 16);
memset(key, 0, 16);
key[15] = 0x01;
cli_putstr("\r\n testing with key: ");
cli_hexdump(key, 16);
cli_hexdump_block(ctx.a, 64, 4, 16);
salsa20_init(key, 128, NULL, &ctx);
cli_putstr("\r\n internal state: ");
cli_hexdump_block(ctx.a, 64, 4, 16);
salsa20_gen(&ctx);
cli_putstr("\r\n internal state: ");
cli_hexdump_block(ctx.a, 64, 4, 16);
cli_putstr("\r\n data: ");
cli_hexdump_block(ctx.buffer, 64, 4, 16);
}
/*
Salsa20(
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
=(
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
).
Salsa20(
211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,191,187,234,136,
49,237,179, 48, 1,106,178,219,175,199,166, 48, 86, 16,179,207,
31,240, 32, 63, 15, 83, 93,161,116,147, 48,113,238, 55,204, 36,
79,201,235, 79, 3, 81,156, 47,203, 26,244,243, 88,118,104, 54)
= (
109, 42,178,168,156,240,248,238,168,196,190,203, 26,110,170,154,
29, 29,150, 26,150, 30,235,249,190,163,251, 48, 69,144, 51, 57,
118, 40,152,157,180, 57, 27, 94,107, 42,236, 35, 27,111,114,114,
219,236,232,135,111,155,110, 18, 24,232, 95,158,179, 19, 48,202
).
Salsa20(
88,118,104, 54, 79,201,235, 79, 3, 81,156, 47,203, 26,244,243,
191,187,234,136,211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,
86, 16,179,207, 49,237,179, 48, 1,106,178,219,175,199,166, 48,
238, 55,204, 36, 31,240, 32, 63, 15, 83, 93,161,116,147, 48,113)
= (
179, 19, 48,202,219,236,232,135,111,155,110, 18, 24,232, 95,158,
26,110,170,154,109, 42,178,168,156,240,248,238,168,196,190,203,
69,144, 51, 57, 29, 29,150, 26,150, 30,235,249,190,163,251, 48,
27,111,114,114,118, 40,152,157,180, 57, 27, 94,107, 42,236, 35
).
Salsa20^1000000 (
6,124, 83,146, 38,191, 9, 50, 4,161, 47,222,122,182,223,185,
75, 27, 0,216, 16,122, 7, 89,162,104,101,147,213, 21, 54, 95,
225,253,139,176,105,132, 23,116, 76, 41,176,207,221, 34,157,108,
94, 94, 99, 52, 90,117, 91,220,146,190,239,143,196,176,130,186)
=(
8, 18, 38,199,119, 76,215, 67,173,127,144,162,103,212,176,217,
192, 19,233, 33,159,197,154,160,128,243,219, 65,171,136,135,225,
123, 11, 68, 86,237, 82, 20,155,133,189, 9, 83,167,116,194, 78,
122,127,195,185,185,204,188, 90,245, 9,183,248,226, 85,245,104
).
*/
uint8_t Salsa20_spectest0_in[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t Salsa20_spectest0_ref[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
uint8_t Salsa20_spectest1_in[] = {
211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,191,187,234,136,
49,237,179, 48, 1,106,178,219,175,199,166, 48, 86, 16,179,207,
31,240, 32, 63, 15, 83, 93,161,116,147, 48,113,238, 55,204, 36,
79,201,235, 79, 3, 81,156, 47,203, 26,244,243, 88,118,104, 54 };
uint8_t Salsa20_spectest1_ref[] = {
109, 42,178,168,156,240,248,238,168,196,190,203, 26,110,170,154,
29, 29,150, 26,150, 30,235,249,190,163,251, 48, 69,144, 51, 57,
118, 40,152,157,180, 57, 27, 94,107, 42,236, 35, 27,111,114,114,
219,236,232,135,111,155,110, 18, 24,232, 95,158,179, 19, 48,202 };
uint8_t Salsa20_spectest2_in[] = {
88,118,104, 54, 79,201,235, 79, 3, 81,156, 47,203, 26,244,243,
191,187,234,136,211,159, 13,115, 76, 55, 82,183, 3,117,222, 37,
86, 16,179,207, 49,237,179, 48, 1,106,178,219,175,199,166, 48,
238, 55,204, 36, 31,240, 32, 63, 15, 83, 93,161,116,147, 48,113 };
uint8_t Salsa20_spectest2_ref[] = {
179, 19, 48,202,219,236,232,135,111,155,110, 18, 24,232, 95,158,
26,110,170,154,109, 42,178,168,156,240,248,238,168,196,190,203,
69,144, 51, 57, 29, 29,150, 26,150, 30,235,249,190,163,251, 48,
27,111,114,114,118, 40,152,157,180, 57, 27, 94,107, 42,236, 35 };
uint8_t Salsa20_spectest3_in[] = {
6,124, 83,146, 38,191, 9, 50, 4,161, 47,222,122,182,223,185,
75, 27, 0,216, 16,122, 7, 89,162,104,101,147,213, 21, 54, 95,
225,253,139,176,105,132, 23,116, 76, 41,176,207,221, 34,157,108,
94, 94, 99, 52, 90,117, 91,220,146,190,239,143,196,176,130,186 };
uint8_t Salsa20_spectest3_ref[] = {
8, 18, 38,199,119, 76,215, 67,173,127,144,162,103,212,176,217,
192, 19,233, 33,159,197,154,160,128,243,219, 65,171,136,135,225,
123, 11, 68, 86,237, 82, 20,155,133,189, 9, 83,167,116,194, 78,
122,127,195,185,185,204,188, 90,245, 9,183,248,226, 85,245,104 };
void spec_test(void){
uint8_t buffer[64];
nessie_first();
cli_putstr("\r\ntesting with vectors from sepcification");
cli_putstr("\r\ntest 0: ");
memcpy(buffer, Salsa20_spectest0_in, 64);
salsa20_hash((uint32_t*)buffer);
if(memcmp(buffer, Salsa20_spectest0_ref, 64)){
cli_putstr(" [fail]");
}else{
cli_putstr(" [ok]");
}
cli_putstr("\r\ntest 1: ");
memcpy(buffer, Salsa20_spectest1_in, 64);
salsa20_hash((uint32_t*)buffer);
if(memcmp(buffer, Salsa20_spectest1_ref, 64)){
cli_putstr(" [fail]");
}else{
cli_putstr(" [ok]");
}
cli_putstr("\r\ntest 2: ");
memcpy(buffer, Salsa20_spectest2_in, 64);
salsa20_hash((uint32_t*)buffer);
if(memcmp(buffer, Salsa20_spectest2_ref, 64)){
cli_putstr(" [fail]");
}else{
cli_putstr(" [ok]");
}
uint32_t count=0;
cli_putstr("\r\ntest 3: ");
memcpy(buffer, Salsa20_spectest3_in, 64);
do{
if((count&0xFFFF)==0){
cli_putc('.');
if((count&0x20FFFF)==0){
cli_putc('\r'); cli_putc('\n');
}
}
salsa20_hash((uint32_t*)buffer);
}while(++count<1000000);
if(memcmp(buffer, Salsa20_spectest0_ref, 64)){
cli_putstr(" [fail]");
}else{
cli_putstr(" [ok]");
}
}
void testrun_nessie_salsa20(void){
scal_nessie_set_estream(1);
scal_nessie_run(&salsa20_desc);
}
void testrun_performance_salsa20(void){
uint64_t t;
char str[16];
uint8_t key[32];
salsa20_ctx_t ctx;
calibrateTimer();
print_overhead();
memset(key, 0, 16);
startTimer(1);
salsa20_init(key, 128, NULL, &ctx);
t = stopTimer();
cli_putstr("\r\n\tctx-gen time: ");
ultoa((unsigned long)t, str, 10);
cli_putstr(str);
startTimer(1);
salsa20_gen(&ctx);
t = stopTimer();
cli_putstr("\r\n\tencrypt time: ");
ultoa((unsigned long)t, str, 10);
cli_putstr(str);
cli_putstr("\r\n");
}
/*****************************************************************************
* main *
*****************************************************************************/
const char nessie_str[] = "nessie";
const char test_str[] = "test";
const char performance_str[] = "performance";
const char echo_str[] = "echo";
cmdlist_entry_t cmdlist[] = {
{ nessie_str, NULL, testrun_nessie_salsa20 },
{ performance_str, NULL, testrun_performance_salsa20},
{ test_str, NULL, spec_test},
{ echo_str, (void*)1, (void_fpt)echo_ctrl},
{ NULL, NULL, NULL}
};
int main (void){
main_setup();
for(;;){
welcome_msg(algo_name);
cmd_interface(cmdlist);
}
}

File diff suppressed because it is too large Load Diff