mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Update test.c
This commit is contained in:
352
test.c
352
test.c
@@ -1,270 +1,108 @@
|
||||
#include <stdio.h>
|
||||
#include "myserpent.h"
|
||||
// test unit for serpent-256
|
||||
// Odzhan
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
unsigned long int key_0,key_1,key_2,key_3; //128bit key input
|
||||
int i;
|
||||
unsigned long int p_0,p_1,p_2,p_3; //plain data in
|
||||
unsigned long int c_0,c_1,c_2,c_3; //cipher data out
|
||||
unsigned long int wi[8] = {0}; //pre_key -8~-1
|
||||
unsigned long int w[132] = {0};//pre_key 0~131
|
||||
unsigned long int sb_in[132] = {0}; //sbox input after data_twist1
|
||||
unsigned long int sb_out[132] = {0};//sbox output
|
||||
unsigned long int k[132] = {0}; //sub_key
|
||||
|
||||
unsigned long int b[132] = {0}; //round input and result
|
||||
unsigned long int xor[132] = {0}; //round data after xor
|
||||
unsigned long int sbox[132] = {0}; //round data after sbox
|
||||
unsigned long int li[132] = {0}; //round data for linear transformation input,sbox output after FP
|
||||
unsigned long int lo[132] = {0}; //round data for linear transformation output,will goto IP
|
||||
|
||||
unsigned long int tmp_0,tmp_4,tmp_5;
|
||||
//here we start to record detail data
|
||||
FILE *fp;
|
||||
fp = fopen("serpent_data.sti","w");
|
||||
|
||||
tmp_4 = 0x1;
|
||||
|
||||
//detail data initial
|
||||
while(1){
|
||||
for( i = 0; i < 132; i++){
|
||||
w[i] = 0x0;
|
||||
sb_in[i] = 0x0;
|
||||
sb_out[i] = 0x0;
|
||||
k[i] = 0x0;
|
||||
b[i] = 0x0;
|
||||
xor[i] = 0x0;
|
||||
sbox[i] = 0x0;
|
||||
li[i] = 0x0;
|
||||
lo[i] = 0x0;
|
||||
}
|
||||
#include "serpent.h"
|
||||
|
||||
//step 0, key & plain data assignment
|
||||
char *plain[] =
|
||||
{ "3DA46FFA6F4D6F30CD258333E5A61369" };
|
||||
|
||||
printf("============================================ \n");
|
||||
printf("=======SERPENT-1 START, RUN_CNT = %d ======= \n",tmp_4);
|
||||
printf("============================================ \n");
|
||||
printf("=======INPUT KEYS======= \n");
|
||||
printf("=======128bit key======= \n");
|
||||
|
||||
printf("PLEASE INPUT KEY_0 IN HEX \n"); scanf_s("%x",&key_0);
|
||||
printf("PLEASE INPUT KEY_1 IN HEX \n"); scanf_s("%x",&key_1);
|
||||
printf("PLEASE INPUT KEY_2 IN HEX \n"); scanf_s("%x",&key_2);
|
||||
printf("PLEASE INPUT KEY_3 IN HEX \n"); scanf_s("%x",&key_3);
|
||||
|
||||
printf("PLEASE INPUT P_0 IN HEX \n"); scanf_s("%x",&p_0);
|
||||
printf("PLEASE INPUT P_1 IN HEX \n"); scanf_s("%x",&p_1);
|
||||
printf("PLEASE INPUT P_2 IN HEX \n"); scanf_s("%x",&p_2);
|
||||
printf("PLEASE INPUT P_3 IN HEX \n"); scanf_s("%x",&p_3);
|
||||
|
||||
//step 1, sub-key generation
|
||||
//setp 1-1, generate 256bit full-length key and start to generate wi[0]~wi[7]
|
||||
char *keys[] =
|
||||
{ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"
|
||||
};
|
||||
|
||||
wi[0] = key_0;
|
||||
wi[1] = key_1;
|
||||
wi[2] = key_2;
|
||||
wi[3] = key_3;
|
||||
//padding the key to 256 bit
|
||||
wi[4] = 0x00000000;
|
||||
wi[5] = 0x00000000;
|
||||
wi[6] = 0x00000000;
|
||||
wi[7] = 0x80000000;
|
||||
|
||||
//setp 1-2, generate w[0]~w[7] with wi[0]~wi[7]
|
||||
//w[i]=(w[i-8]^w[i-5]^w[i-3]^w[i-1]^phai^i)<<<11
|
||||
//w[-8]-->wi[0]
|
||||
//w[-7]-->wi[1]
|
||||
//w[-6]-->wi[2]
|
||||
//w[-5]-->wi[3]
|
||||
//w[-4]-->wi[4]
|
||||
//w[-3]-->wi[5]
|
||||
//w[-2]-->wi[6]
|
||||
//w[-1]-->wi[7]
|
||||
char *cipher[] =
|
||||
{ "00112233445566778899AABBCCDDEEFF" };
|
||||
|
||||
//w[0]
|
||||
tmp_0 = wi[0] ^ wi[3] ^ wi[5] ^ wi[7] ^ 0x9e3779b9 ^ 0x0;
|
||||
w[0] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[1]
|
||||
tmp_0 = wi[1] ^ wi[4] ^ wi[6] ^ w[0] ^ 0x9e3779b9 ^ 0x1;
|
||||
w[1] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[2]
|
||||
tmp_0 = wi[2] ^ wi[5] ^ wi[7] ^ w[1] ^ 0x9e3779b9 ^ 0x2;
|
||||
w[2] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[3]
|
||||
tmp_0 = wi[3] ^ wi[6] ^ w[0] ^ w[2] ^ 0x9e3779b9 ^ 0x3;
|
||||
w[3] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[4]
|
||||
tmp_0 = wi[4] ^ wi[7] ^ w[1] ^ w[3] ^ 0x9e3779b9 ^ 0x4;
|
||||
w[4] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[5]
|
||||
tmp_0 = wi[5] ^ w[0] ^ w[2] ^ w[4] ^ 0x9e3779b9 ^ 0x5;
|
||||
w[5] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[6]
|
||||
tmp_0 = wi[6] ^ w[1] ^ w[3] ^ w[5] ^ 0x9e3779b9 ^ 0x6;
|
||||
w[6] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
//w[7]
|
||||
tmp_0 = wi[7] ^ w[2] ^ w[4] ^ w[6] ^ 0x9e3779b9 ^ 0x7;
|
||||
w[7] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
size_t hex2bin(void *bin, char hex[]) {
|
||||
size_t len, i;
|
||||
int x;
|
||||
uint8_t *p = (uint8_t*)bin;
|
||||
|
||||
//setp 1-3, generate w[8]~w[131] with w[0]~w[7]
|
||||
for( i = 8; i < 132; i++){
|
||||
tmp_0 = w[i-8] ^ w[i-5] ^ w[i-3] ^ w[i-1] ^ 0x9e3779b9 ^ i;
|
||||
w[i] = (tmp_0 << 11) | (tmp_0 >> 21);
|
||||
}
|
||||
|
||||
fprintf(fp,"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \n");
|
||||
fprintf(fp,"DETAIL DATA FOR RUN_CNT = %d \n",tmp_4);
|
||||
for( i = 0; i < 8; i++){
|
||||
fprintf(fp,"w[%d] = %08x \n",i-8,wi[i]);
|
||||
}
|
||||
for( i = 0; i < 132; i++){
|
||||
fprintf(fp,"w[%d] = %08x \n",i,w[i]);
|
||||
}
|
||||
|
||||
//setp 1-4,input w[0]~w[131] to sbox,generate k_0[0]~k_0[131]
|
||||
//data will be permutated before input into SBOX
|
||||
for( i = 0; i < 132; i = i + 4){
|
||||
IP(&w[i+0],&w[i+1],&w[i+2],&w[i+3],&sb_in[i+0],&sb_in[i+1],&sb_in[i+2],&sb_in[i+3]);
|
||||
sb_out[i+0] = sb(((35-i/4)%8),sb_in[i+0]);
|
||||
sb_out[i+1] = sb(((35-i/4)%8),sb_in[i+1]);
|
||||
sb_out[i+2] = sb(((35-i/4)%8),sb_in[i+2]);
|
||||
sb_out[i+3] = sb(((35-i/4)%8),sb_in[i+3]);
|
||||
k[i+0] = sb_out[i+0] ;
|
||||
k[i+1] = sb_out[i+1] ;
|
||||
k[i+2] = sb_out[i+2] ;
|
||||
k[i+3] = sb_out[i+3] ;
|
||||
}
|
||||
|
||||
fprintf(fp,"sub_key data~~~~~~~~~~~~~~~~~~~~ \n");
|
||||
for(i = 0; i < 132; i++){
|
||||
if((i%4) == 0) {fprintf(fp,"=======sub_key[%d]: =======\n",i/4);}
|
||||
fprintf(fp,"sub_key[%d]_%d = %08x \n",i/4,i%4, k[i]);
|
||||
len = strlen(hex);
|
||||
|
||||
if ((len & 1) != 0) {
|
||||
return 0;
|
||||
}
|
||||
fprintf(fp," \n");
|
||||
fprintf(fp," \n");
|
||||
fprintf(fp,"encryption data~~~~~~~~~~~~~~~~~~~~ \n");
|
||||
|
||||
//========================================================================
|
||||
//By now,we've got the sub_key0~32,then we can start to encrypt plain data
|
||||
//step 2, data encryption
|
||||
//initial permutation
|
||||
IP(&p_0,&p_1,&p_2,&p_3,&b[0],&b[1],&b[2],&b[3]);
|
||||
|
||||
fprintf(fp,"p_0 = %08x \n",p_0);
|
||||
fprintf(fp,"p_1 = %08x \n",p_1);
|
||||
fprintf(fp,"p_2 = %08x \n",p_2);
|
||||
fprintf(fp,"p_3 = %08x \n",p_3);
|
||||
|
||||
fprintf(fp,"b_0 = %08x \n",b[0]);
|
||||
fprintf(fp,"b_1 = %08x \n",b[1]);
|
||||
fprintf(fp,"b_2 = %08x \n",b[2]);
|
||||
fprintf(fp,"b_3 = %08x \n",b[3]);
|
||||
|
||||
//step 2-1,32 rounds of data encryption
|
||||
//round0~30, 31 normal rounds
|
||||
for(i = 0; i < 31; i++)
|
||||
{
|
||||
//xor operation
|
||||
xor[i*4+0] = b[i*4+0] ^ k[i*4+0];
|
||||
xor[i*4+1] = b[i*4+1] ^ k[i*4+1];
|
||||
xor[i*4+2] = b[i*4+2] ^ k[i*4+2];
|
||||
xor[i*4+3] = b[i*4+3] ^ k[i*4+3];
|
||||
//SBOX
|
||||
sbox[i*4+0] = sb((i%8),xor[i*4+0]);
|
||||
sbox[i*4+1] = sb((i%8),xor[i*4+1]);
|
||||
sbox[i*4+2] = sb((i%8),xor[i*4+2]);
|
||||
sbox[i*4+3] = sb((i%8),xor[i*4+3]);
|
||||
//linear
|
||||
FP(&sbox[i*4+0],&sbox[i*4+1],&sbox[i*4+2],&sbox[i*4+3],&li[i*4+0],&li[i*4+1],&li[i*4+2],&li[i*4+3]);
|
||||
linear(&li[i*4+0],&li[i*4+1],&li[i*4+2],&li[i*4+3],&lo[i*4+0],&lo[i*4+1],&lo[i*4+2],&lo[i*4+3]);
|
||||
IP(&lo[i*4+0],&lo[i*4+1],&lo[i*4+2],&lo[i*4+3],&b[i*4+4],&b[i*4+5],&b[i*4+6],&b[i*4+7]);
|
||||
|
||||
fprintf(fp,"////////////////////\n");
|
||||
fprintf(fp,"i = %d \n",i);
|
||||
fprintf(fp,"xored[%d] = %08x \n", i*4+0, xor[i*4+0]);
|
||||
fprintf(fp,"xored[%d] = %08x \n", i*4+1, xor[i*4+1]);
|
||||
fprintf(fp,"xored[%d] = %08x \n", i*4+2, xor[i*4+2]);
|
||||
fprintf(fp,"xored[%d] = %08x \n", i*4+3, xor[i*4+3]);
|
||||
|
||||
fprintf(fp,"sbox[%d] = %08x \n", i*4+0, sbox[i*4+0]);
|
||||
fprintf(fp,"sbox[%d] = %08x \n", i*4+1, sbox[i*4+1]);
|
||||
fprintf(fp,"sbox[%d] = %08x \n", i*4+2, sbox[i*4+2]);
|
||||
fprintf(fp,"sbox[%d] = %08x \n", i*4+3, sbox[i*4+3]);
|
||||
|
||||
fprintf(fp,"linear_in[%d] = %08x \n", i*4+0, li[i*4+0]);
|
||||
fprintf(fp,"linear_in[%d] = %08x \n", i*4+1, li[i*4+1]);
|
||||
fprintf(fp,"linear_in[%d] = %08x \n", i*4+2, li[i*4+2]);
|
||||
fprintf(fp,"linear_in[%d] = %08x \n", i*4+3, li[i*4+3]);
|
||||
|
||||
fprintf(fp,"linear_out[%d] = %08x \n", i*4+0, lo[i*4+0]);
|
||||
fprintf(fp,"linear_out[%d] = %08x \n", i*4+1, lo[i*4+1]);
|
||||
fprintf(fp,"linear_out[%d] = %08x \n", i*4+2, lo[i*4+2]);
|
||||
fprintf(fp,"linear_out[%d] = %08x \n", i*4+3, lo[i*4+3]);
|
||||
|
||||
fprintf(fp,"b[%d] = %08x \n", i*4+4, b[i*4+4]);
|
||||
fprintf(fp,"b[%d] = %08x \n", i*4+5, b[i*4+5]);
|
||||
fprintf(fp,"b[%d] = %08x \n", i*4+6, b[i*4+6]);
|
||||
fprintf(fp,"b[%d] = %08x \n", i*4+7, b[i*4+7]);
|
||||
for (i = 0; i<len; i++) {
|
||||
if (isxdigit((int)hex[i]) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//round31
|
||||
//xor operation
|
||||
xor[124] = b[124] ^ k[124];
|
||||
xor[125] = b[125] ^ k[125];
|
||||
xor[126] = b[126] ^ k[126];
|
||||
xor[127] = b[127] ^ k[127];
|
||||
fprintf(fp,"////////////////////\n");
|
||||
fprintf(fp,"i = %d \n", i);
|
||||
fprintf(fp,"xored = %08x \n", xor[i*4+0]);
|
||||
fprintf(fp,"xored = %08x \n", xor[i*4+1]);
|
||||
fprintf(fp,"xored = %08x \n", xor[i*4+2]);
|
||||
fprintf(fp,"xored = %08x \n", xor[i*4+3]);
|
||||
//SBOX
|
||||
sbox[124] = sb(0x7,xor[124]);
|
||||
sbox[125] = sb(0x7,xor[125]);
|
||||
sbox[126] = sb(0x7,xor[126]);
|
||||
sbox[127] = sb(0x7,xor[127]);
|
||||
fprintf(fp,"sbox = %08x \n", sbox[i*4+0]);
|
||||
fprintf(fp,"sbox = %08x \n", sbox[i*4+1]);
|
||||
fprintf(fp,"sbox = %08x \n", sbox[i*4+2]);
|
||||
fprintf(fp,"sbox = %08x \n", sbox[i*4+3]);
|
||||
//xor operation-2
|
||||
b[128] = sbox[124] ^ k[128];
|
||||
b[129] = sbox[125] ^ k[129];
|
||||
b[130] = sbox[126] ^ k[130];
|
||||
b[131] = sbox[127] ^ k[131];
|
||||
fprintf(fp,"k[128]= %08x \n", k[128]);
|
||||
fprintf(fp,"k[129]= %08x \n", k[129]);
|
||||
fprintf(fp,"k[130]= %08x \n", k[130]);
|
||||
fprintf(fp,"k[131]= %08x \n", k[131]);
|
||||
|
||||
fprintf(fp,"b[128]= %08x \n", b[128]);
|
||||
fprintf(fp,"b[129]= %08x \n", b[129]);
|
||||
fprintf(fp,"b[130]= %08x \n", b[130]);
|
||||
fprintf(fp,"b[131]= %08x \n", b[131]);
|
||||
|
||||
//step 2-2, final permutation
|
||||
|
||||
FP(&b[128],&b[129],&b[130],&b[131],&c_0,&c_1,&c_2,&c_3);
|
||||
|
||||
fprintf(fp,"P0 = %08x \n", p_0); fprintf(fp,"P1 = %08x \n", p_1); fprintf(fp,"P2 = %08x \n", p_2); fprintf(fp,"P3 = %08x \n", p_3);
|
||||
fprintf(fp,"KEY0 = %08x \n", key_0); fprintf(fp,"KEY1 = %08x \n", key_1); fprintf(fp,"KEY2 = %08x \n", key_2); fprintf(fp,"KEY3 = %08x \n", key_3);
|
||||
fprintf(fp,"C0 = %08x \n", c_0); fprintf(fp,"C1 = %08x \n", c_1); fprintf(fp,"C2 = %08x \n", c_2); fprintf(fp,"C3 = %08x \n", c_3);
|
||||
//fclose(fp);
|
||||
|
||||
printf("================================== \n");
|
||||
printf("==============RESULT============== \n");
|
||||
printf("================================== \n");
|
||||
printf("P0 = %08x ", p_0); printf("P1 = %08x ", p_1); printf("P2 = %08x ", p_2); printf("P3 = %08x \n", p_3);
|
||||
printf("KEY0 = %08x ", key_0); printf("KEY1 = %08x ", key_1); printf("KEY2 = %08x ", key_2); printf("KEY3 = %08x \n", key_3);
|
||||
printf("C0 = %08x ", c_0); printf("C1 = %08x ", c_1); printf("C2 = %08x ", c_2); printf("C3 = %08x \n", c_3);
|
||||
tmp_4++;
|
||||
printf("WILL YOU CALCULATE SERPENT-1 AGAIN ? 1:YES 0:NO \n");
|
||||
scanf_s("%x",&tmp_5);
|
||||
if(tmp_5 == 0x0)
|
||||
break;
|
||||
fclose(fp);
|
||||
return 0;
|
||||
for (i = 0; i<len / 2; i++) {
|
||||
sscanf(&hex[i * 2], "%2x", &x);
|
||||
p[i] = (uint8_t)x;
|
||||
}
|
||||
return len / 2;
|
||||
}
|
||||
|
||||
void dump_hex(char *s, uint8_t bin[], int len)
|
||||
{
|
||||
int i;
|
||||
printf("\n%s=", s);
|
||||
for (i = 0; i<len; i++) {
|
||||
printf("%02x", bin[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t ct1[32], pt1[32], pt2[32], key[64];
|
||||
int klen, plen, clen, i, j;
|
||||
serpent_key_t skey;
|
||||
serpent_blk ct2;
|
||||
uint32_t *p;
|
||||
|
||||
printf("\nserpent-256 test\n");
|
||||
|
||||
for (i = 0; i<sizeof(keys) / sizeof(char*); i++) {
|
||||
clen = hex2bin(ct1, cipher[i]);
|
||||
plen = hex2bin(pt1, plain[i]);
|
||||
klen = hex2bin(key, keys[i]);
|
||||
|
||||
// set key
|
||||
memset(&skey, 0, sizeof(skey));
|
||||
p = (uint32_t*)&skey.x[0][0];
|
||||
|
||||
serpent_set_encrypt_key(&skey, key);
|
||||
printf("\nkey=");
|
||||
|
||||
for (j = 0; j<sizeof(skey) / sizeof(serpent_subkey_t) * 4; j++) {
|
||||
if ((j % 8) == 0) putchar('\n');
|
||||
printf("%08X ", p[j]);
|
||||
}
|
||||
|
||||
// encrypt
|
||||
memcpy(ct2.b, pt1, SERPENT_BLK_LEN);
|
||||
|
||||
printf("\n\n");
|
||||
dump_hex("plaintext", ct2.b, 16);
|
||||
|
||||
serpent_encrypt(ct2.b, &skey);
|
||||
|
||||
dump_hex("ciphertext", ct2.b, 16);
|
||||
|
||||
if (memcmp(ct1, ct2.b, clen) == 0) {
|
||||
printf("\nEncryption OK");
|
||||
serpent_decrypt(ct2.b, &skey);
|
||||
if (memcmp(pt1, ct2.b, plen) == 0) {
|
||||
printf("\nDecryption OK");
|
||||
dump_hex("plaintext", ct2.b, 16);
|
||||
}
|
||||
else {
|
||||
printf("\nDecryption failed");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("\nEncryption failed");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user