📄 sdes.cpp
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) 1999-2005 Matt Brunk <info@smartcache.net>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License VERSION 2 as
// published by the Free Software Foundation. You are not allowed to
// use any other version of the license; unless you got the explicit
// permission from the author to do so.
//
// 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//------------------------------------------------------------------------------
#include <stdio.h>
#include "sdes.h"
//U8 SDES::s_key = 0x097;
U16 SDES::s_key = 0x06D;
// create the s-boxes
static const U8 S0[4][4] =
{
{ 1, 0, 3, 2 },
{ 3, 2, 1, 0 },
{ 0, 2, 1, 3 },
{ 3, 1, 0, 3 }
};
static const U8 S1[4][4] =
{
{ 0, 1, 2, 3 },
{ 2, 0, 1, 3 },
{ 3, 0, 1, 0 },
{ 2, 1, 0, 3 }
};
/*
I am using macros for two reasons :
1. they avoid the overhead of a function call
2. they are more fun that a barrel of IS students
If you want to see how macros expand use : gcc -E
*/
// bit x of y, evaluate to 1 or 0 ( true/false )
#define B(x,y) ( ((y) >> (x)) & 0x01)
/*
bit reordering permutations and expansions
the bit remapping is prior to each
these are all defined as macros
*/
// p10 9876543210 -> 7583609124
#define p10(x) ( B(7,x) << 9 | B(5,x) << 8 | B(8,x) << 7 | B(3,x) << 6 | \
B(6,x) << 5 | B(0,x) << 4 | B(9,x) << 3 | B(1,x) << 2 | \
B(2,x) << 1 | B(4,x) )
//p8 9876543210 -> 47362501
#define p8(x) ( B(4,x) << 7 | B(7,x) << 6 | B(3,x) << 5 | B(6,x) << 4 | \
B(2,x) << 3 | B(5,x) << 2 | B(0,x) << 1 | B(1,x) )
//p4 3210 -> 2013
#define p4(x) ( B(2,x) << 3 | B(0,x) << 2 | B(1,x) << 1 | B(3,x) )
//ip 76543210 -> 62574031
#define ip(x) ( B(6,x) << 7 | B(2,x) << 6 | B(5,x) << 5 | B(7,x) << 4 | \
B(4,x) << 3 | B(0,x) << 2 | B(3,x) << 1 | B(1,x) )
//ip_inv 76543210 -> 47531602
#define ip_inv(x) ( B(4,x) << 7 | B(7,x) << 6 | B(5,x) << 5 | B(3,x) << 4 | \
B(1,x) << 3 | B(6,x) << 2 | B(0,x) << 1 | B(2,x) )
//ep 3210 -> 03212103
#define ep(x) ( B(0,x) << 7 | B(3,x) << 6 | B(2,x) << 5 | B(1,x) << 4 | \
B(2,x) << 3 | B(1,x) << 2 | B(0,x) << 1 | B(3,x) )
//sw 76543210 -> 32107654
#define sw(x) ( B(3,x) << 7 | B(2,x) << 6 | B(1,x) << 5 | B(0,x) << 4 | \
B(7,x) << 3 | B(6,x) << 2 | B(5,x) << 1 | B(4,x) )
// actually used these
// rotate x left y bits, total size is 5 bits
#define ROT_L5(x,y) ((( (x) << (y) ) | ( (x) >> (5-y) )) & 0x1F )
// get the right 5 bits of x
#define RIGHT5(x) ( (x) & 0x1F )
// get the left 5 bits of x
#define LEFT5(x) ( ( (x) >> 5 ) & 0x1F )
// get the right 4 bits of x
#define RIGHT4(x) ( (x) & 0x0F )
// get the left 4 bits of x
#define LEFT4(x) ( ( (x) >> 4 ) & 0x0F )
// print x as a 10 bit value
void p_bits( U8 x )
{
char arr[13] = "00 0000 0000";
int i, j;
for( i = 9, j = 0 ; i >= 0 ; --i, ++j )
{
// leave 2 and 7 as spaces for readability
if ( ( j == 2 ) || ( j == 7 ) )
{
++j;
}
if( B(i,x ) )
{
arr[ j ] = '1';
}
}
printf ( "%s\n", arr );
}
#ifdef DEBUG
// clean up the debugging stuff
void debugf( char * s, U8 x )
{
printf( "%s", s );
p_bits( x );
}
#else
// make it an empty statement
#define debugf(s,x) ;
#endif
// real des functions
void subkeys( U16 k, U8 * k1, U8 * k2 )
{
U16 n = p10( k );
// split it into two 5 bit halves
U8 l = LEFT5( n );
U8 r = RIGHT5( n );
U16 tmp;
debugf( "ep(k) = ", n );
// rotate each half left by one
l = ROT_L5( l, 1 );
r = ROT_L5( r, 1 );
tmp = ( l << 5 ) | r; // join them
debugf( "ls-1 = ", tmp );
*k1 = p8( tmp );
debugf( "k1 = ", *k1 );
// rotate each half left by two
l = ROT_L5( l, 2 );
r = ROT_L5( r, 2 );
tmp = ( l << 5 ) | r; // join them
debugf( "ls-2 = ", tmp );
*k2 = p8( tmp );
debugf( "k2 = ", *k2 );
}
U8 F( U8 x, U8 k )
{
U8 row,col;
U16 rval;
U8 a = ep(x) ^ k; // expand and add key
U8 l = LEFT4( a );
U8 r = RIGHT4( a );
// row bits 30 , col bits 21
// lookup left 4 in S0
row = ( B(3, l ) << 1 ) | B(0, l );
col = ( B(2, l ) << 1 ) | B(1, l );
rval = S0[row][col] << 2; // the left 2 bits
// lookup right 4 in S1
row = ( B(3, r ) << 1 ) | B(0, r );
col = ( B(2, r ) << 1 ) | B(1, r );
rval |= S1[row][col]; // the right 2 bits
rval = p4(rval);
return (U8)rval;
}
// fk(L,R,SK) = ( L ^ F(R,SK),R )
U8 f_k( U8 x, U8 k )
{
U8 l = LEFT4( x );
U8 r = RIGHT4( x );
U8 y = l ^ F( r, k ); // "add" them, really xor
U8 rval = (U8)(( y << 4 ) | r); // join them
return rval;
}
U8 SDES::Encrypt(U8 in)
{
U8 k1,k2; // key and subkeys
subkeys( s_key, &k1, &k2 );
U8 x = ip( in );
x = f_k( x , k1 );
x = sw( x );
x = f_k( x , k2 );
x = ip_inv( x );
return x;
}
U8 SDES::Decrypt(U8 in)
{
U8 k1,k2; // key and subkeys
subkeys( s_key, &k1, &k2 );
U8 x = ip( in );
x = f_k( x , k2 );
x = sw( x );
x = f_k( x , k1 );
x = ip_inv( x );
return x;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -