Update myserpent.c

Change the interface
This commit is contained in:
GGSuchao
2017-04-06 12:24:12 +08:00
committed by Simon
parent 725588764e
commit 41411e2f9b

View File

@@ -1,319 +1,230 @@
/* This is an implementation of the encryption algorithm: */
/* Serpent by Ross Anderson, Eli Biham and Lars Knudsen */
/* which is a candidate algorithm in the Advanced Encryption Standard */
/* programme of the US National Institute of Standards and Technology. */
/* Copyright in this implementation is held by Dou Qinglin. but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
#include <stdio.h>
#include <stdlib.h>
#include "myserpent.h"
/**
Copyright © 2015 Odzhan
Copyright © 2008 Daniel Otte
All Rights Reserved.
#define IN
#define OUT
void linear(IN unsigned long int *li_0,IN unsigned long int *li_1,IN unsigned long int *li_2,IN unsigned long int *li_3,OUT unsigned long int *lo_0,OUT unsigned long int *lo_1,OUT unsigned long int *lo_2,OUT unsigned long int *lo_3);
void IP(IN unsigned long int *ip_i0,IN unsigned long int *ip_i1,IN unsigned long int *ip_i2,IN unsigned long int *ip_i3,OUT unsigned long int *ip_o0,OUT unsigned long int *ip_o1,OUT unsigned long int *ip_o2,OUT unsigned long int *ip_o3);
void FP(IN unsigned long int *fp_i0,IN unsigned long int *fp_i1,IN unsigned long int *fp_i2,IN unsigned long int *fp_i3,OUT unsigned long int *fp_o0,OUT unsigned long int *fp_o1,OUT unsigned long int *fp_o2,OUT unsigned long int *fp_o3);
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
volatile unsigned long int takbit_in0,takbit_in1,takbit_in2,takbit_in3;
#include "serpent.h"
unsigned char takebit(unsigned char bit_num){
unsigned char bit_out;
if (bit_num< 32) bit_out = ((takbit_in0<< bit_num )&0x80000000)>>31;
else if (bit_num< 64) bit_out = ((takbit_in1<<(bit_num-32))&0x80000000)>>31;
else if (bit_num< 96) bit_out = ((takbit_in2<<(bit_num-64))&0x80000000)>>31;
else if (bit_num< 128) bit_out = ((takbit_in3<<(bit_num-96))&0x80000000)>>31;
else ;
return (bit_out & 0x00000001);
void serpent_whiten(serpent_blk *dst, serpent_key_t *src, int idx) {
uint8_t i;
serpent_blk *p = (serpent_blk*)&src->x[idx];
for (i = 0; i<SERPENT_BLK_LEN / 4; i++) {
dst->w[i] ^= p->w[i];
}
}
//sbox involking func, each block use 1 sbox 32 times by involking this func for 4 times
unsigned long int sb(char sb_num,unsigned long int sb_in_long){
char sb_i[8];
char sb_o[8];
unsigned long int sb_out_long;
char cnt;
//data div, 32bit input divide into 8 parts, each 4bit
sb_i[0] = (sb_in_long>>28) & 0x0f; // 0~3f
sb_i[1] = (sb_in_long>>24) & 0x0f; // 4~7
sb_i[2] = (sb_in_long>>20) & 0x0f; // 8~11
sb_i[3] = (sb_in_long>>16) & 0x0f; // 12~15
sb_i[4] = (sb_in_long>>12) & 0x0f; // 16~19
sb_i[5] = (sb_in_long>> 8) & 0x0f; // 20~23
sb_i[6] = (sb_in_long>> 4) & 0x0f; // 24~27
sb_i[7] = (sb_in_long ) & 0x0f; // 28~31
//judge which sbox to use,and get 8 outputs of 8 independent
switch (sb_num)
void permute(serpent_blk *out,
serpent_blk *in, int type)
{
uint8_t cy;
uint8_t n, m;
for (n = 0; n<SERPENT_BLK_LEN / 4; n++) {
out->w[n] = 0;
}
if (type == SERPENT_IP)
{
case 0: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb0(sb_i[cnt] );break;
case 1: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb1(sb_i[cnt] );break;
case 2: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb2(sb_i[cnt] );break;
case 3: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb3(sb_i[cnt] );break;
case 4: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb4(sb_i[cnt] );break;
case 5: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb5(sb_i[cnt] );break;
case 6: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb6(sb_i[cnt] );break;
case 7: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = sb7(sb_i[cnt] );break;
default: for (cnt = 0; cnt < 8; cnt++) sb_o[cnt] = 0x0; break;
for (n = 0; n<16; n++) {
for (m = 0; m<8; m++) {
cy = in->w[m % 4] & 1;
in->w[m % 4] >>= 1;
out->b[n] = (cy << 7) | (out->b[n] >> 1);
}
}
}
else {
for (n = 0; n<4; n++) {
for (m = 0; m<32; m++) {
cy = in->w[n] & 1;
in->w[n] >>= 1;
out->w[m % 4] = (cy << 31) | (out->w[m % 4] >> 1);
}
}
}
//combine the sbox output together
sb_out_long = (sb_o[0]<<28) + (sb_o[1]<<24) + (sb_o[2]<<20) + (sb_o[3]<<16) + (sb_o[4]<<12) + (sb_o[5]<<8) + (sb_o[6]<<4) + sb_o[7];
return sb_out_long;
}
//define the sbox0~7 un-linear logic
char sb0(char sb0_in){
char sb0_o;
switch (sb0_in){
case 0x0: sb0_o= 3 ;break;
case 0x1: sb0_o= 8 ;break;
case 0x2: sb0_o= 15;break;
case 0x3: sb0_o= 1 ;break;
case 0x4: sb0_o= 10;break;
case 0x5: sb0_o= 6 ;break;
case 0x6: sb0_o= 5 ;break;
case 0x7: sb0_o= 11;break;
case 0x8: sb0_o= 14;break;
case 0x9: sb0_o= 13;break;
case 0xA: sb0_o= 4 ;break;
case 0xB: sb0_o= 2 ;break;
case 0xC: sb0_o= 7 ;break;
case 0xD: sb0_o= 0 ;break;
case 0xE: sb0_o= 9 ;break;
case 0xF: sb0_o= 12;break;
default: sb0_o= 0 ;break;
}
return sb0_o;
#define HI_NIBBLE(b) (((b) >> 4) & 0x0F)
#define LO_NIBBLE(b) ((b) & 0x0F)
uint32_t serpent_gen_w(uint32_t *b, uint32_t i) {
uint32_t ret;
ret = b[0] ^ b[3] ^ b[5] ^ b[7] ^ GOLDEN_RATIO ^ i;
return ROTL32(ret, 11);
}
char sb1(char sb1_in){
char sb1_o;
switch (sb1_in){
case 0x0: sb1_o= 15;break;
case 0x1: sb1_o= 12;break;
case 0x2: sb1_o= 2 ;break;
case 0x3: sb1_o= 7 ;break;
case 0x4: sb1_o= 9 ;break;
case 0x5: sb1_o= 0 ;break;
case 0x6: sb1_o= 5 ;break;
case 0x7: sb1_o= 10;break;
case 0x8: sb1_o= 1 ;break;
case 0x9: sb1_o= 11;break;
case 0xA: sb1_o= 14;break;
case 0xB: sb1_o= 8 ;break;
case 0xC: sb1_o= 6 ;break;
case 0xD: sb1_o= 13;break;
case 0xE: sb1_o= 3 ;break;
case 0xF: sb1_o= 4 ;break;
default: sb1_o= 0 ;break;
void serpent_subbytes(serpent_blk *blk, uint32_t box_idx, int type)
{
serpent_blk tmp_blk, sb;
uint8_t *sbp;
uint8_t i, t;
uint8_t sbox[8][8] =
{ { 0x83, 0x1F, 0x6A, 0xB5, 0xDE, 0x24, 0x07, 0xC9 },
{ 0xCF, 0x72, 0x09, 0xA5, 0xB1, 0x8E, 0xD6, 0x43 },
{ 0x68, 0x97, 0xC3, 0xFA, 0x1D, 0x4E, 0xB0, 0x25 },
{ 0xF0, 0x8B, 0x9C, 0x36, 0x1D, 0x42, 0x7A, 0xE5 },
{ 0xF1, 0x38, 0x0C, 0x6B, 0x52, 0xA4, 0xE9, 0xD7 },
{ 0x5F, 0xB2, 0xA4, 0xC9, 0x30, 0x8E, 0x6D, 0x17 },
{ 0x27, 0x5C, 0x48, 0xB6, 0x9E, 0xF1, 0x3D, 0x0A },
{ 0xD1, 0x0F, 0x8E, 0xB2, 0x47, 0xAC, 0x39, 0x65 }
};
uint8_t sbox_inv[8][8] =
{ { 0x3D, 0x0B, 0x6A, 0xC5, 0xE1, 0x74, 0x9F, 0x28 },
{ 0x85, 0xE2, 0x6F, 0x3C, 0x4B, 0x97, 0xD1, 0x0A },
{ 0x9C, 0x4F, 0xEB, 0x21, 0x30, 0xD6, 0x85, 0x7A },
{ 0x90, 0x7A, 0xEB, 0xD6, 0x53, 0x2C, 0x84, 0x1F },
{ 0x05, 0x38, 0x9A, 0xE7, 0xC2, 0x6B, 0xF4, 0x1D },
{ 0xF8, 0x92, 0x14, 0xED, 0x6B, 0x35, 0xC7, 0x0A },
{ 0xAF, 0xD1, 0x35, 0x06, 0x94, 0x7E, 0xC2, 0xB8 },
{ 0x03, 0xD6, 0xE9, 0x8F, 0xC5, 0x7B, 0x1A, 0x24 }
};
box_idx &= 7;
if (type == SERPENT_ENCRYPT) {
sbp = (uint8_t*)&sbox[box_idx][0];
}
return sb1_o;
else {
sbp = (uint8_t*)&sbox_inv[box_idx][0];
}
for (i = 0; i<16; i += 2) {
t = sbp[i / 2];
sb.b[i + 0] = LO_NIBBLE(t);
sb.b[i + 1] = HI_NIBBLE(t);
}
permute(&tmp_blk, blk, SERPENT_IP);
for (i = 0; i<SERPENT_BLK_LEN; i++) {
t = tmp_blk.b[i];
tmp_blk.b[i] = (sb.b[HI_NIBBLE(t)] << 4) | sb.b[LO_NIBBLE(t)];
}
permute(blk, &tmp_blk, SERPENT_FP);
}
char sb2(char sb2_in){
char sb2_o;
switch (sb2_in){
case 0x0: sb2_o= 8 ;break;
case 0x1: sb2_o= 6 ;break;
case 0x2: sb2_o= 7 ;break;
case 0x3: sb2_o= 9 ;break;
case 0x4: sb2_o= 3 ;break;
case 0x5: sb2_o= 12;break;
case 0x6: sb2_o= 10;break;
case 0x7: sb2_o= 15;break;
case 0x8: sb2_o= 13;break;
case 0x9: sb2_o= 1 ;break;
case 0xA: sb2_o= 14;break;
case 0xB: sb2_o= 4 ;break;
case 0xC: sb2_o= 0 ;break;
case 0xD: sb2_o= 11;break;
case 0xE: sb2_o= 5 ;break;
case 0xF: sb2_o= 2 ;break;
default: sb2_o= 0 ;break;
}
return sb2_o;
}
char sb3(char sb3_in){
char sb3_o;
switch (sb3_in){
case 0x0: sb3_o= 0 ;break;
case 0x1: sb3_o= 15;break;
case 0x2: sb3_o= 11;break;
case 0x3: sb3_o= 8 ;break;
case 0x4: sb3_o= 12;break;
case 0x5: sb3_o= 9 ;break;
case 0x6: sb3_o= 6 ;break;
case 0x7: sb3_o= 3 ;break;
case 0x8: sb3_o= 13;break;
case 0x9: sb3_o= 1 ;break;
case 0xA: sb3_o= 2 ;break;
case 0xB: sb3_o= 4 ;break;
case 0xC: sb3_o= 10;break;
case 0xD: sb3_o= 7 ;break;
case 0xE: sb3_o= 5 ;break;
case 0xF: sb3_o= 14;break;
default: sb3_o= 0 ;break;
}
return sb3_o;
}
char sb4(char sb4_in){
char sb4_o;
switch (sb4_in){
case 0x0: sb4_o= 1 ;break;
case 0x1: sb4_o= 15;break;
case 0x2: sb4_o= 8 ;break;
case 0x3: sb4_o= 3 ;break;
case 0x4: sb4_o= 12;break;
case 0x5: sb4_o= 0 ;break;
case 0x6: sb4_o= 11;break;
case 0x7: sb4_o= 6 ;break;
case 0x8: sb4_o= 2 ;break;
case 0x9: sb4_o= 5 ;break;
case 0xA: sb4_o= 4 ;break;
case 0xB: sb4_o= 10;break;
case 0xC: sb4_o= 9 ;break;
case 0xD: sb4_o= 14;break;
case 0xE: sb4_o= 7 ;break;
case 0xF: sb4_o= 13;break;
default: sb4_o= 0; break;
}
return sb4_o;
}
char sb5(char sb5_in){
char sb5_o;
switch (sb5_in){
case 0x0: sb5_o= 15;break;
case 0x1: sb5_o= 5 ;break;
case 0x2: sb5_o= 2 ;break;
case 0x3: sb5_o= 11;break;
case 0x4: sb5_o= 4 ;break;
case 0x5: sb5_o= 10;break;
case 0x6: sb5_o= 9 ;break;
case 0x7: sb5_o= 12;break;
case 0x8: sb5_o= 0 ;break;
case 0x9: sb5_o= 3 ;break;
case 0xA: sb5_o= 14;break;
case 0xB: sb5_o= 8 ;break;
case 0xC: sb5_o= 13;break;
case 0xD: sb5_o= 6 ;break;
case 0xE: sb5_o= 7 ;break;
case 0xF: sb5_o= 1 ;break;
default: sb5_o= 0; break;
}
return sb5_o;
}
char sb6(char sb6_in){
char sb6_o;
switch (sb6_in){
case 0x0: sb6_o= 7 ;break;
case 0x1: sb6_o= 2 ;break;
case 0x2: sb6_o= 12;break;
case 0x3: sb6_o= 5 ;break;
case 0x4: sb6_o= 8 ;break;
case 0x5: sb6_o= 4 ;break;
case 0x6: sb6_o= 6 ;break;
case 0x7: sb6_o= 11;break;
case 0x8: sb6_o= 14;break;
case 0x9: sb6_o= 9 ;break;
case 0xA: sb6_o= 1 ;break;
case 0xB: sb6_o= 15;break;
case 0xC: sb6_o= 13;break;
case 0xD: sb6_o= 3 ;break;
case 0xE: sb6_o= 10;break;
case 0xF: sb6_o= 0 ;break;
default: sb6_o= 0 ;break;
}
return sb6_o;
}
char sb7(char sb7_in){
char sb7_o;
switch (sb7_in){
case 0x0: sb7_o= 1 ;break;
case 0x1: sb7_o= 13;break;
case 0x2: sb7_o= 15;break;
case 0x3: sb7_o= 0 ;break;
case 0x4: sb7_o= 14;break;
case 0x5: sb7_o= 8 ;break;
case 0x6: sb7_o= 2 ;break;
case 0x7: sb7_o= 11;break;
case 0x8: sb7_o= 7 ;break;
case 0x9: sb7_o= 4 ;break;
case 0xA: sb7_o= 12;break;
case 0xB: sb7_o= 10;break;
case 0xC: sb7_o= 9 ;break;
case 0xD: sb7_o= 3 ;break;
case 0xE: sb7_o= 5 ;break;
case 0xF: sb7_o= 6 ;break;
default: sb7_o= 0 ;break;
}
return sb7_o;
}
void serpent_lt(serpent_blk* x, int enc)
{
uint32_t x0, x1, x2, x3;
//initial permutation
void IP(IN unsigned long int *ip_i0,IN unsigned long int *ip_i1,IN unsigned long int *ip_i2,IN unsigned long int *ip_i3,OUT unsigned long int *ip_o0,OUT unsigned long int *ip_o1,OUT unsigned long int *ip_o2,OUT unsigned long int *ip_o3){
unsigned long int tmp_0,tmp_1,tmp_2,tmp_3;
takbit_in0 = *ip_i0;
takbit_in1 = *ip_i1;
takbit_in2 = *ip_i2;
takbit_in3 = *ip_i3;
//execute takbit function
tmp_0 = (takebit(120)<<31) + (takebit( 88)<<30) + (takebit( 56)<<29) + (takebit( 24)<<28) + (takebit(121)<<27) + (takebit( 89)<<26) + (takebit( 57)<<25) + (takebit( 25)<<24) + (takebit(122)<<23) + (takebit( 90)<<22) + (takebit( 58)<<21) + (takebit( 26)<<20) + (takebit(123)<<19) + (takebit( 91)<<18) + (takebit( 59)<<17) + (takebit( 27)<<16) + (takebit(124)<<15) + (takebit( 92)<<14) + (takebit( 60)<<13) + (takebit( 28)<<12) + (takebit(125)<<11) + (takebit( 93)<<10) + (takebit( 61)<<9 ) + (takebit( 29)<<8 ) + (takebit(126)<<7 ) + (takebit( 94)<<6 ) + (takebit( 62)<<5 ) + (takebit( 30)<<4 ) + (takebit(127)<<3 ) + (takebit( 95)<<2 ) + (takebit( 63)<<1 ) + (takebit( 31) );
tmp_1 = (takebit(112)<<31) + (takebit( 80)<<30) + (takebit( 48)<<29) + (takebit( 16)<<28) + (takebit(113)<<27) + (takebit( 81)<<26) + (takebit( 49)<<25) + (takebit( 17)<<24) + (takebit(114)<<23) + (takebit( 82)<<22) + (takebit( 50)<<21) + (takebit( 18)<<20) + (takebit(115)<<19) + (takebit( 83)<<18) + (takebit( 51)<<17) + (takebit( 19)<<16) + (takebit(116)<<15) + (takebit( 84)<<14) + (takebit( 52)<<13) + (takebit( 20)<<12) + (takebit(117)<<11) + (takebit( 85)<<10) + (takebit( 53)<<9 ) + (takebit( 21)<<8 ) + (takebit(118)<<7 ) + (takebit( 86)<<6 ) + (takebit( 54)<<5 ) + (takebit( 22)<<4 ) + (takebit(119)<<3 ) + (takebit( 87)<<2 ) + (takebit( 55)<<1 ) + (takebit( 23) );
tmp_2 = (takebit(104)<<31) + (takebit( 72)<<30) + (takebit( 40)<<29) + (takebit( 8)<<28) + (takebit(105)<<27) + (takebit( 73)<<26) + (takebit( 41)<<25) + (takebit( 9)<<24) + (takebit(106)<<23) + (takebit( 74)<<22) + (takebit( 42)<<21) + (takebit( 10)<<20) + (takebit(107)<<19) + (takebit( 75)<<18) + (takebit( 43)<<17) + (takebit( 11)<<16) + (takebit(108)<<15) + (takebit( 76)<<14) + (takebit( 44)<<13) + (takebit( 12)<<12) + (takebit(109)<<11) + (takebit( 77)<<10) + (takebit( 45)<<9 ) + (takebit( 13)<<8 ) + (takebit(110)<<7 ) + (takebit( 78)<<6 ) + (takebit( 46)<<5 ) + (takebit( 14)<<4 ) + (takebit(111)<<3 ) + (takebit( 79)<<2 ) + (takebit( 47)<<1 ) + (takebit( 15) );
tmp_3 = (takebit( 96)<<31) + (takebit( 64)<<30) + (takebit( 32)<<29) + (takebit( 0)<<28) + (takebit( 97)<<27) + (takebit( 65)<<26) + (takebit( 33)<<25) + (takebit( 1)<<24) + (takebit( 98)<<23) + (takebit( 66)<<22) + (takebit( 34)<<21) + (takebit( 2)<<20) + (takebit( 99)<<19) + (takebit( 67)<<18) + (takebit( 35)<<17) + (takebit( 3)<<16) + (takebit(100)<<15) + (takebit( 68)<<14) + (takebit( 36)<<13) + (takebit( 4)<<12) + (takebit(101)<<11) + (takebit( 69)<<10) + (takebit( 37)<<9 ) + (takebit( 5)<<8 ) + (takebit(102)<<7 ) + (takebit( 70)<<6 ) + (takebit( 38)<<5 ) + (takebit( 6)<<4 ) + (takebit(103)<<3 ) + (takebit( 71)<<2 ) + (takebit( 39)<<1 ) + (takebit( 7) );
//write data to sb_in[]
*ip_o0 = tmp_0;
*ip_o1 = tmp_1;
*ip_o2 = tmp_2;
*ip_o3 = tmp_3;
// load
x0 = x->w[0];
x1 = x->w[1];
x2 = x->w[2];
x3 = x->w[3];
if (enc == SERPENT_DECRYPT) {
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);
}
else {
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);
}
x->w[0] = x0;
x->w[1] = x1;
x->w[2] = x2;
x->w[3] = x3;
}
//initial permutation
void FP(IN unsigned long int *fp_i0,IN unsigned long int *fp_i1,IN unsigned long int *fp_i2,IN unsigned long int *fp_i3,OUT unsigned long int *fp_o0,OUT unsigned long int *fp_o1,OUT unsigned long int *fp_o2,OUT unsigned long int *fp_o3){
unsigned long int tmp_0,tmp_1,tmp_2,tmp_3;
takbit_in0 = *fp_i0;
takbit_in1 = *fp_i1;
takbit_in2 = *fp_i2;
takbit_in3 = *fp_i3;
//execute takbit function
tmp_3 = (takebit(96)<<31) + (takebit(100 )<<30) + (takebit(104 )<<29) + (takebit(108 )<<28) + (takebit(112 )<<27) + (takebit(116 )<<26) + (takebit(120 )<<25) + (takebit(124 )<<24) + (takebit(64)<<23) + (takebit(68 )<<22) + (takebit(72 )<<21) + (takebit(76 )<<20) + (takebit(80 )<<19) + (takebit(84 )<<18) + (takebit(88 )<<17) + (takebit(92 )<<16) + (takebit(32)<<15) + (takebit(36 )<<14) + (takebit(40 )<<13) + (takebit(44 )<<12) + (takebit(48 )<<11) + (takebit(52 )<<10) + (takebit(56 )<<9) + (takebit(60 )<<8) + (takebit(0 )<<7) + (takebit( 4 )<<6) + (takebit( 8 )<<5) + (takebit(12 )<<4) + (takebit(16 )<<3) + (takebit(20 )<<2) + (takebit(24 )<<1) + takebit(28 );
tmp_2 = (takebit(97)<<31) + (takebit(101 )<<30) + (takebit(105 )<<29) + (takebit(109 )<<28) + (takebit(113 )<<27) + (takebit(117 )<<26) + (takebit(121 )<<25) + (takebit(125 )<<24) + (takebit(65)<<23) + (takebit(69 )<<22) + (takebit(73 )<<21) + (takebit(77 )<<20) + (takebit(81 )<<19) + (takebit(85 )<<18) + (takebit(89 )<<17) + (takebit(93 )<<16) + (takebit(33)<<15) + (takebit(37 )<<14) + (takebit(41 )<<13) + (takebit(45 )<<12) + (takebit(49 )<<11) + (takebit(53 )<<10) + (takebit(57 )<<9) + (takebit(61 )<<8) + (takebit(1 )<<7) + (takebit( 5 )<<6) + (takebit( 9 )<<5) + (takebit(13 )<<4) + (takebit(17 )<<3) + (takebit(21 )<<2) + (takebit(25 )<<1) + takebit(29 );
tmp_1 = (takebit(98)<<31) + (takebit(102 )<<30) + (takebit(106 )<<29) + (takebit(110 )<<28) + (takebit(114 )<<27) + (takebit(118 )<<26) + (takebit(122 )<<25) + (takebit(126 )<<24) + (takebit(66)<<23) + (takebit(70 )<<22) + (takebit(74 )<<21) + (takebit(78 )<<20) + (takebit(82 )<<19) + (takebit(86 )<<18) + (takebit(90 )<<17) + (takebit(94 )<<16) + (takebit(34)<<15) + (takebit(38 )<<14) + (takebit(42 )<<13) + (takebit(46 )<<12) + (takebit(50 )<<11) + (takebit(54 )<<10) + (takebit(58 )<<9) + (takebit(62 )<<8) + (takebit(2 )<<7) + (takebit( 6 )<<6) + (takebit(10 )<<5) + (takebit(14 )<<4) + (takebit(18 )<<3) + (takebit(22 )<<2) + (takebit(26 )<<1) + takebit(30 );
tmp_0 = (takebit(99)<<31) + (takebit(103 )<<30) + (takebit(107 )<<29) + (takebit(111 )<<28) + (takebit(115 )<<27) + (takebit(119 )<<26) + (takebit(123 )<<25) + (takebit(127 )<<24) + (takebit(67)<<23) + (takebit(71 )<<22) + (takebit(75 )<<21) + (takebit(79 )<<20) + (takebit(83 )<<19) + (takebit(87 )<<18) + (takebit(91 )<<17) + (takebit(95 )<<16) + (takebit(35)<<15) + (takebit(39 )<<14) + (takebit(43 )<<13) + (takebit(47 )<<12) + (takebit(51 )<<11) + (takebit(55 )<<10) + (takebit(59 )<<9) + (takebit(63 )<<8) + (takebit(3 )<<7) + (takebit( 7 )<<6) + (takebit(11 )<<5) + (takebit(15 )<<4) + (takebit(19 )<<3) + (takebit(23 )<<2) + (takebit(27 )<<1) + takebit(31 );
//data out
*fp_o0 = tmp_0;
*fp_o1 = tmp_1;
*fp_o2 = tmp_2;
*fp_o3 = tmp_3;
void serpent_set_encrypt_key(serpent_key_t *key, void *user_key)
{
union {
uint8_t b[32];
uint32_t w[8];
} s_ws;
uint32_t i, j;
// copy key input to local buffer
memcpy(&s_ws.b[0], user_key, SERPENT_KEY256);
// expand the key
for (i = 0; i <= SERPENT_ROUNDS; i++) {
for (j = 0; j<4; j++) {
key->x[i][j] = serpent_gen_w(s_ws.w, i * 4 + j);
memmove(&s_ws.b, &s_ws.b[4], 7 * 4);
s_ws.w[7] = key->x[i][j];
}
serpent_subbytes((serpent_blk*)&key->x[i], 3 - i, SERPENT_ENCRYPT);
}
}
void linear(IN unsigned long int *li_0,IN unsigned long int *li_1,IN unsigned long int *li_2,IN unsigned long int *li_3,OUT unsigned long int *lo_0,OUT unsigned long int *lo_1,OUT unsigned long int *lo_2,OUT unsigned long int *lo_3){
unsigned long int tmp_0,tmp_1,tmp_2,tmp_3;
tmp_0 = *li_0;
tmp_1 = *li_1;
tmp_2 = *li_2;
tmp_3 = *li_3;
tmp_0 = rotl(tmp_0, 13);
tmp_2 = rotl(tmp_2, 3);
tmp_1 = tmp_1 ^ tmp_0 ^ tmp_2;
tmp_3 = tmp_3 ^ tmp_2 ^ (tmp_0 << 3);
tmp_1 = rotl(tmp_1, 1);
tmp_3 = rotl(tmp_3, 7);
tmp_0 = tmp_0 ^ tmp_1 ^ tmp_3;
tmp_2 = tmp_2 ^ tmp_3 ^ (tmp_1 << 7);
tmp_0 = rotl(tmp_0, 5);
tmp_2 = rotl(tmp_2, 22);
*lo_0 = tmp_0;
*lo_1 = tmp_1;
*lo_2 = tmp_2;
*lo_3 = tmp_3;
void serpent_encrypt(void *in, serpent_key_t *key)
{
int8_t i;
serpent_blk *out = in;
i = 0;
for (;;) {
// xor with subkey
serpent_whiten(out, key, i);
// apply sbox
serpent_subbytes(out, i, SERPENT_ENCRYPT);
if (++i == SERPENT_ROUNDS) break;
// linear transformation
serpent_lt(out, SERPENT_ENCRYPT);
}
serpent_whiten(out, key, i);
}
void serpent_decrypt(void *in, serpent_key_t *key)
{
int8_t i;
serpent_blk *out = in;
i = SERPENT_ROUNDS;
serpent_whiten(out, key, i);
for (;;) {
--i;
// apply sbox
serpent_subbytes(out, i, SERPENT_DECRYPT);
// xor with subkey
serpent_whiten(out, key, i);
if (i == 0) break;
// linear transformation
serpent_lt(out, SERPENT_DECRYPT);
}
}