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

📄 h_des.cpp

📁 des算法源码 des算法源码 des算法源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    
    if (doEncrypt)
    {
        /* Do the 16 rounds */
        for (i = 0; i < 16; i++)
            Round(i, work);
        
        /* Left/right half swap */
        tmp     = work[0];
        work[0] = work[1];
        work[1] = tmp;
    } /* end of if */
    else
    {
        /* Left/right half swap */
        tmp     = work[0];
        work[0] = work[1];
        work[1] = tmp;
        
        /* Do the 16 rounds in reverse order */
        for (i = 15; i >= 0; i--)
            Round(i, work);
    } /* end of else */
    
    work[0] = ByteSwap(work[0]);
    work[1] = ByteSwap(work[1]);
    
    /* Inverse initial permutation */
    Permute((BYTE *)work, fperm, data);
} /* DES() */


/************************************************************************
*  Function name   : SetKey
*  Description     : initialize key schedule array
*                  :
*  Parameters      : key
*  Returns         : -
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static void SetKey(const IN BYTE *key)
{
    char           pc1m[56];      /* Place to modify pc1 into */
    char           pcr[56];       /* Place to rotate pc1 into */
    register int   i ,j , k;
    int            m;
    
    #if 0
    /*
    In mode 2, the 128 bytes of subkey are set directly from the
    user's key, allowing him to use completely independent
    subkeys for each round. Note that the user MUST specify a
    full 128 bytes.
    
    I would like to think that this technique gives the NSA a real
    headache, but I'm not THAT naive.
    */
    if (desmode == 2)
    {
        for (i = 0; i < 16; i++)
        {
            for (j = 0; j < 8; j++)
                kn[i][j] = *key++;
        } /* end of for i */
        
        return;
    } /* end of if */
    #endif
    
    /* Clear key schedule */
    for (i = 0; i < 16; i++)
    {
        for (j = 0; j < 8; j++)
            kn[i][j] = 0;
    } /* end of for i */
    
    /* Convert pc1 to bits of key */
    for (j = 0; j < 56; j++)
    {
        k = pc1[j] - 1;      /* Integer bit location */
        m = k & 07;          /* find bit             */
        
        /*
        Find which key byte l is in and which bit of that byte
        and store 1-bit result
        */
        pc1m[j] = (key[k >> 3] & byteBit[m]) ? 1 : 0;
    } /* end of for j */
    
    /* Key chunk for each iteration */
    for (i = 0; i < 16; i++)
    {
        /* rotate pc1 the right amount */
        for (j = 0; j < 56; j++)
        {
            k      = j + totRot[i];
            pcr[j] = pc1m[(k < (j < 28 ? 28 : 56)) ? k : k - 28];
        } /* end of for j */
        
        /* Rotate left and right halves independently */
        for (j=0; j<48; j++)
        {
            /* Select bits individually, check bit that goes to kn[j] */
            if (pcr[pc2[j] - 1])
            {
                /* mask it in if it's there */
                k             = j % 6;
                kn[i][j / 6] |= byteBit[k] >> 2;
            } /* end of if */
        } /* end of j */
    } /* end of for i */
    
    return;
} /* SetKey() */


/************************************************************************
*  Function name   : Permute
*  Description     :
*                  :
*  Parameters      : inBlock  -
*                  : perm     -
*                  : outBlock -
*  Returns         : -
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static void Permute(BYTE *inBlock, char perm[16][16][8],
BYTE *outBlock
)
{
    int            i;
    int            j;
    char           *p;
    char           *q;
    BYTE  *oBlock;
    
    if (perm == NULL)
    {
        /* No permutation, just copy */
        for (i = 8; i != 0; i--)
            *outBlock++ = *inBlock++;
        
        return;
    } /* end of if */
    
    /* Clear output block    */
    memset(outBlock, 0, 8);
    
    for (j = 0; j < 16; j += 2)
    {
        oBlock = outBlock;
        
        /* For each input nibble and each output byte, OR the masks together */
        p = perm[j][(*inBlock >> 4) & 017];
        q = perm[j + 1][*inBlock & 017];
        for (i = 8; i != 0; i--)
            *oBlock++ |= *p++ | *q++;
        
        inBlock++;
    } /* end of for j */
    
    return;
} /* Permute() */


/************************************************************************
*  Function name   : Round
*  Description     : Do one DES cipher round
*                  :
*  Parameters      : num   -
*                  : block -
*  Returns         : -
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static void Round(int num, DWORD *block)
{
    /*
    The rounds are numbered from 0 to 15. On even rounds
    the right half is fed to f() and the result exclusive-ORs
    the left half; on odd rounds the reverse is done.
    */
    if (num & 1)
        block[1] ^= F_DES(block[0], kn[num]);
    else
        block[0] ^= F_DES(block[1], kn[num]);
    
    return;
} /* Round() */


