AES128加密-S盒和逆S盒構造推導及代碼實現


文檔引用了《密碼編碼學與網絡安全--原理和實踐》里邊的推導過程,如有不妥,請與我聯系修改。

 

文檔《FIPS 197》高級加密標准AES,里邊有個S盒構造,涉及到了數論和有限域的一些概念,一臉懵逼,所以賤賤的研究了下,花了好久時間。

在網上找的S盒構造的詳細步驟總是缺了點什么,要么步驟不詳細,要么只貼了程序,難以搞清楚由幾個基本概念一步一步推導出最終的S盒。最后,還是《密碼編碼學與網絡安全--原理和實踐》這本書講得比較詳細。教材果然還是經過精雕細琢過的,符合大部分人的認知過程。

這篇文章其一是記錄下來這個學習步驟,其二是希望我的這篇能夠更詳細些。 

 

先貼出來《FIPS 197》中對S盒構造的描述步驟:

 

就這兩條。實際上是三個步驟,《密碼編碼學與網絡安全--原理和實踐》教材里會講得更詳細些。

 

一下都按照《密碼編碼學與網絡安全--原理和實踐》教材里邊的三個步驟進行推導。

步驟1、3都比較淺顯,即使沒有數論和有限域概念,一樣可以編程寫出來。

步驟一:

根據行標號和列標號組合成16X16的二維數組,行標號作為高4bit,列標號作為低4bit;

生成代碼如下:

1     for(i=0;i<0x10;i++)
2  { 3 for(j=0;j<0x10;j++) 4  { 5 s_box_ary[i][j] = ((i<<4)&0xF0) + (j&(0xF)); 6  } 7 }

代碼產生的數組:

 1     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 2  0  0  1  2  3  4  5  6  7  8  9 a b c d e f 3 1 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 4 2 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 5 3 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 6 4 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 7 5 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 8 6 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 9 7 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 10 8 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 11 9 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f 12  a a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af 13  b b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf 14  c c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf 15  d d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df 16  e e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef 17 f f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff

本文重點敘述步驟2的推導。

步驟二:

這里邊有三個概念:有限域、GF(2^8)、逆。

有限域:我的理解是,有一些元素構成了一個集合,集合中的一個或多個元素,進行某種運算,所得的結果仍然是集合中的元素。 元素,可以是具體的數字,也可以是字母,或是表達式,等等;某種運算,可以是加減乘除,或者邏輯運算,或者求余,或者是這幾種運算的組合,等等。  這個定義當然很不嚴格,但是我覺得對於理解這個S盒推導夠用了。

 

GF(2^8):GF()是代表一個有限域,2^8=256,是指這個有限域內的元素的個數,即256個。

舉個是有限域的集合的例子吧。

GF(7)={0,1,2,3,4,5,6},它是關於任意兩個元素的相加/乘積模7運算的有限域。特點是任意兩個元素相加/乘積,對7取余數,這個余數仍然在GF(7)內。

截取《密碼編碼學與網絡安全--原理和實踐》中的例子:

 

 此外,這個GF(7)的7叫做階,特點是階與域內的元素都互素(互質)。

在計算機中,一個字節是8位,0~255剛好是一個字節所能代表的所有數字,但是呢,GF(256),256對於0~255內的元素並不是每個都互素(互質),當以251為模時,251~255又不能用,造成浪費,所以不能直接使用上邊的計算形式。但是我們還得必須用0~255這256個整數作為一個集合,通過某種運算構成有限域,所有只能把研究重點放在“某種運算”上。可能是為了區分GF(256),所以用GF(2^8)。

 

逆:乘法逆元。定義:GF(p),   (a)、(b)、(a-1)都在GF(p)內,其中(a)、(a-1)互為乘法逆元,則有:[(a) X (a-1)] mod p = 1;

 

第二個步驟,就是 在步驟一得到的數組基礎上,對每個元素 在 GF(2^8)有限域上求解出乘法逆元,在原位置替換該元素。

如何求解有限域上的逆元?《密碼編碼學與網絡安全--原理和實踐》中從歐幾里得算法開始做知識鋪墊,到擴展歐幾里得算法。我們可以得出求乘法逆元的一個程序上可實現的方法。

d=gcd(a,b),d是a和b的最大公約數,或者叫最大公因子。求解步驟:

1、定義變量:r0, r1, r2

2、賦初值r0=a;r1=b;

3、求解r0、r1的余數:r3=r0 Mod r1;

4、更新變量:r0=r1;r1=r2;

5、從3開始重復,一直到求解的余數r1是0結束。

6、r0就是要求解的最大公約數。

long gcd(long a, long b)
{
	long tmp;
	while(b)
	{
		tmp=a;
		a=b;
		b=tmp%b;
	}
	return a;
}

歐幾里得算法的關鍵是gcd(a,b)=gcd(b,(a mod b));為什么能成立?

可以證明:

當a>b,就有,a=q1 * b + r1,r1 = a - q1 * b;

假設 d=gcd(a,b),那么d分別是a和b的最大公因子,記作:d|a,d|b,所以:d|(a-q1 * b)=d|r1

所以有d=gcd(b,r1)=gcd(b, (a mod b));

《密碼編碼學與網絡安全--原理和實踐》里邊講解會更詳細:

 

 擴展歐幾里得算法的計算步驟同歐幾里得算法的步驟相似,由一個公式迭代計算,一直達到某個條件成立結束迭代,返回結果。

擴展歐幾里得算法用來求解乘法逆元,為什么?

上邊已經有了公式:[(a) * (a-1)] mod p = 1;

可以等效變換成:p * x + 1 = (a) * (a-1)

========>     - p * x + (a) * (a-1) = 1

 與ax+by=1的形式是不是很像?

與ax+by=gcd(a,b)=1的形式是不是很像?

gcd(a,b)=1,就是a、b互素即可。

可以看出,可以運用歐幾里得算法的步驟計算乘法逆元,但是怎么計算呢?

這點我還是照搬《密碼編碼學與網絡安全--原理和實踐》里邊的講解步驟吧,我覺得不會比他講得更好了。

就是這樣,初始條件:(R-1) = a; R0=b; (X-1)=1;X0=0;(Y-1)=0;Y0=1;

迭代步驟:Rn=(Rn-2) Mod (Rn-1);Qn = [(Rn-2) /(Rn-1)]   {(Rn-2) /(Rn-1)的商};Xn = (Xn-2) - (Xn-2) ;Yn = (Yn-2) - (Yn-2) 。

終止條件:Rn=1時,計算出來的Yn即是結果。

如果結果為負數,需要加上模值變為正數。

代碼如下:

long multiplicativeInverse(long a, long b)
{
    long r0,r1,r2,q1,x0,x1,x2,y0,y1,y2; long d = gcd(a,b); if((d!=1)&&(d!=-1)) { printf("a、b不互質\r\n"); return -1; } r0=a; r1=b; x0=1; y0=0; x1=0; y1=1; if((b==1)||(b==-1)) { y2=y1; } while((r1!=1)&&(r1!=-1)) { q1=r0/r1; r2=r0%r1; x2=x0-q1*x1; y2=y0-q1*y1; r0=r1; r1=r2; x0=x1; x1=x2; y0=y1; y1=y2; } if(y2 < 0) { y2=a+y2; } return y2; }

 回歸到GF(2^8)有限域,需要找到“某種運算”,使GF(2^8)有限域成立。這種運算是多項式除法運算。

多項式如下形式:

我們可以把GF(2^8)有限域內的每一個元素,按照下列方式寫成多項式的形式:

設 字節a ∈ GF(2^8),寫成二進制的形式a=b7b6b5b4b3b2b1b0,用bn代表a的每一位,其中n是二進制數中的位置;

那么,bn當作系數,n作為變量x的指數;

可以把一個字節寫成:

 

這種形式。

舉例:

0x9A=(b)10011010,寫成多項式形式:x^7+x^4+x^3+x。

多項式除法運算,計算規則:

1、遵循代數基本規則中的普通多項式運算規則;

2、系數運算遵循以2為模的加法和乘法運算;(原話是:系數運算以p為模,即遵循有限域Zp上的運算規則);

3、如果乘法運算的結果是次數大於7(原文:n-1)的多項式,那么必須將其除以某個次數為8(原文:n)的即約多項式m(x)並取余式,對於多項式f(x),這個余數可表示為:即r(x) = f(x) mod m(x)。

高級加密標准AES使用有限域GF(2^8)上的運算,其中即約多項式m(x)=x^8 + x^4 + x^3 + x + 1;

舉例:

m(x)=x^8 + x^4 + x^3 + x + 1;

f(x) =x^6 + x^4 + x^2 + x + 1;g(x) =x^7 +  x + 1;

f(x) * g(x) = (x^6 + x^4 + x^2 + x + 1) * (x^7 +  x + 1)

                = x^13 + x^11 + x^9 + x^8 + x^7

                                                          + x^7 + x^5 + x^3 + x^2 + x

                                                              + x^6 + x^4      + x^2 + x + 1

             = x^13 + x^11 + x^9 + x^8 + x^6+ x^5 + x^4 + x^3 + 1

r(x) = [f(x) * g(x)] mod m(x)   =>    m(x) * q(x) + r(x) = f(x) * g(x):

 

 q(x) = x^5 + x^3;r(x) = x^7 + x^6 + 1。

上文已經講到:擴展歐幾里得算法用來求解乘法逆元。

 (b-1)*b mod a = 1;   =>  ax+by=1=gcd(a, b)

把a、b用多項式替代,形式如下:

b-1(x) * b(x)  mod m(x) = 1    =>  m(x)v(x) + b(x)w(x) = 1 = gcd(m(x), b(x))

 直接引用上邊求乘法逆元的步驟,用多項式直接替代數值計算:

重述如下:

1、把帶求解的字節變換成多項式形式b(x);

2、初始條件:

(R-1) = m(x);        R0=b(x);

(v-1)(x)=1;            v0(x)=0;

(w-1)(x)=0;           w0(x)=1;

3、迭代步驟:

Rn(x)=(Rn-2)(x)  Mod  (Rn-1)(x);

Qn(x) = [(Rn-2)(x)  /  (Rn-1)(x)]   即:{(Rn-2) /(Rn-1)的商};

vn(x) = (vn-2)(x) - Qn(x)*(vn-2)(x) ;

wn(x) = (wn-2)(x) - Qn(x)*(wn-2) 。

4、終止條件:

Rn(x)=1時,計算出來的wn(x)即是結果多項式。

5、把wn(x)變換回字節。

上述步驟中,需要專門的多項式乘法、多項式除法、多項式求余運算的實現函數。

 多項式乘法函數:

//GF(2^8)的多項式乘法
uint16_t polynomialMutil(uint8_t a, uint8_t b)
{
    uint16_t tmp[8]={0};
    uint8_t i;
    for(i=0;i<8;i++)
    {
        tmp[i] = (a<<i)*((b>>i)&0x1);
    }

    tmp[0] = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3] ^ tmp[4] ^ tmp[5] ^ tmp[6] ^ tmp[7];
    
    return tmp[0];
}

多項式除法函數:

//找到最高位
uint8_t findHigherBit(uint16_t val)
{
    int i=0;
    while(val)
    {
        i++;
        val = val>>1;
    }
    return i;
}

//GF(2^8)的多項式除法
uint8_t gf28_div(uint16_t div_ed, uint16_t div, uint16_t *remainder)
{
    uint16_t r0=0; 
    uint8_t  qn=0;
    int bitCnt=0;

    r0=div_ed;

    bitCnt = findHigherBit(r0)-findHigherBit(div);
    while(bitCnt>=0)
    {
        qn = qn | (1<<bitCnt);
        r0 = r0 ^ (div<<bitCnt);
        bitCnt = findHigherBit(r0)-findHigherBit(div);
    }
    *remainder = r0;
    return qn;
}

多項式的擴展歐幾里得算法:

//GF(2^8)多項式的擴展歐幾里得算法
uint8_t extEuclidPolynomial(uint8_t a, uint16_t m)
{
    uint16_t r0, r1, r2;
    uint8_t  qn, v0, v1, v2, w0, w1, w2;

    r0=m;
    r1=a;

    v0=1;
    v1=0;

    w0=0;
    w1=1;

    while(r1!=1)
    {
        qn=gf28_div(r0, r1, &r2);

        v2=v0^polynomialMutil(qn, v1);
        w2=w0^polynomialMutil(qn, w1);

        r0=r1;
        r1=r2;

        v0=v1;
        v1=v2;

        w0=w1;
        w1=w2;
    }
    return w1;
}

至此,S盒變換的第二步驟實現完成。

根據 擴展歐幾里得算法,得到的中間狀態的S盒如下:

    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0  0  1 8d f6 cb 52 7b d1 e8 4f 29 c0 b0 e1 e5 c7
 1 74 b4 aa 4b 99 2b 60 5f 58 3f fd cc ff 40 ee b2
 2 3a 6e 5a f1 55 4d a8 c9 c1  a 98 15 30 44 a2 c2
 3 2c 45 92 6c f3 39 66 42 f2 35 20 6f 77 bb 59 19
 4 1d fe 37 67 2d 31 f5 69 a7 64 ab 13 54 25 e9  9
 5 ed 5c  5 ca 4c 24 87 bf 18 3e 22 f0 51 ec 61 17
 6 16 5e af d3 49 a6 36 43 f4 47 91 df 33 93 21 3b
 7 79 b7 97 85 10 b5 ba 3c b6 70 d0  6 a1 fa 81 82
 8 83 7e 7f 80 96 73 be 56 9b 9e 95 d9 f7  2 b9 a4
 9 de 6a 32 6d d8 8a 84 72 2a 14 9f 88 f9 dc 89 9a
 a fb 7c 2e c3 8f b8 65 48 26 c8 12 4a ce e7 d2 62
 b  c e0 1f ef 11 75 78 71 a5 8e 76 3d bd bc 86 57
 c  b 28 2f a3 da d4 e4  f a9 27 53  4 1b fc ac e6
 d 7a  7 ae 63 c5 db e2 ea 94 8b c4 d5 9d f8 90 6b
 e b1  d d6 eb c6  e cf ad  8 4e d7 e3 5d 50 1e b3
 f 5b 23 38 34 68 46  3 8c dd 9c 7d a0 cd 1a 41 1c

 

步驟三:S盒字節變換和逆S盒字節變換:

//S盒字節變換
uint8_t byteTransformation(uint8_t a, uint8_t x)
{
    uint8_t tmp[8]={0};

    for(uint8_t i=0;i<8;i++)
    {
        tmp[i]= (((a>>i)&0x1)^((a>>((i+4)%8))&0x1)^((a>>((i+5)%8))&0x1)^((a>>((i+6)%8))&0x1)^((a>>((i+7)%8))&0x1)^((x>>i)&0x1)) << i;
    }
    tmp[0] = tmp[0]+tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7];
    return tmp[0];
}

//逆S盒字節變換
uint8_t invByteTransformation(uint8_t a, uint8_t x)
{
    uint8_t tmp[8]={0};

    for(uint8_t i=0;i<8;i++)
    {
        tmp[i]= (((a>>((i+2)%8))&0x1)^((a>>((i+5)%8))&0x1)^((a>>((i+7)%8))&0x1)^((x>>i)&0x1)) << i;
    }
    tmp[0] = tmp[0]+tmp[1]+tmp[2]+tmp[3]+tmp[4]+tmp[5]+tmp[6]+tmp[7];
    return tmp[0];
}

 

S盒變換代碼:

//S盒產生
void s_box_gen(void)
{
    uint8_t i,j;
    uint8_t s_box_ary[16][16] = {0};

//初始化S盒
    for(i=0;i<0x10;i++)
    {
        for(j=0;j<0x10;j++)
        {
            s_box_ary[i][j] = ((i<<4)&0xF0) + (j&(0xF));
        }
    }

    printf("    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
    for(i=0;i<0x10;i++)
    {
        printf("\r\n%2x",i);
        for(j=0;j<0x10;j++)
        {
            printf(" %2x",s_box_ary[i][j]);
        }
    }
//求在GF(2^8)域上的逆,0映射到自身
    printf("\r\n");
    for(i=0;i<0x10;i++)
    {
        for(j=0;j<0x10;j++)
        {
            if(s_box_ary[i][j] != 0)
            {
                s_box_ary[i][j] = extEuclidPolynomial(s_box_ary[i][j],0x11B);
            }
        }
    }

    printf("\r\n\r\n    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
    for(i=0;i<0x10;i++)
    {
        printf("\r\n%2x",i);
        for(j=0;j<0x10;j++)
        {
            printf(" %2x",s_box_ary[i][j]);
        }
    }
//對每個字節做變換
    for(i=0;i<0x10;i++)
    {
        for(j=0;j<0x10;j++)
        {
            s_box_ary[i][j]=byteTransformation(s_box_ary[i][j], 0x63);
        }
    }

    printf("\r\n\r\n    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
    for(i=0;i<0x10;i++)
    {
        printf("\r\n%2x",i);
        for(j=0;j<0x10;j++)
        {
            printf(" %2x",s_box_ary[i][j]);
        }
    }
}

輸出如下:

    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 1 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
 2 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
 3 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
 4 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
 5 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
 6 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
 7 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
 8 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
 9 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f
 a a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af
 b b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf
 c c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf
 d d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df
 e e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef
 f f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff


    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0  0  1 8d f6 cb 52 7b d1 e8 4f 29 c0 b0 e1 e5 c7
 1 74 b4 aa 4b 99 2b 60 5f 58 3f fd cc ff 40 ee b2
 2 3a 6e 5a f1 55 4d a8 c9 c1  a 98 15 30 44 a2 c2
 3 2c 45 92 6c f3 39 66 42 f2 35 20 6f 77 bb 59 19
 4 1d fe 37 67 2d 31 f5 69 a7 64 ab 13 54 25 e9  9
 5 ed 5c  5 ca 4c 24 87 bf 18 3e 22 f0 51 ec 61 17
 6 16 5e af d3 49 a6 36 43 f4 47 91 df 33 93 21 3b
 7 79 b7 97 85 10 b5 ba 3c b6 70 d0  6 a1 fa 81 82
 8 83 7e 7f 80 96 73 be 56 9b 9e 95 d9 f7  2 b9 a4
 9 de 6a 32 6d d8 8a 84 72 2a 14 9f 88 f9 dc 89 9a
 a fb 7c 2e c3 8f b8 65 48 26 c8 12 4a ce e7 d2 62
 b  c e0 1f ef 11 75 78 71 a5 8e 76 3d bd bc 86 57
 c  b 28 2f a3 da d4 e4  f a9 27 53  4 1b fc ac e6
 d 7a  7 ae 63 c5 db e2 ea 94 8b c4 d5 9d f8 90 6b
 e b1  d d6 eb c6  e cf ad  8 4e d7 e3 5d 50 1e b3
 f 5b 23 38 34 68 46  3 8c dd 9c 7d a0 cd 1a 41 1c

    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0 63 7c 77 7b f2 6b 6f c5 30  1 67 2b fe d7 ab 76
 1 ca 82 c9 7d fa 59 47 f0 ad d4 a2 af 9c a4 72 c0
 2 b7 fd 93 26 36 3f f7 cc 34 a5 e5 f1 71 d8 31 15
 3  4 c7 23 c3 18 96  5 9a  7 12 80 e2 eb 27 b2 75
 4  9 83 2c 1a 1b 6e 5a a0 52 3b d6 b3 29 e3 2f 84
 5 53 d1  0 ed 20 fc b1 5b 6a cb be 39 4a 4c 58 cf
 6 d0 ef aa fb 43 4d 33 85 45 f9  2 7f 50 3c 9f a8
 7 51 a3 40 8f 92 9d 38 f5 bc b6 da 21 10 ff f3 d2
 8 cd  c 13 ec 5f 97 44 17 c4 a7 7e 3d 64 5d 19 73
 9 60 81 4f dc 22 2a 90 88 46 ee b8 14 de 5e  b db
 a e0 32 3a  a 49  6 24 5c c2 d3 ac 62 91 95 e4 79
 b e7 c8 37 6d 8d d5 4e a9 6c 56 f4 ea 65 7a ae  8
 c ba 78 25 2e 1c a6 b4 c6 e8 dd 74 1f 4b bd 8b 8a
 d 70 3e b5 66 48  3 f6  e 61 35 57 b9 86 c1 1d 9e
 e e1 f8 98 11 69 d9 8e 94 9b 1e 87 e9 ce 55 28 df
 f 8c a1 89  d bf e6 42 68 41 99 2d  f b0 54 bb 16

 

 

逆S盒變換代碼:

//逆S盒產生
void inv_s_box_gen(void)
{
    uint8_t i,j;
    uint8_t s_box_ary[16][16] = {0};
    uint8_t b=0, bb=0;

//初始化S盒
    for(i=0;i<0x10;i++)
    {
        for(j=0;j<0x10;j++)
        {
            s_box_ary[i][j] = ((i<<4)&0xF0) + (j&(0xF));
        }
    }

    printf("    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
    for(i=0;i<0x10;i++)
    {
        printf("\r\n%2x",i);
        for(j=0;j<0x10;j++)
        {
            printf(" %2x",s_box_ary[i][j]);
        }
    }
//對每個字節做變換
    for(i=0;i<0x10;i++)
    {
        for(j=0;j<0x10;j++)
        {
            s_box_ary[i][j]=invByteTransformation(s_box_ary[i][j], 0x05);
        }
    }

    printf("\r\n\r\n    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
    for(i=0;i<0x10;i++)
    {
        printf("\r\n%2x",i);
        for(j=0;j<0x10;j++)
        {
            printf(" %2x",s_box_ary[i][j]);
        }
    }

//求在GF(2^8)域上的逆,0映射到自身
    printf("\r\n");
    for(i=0;i<0x10;i++)
    {
        for(j=0;j<0x10;j++)
        {
            if(s_box_ary[i][j] != 0)
            {
                s_box_ary[i][j] = extEuclidPolynomial(s_box_ary[i][j],0x11B);
            }
        }
    }

    printf("\r\n\r\n    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F");
    for(i=0;i<0x10;i++)
    {
        printf("\r\n%2x",i);
        for(j=0;j<0x10;j++)
        {
            printf(" %2x",s_box_ary[i][j]);
        }
    }
}

 輸出如下:

    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 1 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
 2 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
 3 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
 4 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
 5 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
 6 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
 7 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
 8 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
 9 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f
 a a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af
 b b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf
 c c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf
 d d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df
 e e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef
 f f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff

    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0  5 4f 91 db 2c 66 b8 f2 57 1d c3 89 7e 34 ea a0
 1 a1 eb 35 7f 88 c2 1c 56 f3 b9 67 2d da 90 4e  4
 2 4c  6 d8 92 65 2f f1 bb 1e 54 8a c0 37 7d a3 e9
 3 e8 a2 7c 36 c1 8b 55 1f ba f0 2e 64 93 d9  7 4d
 4 97 dd  3 49 be f4 2a 60 c5 8f 51 1b ec a6 78 32
 5 33 79 a7 ed 1a 50 8e c4 61 2b f5 bf 48  2 dc 96
 6 de 94 4a  0 f7 bd 63 29 8c c6 18 52 a5 ef 31 7b
 7 7a 30 ee a4 53 19 c7 8d 28 62 bc f6  1 4b 95 df
 8 20 6a b4 fe  9 43 9d d7 72 38 e6 ac 5b 11 cf 85
 9 84 ce 10 5a ad e7 39 73 d6 9c 42  8 ff b5 6b 21
 a 69 23 fd b7 40  a d4 9e 3b 71 af e5 12 58 86 cc
 b cd 87 59 13 e4 ae 70 3a 9f d5  b 41 b6 fc 22 68
 c b2 f8 26 6c 9b d1  f 45 e0 aa 74 3e c9 83 5d 17
 d 16 5c 82 c8 3f 75 ab e1 44  e d0 9a 6d 27 f9 b3
 e fb b1 6f 25 d2 98 46  c a9 e3 3d 77 80 ca 14 5e
 f 5f 15 cb 81 76 3c e2 a8  d 47 99 d3 24 6e b0 fa


    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
 0 52  9 6a d5 30 36 a5 38 bf 40 a3 9e 81 f3 d7 fb
 1 7c e3 39 82 9b 2f ff 87 34 8e 43 44 c4 de e9 cb
 2 54 7b 94 32 a6 c2 23 3d ee 4c 95  b 42 fa c3 4e
 3  8 2e a1 66 28 d9 24 b2 76 5b a2 49 6d 8b d1 25
 4 72 f8 f6 64 86 68 98 16 d4 a4 5c cc 5d 65 b6 92
 5 6c 70 48 50 fd ed b9 da 5e 15 46 57 a7 8d 9d 84
 6 90 d8 ab  0 8c bc d3  a f7 e4 58  5 b8 b3 45  6
 7 d0 2c 1e 8f ca 3f  f  2 c1 af bd  3  1 13 8a 6b
 8 3a 91 11 41 4f 67 dc ea 97 f2 cf ce f0 b4 e6 73
 9 96 ac 74 22 e7 ad 35 85 e2 f9 37 e8 1c 75 df 6e
 a 47 f1 1a 71 1d 29 c5 89 6f b7 62  e aa 18 be 1b
 b fc 56 3e 4b c6 d2 79 20 9a db c0 fe 78 cd 5a f4
 c 1f dd a8 33 88  7 c7 31 b1 12 10 59 27 80 ec 5f
 d 60 51 7f a9 19 b5 4a  d 2d e5 7a 9f 93 c9 9c ef
 e a0 e0 3b 4d ae 2a f5 b0 c8 eb bb 3c 83 53 99 61
 f 17 2b  4 7e ba 77 d6 26 e1 69 14 63 55 21  c 7d

 

 

以上代碼肯定不是最優代碼,歡迎拍磚,並在留言區留下您寶貴意見,謝謝!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM