dfc.c

来自「文件驱动加密,功能强大,可产生加密分区,支持AES,MD2,MD4,MD5MD2」· C语言 代码 · 共 414 行 · 第 1/2 页

C
414
字号
    c = hi(c) + hi(t0) + hi(t1) + hi(t2);                       \
    t0 = x0 * y3; t1 = x1 * y2; t2 = x2 * y1; t3 = x3 * y0;     \
    c += lo(t0) + lo(t1) + lo(t2) + lo(t3); r[1] += (c << 16);  \
    c = hi(c) + hi(t0) + hi(t1) + hi(t2) + hi(t3);              \
    t0 = x1 * y3; t1 = x2 * y2; t2 = x3 * y1;                   \
    c += lo(t0) + lo(t1) + lo(t2); r[2] = lo(c);                \
    c = hi(c) + hi(t0) + hi(t1) + hi(t2);                       \
    t0 = x2 * y3; t1 = x3 * y2; c += lo(t0) + lo(t1);           \
    r[2] += (c << 16); c = hi(c) + hi(t0) + hi(t1);             \
    r[3] = c + x3 * y3

#define add_64(r,hi,lo)     \
    if((r[0] += lo) < lo)   \
        if(!++r[1])         \
            if(!++r[2])     \
                ++r[3];     \
    if((r[1] += hi) < hi)   \
        if(!++r[2])         \
            ++r[3]
    
#define mult_13(r)                  \
    c = 13 * lo((r)[0]);            \
    d = hi((r)[0]);                 \
    (r)[0] = lo(c);                 \
    c = hi(c) + 13 * d;             \
    (r)[0] += (c << 16);            \
    c = hi(c) + 13 * lo((r)[1]);    \
    d = hi((r)[1]);                 \
    (r)[1] = lo(c);                 \
    c = hi(c) + 13 * d;             \
    (r)[1] += (c << 16);            \
    (r)[2] = hi(c)

/* Where necessary this is where conversion from big endian to  */
/* little endian format is performed.  Since all the maths is   */
/* little endian care is needed when 64 bit blocks are being    */
/* used to get them in the right order by reversing the order   */
/* in which these are stored. This applies to the key array     */
/* which gives the two values A and B and to the constant KD.   */
/* Since the input and output blocks are big endian we also     */
/* have to invert the order of the 32 bit words in the 64 bit   */
/* blocks being processed.                                      */ 

void r_fun(u4byte outp[2], const u4byte inp[2], const u4byte key[4])
{   u4byte  acc[5], x0, x1, x2, x3, y0, y1, y2, y3, t0, t1, t2, t3, c, d;

    mult_64(acc, inp, key);  add_64(acc, key[2], key[3]);

    /* we need the value in the accumulator mod 2^64 + 13 so if */
    /* the accumulator value is hi * 2^64 + lo we need to find  */
    /* a k value such that r = hi * 2^64 + lo - k * (2^64 + 13) */
    /* is 0 <= r < 2^64 + 13.  We can see that k will be close  */
    /* to hi in value - it may equal hi but will not be greater */
    /* and we can let k = hi - e with e >= 0 so that r is given */
    /* by r = e * (2^64 + 13) + lo - 13 * hi. If we compute the */
    /* lo - 13 * hi value, the overflow into the top 64 bits of */
    /* the accumulator has to be 'zeroed' by the e * (2^64 + 13)*/
    /* term and this sets the e value (in fact such an overlow  */
    /* is only removed when the lower word is higher than 12).  */

    mult_13(acc + 2);   /* multiply top of accumulator by 13    */

    /* calculate lo - 13 * hi in acc[0] and acc[1] with any     */
    /* overflow into top 64 bits in c                           */

    d = acc[0]; acc[0] -= acc[2]; c = (acc[0] > d ? 1 : 0);

    d = acc[1]; acc[1] -= acc[3] + c;
    c = (acc[1] > d ? 1 : (acc[1] == d ? c : 0));

    c = 13 * (acc[4] + c);  /* overflow into top 64 bits of acc */

    if(((acc[0] += c) < c) && !(++acc[1]))
    {
        if(acc[0] > 12)

            acc[0] -= 13;
    }

    /* do the confusion permutation */

    d = acc[1] ^ kc; c = acc[0] ^ rt64[acc[1] >> 26];  
    
    c += kd2[0] + ((d += kd2[1]) < kd2[1] ? 1 : 0);

    outp[0] ^= c; outp[1] ^= d; 
};

u4byte *set_key(const u4byte in_key[], const u4byte key_len)
{   u4byte  i, lk[32], rk[4];

    for(i = 0; i < key_len / 32; ++i)

        lk[i] = io_swap(in_key[i]);

    /* pad the key with the KS array            */

    for(i = 0; i < 8 - key_len / 32; ++i)    /* K|KS */

        lk[i + key_len / 32] = ks8[i];

    /* do the reordering of the key parameters  */
    /* the OAP[1]|OBP[1]|OAP[2]... sequence is  */
    /* at lk[0]... and the other at lk[16]...   */
    
    lk[18] = lk[5]; lk[19] = lk[2]; /* EBP */ 
    lk[16] = lk[1]; lk[17] = lk[6]; /* EAP */
    lk[ 2] = lk[4]; lk[ 3] = lk[3]; /* OBP */
    lk[ 0] = lk[0]; lk[ 1] = lk[7]; /* OAP */

    /* create other elements using KA and KB    */

    for(i = 0; i < 6; i += 2)
    {
        lk[i + i +   4] = lk[ 0] ^ ka2[i];      /* OAP[i] ms */
        lk[i + i +   5] = lk[ 1] ^ ka2[i + 1];  /* OAP[i] ls */
        lk[i + i +   6] = lk[ 2] ^ kb2[i];      /* OBP[i] ms */
        lk[i + i +   7] = lk[ 3] ^ kb2[i + 1];  /* OBP[i] ls */
        lk[i + i +  20] = lk[16] ^ ka2[i];      /* EAP[i] ms */
        lk[i + i +  21] = lk[17] ^ ka2[i + 1];  /* EAP[i] ls */
        lk[i + i +  22] = lk[18] ^ kb2[i];      /* EBP[i] ms */
        lk[i + i +  23] = lk[19] ^ kb2[i + 1];  /* EBP[i] ls */
    }

    rk[0] = rk[1] = rk[2] = rk[3] = 0;

    /* do the 4 round key mixing encryption     */

    for(i = 0; i < 32; i += 8)
    {
        r_fun(rk, rk + 2, lk);      /*  R2|R1   */
        r_fun(rk + 2, rk, lk +  4); /*  R2|R3   */
        r_fun(rk, rk + 2, lk +  8); /*  R4|R3   */
        r_fun(rk + 2, rk, lk + 12); /*  R4|R5   */

        /* keep key in big endian format with   */
        /* the most significant 32 bit words    */
        /* first (lowest) in the key schedule   */
        /* - note that the upper and lower 64   */
        /* bit blocks are in inverse order at   */
        /* this point in the loop               */

        l_key[i + 0] = rk[2]; l_key[i + 1] = rk[3]; 
        l_key[i + 2] = rk[0]; l_key[i + 3] = rk[1]; 

        r_fun(rk + 2, rk, lk + 16); /*  R1|R2   */
        r_fun(rk, rk + 2, lk + 20); /*  R3|R2   */
        r_fun(rk + 2, rk, lk + 24); /*  R3|R4   */  
        r_fun(rk, rk + 2, lk + 28); /*  R5|R4   */

        l_key[i + 4] = rk[0]; l_key[i + 5] = rk[1]; 
        l_key[i + 6] = rk[2]; l_key[i + 7] = rk[3];
    }
    
    return l_key;
};

void encrypt(const u4byte in_blk[4], u4byte out_blk[4])
{   u4byte  blk[4];

    /* the input/output format is big endian -  */
    /* any reversals needed are performed when  */
    /* maths is done in the round function      */

    blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);
    blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);

    r_fun(blk, blk + 2, l_key +  0); /*  R2|R1  */ 
    r_fun(blk + 2, blk, l_key +  4); /*  R2|R3  */
    r_fun(blk, blk + 2, l_key +  8); /*  R4|R3  */
    r_fun(blk + 2, blk, l_key + 12); /*  R4|R5  */
    r_fun(blk, blk + 2, l_key + 16); /*  R6|R5  */
    r_fun(blk + 2, blk, l_key + 20); /*  R6|R7  */
    r_fun(blk, blk + 2, l_key + 24); /*  R8|R7  */
    r_fun(blk + 2, blk, l_key + 28); /*  R8|R9  */

    /* swap order to obtain the result R9|R8    */

    out_blk[0] = io_swap(blk[2]); out_blk[1] = io_swap(blk[3]);
    out_blk[2] = io_swap(blk[0]); out_blk[3] = io_swap(blk[1]);
};

void decrypt(const u4byte in_blk[4], u4byte out_blk[4])
{   u4byte  blk[4];

    /* the input/output format is big endian -  */
    /* any reversals needed are performed when  */
    /* maths is done in the round function      */

    blk[0] = io_swap(in_blk[0]); blk[1] = io_swap(in_blk[1]);
    blk[2] = io_swap(in_blk[2]); blk[3] = io_swap(in_blk[3]);

    r_fun(blk, blk + 2, l_key + 28); /*  R7|R8  */
    r_fun(blk + 2, blk, l_key + 24); /*  R7|R6  */
    r_fun(blk, blk + 2, l_key + 20); /*  R5|R6  */
    r_fun(blk + 2, blk, l_key + 16); /*  R5|R4  */
    r_fun(blk, blk + 2, l_key + 12); /*  R3|R4  */
    r_fun(blk + 2, blk, l_key +  8); /*  R3|R2  */
    r_fun(blk, blk + 2, l_key +  4); /*  R1|R2  */
    r_fun(blk + 2, blk, l_key     ); /*  R1|R0  */ 

    /* swap order to obtain the result R1|R0    */

    out_blk[0] = io_swap(blk[2]); out_blk[1] = io_swap(blk[3]);
    out_blk[2] = io_swap(blk[0]); out_blk[3] = io_swap(blk[1]);   
};

⌨️ 快捷键说明

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