/************************************************************************
*  Function name   : F_DES
*  Description     : The nonlinear function F(r, k), the heart of DES
*                  :
*  Parameters      : r        -
*                  : subKey   -
*  Returns         : ...
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static long F_DES(DWORD r, BYTE subKey[8])
{
    DWORD  rVal, rt;
    
    /*
    Run E(R) ^ K through the combined S & P boxes
    This code takes advantage of a convenient regularity in
    E, namely that each group of 6 bits in E(R) feeding
    a single S-box is a contiguous segment of R.
    */
    rt    = (r >> 1) | ((r & 1) ? 0x80000000 : 0);
    rVal  = 0;
    rVal |= sp[0][((rt >> 26) ^ *subKey++) & 0x3f];
    rVal |= sp[1][((rt >> 22) ^ *subKey++) & 0x3f];
    rVal |= sp[2][((rt >> 18) ^ *subKey++) & 0x3f];
    rVal |= sp[3][((rt >> 14) ^ *subKey++) & 0x3f];
    rVal |= sp[4][((rt >> 10) ^ *subKey++) & 0x3f];
    rVal |= sp[5][((rt >> 6)  ^ *subKey++) & 0x3f];
    rVal |= sp[6][((rt >> 2)  ^ *subKey++) & 0x3f];
    rt    = (r << 1) | ((r & 0x80000000) ? 1 : 0);
    rVal |= sp[7][(rt ^ *subKey) & 0x3f];
    
    return rVal;
} /* F_DES() */


/************************************************************************
*  Function name   : PermInit
*  Description     : Initialize a perm array
*                  :
*  Parameters      :
*  Returns         :
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static void PermInit(char perm[16][16][8], const char p[64])
{
    int i, j, k, m, n;
    
    /* Clear the permutation array */
    for (i = 0; i < 16; i++)
    {
        for (j = 0; j < 16; j++)
        {
            for (k = 0; k < 8; k++)
                perm[i][j][k]=0;
        } /* end of for j */
    } /* end of for i */
    
    for (i = 0; i < 16; i++)         /* Each input nibble position */
    {
        for (j = 0; j < 16; j++)      /* Each possible input nibble */
        {
            for (k = 0; k < 64; k++)   /* Each output bit position   */
            {
                n = p[k] - 1;
                
                /* Does this bit come from input position ? */
                if ((n >> 2) != i)
                    continue;            /* No, bit k is 0             */
                
                if (!(j & nibbleBit[n & 3]))
                    continue;
                
                m                   = k & 07; /* Which bit is this in the byte */
                perm[i][j][k >> 3] |= byteBit[m];
            } /* end of for k */
        } /* end of for j */
    } /* end of for i */
    
    return;
} /* PermInit() */


/************************************************************************
*  Function name   : SPInit
*  Description     : Initialize the lookup table for the combined S and P
*                  : boxes
*  Parameters      : -
*  Returns         : -
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static void SPInit(void)
{
    char  pBox[32];
    int   p, i, s, j, rowCol;
    long  val;
    
    /* Compute pbox, the inverse of p32i. This is easier to work with. */
    for (p = 0; p < 32; p++)
    {
        for (i = 0;i < 32; i++)
        {
            if (p32i[i] - 1 == p)
            {
                pBox[p] = i;
                break;
            } /* end of if */
        } /* end of for i */
    } /* end of for p */
    
    for (s = 0; s < 8; s++)       /* For each S-box          */
    {
        for(i = 0; i < 64; i++)    /* For each possible input */
        {
            val = 0;
            /*
            The row number is formed from the first and last
            bits; the column number is from the middle 4.
            */
            rowCol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf);
            for (j = 0; j < 4; j++)    /* For each output bit */
            {
                if (si[s][rowCol] & (8 >> j))
                    val |= 1L << (31 - pBox[4 * s + j]);
            } /* end of for */
            sp[s][i] = val;
        } /* end of for */
    } /* end of for s */
    
    return;
} /* SPInit() */


/************************************************************************
*  Function name   : ByteSwap
*  Description     : Byte swap a long
*                  :
*  Parameters      : x
*  Returns         : ...
*  Author          : Richard Shen
* ----------------------------------------------------------------------
*  Date     By       Description
* ----------------------------------------------------------------------
*  20Jan99  RCS      Created.
************************************************************************/
static DWORD ByteSwap(DWORD x)
{
    char  tmp;
    char  *cp;

    cp    = (char *)&x;
    tmp   = cp[3];
    cp[3] = cp[0];
    cp[0] = tmp;

    tmp   = cp[2];
    cp[2] = cp[1];
    cp[1] = tmp;

    return x;
} /* ByteSwap() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -