Adding Serpent

This commit is contained in:
bg 2011-02-04 17:26:55 +01:00
parent c3885c4a83
commit 6131049b56
13 changed files with 36971 additions and 2 deletions

View File

@ -27,7 +27,7 @@ def read_line(error_msg=true)
puts("ERROR: read timeout!\n") if error_msg
return nil
end
s.gsub(/\006/, '');
return s.delete("\006");
end
def readTestVector(param)
@ -77,7 +77,7 @@ def readTestVector(param)
set=m[1].to_i;
print("\nSet "+m[1]+":");
end
if (m=/Set [0-9]*, vector#[\s]*([0-9]+):/.match(lb))
if (m=/Set [0-9], vector#[\s]*([0-9]+):/.match(lb))
vector=m[1].to_i;
#print(" "+m[1]);
if(vector!=0 && vector % $linewidth==0)

View File

@ -0,0 +1,13 @@
# Makefile for serpent
ALGO_NAME := SERPENT_BITSLICE
# comment out the following line for removement of serpent from the build process
BLOCK_CIPHERS += $(ALGO_NAME)
$(ALGO_NAME)_DIR := serpent/
$(ALGO_NAME)_INCDIR := bcal/ memxor/
$(ALGO_NAME)_OBJ := serpent.o serpent-sboxes-bitslice.o memxor.o
$(ALGO_NAME)_TEST_BIN := main-serpent-test.o bcal_serpent.o $(CLI_STD) $(BCAL_STD)
$(ALGO_NAME)_NESSIE_TEST := "nessie"
$(ALGO_NAME)_PERFORMANCE_TEST := "performance"

13
mkfiles/serpent_c.mk Normal file
View File

@ -0,0 +1,13 @@
# Makefile for serpent
ALGO_NAME := SERPENT_C
# comment out the following line for removement of serpent from the build process
BLOCK_CIPHERS += $(ALGO_NAME)
$(ALGO_NAME)_DIR := serpent/
$(ALGO_NAME)_INCDIR := bcal/ memxor/
$(ALGO_NAME)_OBJ := serpent.o serpent-sboxes_c.o memxor.o
$(ALGO_NAME)_TEST_BIN := main-serpent-test.o bcal_serpent.o $(CLI_STD) $(BCAL_STD)
$(ALGO_NAME)_NESSIE_TEST := "nessie"
$(ALGO_NAME)_PERFORMANCE_TEST := "performance"

View File

@ -0,0 +1,476 @@
/* serpent-sboxes-bitslice.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2010 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/>.
*/
/* serpent-sboxes.c
* a bitsliced implementation of the serpent sboxes
* author: Daniel Otte
* email: daniel.otte@rub.de
* license: GPLv3
*/
#include <stdint.h>
#include <string.h>
#include "serpent-sboxes.h"
/* S0: 3 8 15 1 10 6 5 11 14 13 4 2 7 0 9 12 */
/* depth = 5,7,4,2, Total gates=18 */
static
void sb0(uint8_t* out, const uint8_t* in){
// (a,b,c,d,w,x,y,z)
uint8_t t01, t02, t03, t05, t06, t07, t08, t09, t11, t12, t13, t14, t15, t17;
t01 = in[4*1] ^ in[4*2];
t02 = in[4*0] | in[4*3];
t03 = in[4*0] ^ in[4*1];
out[4*3] = t02 ^ t01;
t05 = in[4*2] | out[4*3];
t06 = in[4*0] ^ in[4*3];
t07 = in[4*1] | in[4*2];
t08 = in[4*3] & t05;
t09 = t03 & t07;
out[4*2] = t09 ^ t08;
t11 = t09 & out[4*2];
t12 = in[4*2] ^ in[4*3];
t13 = t07 ^ t11;
t14 = in[4*1] & t06;
t15 = t06 ^ t13;
out[4*0] = ~ t15;
t17 = out[4*0] ^ t14;
out[4*1] = t12 ^ t17;
}
/* InvS0: 13 3 11 0 10 6 5 12 1 14 4 7 15 9 8 2 */
/* depth = 8,4,3,6, Total gates=19 */
static
void sb0_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t12, t13, t14, t15, t17, t18, t01;
t01 = in[4*2] ^ in[4*3];
t02 = in[4*0] | in[4*1];
t03 = in[4*1] | in[4*2];
t04 = in[4*2] & t01;
t05 = t02 ^ t01;
t06 = in[4*0] | t04;
out[4*2] = ~ t05;
t08 = in[4*1] ^ in[4*3];
t09 = t03 & t08;
t10 = in[4*3] | out[4*2];
out[4*1] = t09 ^ t06;
t12 = in[4*0] | t05;
t13 = out[4*1] ^ t12;
t14 = t03 ^ t10;
t15 = in[4*0] ^ in[4*2];
out[4*3] = t14 ^ t13;
t17 = t05 & t13;
t18 = t14 | t17;
out[4*0] = t15 ^ t18;
}
/* S1: 15 12 2 7 9 0 5 10 1 11 14 8 6 13 3 4 */
/* depth = 10,7,3,5, Total gates=18 */
static
void sb1(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t07, t08, t10, t11, t12, t13, t16, t17, t01;
t01 = in[4*0] | in[4*3];
t02 = in[4*2] ^ in[4*3];
t03 = ~ in[4*1];
t04 = in[4*0] ^ in[4*2];
t05 = in[4*0] | t03;
t06 = in[4*3] & t04;
t07 = t01 & t02;
t08 = in[4*1] | t06;
out[4*2] = t02 ^ t05;
t10 = t07 ^ t08;
t11 = t01 ^ t10;
t12 = out[4*2] ^ t11;
t13 = in[4*1] & in[4*3];
out[4*3] = ~ t10;
out[4*1] = t13 ^ t12;
t16 = t10 | out[4*1];
t17 = t05 & t16;
out[4*0] = in[4*2] ^ t17;
}
/* InvS1: 5 8 2 14 15 6 12 3 11 4 7 9 1 13 10 0 */
/* depth = 7,4,5,3, Total gates=18 */
static void sb1_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t14, t15, t17, t01;
t01 = in[4*0] ^ in[4*1];
t02 = in[4*1] | in[4*3];
t03 = in[4*0] & in[4*2];
t04 = in[4*2] ^ t02;
t05 = in[4*0] | t04;
t06 = t01 & t05;
t07 = in[4*3] | t03;
t08 = in[4*1] ^ t06;
t09 = t07 ^ t06;
t10 = t04 | t03;
t11 = in[4*3] & t08;
out[4*2] = ~ t09;
out[4*1] = t10 ^ t11;
t14 = in[4*0] | out[4*2];
t15 = t06 ^ out[4*1];
out[4*3] = t01 ^ t04;
t17 = in[4*2] ^ t15;
out[4*0] = t14 ^ t17;
}
/* S2: 8 6 7 9 3 12 10 15 13 1 14 4 0 11 5 2 */
/* depth = 3,8,11,7, Total gates=16 */
static void sb2(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t05, t06, t07, t08, t09, t10, t12, t13, t14, t01;
t01 = in[4*0] | in[4*2];
t02 = in[4*0] ^ in[4*1];
t03 = in[4*3] ^ t01;
out[4*0] = t02 ^ t03;
t05 = in[4*2] ^ out[4*0];
t06 = in[4*1] ^ t05;
t07 = in[4*1] | t05;
t08 = t01 & t06;
t09 = t03 ^ t07;
t10 = t02 | t09;
out[4*1] = t10 ^ t08;
t12 = in[4*0] | in[4*3];
t13 = t09 ^ out[4*1];
t14 = in[4*1] ^ t13;
out[4*3] = ~ t09;
out[4*2] = t12 ^ t14;
}
/* InvS2: 12 9 15 4 11 14 1 2 0 3 6 13 5 8 10 7 */
/* depth = 3,6,8,3, Total gates=18 */
static void sb2_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t12, t15, t16, t17, t01;
t01 = in[4*0] ^ in[4*3];
t02 = in[4*2] ^ in[4*3];
t03 = in[4*0] & in[4*2];
t04 = in[4*1] | t02;
out[4*0] = t01 ^ t04;
t06 = in[4*0] | in[4*2];
t07 = in[4*3] | out[4*0];
t08 = ~ in[4*3];
t09 = in[4*1] & t06;
t10 = t08 | t03;
t11 = in[4*1] & t07;
t12 = t06 & t02;
out[4*3] = t09 ^ t10;
out[4*1] = t12 ^ t11;
t15 = in[4*2] & out[4*3];
t16 = out[4*0] ^ out[4*1];
t17 = t10 ^ t15;
out[4*2] = t16 ^ t17;
}
/* S3: 0 15 11 8 12 9 6 3 13 1 2 4 10 7 5 14 */
/* depth = 8,3,5,5, Total gates=18 */
static void sb3(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t13, t14, t15, t01;
t01 = in[4*0] ^ in[4*2];
t02 = in[4*0] | in[4*3];
t03 = in[4*0] & in[4*3];
t04 = t01 & t02;
t05 = in[4*1] | t03;
t06 = in[4*0] & in[4*1];
t07 = in[4*3] ^ t04;
t08 = in[4*2] | t06;
t09 = in[4*1] ^ t07;
t10 = in[4*3] & t05;
t11 = t02 ^ t10;
out[4*3] = t08 ^ t09;
t13 = in[4*3] | out[4*3];
t14 = in[4*0] | t07;
t15 = in[4*1] & t13;
out[4*2] = t08 ^ t11;
out[4*0] = t14 ^ t15;
out[4*1] = t05 ^ t04;
}
/* InvS3: 0 9 10 7 11 14 6 13 3 5 12 2 4 8 15 1 */
/* depth = 3,6,4,4, Total gates=17 */
static void sb3_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t07, t09, t11, t12, t13, t14, t16, t01;
t01 = in[4*2] | in[4*3];
t02 = in[4*0] | in[4*3];
t03 = in[4*2] ^ t02;
t04 = in[4*1] ^ t02;
t05 = in[4*0] ^ in[4*3];
t06 = t04 & t03;
t07 = in[4*1] & t01;
out[4*2] = t05 ^ t06;
t09 = in[4*0] ^ t03;
out[4*0] = t07 ^ t03;
t11 = out[4*0] | t05;
t12 = t09 & t11;
t13 = in[4*0] & out[4*2];
t14 = t01 ^ t05;
out[4*1] = in[4*1] ^ t12;
t16 = in[4*1] | t13;
out[4*3] = t14 ^ t16;
}
/* S4: 1 15 8 3 12 0 11 6 2 5 4 10 9 14 7 13 */
/* depth = 6,7,5,3, Total gates=19 */
static void sb4(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t12, t13, t14, t15, t16, t01;
t01 = in[4*0] | in[4*1];
t02 = in[4*1] | in[4*2];
t03 = in[4*0] ^ t02;
t04 = in[4*1] ^ in[4*3];
t05 = in[4*3] | t03;
t06 = in[4*3] & t01;
out[4*3] = t03 ^ t06;
t08 = out[4*3] & t04;
t09 = t04 & t05;
t10 = in[4*2] ^ t06;
t11 = in[4*1] & in[4*2];
t12 = t04 ^ t08;
t13 = t11 | t03;
t14 = t10 ^ t09;
t15 = in[4*0] & t05;
t16 = t11 | t12;
out[4*2] = t13 ^ t08;
out[4*1] = t15 ^ t16;
out[4*0] = ~ t14;
}
/* InvS4: 5 0 8 3 10 9 7 14 2 12 11 6 4 15 13 1 */
/* depth = 6,4,7,3, Total gates=17 */
static void sb4_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t07, t09, t10, t11, t12, t13, t15, t01;
t01 = in[4*1] | in[4*3];
t02 = in[4*2] | in[4*3];
t03 = in[4*0] & t01;
t04 = in[4*1] ^ t02;
t05 = in[4*2] ^ in[4*3];
t06 = ~ t03;
t07 = in[4*0] & t04;
out[4*1] = t05 ^ t07;
t09 = out[4*1] | t06;
t10 = in[4*0] ^ t07;
t11 = t01 ^ t09;
t12 = in[4*3] ^ t04;
t13 = in[4*2] | t10;
out[4*3] = t03 ^ t12;
t15 = in[4*0] ^ t04;
out[4*2] = t11 ^ t13;
out[4*0] = t15 ^ t09;
}
/* S5: 15 5 2 11 4 10 9 12 0 3 14 8 13 6 7 1 */
/* depth = 4,6,8,6, Total gates=17 */
static void sb5(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t14, t01;
t01 = in[4*1] ^ in[4*3];
t02 = in[4*1] | in[4*3];
t03 = in[4*0] & t01;
t04 = in[4*2] ^ t02;
t05 = t03 ^ t04;
out[4*0] = ~ t05;
t07 = in[4*0] ^ t01;
t08 = in[4*3] | out[4*0];
t09 = in[4*1] | t05;
t10 = in[4*3] ^ t08;
t11 = in[4*1] | t07;
t12 = t03 | out[4*0];
t13 = t07 | t10;
t14 = t01 ^ t11;
out[4*2] = t09 ^ t13;
out[4*1] = t07 ^ t08;
out[4*3] = t12 ^ t14;
}
/* InvS5: 8 15 2 9 4 1 13 14 11 6 5 3 7 12 10 0 */
/* depth = 4,6,9,7, Total gates=17 */
static void sb5_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t12, t13, t15, t16, t01;
t01 = in[4*0] & in[4*3];
t02 = in[4*2] ^ t01;
t03 = in[4*0] ^ in[4*3];
t04 = in[4*1] & t02;
t05 = in[4*0] & in[4*2];
out[4*0] = t03 ^ t04;
t07 = in[4*0] & out[4*0];
t08 = t01 ^ out[4*0];
t09 = in[4*1] | t05;
t10 = ~ in[4*1];
out[4*1] = t08 ^ t09;
t12 = t10 | t07;
t13 = out[4*0] | out[4*1];
out[4*3] = t02 ^ t12;
t15 = t02 ^ t13;
t16 = in[4*1] ^ in[4*3];
out[4*2] = t16 ^ t15;
}
/* S6: 7 2 12 5 8 4 6 11 14 9 1 15 13 3 10 0 */
/* depth = 8,3,6,3, Total gates=19 */
static void sb6(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t07, t08, t09, t10, t11, t12, t13, t15, t17, t18, t01;
t01 = in[4*0] & in[4*3];
t02 = in[4*1] ^ in[4*2];
t03 = in[4*0] ^ in[4*3];
t04 = t01 ^ t02;
t05 = in[4*1] | in[4*2];
out[4*1] = ~ t04;
t07 = t03 & t05;
t08 = in[4*1] & out[4*1];
t09 = in[4*0] | in[4*2];
t10 = t07 ^ t08;
t11 = in[4*1] | in[4*3];
t12 = in[4*2] ^ t11;
t13 = t09 ^ t10;
out[4*2] = ~ t13;
t15 = out[4*1] & t03;
out[4*3] = t12 ^ t07;
t17 = in[4*0] ^ in[4*1];
t18 = out[4*2] ^ t15;
out[4*0] = t17 ^ t18;
}
/* InvS6: 15 10 1 13 5 3 6 0 4 9 14 7 2 12 8 11 */
/* depth = 5,3,8,6, Total gates=19 */
static void sb6_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t07, t08, t09, t12, t13, t14, t15, t16, t17, t01;
t01 = in[4*0] ^ in[4*2];
t02 = ~ in[4*2];
t03 = in[4*1] & t01;
t04 = in[4*1] | t02;
t05 = in[4*3] | t03;
t06 = in[4*1] ^ in[4*3];
t07 = in[4*0] & t04;
t08 = in[4*0] | t02;
t09 = t07 ^ t05;
out[4*1] = t06 ^ t08;
out[4*0] = ~ t09;
t12 = in[4*1] & out[4*0];
t13 = t01 & t05;
t14 = t01 ^ t12;
t15 = t07 ^ t13;
t16 = in[4*3] | t02;
t17 = in[4*0] ^ out[4*1];
out[4*3] = t17 ^ t15;
out[4*2] = t16 ^ t14;
}
/* S7: 1 13 15 0 14 8 2 11 7 4 12 10 9 3 5 6 */
/* depth = 10,7,10,4, Total gates=19 */
static void sb7(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t05, t06, t08, t09, t10, t11, t13, t14, t15, t16, t17, t01;
t01 = in[4*0] & in[4*2];
t02 = ~ in[4*3];
t03 = in[4*0] & t02;
t04 = in[4*1] | t01;
t05 = in[4*0] & in[4*1];
t06 = in[4*2] ^ t04;
out[4*3] = t03 ^ t06;
t08 = in[4*2] | out[4*3];
t09 = in[4*3] | t05;
t10 = in[4*0] ^ t08;
t11 = t04 & out[4*3];
out[4*1] = t09 ^ t10;
t13 = in[4*1] ^ out[4*1];
t14 = t01 ^ out[4*1];
t15 = in[4*2] ^ t05;
t16 = t11 | t13;
t17 = t02 | t14;
out[4*0] = t15 ^ t17;
out[4*2] = in[4*0] ^ t16;
}
/* InvS7: 3 0 6 13 9 14 15 8 5 12 11 7 10 1 4 2 */
/* depth = 9,7,3,3, Total gates=18 */
static void sb7_inv(uint8_t* out, const uint8_t* in){
uint8_t t02, t03, t04, t06, t07, t08, t09, t10, t11, t13, t14, t15, t16, t01;
t01 = in[4*0] & in[4*1];
t02 = in[4*0] | in[4*1];
t03 = in[4*2] | t01;
t04 = in[4*3] & t02;
out[4*3] = t03 ^ t04;
t06 = in[4*1] ^ t04;
t07 = in[4*3] ^ out[4*3];
t08 = ~ t07;
t09 = t06 | t08;
t10 = in[4*1] ^ in[4*3];
t11 = in[4*0] | in[4*3];
out[4*1] = in[4*0] ^ t09;
t13 = in[4*2] ^ t06;
t14 = in[4*2] & t11;
t15 = in[4*3] | out[4*1];
t16 = t01 | t10;
out[4*0] = t13 ^ t15;
out[4*2] = t14 ^ t16;
}
typedef void(*sb_fpt)(uint8_t*, const uint8_t*);
const sb_fpt sf_tab[]= {
sb0, sb1, sb2, sb3,
sb4, sb5, sb6, sb7
};
const sb_fpt sinvf_tab[] = {
sb0_inv, sb1_inv, sb2_inv, sb3_inv,
sb4_inv, sb5_inv, sb6_inv, sb7_inv
};
void sbox128(void * w, uint8_t box){
uint8_t i, buffer[16];
box &= 0x7;
sb_fpt fp;
fp = (sb_fpt)(sf_tab[box]);
for(i=0; i<4; ++i){
fp(buffer+i, (uint8_t*)w+i);
}
memcpy(w, buffer, 16);
}
void inv_sbox128(void * w, uint8_t box){
uint8_t i, buffer[16];
box &= 0x7;
sb_fpt fp;
fp = (sb_fpt)(sinvf_tab[box]);
for(i=0; i<4; ++i){
fp(buffer+i, (uint8_t*)w+i);
}
memcpy(w, buffer, 16);
}

28
serpent/serpent-sboxes.h Normal file
View File

@ -0,0 +1,28 @@
/* serpent-sboxes.h */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2008 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 SERPENTSBOXES_H_
#define SERPENTSBOXES_H_
#include <stdint.h>
void sbox128(void * w, uint8_t box);
void inv_sbox128(void * w, uint8_t box);
#endif /*SERPENTSBOXES_H_*/

127
serpent/serpent-sboxes_c.c Normal file
View File

@ -0,0 +1,127 @@
/* serpent-sboxes.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2010 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/>.
*/
/* serpent-sboxes.c
* a non-bitsliced implementation of the serpent sboxes
* author: Daniel Otte
* email: daniel.otte@rub.de
* license: GPLv3
*/
#include <stdint.h>
#include <string.h> /* memset() */
#include "serpent-sboxes.h"
const uint8_t sbox[] = {
0x38, 0xF1, 0xA6, 0x5B, 0xED, 0x42, 0x70, 0x9C,
0xFC, 0x27, 0x90, 0x5A, 0x1B, 0xE8, 0x6D, 0x34,
0x86, 0x79, 0x3C, 0xAF, 0xD1, 0xE4, 0x0B, 0x52,
0x0F, 0xB8, 0xC9, 0x63, 0xD1, 0x24, 0xA7, 0x5E,
0x1F, 0x83, 0xC0, 0xB6, 0x25, 0x4A, 0x9E, 0x7D,
0xF5, 0x2B, 0x4A, 0x9C, 0x03, 0xE8, 0xD6, 0x71,
0x72, 0xC5, 0x84, 0x6B, 0xE9, 0x1F, 0xD3, 0xA0,
0x1D, 0xF0, 0xE8, 0x2B, 0x74, 0xCA, 0x93, 0x56,
/* now the inverted sboxes */
0xD3, 0xB0, 0xA6, 0x5C, 0x1E, 0x47, 0xF9, 0x82,
0x58, 0x2E, 0xF6, 0xC3, 0xB4, 0x79, 0x1D, 0xA0,
0xC9, 0xF4, 0xBE, 0x12, 0x03, 0x6D, 0x58, 0xA7,
0x09, 0xA7, 0xBE, 0x6D, 0x35, 0xC2, 0x48, 0xF1,
0x50, 0x83, 0xA9, 0x7E, 0x2C, 0xB6, 0x4F, 0xD1,
0x8F, 0x29, 0x41, 0xDE, 0xB6, 0x53, 0x7C, 0xA0,
0xFA, 0x1D, 0x53, 0x60, 0x49, 0xE7, 0x2C, 0x8B,
0x30, 0x6D, 0x9E, 0xF8, 0x5C, 0xB7, 0xA1, 0x42
};
#define SHR_O(a) c=(a)&1; ((a) = (a)>>1)
#define SHR_I(a) ((a) = (c?0x80:0x00)| ((a)>>1))
static void serpent_ip(uint32_t *i, uint8_t *o){
uint8_t c; // carry
uint8_t n,m;
memset(o, 0, 16);
for(n=0; n<16; ++n){
for(m=0; m<2; ++m){
SHR_O(i[0]);
SHR_I(o[n]);
SHR_O(i[1]);
SHR_I(o[n]);
SHR_O(i[2]);
SHR_I(o[n]);
SHR_O(i[3]);
SHR_I(o[n]);
}
}
}
#undef SHR_I
#define SHR_I(a) ((a) = (c?0x80000000L:0x00L)| ((a)>>1)) /* we use 32-bit words here */
static void serpent_fp(uint32_t *i, uint32_t *o){
uint8_t c; // carry
uint8_t n,m;
memset(o, 0, 16);
for(n=0; n<4; ++n){
for(m=0; m<8; ++m){
SHR_O(i[n]);
SHR_I(o[0]);
SHR_O(i[n]);
SHR_I(o[1]);
SHR_O(i[n]);
SHR_I(o[2]);
SHR_O(i[n]);
SHR_I(o[3]);
}
}
}
/******************************************************************************/
static void sbox128x(uint8_t box, void* w){
uint8_t sb[16];
uint8_t i,t,x;
box &= 0x0f;
/* load sbox */
for(i=0; i<8; ++i){
t = sbox[box*8 + i];
sb[2*i+0]=t>>4;
sb[2*i+1]=t&0xf;
}
uint8_t o[16];
serpent_ip(w,o);
for(i=0; i<16; ++i){
t = ((uint8_t*)o)[i];
x = sb[t>>4];
x <<= 4;
x |= sb[t&0xf];
((uint8_t*)o)[i] = x;
}
serpent_fp((uint32_t*)o, w);
}
void sbox128(void * w, uint8_t box){
sbox128x(box&0x7, w);
}
void inv_sbox128(void * w, uint8_t box){
sbox128x(((box&0x7)|0x8), w);
}

139
serpent/serpent.c Normal file
View File

@ -0,0 +1,139 @@
/* serpent.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2010 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/>.
*/
/* serpent.c
* a bitsliced implementation of the serpent cipher for avr microcontrollers
* author: Daniel Otte
* email: daniel.otte@rub.de
* license: GPLv3
*/
#include <stdint.h>
#include <string.h> /* memset() */
#include "memxor.h"
#include "serpent.h"
#include "serpent-sboxes.h"
/******************************************************************************/
uint32_t rotl32(uint32_t a, uint8_t n){
return ((a<<n) | (a>>(32-n)));
}
uint32_t rotr32(uint32_t a, uint8_t n){
return ((a>>n) | (a<<(32-n)));
}
#define X0 (((uint32_t*)b)[0])
#define X1 (((uint32_t*)b)[1])
#define X2 (((uint32_t*)b)[2])
#define X3 (((uint32_t*)b)[3])
static void serpent_lt(uint8_t *b){
X0 = rotl32(X0, 13);
X2 = rotl32(X2, 3);
X1 ^= X0 ^ X2;
X3 ^= X2 ^ (X0 << 3);
X1 = rotl32(X1, 1);
X3 = rotl32(X3, 7);
X0 ^= X1 ^ X3;
X2 ^= X3 ^ (X1 << 7);
X0 = rotl32(X0, 5);
X2 = rotr32(X2, 10);
}
static void serpent_inv_lt(uint8_t *b){
X2 = rotl32(X2, 10);
X0 = rotr32(X0, 5);
X2 ^= X3 ^ (X1 << 7);
X0 ^= X1 ^ X3;
X3 = rotr32(X3, 7);
X1 = rotr32(X1, 1);
X3 ^= X2 ^ (X0 << 3);
X1 ^= X0 ^ X2;
X2 = rotr32(X2, 3);
X0 = rotr32(X0, 13);
}
#define GOLDEN_RATIO 0x9e3779b9l
static uint32_t serpent_gen_w(uint32_t * b, uint8_t i){
uint32_t ret;
ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ (uint32_t)i;
ret = rotl32(ret, 11);
return ret;
}
void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx){
uint32_t buffer[8];
uint8_t i,j;
if(keysize_b<256){
/* keysize is less than 256 bit, padding needed */
memset(buffer, 0, 32);
memcpy(buffer, key, (keysize_b+7)/8);
((uint8_t*)buffer)[keysize_b/8] |= 1<<(keysize_b%8);
} else {
/* keysize is 256 bit */
memcpy((void*)buffer, key, 32);
}
for(i=0; i<33; ++i){
for(j=0; j<4; ++j){
ctx->k[i][j] = serpent_gen_w(buffer, i*4+j);
memmove(buffer, &(buffer[1]), 7*4); /* shift buffer one to the "left" */
buffer[7] = ctx->k[i][j];
}
}
for(i=0; i<33; ++i){
sbox128(ctx->k[i],3-i);
}
}
void serpent_enc(void* buffer, const serpent_ctx_t* ctx){
uint8_t i;
for(i=0; i<31; ++i){
memxor(buffer, ctx->k[i], 16);
sbox128(buffer, i);
serpent_lt((uint8_t*)buffer);
}
memxor(buffer, ctx->k[i], 16);
sbox128(buffer, i);
++i;
memxor(buffer, ctx->k[i], 16);
}
void serpent_dec(void* buffer, const serpent_ctx_t* ctx){
int8_t i=32;
memxor(buffer, ctx->k[i], 16);
--i;
inv_sbox128(buffer, i);
memxor((uint8_t*)buffer, ctx->k[i], 16);
--i;
for(; i>=0; --i){
serpent_inv_lt(buffer);
inv_sbox128(buffer, i);
memxor(buffer, ctx->k[i], 16);
}
}

47
serpent/serpent.h Normal file
View File

@ -0,0 +1,47 @@
/* serpent.h */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2008 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/>.
*/
/** \file serpent.h
* \author Daniel Otte
* \license GPLv3
* \brief a implementation of the serpent cipher for avr microcontrollers
*/
#ifndef SERPENT_H_
#define SERPENT_H_
#include <stdint.h>
typedef uint32_t serpent_subkey_t[4];
typedef struct serpent_ctx_st {
serpent_subkey_t k[33];
} serpent_ctx_t;
#define SERPENT_KEY128 128
#define SERPENT_KEY192 192
#define SERPENT_KEY256 256
/* key must be 256bit (32 byte) large! */
void serpent_init(const void* key, uint16_t keysize_b, serpent_ctx_t* ctx);
void serpent_enc(void* buffer, const serpent_ctx_t* ctx);
void serpent_dec(void* buffer, const serpent_ctx_t* ctx);
#endif /*SERPENT_H_*/

View File

@ -0,0 +1,150 @@
/* main-serpent-test.c */
/*
This file is part of the ARM-Crypto-Lib.
Copyright (C) 2006-2010 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/>.
*/
/*
* serpent test-suit
*
*/
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "cli.h"
#include "dump.h"
#include "uart_lowlevel.h"
#include "sysclock.h"
#include "hw_gptm.h"
#include "serpent.h"
#include "nessie_bc_test.h"
#include "performance_test.h"
#include "bcal-performance.h"
#include "bcal_serpent.h"
char* algo_name = "Serpent";
void uart0_putc(char byte){
uart_putc(UART_0, byte);
}
char uart0_getc(void){
return uart_getc(UART_0);
}
const bcdesc_t* algolist[] = {
(bcdesc_t*)&serpent_desc,
NULL
};
/*****************************************************************************
* additional validation-functions *
*****************************************************************************/
void testrun_nessie_serpent(void){
nessie_bc_ctx.blocksize_B = 16;
nessie_bc_ctx.keysize_b = 128;
nessie_bc_ctx.name = algo_name;
nessie_bc_ctx.ctx_size_B = sizeof(serpent_ctx_t);
nessie_bc_ctx.cipher_enc = (nessie_bc_enc_fpt)serpent_enc;
nessie_bc_ctx.cipher_dec = (nessie_bc_dec_fpt)serpent_dec;
nessie_bc_ctx.cipher_genctx = (nessie_bc_gen_fpt)serpent_init;
nessie_bc_run();
nessie_bc_ctx.keysize_b = 192;
nessie_bc_run();
nessie_bc_ctx.keysize_b = 256;
nessie_bc_run();
}
void testrun_test_serpent(void){
uint8_t key[32];
serpent_ctx_t ctx;
uint8_t i;
memset(key, 0, 16);
serpent_init(key, 128, &ctx);
for(i=0; i<33; ++i){
cli_putstr("\r\n subkekey ");
cli_hexdump(&i, 1);
cli_putstr(" : ");
cli_hexdump(ctx.k[i], 16);
}
}
void testrun_serpent256(void){
uint8_t key[32];
uint8_t data[16];
serpent_ctx_t ctx;
memset(key, 0, 32);
memset(data, 0, 16);
key[0] = 0x80;
cli_putstr("\r\n== small test Serpent-256 ==");
cli_putstr("\r\n key = ");
cli_hexdump(key, 32);
cli_putstr("\r\n plain = ");
cli_hexdump(data, 16);
serpent_init(key, 256, &ctx);
serpent_enc(data, &ctx);
cli_putstr("\r\n cipher = ");
cli_hexdump(data, 16);
}
void testrun_performance_serpent(void){
bcal_performance_multiple(algolist);
}
/*****************************************************************************
* main *
*****************************************************************************/
const char nessie_str[] = "nessie";
const char test_str[] = "test";
const char test256_str[] = "test256";
const char performance_str[] = "performance";
const char echo_str[] = "echo";
const cmdlist_entry_t cmdlist[] = {
{ nessie_str, NULL, testrun_nessie_serpent},
{ test_str, NULL, testrun_test_serpent},
{ test256_str, NULL, testrun_serpent256},
{ performance_str, NULL, testrun_performance_serpent},
{ echo_str, (void*)1, (void_fpt)echo_ctrl},
{ NULL, NULL, NULL}
};
int main (void){
sysclk_set_freq(SYS_FREQ);
sysclk_mosc_verify_enable();
uart_init(UART_0, 115200, 8, UART_PARATY_NONE, UART_STOPBITS_ONE);
gptm_set_timer_32periodic(TIMER0);
cli_rx = uart0_getc;
cli_tx = uart0_putc;
for(;;){
cli_putstr("\r\n\r\nARM-Crypto-Lib VS (");
cli_putstr(algo_name);
cli_putstr("; ");
cli_putstr(__DATE__);
cli_putc(' ');
cli_putstr(__TIME__);
cli_putstr(")\r\nloaded and running\r\n");
cmd_interface(cmdlist);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff