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

📄 aesvec.c

📁 escription: The Rijndael Encryption algorithm has been recently recognized as an AES (Advanced Encry
💻 C
📖 第 1 页 / 共 2 页
字号:

// Copyright in this code is held by Dr B. R. Gladman but free direct or
// derivative use is permitted subject to acknowledgement of its origin.
// Dr B. R. Gladman <brg@gladman.uk.net> 1st June 2001.
//
// This is an implementation of the AES encryption algorithm (Rijndael)
// designed by Joan Daemen and Vincent Rijmen. This version is based on
// the reference implementation and is not efficient. It can run with
// either big or little endian internal byte order.  This version has
// been modified to output the values in the round state array during
// its operation in order to provide development test vectors. 

// IMPORTANT NOTE: undefine AES_DLL in aes.h

#include <stdio.h>
#include <memory.h>

#include "aes.h"
#include "aestst.h"

typedef byte        wa_ptr[4];
typedef const byte cwa_ptr[4];

const byte m_poly = 0x1b;

int mod = 0;                // true (1) if decryption order is modified

byte inv_tab[] =    // Table of finite field inverses
{
    0x00, 0x01, 0x8d, 0xf6, 0xcb, 0x52, 0x7b, 0xd1,
    0xe8, 0x4f, 0x29, 0xc0, 0xb0, 0xe1, 0xe5, 0xc7,
    0x74, 0xb4, 0xaa, 0x4b, 0x99, 0x2b, 0x60, 0x5f,
    0x58, 0x3f, 0xfd, 0xcc, 0xff, 0x40, 0xee, 0xb2,
    0x3a, 0x6e, 0x5a, 0xf1, 0x55, 0x4d, 0xa8, 0xc9,
    0xc1, 0x0a, 0x98, 0x15, 0x30, 0x44, 0xa2, 0xc2,
    0x2c, 0x45, 0x92, 0x6c, 0xf3, 0x39, 0x66, 0x42,
    0xf2, 0x35, 0x20, 0x6f, 0x77, 0xbb, 0x59, 0x19,
    0x1d, 0xfe, 0x37, 0x67, 0x2d, 0x31, 0xf5, 0x69,
    0xa7, 0x64, 0xab, 0x13, 0x54, 0x25, 0xe9, 0x09,
    0xed, 0x5c, 0x05, 0xca, 0x4c, 0x24, 0x87, 0xbf,
    0x18, 0x3e, 0x22, 0xf0, 0x51, 0xec, 0x61, 0x17,
    0x16, 0x5e, 0xaf, 0xd3, 0x49, 0xa6, 0x36, 0x43,
    0xf4, 0x47, 0x91, 0xdf, 0x33, 0x93, 0x21, 0x3b,
    0x79, 0xb7, 0x97, 0x85, 0x10, 0xb5, 0xba, 0x3c,
    0xb6, 0x70, 0xd0, 0x06, 0xa1, 0xfa, 0x81, 0x82,
    0x83, 0x7e, 0x7f, 0x80, 0x96, 0x73, 0xbe, 0x56,
    0x9b, 0x9e, 0x95, 0xd9, 0xf7, 0x02, 0xb9, 0xa4,
    0xde, 0x6a, 0x32, 0x6d, 0xd8, 0x8a, 0x84, 0x72,
    0x2a, 0x14, 0x9f, 0x88, 0xf9, 0xdc, 0x89, 0x9a,
    0xfb, 0x7c, 0x2e, 0xc3, 0x8f, 0xb8, 0x65, 0x48,
    0x26, 0xc8, 0x12, 0x4a, 0xce, 0xe7, 0xd2, 0x62,
    0x0c, 0xe0, 0x1f, 0xef, 0x11, 0x75, 0x78, 0x71,
    0xa5, 0x8e, 0x76, 0x3d, 0xbd, 0xbc, 0x86, 0x57,
    0x0b, 0x28, 0x2f, 0xa3, 0xda, 0xd4, 0xe4, 0x0f,
    0xa9, 0x27, 0x53, 0x04, 0x1b, 0xfc, 0xac, 0xe6,
    0x7a, 0x07, 0xae, 0x63, 0xc5, 0xdb, 0xe2, 0xea,
    0x94, 0x8b, 0xc4, 0xd5, 0x9d, 0xf8, 0x90, 0x6b,
    0xb1, 0x0d, 0xd6, 0xeb, 0xc6, 0x0e, 0xcf, 0xad,
    0x08, 0x4e, 0xd7, 0xe3, 0x5d, 0x50, 0x1e, 0xb3,
    0x5b, 0x23, 0x38, 0x34, 0x68, 0x46, 0x03, 0x8c,
    0xdd, 0x9c, 0x7d, 0xa0, 0xcd, 0x1a, 0x41, 0x1c
};

// finite field multiply by 0x02 (x)

byte FFmulX(const byte a)
{
    return (a << 1) ^ (a & 0x80 ? m_poly : 0);
}

byte fwd_affine(byte x)
{   word w = x;
    
    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
    
    return 0x63 ^ (byte)(w ^ (w >> 8));
}

byte inv_affine(byte x)
{   word w = x;

    w = (w << 1) ^ (w << 3) ^ (w << 6);
    
    return 0x05 ^ (byte)(w ^ (w >> 8));
}

// the SubWord transformation performed on the bytes in a column

word SubWord(const word x)
{
    return  bytes2word(
                    fwd_affine(inv_tab[bval(x,0)]), 
                    fwd_affine(inv_tab[bval(x,1)]),
                    fwd_affine(inv_tab[bval(x,2)]), 
                    fwd_affine(inv_tab[bval(x,3)])  );
}

// the RotWord transformation performed on the bytes in a column

word RotWord(const word x)
{
    return  upr(x,3);
}

// the SubBytes transformation performed on all bytes in the state

void SubBytes(byte state[][4], word Ncol)
{   word col;
    for(col = 0; col < Ncol; ++col)
    {
        state[col][0] = fwd_affine(inv_tab[state[col][0]]);
        state[col][1] = fwd_affine(inv_tab[state[col][1]]);
        state[col][2] = fwd_affine(inv_tab[state[col][2]]);
        state[col][3] = fwd_affine(inv_tab[state[col][3]]);
    }
}

// the inverse SubBytes transformation performed on all bytes in the state

void InvSubBytes(byte state[][4], word Ncol)
{   word col;
    for(col = 0; col < Ncol; ++col)
    {
        state[col][0] = inv_tab[inv_affine(state[col][0])];
        state[col][1] = inv_tab[inv_affine(state[col][1])];
        state[col][2] = inv_tab[inv_affine(state[col][2])];
        state[col][3] = inv_tab[inv_affine(state[col][3])];
    }
}

// the ShiftRows transformation performed on rows 1, 2 and 3 of the state

void ShiftRows(byte state[][4], const word Ncol, const word Shr[])
{   word    col, t[Mcol];

    for(col = 0; col < Ncol; ++col)
        t[col] = bytes2word(0, state[col][1], state[col][2], state[col][3]);

    for(col = 0; col < Ncol; ++col)
    {
        state[col][1] = bval(t[(col + Shr[1]) % Ncol], 1);
        state[col][2] = bval(t[(col + Shr[2]) % Ncol], 2);
        state[col][3] = bval(t[(col + Shr[3]) % Ncol], 3);
    }
}

// the inverse ShiftRows transformation performed on rows 1, 2 and 3 of state

void InvShiftRows(byte state[][4], const word Ncol, const word Shr[])
{   word    col, t[Mcol];

    for(col = 0; col < Ncol; ++col)
        t[col] = bytes2word(0, state[col][1], state[col][2], state[col][3]);

    for(col = 0; col < Ncol; ++col)
    {
        state[(col + Shr[1]) % Ncol][1] = bval(t[col], 1);
        state[(col + Shr[2]) % Ncol][2] = bval(t[col], 2);
        state[(col + Shr[3]) % Ncol][3] = bval(t[col], 3);
    }
}

// the MixColumns transformation performed on all columns of the state

void MixColumns(byte state[][4], word Ncol)
{   word col;
    byte t, u;
    for(col = 0; col < Ncol; ++col)
    {   t = state[col][0];
        u = state[col][0] ^ state[col][1] ^ state[col][2] ^ state[col][3];

        state[col][0] ^= u ^ FFmulX(t ^ state[col][1]);
        state[col][1] ^= u ^ FFmulX(state[col][1] ^ state[col][2]);
        state[col][2] ^= u ^ FFmulX(state[col][2] ^ state[col][3]);
        state[col][3] ^= u ^ FFmulX(state[col][3] ^ t);
    }
}

// the inverse MixColumns transformation performed on all columns of the state

void InvMixColumns(byte state[][4], word Ncol)
{   word col;
    byte t, u, v;
    for(col = 0; col < Ncol; ++col)
    {   t = state[col][0];
        u = state[col][0] ^ state[col][1] ^ state[col][2] ^ state[col][3];

        u ^= FFmulX(FFmulX(FFmulX(u)));
        v = u ^ FFmulX(FFmulX(state[col][1] ^ state[col][3]));
        u ^= FFmulX(FFmulX(state[col][0] ^ state[col][2]));

        state[col][0] ^= u ^ FFmulX(t ^ state[col][1]);
        state[col][1] ^= v ^ FFmulX(state[col][1] ^ state[col][2]);
        state[col][2] ^= u ^ FFmulX(state[col][2] ^ state[col][3]);
        state[col][3] ^= v ^ FFmulX(state[col][3] ^ t);
    }
}

// XorRoundKey - add the round key to the state

void XorRoundKey(byte state[][4], const word rk[], const word Ncol)
{   word col, t;
    for(col = 0; col < Ncol; ++col)
    {   t = rk[col];

        state[col][0] ^= bval(t,0);
        state[col][1] ^= bval(t,1);
        state[col][2] ^= bval(t,2);
        state[col][3] ^= bval(t,3);
    }
}

// input the state from the input byte array

void GetState(byte state[][4], const byte in[], const word Ncol)
{   word col, i;
    for(col = 0, i = 0; col < Ncol; ++col)
    {
        state[col][0] = in[i++];
        state[col][1] = in[i++];
        state[col][2] = in[i++];
        state[col][3] = in[i++];
    }
}

// output the state to the output byte array

void PutState(const byte state[][4], byte out[], const word Ncol)
{   word col, i;
    for(col = 0, i = 0; col < Ncol; ++col)
    {
        out[i++] = state[col][0];
        out[i++] = state[col][1];
        out[i++] = state[col][2];
        out[i++] = state[col][3];
    }
}

#if(0)

// code to test the generation of the key schedule from the top downwards

static word t_key[128];

void reverse(const word Ncol, const word Nrnd, const word Nkey, const byte e_key[])
{   word    i;

    i = Ncol * (Nrnd + 1);
    while(i-- > Ncol * (Nrnd + 1) - Nkey)
    {
        t_key[i] = e_key[i];
    }

    i = Ncol * (Nrnd + 1);
    while(i-- > Nkey)
    {
        word    t = t_key[i - 1];

        if(i % Nkey == 0)
        {
            t = SubWord(RotWord(t)) ^ bytes2word(rc_tab[i / Nkey - 1], 0, 0, 0);
        }
        else if(Nkey == 8 && i % Nkey == 4)

            t = SubWord(t);

        t_key[i - Nkey] = t_key[i] ^ t;
    }
}

#endif

// Subroutne to set the block size (if variable)

#if defined(BLOCK_SIZE)
#define nc   (Ncol)
#else
#define nc   (cx->Ncol)
#endif

#if !defined(BLOCK_SIZE)
cf_dec c_name(set_blk)(const word n_bytes, c_name(aes) *cx) 
{
    if((n_bytes & 3) || n_bytes < 16 || n_bytes > 32) 
    {     
        return (n_bytes ? cx->mode &= ~0x07, aes_bad : (aes_ret)(nc << 2));
    }

    cx->mode = cx->mode & ~0x07 | 0x04;
    nc = n_bytes >> 2;
    return aes_good;
}
#endif

// Key Expansion - expand the key to form the key schedule from the
// user supplied key, where Nk is the key length in bits divided by
// 32 with a value of 4, 6 or 8

cf_dec c_name(set_key)(const byte key[], const word n_bytes, const enum aes_key f, c_name(aes) *cx)
{   word        i;
    byte        rc;
    const byte  *p;

    if((n_bytes & 3) || n_bytes < 16 || n_bytes > 32 || !(f & 1) && !(f & 2)) 
    {     
        return (n_bytes ? cx->mode &= ~0x03, aes_bad : (aes_ret)(cx->Nkey << 2));
    }

    cx->mode = cx->mode & ~0x03 | (byte)f & 0x03;      
    cx->Nkey = n_bytes >> 2;
    cx->Nrnd = Nr(cx->Nkey, nc);

    i = 0; p = key;
    while (i < cx->Nkey)
    {
        cx->e_key[i] = bytes2word(p[0], p[1], p[2], p[3]);

        i = i + 1; p += Nrow;
    }

    i = cx->Nkey; rc = 1;
    while(i < nc * (cx->Nrnd + 1))
    {
        word    t = cx->e_key[i - 1];

        if(i % cx->Nkey == 0)
        {
            t = SubWord(RotWord(t)) ^ bytes2word(rc, 0, 0, 0); rc = FFmulX(rc);
        }
        else if(cx->Nkey > 6 && i % cx->Nkey == 4)

            t = SubWord(t);

        cx->e_key[i] = cx->e_key[i - cx->Nkey] ^ t;

        i = i + 1;
    }

    if(cx->mode != enc)
    {
        for(i = 0; i < (cx->Nrnd + 1) * nc; ++i)
            cx->d_key[i] = cx->e_key[i];

// typedef byte        wa_ptr[4];

        for(i = 1; i < cx->Nrnd; ++i)
            InvMixColumns((wa_ptr*)(cx->d_key + i * nc), nc);
    }

//  reverse(nc, Nrnd, Nkey, e_key);

    return aes_good;
}

#if(1)

FILE    *outf = 0L;

static char    *hxx = "0123456789abcdef";

void block_out(const word round, const char* xt, const byte b[][4], const word Ncol)
{   word row, col;

⌨️ 快捷键说明

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