⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdes.cpp

📁 This is a code relatesd to smart card secuiry DES/3-DES
💻 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 + -