�s���H�ƍ������w�Z�i���A�����s���Y�ƋZ�p�������w�Z�j�𑲋ƁA
�@�B�H�w����U�������Ȃɘ_����H��I�[�f�B�I�W�̋Z�p�҂炵���B
��Ƃ��āA���y�W�̃t���[�\�t�g�J����A�c�s�l�E�`�b�v�`���[��������������A
�I�[�P�X�g�������t�y�c���I�[�{�G�𐁂��Ă�l�B
Top Page�^ AES�� top�^
aes_c.zip�@�c�@Visual C++�݂̂ŏ��������B
�|���Z��SubByte()���ɍs���B
���Ȃ݂ɁAVisual C++.net 2008 Express Edition�ł́A�b�����SSE2���߂̍œK���͓��ǂ��Ȃ������ł��B
�b�o�t�̖��߃f�R�[�h�̌��������l�������߂̕��בւ��ʂ͂��Ă���܂����A��������������A�N�Z�X�������đ������������Ă��܂��B
�����I��閈�ɁA���Z���ʂ�xmm���W�X�^���烁�����Ɋi�[���ČĂяo�����ɓn���āA
�Ăяo�����ł��̃���������ǂݍ����xmm���W�X�^�ɑ������Ƃ��A����Ȗ��ʂȎ������\����Ă��܂��B
�Ƃɂ����A�������A�N�Z�X�������œK���ɂȂ��Ă��܂����B
�ȉ��A�A�Z���u������ŏ��������̂́A���̂悤�Ȗ��ʂ�r�����A�����Ă��܂��B
aes_asm.zip�@�c�@�A�Z���u������ŏ����āA��荂���������݂����B
�S�́i�Í��E�����j�ɋ��ʂ��Ď{�����œK���͈ȉ��̒ʂ�ł��B
���̑��A�Í����ɂ����ẮA�K���A��GF(28)�̏�Z��SubByte()���ɍs���e�[�u���ɒu�������܂����B
���̂��߁A�K���A��GF(28)�̏�Z���[�`���̌Ăяo���͖����Ȃ�܂������A�e�[�u���Q�Ɓi�܂胁�����ǂݍ��݁j�͑����Ă��܂��B
�����̃A���S���Y�����œK��������@�͎v�������т܂���ł����B
InvSubByte()��InvAddRound()�̏��Ԃ͓���ւ���Ȃ��̂ŁB
SSE���߂ŁA�X�ɍ����������@�����邩������܂���B���������C�t������������܂�����A�����Ē�����Ɗ������ł��B
�ȉ��A�W[MByte]�̈Í��E�����ɗv�����N���b�N���̑�܂��Ȍv�����ʂł��B
�b����ŏ��������́A�A�Z���u������ŏ��������́A�����SSE2�ɂ��x�N�g�������Ȃ���Ă��܂��B
���AVisual C++.net�̃v���W�F�N�g���ł́A�R���p�C���I�v�V���������s���x�ōœK������悤�ɐݒ肵�Ă���܂��B
�v���O���� | �� | ���� |
---|---|---|
�b���� | �� 1,848 Mclk �i�� 1,643 Mclk �c ���j | �� 2,943 Mclk |
�A�Z���u������ | �� 1,282 Mclk �c �� | �� 1,774 Mclk |
�Z�������ł́A�Í��E�������ɃA�Z���u������ɂ����ʂ��o�Ă���B
�Í��́A�K���A��GF(28)�̏�Z���[�`���̌Ăяo����r���������ɂ����ʂ��傫���B
�����ł̓K���A��GF(28)�̏�Z���[�`�����Ăяo���Ă��邪�A����ȏ�ɃA�Z���u������ɂ�鍂�����������Ă���B
�v���O���� | �� | ���� |
---|---|---|
�b���� | �� 973 Mclk | �� 1,532 Mclk |
�A�Z���u������ | �� 986 Mclk �c �� | �� 1,048 Mclk |
Core2 Quad�ł́A�Í��͋t�Ɏ�x���Ȃ��Ă���B
�A�Z���u������ɂ�鍂�����ɁA�e�[�u���Q�Ɓi�������ǂݍ��݁j�̒x�����������������Ă���Ǝv����B
�����́A�b����ŏ��������̂Ƃقړ����A���S���Y���ł��邪�A�A�Z���u������ɂ�鍂�����������Ă���B
Core2 Quad�̗l�ɓ��쑬�x�������b�o�t�ɂ����ẮA�������ǂݍ��݂��s���e�[�u���Q�Ƃ����A
�K���A��GF(28)�̏�Z���v�Z���Ă��܂������A�X�ɍ������������߂邩������Ȃ��B
�����̎����ł̌v�����ʂ́A�t�@�C���A�N�Z�X�̎��ԁA�Í��������̎��Ԃ��܂݂܂���B
���X�P�W���[���̐����ɂ��ẮASSE2���߂�p�����x�N�g�����͎v�������Ȃ������B
�Ȃ̂ŁA���X�P�W���[���̐������@�́A�ʓr"�A"fips-197"���Q�Ƃ��Ă��炢�����B
������������A�ǂ����@������̂�������Ȃ��B
�Ƃ肠�����A�b++�ɂ��\�[�X���ȉ��ɏ����Ă����B
//==============================================================
// fips-197 5.2 Key Expansion
//--------------------------------------------------------------
// ������
// char cNK = 4(0100) : 128bit AES
// = 6(0110) : 192bit AES
// = 8(1000) : 256bit AES
// const unsigned char Key[] : Cipher Key
// ���Ԓl
// ����
//==============================================================
void AES::KeyExpansion(char cNk, const unsigned char *key)
{
//The round constant word array.
static const unsigned int Rcon[10]={
0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};
unsigned int i;
int iR;
int iRm;
int temp;
Nk = cNk & 0xFE;
Nr = Nk + 6;
//�����������R�s�[
i = 0;
do{
_mm_storel_epi64((__m128i*)&w[i], _mm_loadl_epi64((__m128i*)&key[i*4]));
i++;
i++;
} while (i < Nk);
i = Nk;
temp = w[i-1];
do{
iR = i/Nk;
iRm = i%Nk; //����Z���߂��Q�f���ܑ͖̖̂����B
if(iRm==0){
temp = SubWord(RotWord(temp)) ^ Rcon[(iR)-1];
} else if((Nk > 6) && ( (i%Nk) == 4)){
temp = SubWord(temp);
}
temp ^= w[i-Nk];
w[i] = temp;
i++;
} while (i < Nb * (Nr+1));
}
�R�����g�A�E�g�ɂ������Ă��邪�A4Byte�P�ʂ̉�]�̓A�Z���u�������ror���߂��g���ƌ������ǂ��A
�œK���ɂ����ror ���߂ɂȂ�悤�ɁA�\�[�X�������Ƒ����Ȃ�B
//==============================================================
// fips-197 5.2 RotWord()
//--------------------------------------------------------------
// ������
// unsigned int data 4Byte�̐��l
// ���Ԓl
// unsigned int ror data,8 �̌���
//==============================================================
unsigned int AES::RotWord(unsigned int data)
{
return( (data>>8) | (data<<24) ); //�܂� ror data,8
}
Sbox���̃e�[�u���u���́A�ǂ����悤���Ȃ��Ǝv���B
�������Ȃ���A4Byte�A���C�����g����Ă��Ȃ��������ǂݍ��݂ɂ̓y�i���e�B�[������̂ŁA
�w�ϊ����悤�Ƃ���f�[�^4Byte�͓����Ƀ���������ǂݍ��ށx�R�[�h�ɍœK�������l�ɁA�\�[�X�������B
"static const unsigned char Sbox[256]"��
"static const unsigned int Sbox[256]"�ɏ��������ƁA�܂������Ȃ邩������Ȃ��B
���ACPU����1���L���b�V���ɗ��߂����Ă������߂ɁA�e�[�u���̃T�C�Y�͏����������ǂ���������Ȃ��B
���̊��́A�Í����̍ۂɂ��Ă��B
//==============================================================
// fips-197 5.2 Sbox() (4Byte������)
//--------------------------------------------------------------
// ������
// unsigned int data 4Byte�̐��l
// ���Ԓl
// unsigned int SBox�K�p��
//==============================================================
unsigned int AES::SubWord(unsigned int data)
{
// fips-197 Figure 7
static const unsigned char Sbox[256]={
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
};
//�e�[�u���ϊ��Ɋւ���SIMD���߂͖����H
unsigned char a0 = Sbox[(data ) & 0xFF];
unsigned char a1 = Sbox[(data>>8 ) & 0xFF];
unsigned char a2 = Sbox[(data>>16) & 0xFF];
unsigned char a3 = Sbox[(data>>24)];
return(a0 | a1<<8 | a2<<16 | a3<<24);
}
���SubWord()���̋t�ϊ���������́B
���̊��́A�����̍ۂɌĂ����̂ł��邪�A�����ɏ����Ă����B
//==============================================================
// fips-197 5.2 InvSbox() (4Byte������)
//--------------------------------------------------------------
// ������
// unsigned int data 4Byte�̐��l
// ���Ԓl
// unsigned int InvSBox�K�p��
//==============================================================
unsigned int AES::InvSubWord(unsigned int data)
{
// fips-197 Figure 14
static const unsigned char InvSbox[256]={
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};
//�e�[�u���ϊ��Ɋւ���SIMD���߂͖����H
unsigned char a0 = InvSbox[(data ) & 0xFF];
unsigned char a1 = InvSbox[(data>>8 ) & 0xFF];
unsigned char a2 = InvSbox[(data>>16) & 0xFF];
unsigned char a3 = InvSbox[(data>>24)];
return(a0 | a1<<8 | a2<<16 | a3<<24);
}
16Byte�P�ʂňÍ���������B
���̂悤�ȈÍ����w�u���b�N�Í��x�ƌĂсA�u���b�N�P�ʂňÍ��^���������B
���̊�����сA��������ׂ̊����ĂԑO�ɂ́A���X�P�W���[�������Ȃ���Ȃ�Ȃ��B
�Í����́A�ȉ��̏����ŁA�e�����J��Ԃ��Ă�A���������B
Round | Function |
---|---|
0 ���E���h | AddRoundKey() |
1 �` (Nr-1) | SubBytes() ShiftRows() MixColumns() AddRoundKey() |
Nr �ŏI���E���h | SubBytes() ShiftRows() AddRoundKey() |
���E���h���́A���ʌ����ɂ���ĈقȂ�B
���ʌ��� | ���E���h���iNr�j |
---|---|
128 bit | 10 |
192 bit | 12 |
256 bit | 14 |
//==============================================================
// fips-197 5.1 Cipher
//--------------------------------------------------------------
// ������
// __m128i data Plain-text
// ���Ԓl
// __m128i Cipher-text
//==============================================================
__m128i AES::Cipher(__m128i data)
{
//��Round [0]
int i=0;
data = AddRoundKey(data, i);
i++;
//��Round (1) �` (Nr-1)
do{
data = AddRoundKey(MixColumns(ShiftRows(SubBytes(data))),i);
i++;
} while(i < Nr);
//��Round (Nr)
data = AddRoundKey(ShiftRows(SubBytes(data)),i);
return(data);
}
���X�P�W���[���̐����ł��q�ׂ��悤�ɁASBox�̃e�[�u���ϊ��ɂ��ẮASIMD��������@��S���v�����Ȃ��B
�Ƃ肠�����A4Byte���ɕϊ����s���B
//==============================================================
// fips-197 5.1.1 SubBytes
//--------------------------------------------------------------
// ������
// __m128i data Input
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::SubBytes(__m128i data)
{
//�e�[�u���ϊ��́ASIMD���ł��Ȃ��H
data.m128i_u32[0] = SubWord(data.m128i_u32[0]);
data.m128i_u32[1] = SubWord(data.m128i_u32[1]);
data.m128i_u32[2] = SubWord(data.m128i_u32[2]);
data.m128i_u32[3] = SubWord(data.m128i_u32[3]);
return(data);
}
������肽�����Ƃ����ƁA
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
D[ 2] | D[ 6] | D[10] | D[14] |
D[ 3] | D[ 7] | D[11] | D[15] |
�Ƃ������͂ɑ���
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 5] | D[ 9] | D[13] | D[ 1] |
D[10] | D[14] | D[ 2] | D[ 6] |
D[15] | D[ 3] | D[ 7] | D[11] |
�ɕ��בւ��ďo�͂������ShiftRows()�B
���̔z��������@�Ƃ��ẮA�܂��Aa0�`a3�����B
����a0�`a3�́A_mm_shuffle_epi32()�ɂ���āA���͂��ꂽ�z���32bit�P�ʂœ���ւ������́B
a0 �� ����
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
D[ 2] | D[ 6] | D[10] | D[14] |
D[ 3] | D[ 7] | D[11] | D[15] |
pshufd a1, ����, 00111001b
D[ 4] | D[ 8] | D[12] | D[ 0] |
D[ 5] | D[ 9] | D[13] | D[ 1] |
D[ 6] | D[10] | D[14] | D[ 2] |
D[ 7] | D[11] | D[15] | D[ 3] |
pshufd a2, ����, 01001110b
D[ 8] | D[12] | D[ 0] | D[ 4] |
D[ 9] | D[13] | D[ 1] | D[ 5] |
D[10] | D[14] | D[ 2] | D[ 6] |
D[11] | D[15] | D[ 3] | D[ 7] |
pshufd a3, ����, 10010011b
D[12] | D[ 0] | D[ 4] | D[ 8] |
D[13] | D[ 1] | D[ 5] | D[ 9] |
D[14] | D[ 2] | D[ 6] | D[10] |
D[15] | D[ 3] | D[ 7] | D[11] |
���ɁA�s�v�Ȑ��l���}�X�N���āA"0"�ɂ���B
D[ 0] | D[ 4] | D[ 8] | D[12] |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
D[ 5] | D[ 9] | D[13] | D[ 1] |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
D[10] | D[14] | D[ 2] | D[ 6] |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 |
D[15] | D[ 3] | D[ 7] | D[11] |
����a0�`a3���A�_���a���Z(OR)����ƁA�����Ɋ��҂̔z�o���オ��B
�o�� �� a0 | a1 | a2 | a3
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 5] | D[ 9] | D[13] | D[ 1] |
D[10] | D[14] | D[ 2] | D[ 6] |
D[15] | D[ 3] | D[ 7] | D[11] |
//==============================================================
// fips-197 5.1.2 ShiftRows
//--------------------------------------------------------------
// ������
// __m128i data Input
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::ShiftRows(__m128i data)
{
__declspec(align(16)) static const unsigned int mask0[4] = {0x000000FF,0x000000FF,0x000000FF,0x000000FF};
__declspec(align(16)) static const unsigned int mask1[4] = {0x0000FF00,0x0000FF00,0x0000FF00,0x0000FF00};
__declspec(align(16)) static const unsigned int mask2[4] = {0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000};
__declspec(align(16)) static const unsigned int mask3[4] = {0xFF000000,0xFF000000,0xFF000000,0xFF000000};
const __m128i _mm_mask0 = _mm_load_si128((__m128i*)&mask0);
const __m128i _mm_mask1 = _mm_load_si128((__m128i*)&mask1);
const __m128i _mm_mask2 = _mm_load_si128((__m128i*)&mask2);
const __m128i _mm_mask3 = _mm_load_si128((__m128i*)&mask3);
__m128i a0 = _mm_and_si128(_mm_mask0, data); //�c�����̉�]
__m128i a1 = _mm_and_si128(_mm_mask1, _mm_shuffle_epi32(data, 0x39)); //0011 1001 b
__m128i a2 = _mm_and_si128(_mm_mask2, _mm_shuffle_epi32(data, 0x4E)); //0100 1110 b
__m128i a3 = _mm_and_si128(_mm_mask3, _mm_shuffle_epi32(data, 0x93)); //1001 0011 b
return(_mm_or_si128(_mm_or_si128(a0,a1),_mm_or_si128(a2,a3)));
}
4Byte�P�ʂŁA�K���A��GF(28)�ɂ�����s��̉��Z���s���B
�i�K���A�́i�L���́j�ɂ��ẮA���w�̐�发���Q�Ƃ̎��B�j
�@| O[0] |�@ �@�@| �Q�@�R�@�P�@�P || I[0] |
�@| O[1] |�@���@| �P�@�Q�@�R�@�P || I[1] |
�@| O[2] |�@ �@�@| �P�@�P�@�Q�@�R || I[2] |
�@| O[3] |�@ �@�@| �R�@�P�@�P�@�Q || I[3] |
�܂�A
�@O[0] �� 2I[0] �{ 3I[1] �{�@I[2] �{�@I[3]
�@O[1] ���@I[0] �{ 2I[1] �{ 3I[2] �{�@I[3]
�@O[2] ���@I[0] �{�@I[1] �{ 2I[2] �{ 3I[3]
�@O[3] �� 3I[0] �{�@I[1] �{�@I[2] �{ 2I[3]
���̌v�Z���A�s���B
SIMD������ɓ������ẮA�ȉ��̃v���Z�X�Ƃ����B
���͂ɑ��āA�Q�{���ꂽ�z��ia0�j�ƁA�P�{���ꂽ�z����Q�ia1,a2�j�A�R�{���ꂽ�z��ia3�j��p�ӂ���B
a0 �� �Q �~ ����
2D[ 0] | 2D[ 4] | 2D[ 8] | 2D[12] |
2D[ 1] | 2D[ 5] | 2D[ 9] | 2D[13] |
2D[ 2] | 2D[ 6] | 2D[10] | 2D[14] |
2D[ 3] | 2D[ 7] | 2D[11] | 2D[15] |
a1 �� �P �~ ����
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
D[ 2] | D[ 6] | D[10] | D[14] |
D[ 3] | D[ 7] | D[11] | D[15] |
a2 �� �P �~ ����
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
D[ 2] | D[ 6] | D[10] | D[14] |
D[ 3] | D[ 7] | D[11] | D[15] |
a3 �� �R �~ ����
3D[ 0] | 3D[ 4] | 3D[ 8] | 3D[12] |
3D[ 1] | 3D[ 5] | 3D[ 9] | 3D[13] |
3D[ 2] | 3D[ 6] | 3D[10] | 3D[14] |
3D[ 3] | 3D[ 7] | 3D[11] | 3D[15] |
���ɂ�邱�Ƃ́A32bit�P�ʂŁAa0�`a3����]�B
rol a0,0�@�@�i�܂��]���Ȃ��B�j
2D[ 0] | 2D[ 4] | 2D[ 8] | 2D[12] |
2D[ 1] | 2D[ 5] | 2D[ 9] | 2D[13] |
2D[ 2] | 2D[ 6] | 2D[10] | 2D[14] |
2D[ 3] | 2D[ 7] | 2D[11] | 2D[15] |
rol a1,8�@�@�i��8bit��]�j
D[ 3] | D[ 7] | D[11] | D[15] |
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
D[ 2] | D[ 6] | D[10] | D[14] |
rol a2,16�@�@�i��16bit��]�j
D[ 2] | D[ 6] | D[10] | D[14] |
D[ 3] | D[ 7] | D[11] | D[15] |
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
rol a3,24�@�@�i��24bit��]�j
3D[ 1] | 3D[ 5] | 3D[ 9] | 3D[13] |
3D[ 2] | 3D[ 6] | 3D[10] | 3D[14] |
3D[ 3] | 3D[ 7] | 3D[11] | 3D[15] |
3D[ 0] | 3D[ 4] | 3D[ 8] | 3D[12] |
��]��A����a0�`a3�����Z����A���Ғl�̔z������킯�ł��B
�����ł̉��Z�́A�K���A��GF(28)�ɂ����鉉�Z�ł���̂ŁA
���Ғl �� a0 ^ a1 ^ a2 ^ a3
//==============================================================
// fips-197 5.1.3 MixColumns
//--------------------------------------------------------------
// ������
// __m128i data Input
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::MixColumns(__m128i data)
{
__m128i a0 = mul(data, 2);
__m128i a1 = data; // = mul(data, 1);
__m128i a2 = data; // = mul(data, 1);
__m128i a3 = mul(data, 3);
// ����SSE���߂�ror����������
// �����������Ɓi32bit�E��]�j
a1 = _mm_or_si128(_mm_srli_epi32(a1,24),_mm_slli_epi32(a1, 8)); // prord a1, 24
a2 = _mm_or_si128(_mm_srli_epi32(a2,16),_mm_slli_epi32(a2,16)); // prord a2, 16
a3 = _mm_or_si128(_mm_srli_epi32(a3, 8),_mm_slli_epi32(a3,24)); // prord a3, 8
return(_mm_xor_si128(_mm_xor_si128(a0,a1),_mm_xor_si128(a2,a3)));
}
�ȉ��́A�K���A��GF(28)�ɂ������Z���s�����B
�L�����[�i���オ��j����������ׁA�z��v�f�����ɕ����āA8bit���̔z���16bit���ɂ��A���Z���Ă���B
�K���A��GF(28)�ɂ����āA�wx8 + x4 + x3 + x2 + 1 �� 0�x�ł���ׁA���オ�莞�́A���̒l�i0x011B�j�����Z�iXOR�j����B
//==============================================================
// fips-197 4.2 Multiplication
//--------------------------------------------------------------
// ������
// __m128i data Input
// unsigned char n
// ���Ԓl
// __m128i Result (data[0..15] �~ n)
//==============================================================
__m128i AES::mul(__m128i data, unsigned char n)
{
__declspec(align(16)) static const unsigned __int16 _FF00[8] = {0xFF00,0xFF00,0xFF00,0xFF00, 0xFF00,0xFF00,0xFF00,0xFF00};
__declspec(align(16)) static const unsigned __int16 _00FF[8] = {0x00FF,0x00FF,0x00FF,0x00FF, 0x00FF,0x00FF,0x00FF,0x00FF};
__declspec(align(16)) static const unsigned __int16 _011B[8] = {0x011B,0x011B,0x011B,0x011B, 0x011B,0x011B,0x011B,0x011B};
const __m128i _mm_FF00 = _mm_load_si128((__m128i*)&_FF00);
const __m128i _mm_00FF = _mm_load_si128((__m128i*)&_00FF);
const __m128i _mm_011B = _mm_load_si128((__m128i*)&_011B);
__m128i data1 = _mm_srli_epi16( _mm_and_si128(data, _mm_FF00), 8);
__m128i data2 = _mm_and_si128(data, _mm_00FF);
__m128i result1 = _mm_setzero_si128();
__m128i result2 = _mm_setzero_si128();
unsigned char i = 0x08;
do{
result1 = _mm_slli_epi16(result1, 1);
result2 = _mm_slli_epi16(result2, 1);
result1 = _mm_xor_si128(result1, _mm_and_si128(_mm_cmpgt_epi16(result1, _mm_00FF), _mm_011B));
result2 = _mm_xor_si128(result2, _mm_and_si128(_mm_cmpgt_epi16(result2, _mm_00FF), _mm_011B));
if(i & n){
result1 = _mm_xor_si128(result1, data1);
result2 = _mm_xor_si128(result2, data2);
}
i >>= 1;
} while (i>0);
return(_mm_or_si128(_mm_slli_epi16(result1, 8), result2));
}
���E���h���ɉ��������X�P�W���[���ƁA�r���I�_���a(XOR)���邾���B
//==============================================================
// fips-197 5.1.4 AddRoundKey
//--------------------------------------------------------------
// ������
// __m128i data Input
// int i Round
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::AddRoundKey(__m128i data, int i)
{
return(_mm_xor_si128(data, _mm_load_si128((__m128i*)&w[i*4])));
}
�Í����̋t�̏��ԂƂȂ�B
Round | Function |
---|---|
Nr ���E���h | InvAddRoundKey() |
(Nr-1) �` 1 | InvShiftRows() InvSubBytes() InvAddRoundKey() InvMixColumns() |
0 �ŏI���E���h | InvShiftRows() InvSubBytes() InvAddRoundKey() |
//==============================================================
// fips-197 5.3 InvCipher
//--------------------------------------------------------------
// ������
// __m128i data Cipher-text
// ���Ԓl
// __m128i Plain-text
//==============================================================
__m128i AES::InvCipher(__m128i data)
{
//��Round (Nr)
int i=Nr;
data = InvAddRoundKey(data, i);
i--;
//��Round (Nr-1) �` (1)
do{
data = InvMixColumns(InvAddRoundKey(InvSubBytes(InvShiftRows(data)),i));
i--;
} while(i > 0);
//��Round (0)
data = InvAddRoundKey(InvSubBytes(InvShiftRows(data)), i);
return(data);
}
������肽�����Ƃ����ƁAShiftRows()�̋t�̉�]�B
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[ 1] | D[ 5] | D[ 9] | D[13] |
D[ 2] | D[ 6] | D[10] | D[14] |
D[ 3] | D[ 7] | D[11] | D[15] |
�Ƃ������͂ɑ���
D[ 0] | D[ 4] | D[ 8] | D[12] |
D[13] | D[ 1] | D[ 5] | D[ 9] |
D[10] | D[14] | D[ 2] | D[ 6] |
D[ 7] | D[11] | D[15] | D[ 3] |
�ɕ��בւ��ďo�͂������InvShiftRows()�B
ShiftRows()�ƁA���l�̕��@�ʼn�]�ł���B
//==============================================================
// fips-197 5.3.1 InvShiftRows
//--------------------------------------------------------------
// ������
// __m128i data Input
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::InvShiftRows(__m128i data)
{
__declspec(align(16)) static const unsigned int mask0[4] = {0x000000FF,0x000000FF,0x000000FF,0x000000FF};
__declspec(align(16)) static const unsigned int mask1[4] = {0x0000FF00,0x0000FF00,0x0000FF00,0x0000FF00};
__declspec(align(16)) static const unsigned int mask2[4] = {0x00FF0000,0x00FF0000,0x00FF0000,0x00FF0000};
__declspec(align(16)) static const unsigned int mask3[4] = {0xFF000000,0xFF000000,0xFF000000,0xFF000000};
const __m128i _mm_mask0 = _mm_load_si128((__m128i*)&mask0);
const __m128i _mm_mask1 = _mm_load_si128((__m128i*)&mask1);
const __m128i _mm_mask2 = _mm_load_si128((__m128i*)&mask2);
const __m128i _mm_mask3 = _mm_load_si128((__m128i*)&mask3);
__m128i a0 = _mm_and_si128(_mm_mask0, data); //�c�����̉�]
__m128i a1 = _mm_and_si128(_mm_mask3, _mm_shuffle_epi32(data, 0x39)); //0011 1001 b
__m128i a2 = _mm_and_si128(_mm_mask2, _mm_shuffle_epi32(data, 0x4E)); //0100 1110 b
__m128i a3 = _mm_and_si128(_mm_mask1, _mm_shuffle_epi32(data, 0x93)); //1001 0011 b
return(_mm_or_si128(_mm_or_si128(a0,a1),_mm_or_si128(a2,a3)));
}
SubBytes()���̋t�ϊ����s���B
//==============================================================
// fips-197 5.3.2 InvSubBytes
//--------------------------------------------------------------
// ������
// __m128i data Input
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::InvSubBytes(__m128i data)
{
//�e�[�u���ϊ��́ASIMD���ł��Ȃ��H
data.m128i_u32[0] = InvSubWord(data.m128i_u32[0]);
data.m128i_u32[1] = InvSubWord(data.m128i_u32[1]);
data.m128i_u32[2] = InvSubWord(data.m128i_u32[2]);
data.m128i_u32[3] = InvSubWord(data.m128i_u32[3]);
return(data);
}
MixColumns()�ōs�����s�Z�ɂĎg�p�����s��̋t�s���p���ĉ��Z����B
���͂��ꂽ�z���I[0]�`I[3]�A�o�͂��ׂ��z���O[0]�`O[3]�Ɖ��肷��ƁA
�@| O[0] |�@ �@�@| 14�@09�@13�@11 || I[0] |
�@| O[1] |�@���@| 11�@14�@09�@13 || I[1] |
�@| O[2] |�@ �@�@| 13�@11�@14�@09 || I[2] |
�@| O[3] |�@ �@�@| 09�@13�@11�@14 || I[3] |
�܂�A
�@O[0] ��14I[0] �{ 9I[1] �{13I[2] �{11I[3]
�@O[1] ��11I[0] �{14I[1] �{ 9I[2] �{13I[3]
�@O[2] ��13I[0] �{11I[1] �{14I[2] �{ 9I[3]
�@O[3] �� 9I[0] �{13I[1] �{11I[2] �{14I[3]
���̌v�Z���A�s���B
���͂ɑ��āA14�{���ꂽ�z��ia0�j�A9�{���ꂽ�z��ia1�j�A13�{���ꂽ�z��ia2�j�ƁA11�{���ꂽ�z��ia3�j��p�ӂ��A
MixColumns()�����l�Ɍv�Z�ł���B
//==============================================================
// fips-197 5.3.3 InvMixColumns
//--------------------------------------------------------------
// ������
// __m128i data Input
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::InvMixColumns(__m128i data)
{
__m128i a0 = mul(data, 0x0E);
__m128i a1 = mul(data, 0x09);
__m128i a2 = mul(data, 0x0D);
__m128i a3 = mul(data, 0x0B);
// ����SSE���߂�ror����������
// �����������Ɓi32bit�E��]�j
a1 = _mm_or_si128(_mm_srli_epi32(a1,24),_mm_slli_epi32(a1, 8)); // prord a1, 24
a2 = _mm_or_si128(_mm_srli_epi32(a2,16),_mm_slli_epi32(a2,16)); // prord a2, 16
a3 = _mm_or_si128(_mm_srli_epi32(a3, 8),_mm_slli_epi32(a3,24)); // prord a3, 8
return(_mm_xor_si128(_mm_xor_si128(a0,a1),_mm_xor_si128(a2,a3)));
}
���E���h���ɉ��������X�P�W���[���ƁA�r���I�_���a(XOR)���邾���B
//==============================================================
// fips-197 5.3.4 InvAddRoundKey
//--------------------------------------------------------------
// ������
// __m128i data Input
// int i Round
// ���Ԓl
// __m128i Output
//==============================================================
__m128i AES::InvAddRoundKey(__m128i data, int i)
{
return(_mm_xor_si128(data, _mm_load_si128((__m128i*)&w[i*4])));
}
��̃A�h���X�́w@�x�Ɓwnifty�x�̊ԂɁwspa.�x��lj����ĉ������B
�摜�ŋL�ڂ���Ă���A�h���X�ł��͂��܂����A�X�p���h�~�̃t�B���^�[�𑽐��������Ă��܂��B
�{�z�[���y�[�W�̓����N�t���[�ł��B
�����N�́A�g�b�v�y�[�W
"http://shaw.la.coocan.jp/"
�ɂ��肢�������܂��B