mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 08:56:17 +08:00
Update myserpent.c
Change the interface
This commit is contained in:
509
myserpent.c
509
myserpent.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user