Warrior0322

导航

关于32bit密钥分段16bit的SPN的简短实现方案

(以下方案无法用于密钥更长的SPN类型。可以试试,不过消耗时间会异常多)

#define uint unsigned int
#define us unsigned short
#define Nr 65536

using namespace std;

int K[7];
int S2[16] = { 14,3,4,8,1,12,10,15,7,13,9,6,11,2,0,5 };
int S1[16] = { 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7 };
int P1[16] = { 1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16 };
int P2[16] = { 1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16 };
int putins1[0x10000], putins2[0x10000], putinp1[0x10000], putinp2[0x10000];

 

inline int SPN(int x, int* inS, int* inP)
{
  return inS[inP[inS[inP[inS[inP[inS[x ^ K[1]]] ^ K[2]]] ^ K[3]]] ^ K[4]] ^ K[5];
}

 

 

inline void GetRoundKey(uint Key, int flag)
{
  if (!flag)//flag==0->Encry
    {
      K[1] = Key >> 16 & 0xffff; K[2] = Key >> 12 & 0xffff; K[3] = Key >> 8 & 0xffff; K[4] = Key >> 4 & 0xffff; K[5] = Key & 0xffff;
    }
  else//decry
    {
      K[5] = Key >> 16 & 0xffff; K[4] = putinp2[Key >> 12 & 0xffff]; K[3] = putinp2[Key >> 8 & 0xffff]; K[2] = putinp2[Key >> 4 & 0xffff]; K[1] = Key & 0xffff;
    }
}

 

void init()
{
  for (int i = 0; i < 0x10000; i++)
    {
      for (int j = 0; j < 4; j++)
        {
          putins1[i] |= S1[i >> 4 * j & 15] << 4 * j;
          putins2[i] |= S2[i >> 4 * j & 15] << 4 * j;
        }
      for (int j = 0; j < 16; j++)
        {
          putinp1[i] |= (i >> (16 - P1[j]) & 1) << (15 - j);
          putinp2[i] |= (i >> (16 - P2[j]) & 1) << (15 - j);
        }
    }
}

 

posted on 2020-09-17 10:38  Warrior0322  阅读(167)  评论(0编辑  收藏  举报