Advanced Encryption Standard (AES) Source [unvollständig]
Verfasst: 08.06.2006 13:57
Hallo @all,
inspiriert von einem Thread im englischen PB-Forum habe ich mich an die Portierung von Mike Scott's AES | Rijndal C-Code zu PB gemacht. Auch nach intensiver Studie der FIPS 197 ist mir noch einiges in AES verschlossen.
Bevor ich mich nun weiter alleine durchquäle dachte ich daran mein Zwischenergebnis hier zu veröffentlichen und hoffe auf mithilfe bei der Portierung im ersten Schritt und im zweiten Schritt auf eine Optimierung für PB.
WARNUNG: Dieser Code ist sowohl unvollständig, als auch noch fehlerhaft!
Aktalisierte Version vom 02.08.2006
inspiriert von einem Thread im englischen PB-Forum habe ich mich an die Portierung von Mike Scott's AES | Rijndal C-Code zu PB gemacht. Auch nach intensiver Studie der FIPS 197 ist mir noch einiges in AES verschlossen.
Bevor ich mich nun weiter alleine durchquäle dachte ich daran mein Zwischenergebnis hier zu veröffentlichen und hoffe auf mithilfe bei der Portierung im ersten Schritt und im zweiten Schritt auf eine Optimierung für PB.
WARNUNG: Dieser Code ist sowohl unvollständig, als auch noch fehlerhaft!
Aktalisierte Version vom 02.08.2006
Code: Alles auswählen
;
; AES
;
; Written by Mike Scott in C
; Portiert 2006 by Marc Kraemer to PB
; marc.kraemer[attttt]web.de
; Allgemeines zur Portierung:
;
; Die Portierung des AES Algorithmus aus Mike Scott's C Code wurde unter
; Berücksichtigung des fips 197 (Federal Information Processing Standards Publication 197)
; vorgenommen.
;
; Anmerkung zur Datentypen:
;
; Datentypen aus C lassen sich nicht 1:1 nach PB übertragen, da einige Datentypen
; in C vorzeichenlos (unsigned) und in PB hingegen mit einem vorzeichen (signed)
; definiert sind. Daher mussten bei der Portierung auf andere Datentypen ausgewichen
; und in einigen wenigen Fällen eine Änderung der Bit-Arithemtik vorgenommen werden.
;
;
; Datentyp im Orginal | Datentyp in PB
; ------------------------+---------------------------
; WORD (4 Byte unsigned) | QUAD (8 Byte signed) - nicht LONG
; BYTE (8 Bit unsigned) | CHAR (8 Bit unsigned)
; Schleifen in PB sind nicht mit Byte zu realisieren
Procedure.c ROTL(x.c)
; Übersetzt: Vollständig
; Geprüft : Ja, noch nicht gegenüber C-Code
; Getestet : Ja, noch nicht gegenüber C-Code
; CHAR (8 Bit) um jeweils ein Bit nach links rotieren
; function
; #define ROTL(x) (((x)>>7)|((x)<<1))
x.c>>7|x.c<<1
ProcedureReturn x.c
; rotates x one bit to the left
EndProcedure
Procedure.q ROTL8(x.q)
; Übersetzt: Vollständig
; Geprüft : Ja, noch nicht gegenüber C-Code
; Getestet : Ja, noch nicht gegenüber C-Code
; 32 Bit um jeweils 8 Bit nach links rotieren
; Im Original C-Code wird hier ein Datentyp (32 Bit) verarbeitet in dieser
; PB Portierung wird stattdessen ein QUAD verarbeitet (64 Bit) verarbeitet
; function
; #define ROTL8(x) (((x)<<8)|((x)>>24))
Debug "Function ROTL8 (Input : "+RSet(BinQ(x.q),64,"0")+")"
x.q << 8 | x.q >> 24 & $FFFFFFFF
Debug "Function ROTL8 (Return: "+RSet(BinQ(x.q),64,"0")
ProcedureReturn x.q
EndProcedure
Procedure.q ROTL16(x.q)
; Übersetzt: Vollständig
; Geprüft : Ja, noch nicht gegenüber C-Code
; Getestet : Ja, noch nicht gegenüber C-Code
; 32 Bit um jeweils 16 Bit nach links rotieren
; Im Original C-Code wird hier ein Datentyp (32 Bit) verarbeitet in dieser
; PB Portierung wird stattdessen ein QUAD verarbeitet (64 Bit) verarbeitet
; function
; #define ROTL16(x) (((x)<<16)|((x)>>16))
Debug "Function ROTL16 (Input : "+RSet(BinQ(x.q),64,"0")+")"
x.q<<16 | x.q>>16 & $FFFFFFFF
Debug "Function ROTL16 (Return: "+RSet(BinQ(x.q),64,"0")
ProcedureReturn x
EndProcedure
Procedure.q ROTL24(x.q)
; Übersetzt: Vollständig
; Geprüft : Ja, noch nicht gegenüber C-Code
; Getestet : Ja, noch nicht gegenüber C-Code
; 32 Bit um jeweils 24 Bit nach links rotieren
; Im Original C-Code wird hier ein Datentyp (32 Bit) verarbeitet in dieser
; PB Portierung wird stattdessen ein QUAD verarbeitet (64 Bit) verarbeitet
; function
; #define ROTL24(x) (((x)<<24)|((x)>>8))
Debug "Function ROTL24 (Input : "+RSet(BinQ(x.q),64,"0")+")"
x.q <<24 | x.q >> 8 & $FFFFFFFF
Debug "Function ROTL24 (Return: "+RSet(BinQ(x.q),64,"0")
ProcedureReturn x
EndProcedure
Global Dim InCo.c(4)
InCo.c(0) = $B
InCo.c(1) = $D
InCo.c(2) = $9
InCo.c(3) = $E
;Static BYTE InCo[4]={0xB,0xD,0x9,0xE}; /* Inverse Coefficients */
Global Dim fbsub.c(256) ; S-Box laut fips
Global Dim rbsub.c(256) ; Inverse S-box laut fips
Global Dim ptab.c(256)
Global Dim ltab.c(256)
Global Dim ftable.q(256)
Global Dim rtable.q(256)
Global Dim rco.q(30)
; Static BYTE fbsub[256];
; Static BYTE rbsub[256];
; Static BYTE ptab[256],ltab[256];
; Static WORD ftable[256];
; Static WORD rtable[256];
; Static WORD rco[30];
; /* Parameter-dependent data */
Global Nk.l, Nb.l, Nr.l
; int Nk,Nb,Nr;
; Anmerkung aus fips-197:
; Nk = Number of 32-bit words comprising the Cipher Key. For this standard, Nk = 4, 6, Or 8
; Nb = Number of columns (32-bit words) comprising the State. For this standard, Nb = 4
; Nr = Number of rounds, which is a function of Nk and Nb (which is fixed). For this standard, Nr = 10, 12, Or 14.
Global Dim fi.c(24)
Global Dim ri.c(24)
Global Dim fkey.q(120)
Global Dim rkey.q(120)
; BYTE fi[24],ri[24];
; WORD fkey[120];
; WORD rkey[120];
Procedure.q pack(LokalBytearray.c(1))
; Übersetzt: Ja
; Geprüft : Ja, gegenüber dem C-Code
; Getestet : Ja, gegenüber dem C-Code
; Packt ein Array von 4 Bytes in 32 Bit (in PB hier in 64Bit Quad)
Define ReturnValue.q
Define local_b3.c
local_b3.c = LokalBytearray.c(3)
local_b2.c = LokalBytearray.c(2)
local_b1.c = LokalBytearray.c(1)
local_b0.c = LokalBytearray.c(0)
ReturnValue.q = local_b3.c << 24 | local_b2.c << 16 | local_b1.c << 8 | local_b0.c
;
; Die folgende Übersetzung funktionierte leider nicht, daher bin ich
; über dem Umweg lokaler Chars gegangen.
;
;ReturnValue.q = (LokalBytearray.c(3) <<24) | (LokalBytearray.c(2) << 16) | (LokalBytearray.c(1) << 8) | (LokalBytearray.c(0))
;Static WORD pack(BYTE *b)
;{ /* pack bytes into a 32-bit Word */
;Return ((WORD)b[3]<<24)|((WORD)b[2]<<16)|((WORD)b[1]<<8)|(WORD)b[0];
;}
ProcedureReturn ReturnValue.q
EndProcedure
Procedure unpack (a.q, b.c(1)) ; Array mit einer Dimension
; Übersetzt: Vollständig
; Geprüft : Ja, noch nicht gegenüber C-Code
; Getestet : Ja, noch nicht gegenüber C-Code
; Entnimmt einem 32 Bit WORD (in PB hier 64 Bit QUAD) jeweils 4 x 8 Bit
b.c(0) = a & $00000000000000FF
b.c(1) = a>>8 & $00000000000000FF
b.c(2) = a>>16 & $00000000000000FF
b.c(3) = a>>24 & $00000000000000FF
; Static void unpack(WORD a,BYTE *b)
; { /* unpack bytes from a word */
; b[0]=(BYTE)a;
; b[1]=(BYTE)(a>>8);
; b[2]=(BYTE)(a>>16);
; b[3]=(BYTE)(a>>24);
; }
ProcedureReturn b.c
EndProcedure
Procedure.c xtime(a.c)
; Übersetzt: Vollständig
; Geprüft : Ja; gegenüber dem C-Source
; Getestet : Ja; gegenüber dem C-Source
;
;
; Anmerkung: Die Funktion findet sich auch im VB Source und
; wurde mit dieser abgeglichen.
; Static BYTE xtime(BYTE a)
; {
Define b.c
; BYTE b;
If (a.c & $80) ; Ein Bitweises AND (&) kein logisches AND (AND)
; Wenn a.c and 128 dann b.c = 27
b.c=$1b
Else
b.c=0
EndIf
; If (a&0x80) b=0x1B;
; Else b=0;
a.c<<1
; a<<=1;
a.c=a.c ! b.c ; a = a Xor b
; a^=b;
ProcedureReturn a.c
; Return a;
; }
EndProcedure
Procedure.c bmul(x.c, y.c)
; Übersetzt: Vollständig
; Geprüft : Ja, gegen den C-Code
; Getestet : Ja, gegen den C-Code
; Static BYTE bmul(BYTE x,BYTE y)
; { /* x.y= AntiLog(Log(x) + Log(y)) */
Define retval.c
If (x <> 0) And (y <> 0)
;If (x && y)
retval.c = ptab((ltab(x)+ltab(y)) % 255)
Else
retval.c = 0
EndIf
ProcedureReturn retval.c
; If (x && y) Return ptab[(ltab[x]+ltab[y])%255];
; Else Return 0;
; }
EndProcedure
Procedure.l SubByte(a.l)
; Übersetzt: Vollständig
; Geprüft : Nein
; Getestet : Nein
; Static WORD SubByte(WORD a)
; {
Dim b.c(3)
; BYTE b[4];
unpack(a.l,b.c())
; unpack(a,b);
b.c(0) = fbsub.c(b.c(0))
; b[0]=fbsub[b[0]];
b.c(1) = fbsub.c(b.c(1))
; b[1]=fbsub[b[1]];
b.c(2) = fbsub.c(b.c(2))
; b[2]=fbsub[b[2]];
b.c(3) = fbsub.c(b.c(3))
; b[3]=fbsub[b[3]];
ProcedureReturn pack(b.c())
; Return pack(b);
; }
EndProcedure
Procedure.c product(x.l,y.l)
Debug "Function product (Input : "+Str(x.l)+" & "+Str(y.l)+")"
; Übersetzt: Vollständig
; Geprüft : Nein
; Getestet : Nein
;
; Static BYTE product(WORD x,WORD y)
; { /* dot product of two 4-byte arrays */
Dim xb.c(3)
Dim yb.c(3)
; BYTE xb[4],yb[4];
unpack (x.l,xb.c())
; unpack(x,xb);
unpack (y.l,yb.c())
; unpack(y,yb);
ProcedureReturn bmul(xb.c(0),yb.c(0))!bmul(xb.c(1),yb.c(1))!bmul(xb.c(2),yb.c(2))!bmul(xb.c(3),yb.c(3))
; Return bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3]);
; }
EndProcedure
;
Procedure.l InvMixCol(x.l)
; Übersetzt: Vollständig
; Geprüft : Nein
; Getestet : Nein
; Static WORD InvMixCol(WORD x)
; { /* matrix Multiplication */
Define y.l
Define m.l
Dim b.c(3)
; WORD y,m;
; BYTE b[4];
;
m = pack(InCo())
; m=pack(InCo);
b(3)=product(m,x)
; b[3]=product(m,x);
m=rotl24(m)
; m=ROTL24(m);
b(2)=product(m,x)
; b[2]=product(m,x);
m=rotl24(m)
; m=ROTL24(m);
b(1)=product(m,x)
; b[1]=product(m,x);
m=rotl24(m)
; m=ROTL24(m);
b(0)=product(m,x)
; b[0]=product(m,x);
y=pack(b())
; y=pack(b);
ProcedureReturn y
; Return y;
; }
EndProcedure
Procedure.c Bytesub(x.c)
; Übersetzt: Vollständig
; Geprüft : Ja; gegen den C-Code
; Getestet : Ja; gegen den C-Code
; BYTE ByteSub(BYTE x)
; {
Define y.c
y.c = ptab.c(255-ltab.c(x.c))
; BYTE y=ptab[255-ltab[x]]; /* multiplicative inverse */
x.c=y.c
x.c=ROTL(x.c)
y.c=y.c ! x.c ; xor
x.c=ROTL(x.c)
; x=y; x=ROTL(x);
; y^=x; x=ROTL(x);
y.c=y.c ! x.c
x.c=ROTL(x.c)
; y^=x; x=ROTL(x);
y.c=y.c ! x.c
x.c=ROTL(x.c)
; y^=x; x=ROTL(x);
y.c=y.c ! x.c
y.c=y.c ! 99 ; xor $63
; y^=x; y^=0x63;
retval = y.c
ProcedureReturn retval
; Return y;yy
EndProcedure
Procedure gentables()
; Übersetzt: Vollständig
; Geprüft : Ja, gegenüber dem C-Code
; Getestet : Ja, gegenüber dem C-Code
;
;
; Anmerkung: Die Funktion findet sich auch im VB Source und
; wurde mit dieser abgeglichen.
; void gentables(void)
; { /* generate tables */
;Define i.c ; WICHTIG! Klappte nicht mit Datentyp long!
Define i.l
Define ii.c
Define y.c
Dim b.c(3)
; int i;
; BYTE y,b[4];
;
; /* use 3 As primitive root To generate power And log tables */
ltab.c(0)=0
ptab.c(0)=1
ltab.c(1)=0
ptab.c(1)=3
ltab.c(3)=1
; ltab[0]=0;
; ptab[0]=1; ltab[1]=0;
; ptab[1]=3; ltab[3]=1;
; ANMERKUNG: Achtung, der vorhandene PB Bug bei for-next Schleifen mit Chars (hier i.c)
; hat mich die for-next Schleife auf eine While-Wend mit i.l (long) umstellen lassen
; ptab füllen (Werte stimmen mit C-Programm überein)
; ltab füllen (Werte stimmen mit C-Programm überein)
i.l = 2
While i.l < 256
ii.c = i.l
; For (i=2;i<256;i++)
; {
ptab.c(ii.c) = ptab.c(ii.c - 1) ! xtime(ptab.c(ii.c - 1))
; ptab[i]=ptab[i-1]^xtime(ptab[i-1]);
ltab.c(ptab.c(ii.c)) = ii.c
; ltab[ptab[i]]=i;
; }
i.l+1
Wend
;
; /* affine transformation:- each bit is xored With itself shifted one bit */
;
fbsub.c(0) = $63
rbsub.c($63) = 0
; fbsub[0]=0x63;
; rbsub[0x63]=0;
; fbsub füllen (Werte stimmen mit C-Programm überein)
; rbsub füllen (Werte stimmen mit C-Programm überein)
i.l = 1
While i.l < 256
ii.c = i.l
; For (i=1;i<256;i++)
; {
y = ByteSub(ii.c)
; y=ByteSub((BYTE)i);
fbsub(ii.c) = y
rbsub(y) = ii.c
; fbsub[i]=y; rbsub[y]=i;
; }
i.l+1
Wend
y=1
i.l = 0
While i.l < 30
ii.c = i.l
; For (i=0,y=1;i<30;i++)
; {
rco.q(ii.c) = y
y = xtime(y)
; rco[i]=y;
; y=xtime(y);
; }
i.l +1
Wend
i.l = 0
While i.l < 256
ii.c = i.l
; /* calculate forward And reverse tables */
; For (i=0;i<256;i++)
; {
y=fbsub.c(ii.c)
b.c(3)=y ! xtime(y)
b.c(2)=y
b.c(1)=y
b.c(0)=xtime(y)
; y=fbsub[i];
; b[3]=y^xtime(y); b[2]=y;
; b[1]=y; b[0]=xtime(y);
ftable.q(i.l)=pack(b())
; ftable[i]=pack(b);
;
y=rbsub(ii.c)
b.c(3) = bmul(InCo.c(0),y)
b.c(2) = bmul(InCo.c(1),y)
b.c(1) = bmul(InCo.c(2),y)
b.c(0) = bmul(InCo.c(3),y)
; y=rbsub[i];
; b[3]=bmul(InCo[0],y); b[2]=bmul(InCo[1],y);
; b[1]=bmul(InCo[2],y); b[0]=bmul(InCo[3],y);
rtable.q(ii.c)=pack(b())
; rtable[i]=pack(b);
; }
i.l + 1
Wend
; }
EndProcedure
Procedure gkey(nb,nk,key.c(1))
; Übersetzt: Unvollständig
; Geprüft : Aktuell in der Prüfung
; Getestet : Aktuell in der Prüfung
; void gkey(int nb,int nk,char *key)
; { /* blocksize=32*nb bits. Key=32*nk bits */
; /* currently nb,bk = 4, 6 Or 8 */
; /* key comes As 4*Nk bytes */
; /* Key Scheduler. Create expanded encryption key */
Define i,j,k,m,N
Define C1,C2,C3
Dim Cipherkey.q(7)
Debug "START gkey";
Debug "Parameter nb = "+Str(nb)
Debug "Parameter nk = "+Str(nk)
Debug "Parameter key.c = "+StrU(key.c(1),0)
; int i,j,k,m,N;
; int C1,C2,C3;
; WORD CipherKey[8];
Nb=nb
Nk=nk
;
; Nb=nb; Nk=nk;
;
; /* Nr is number of rounds */
If (Nb>=Nk)
Nr=6+Nb
Else
Nr=6+Nk
EndIf
; If (Nb>=Nk) Nr=6+Nb;
; Else Nr=6+Nk;
;
C1 = 1
If (Nb<8)
C2=2
C3=3
Else
C2=3
C3=4
EndIf
; C1=1;
; If (Nb<8) { C2=2; C3=3; }
; Else { C2=3; C3=4; }
;
; /* pre-calculate forward And reverse increments */
m=0
j=0
While j<nk
; For (m=j=0;j<nb;j++,m+=3)
; {
fi(m)=(j+C1)%nb
; fi[m]=(j+C1)%nb;
fi(m+1)=(j+C2)%nb
; fi[m+1]=(j+C2)%nb;
fi(m+2)=(j+C3)%nb
; fi[m+2]=(j+C3)%nb;
ri(m)=(nb+j-C1)%nb
; ri[m]=(nb+j-C1)%nb;
ri(m+1)=(nb+j-C2)%nb
; ri[m+1]=(nb+j-C2)%nb;
ri(m+2)=(nb+j-C3)%nb
; ri[m+2]=(nb+j-C3)%nb;
; }
j=j+1
m=m+3
Wend
;
N = Nb*(Nr+1)
; N=Nb*(Nr+1);
i=0
j=0
While (i<Nk);
; For (i=j=0;i<Nk;i++,j+=4)
; {
CipherKey.q(i)=pack(key.c())
Debug "CipherKey("+Str(i)+")="+StrU(CipherKey.q,4)
; CipherKey[i]=pack((BYTE *)&key[j]);
; }
i+1
j=j+4
Wend
i=0
While (i<Nk)
Debug "- Schleife"
Debug "i = "+Str(i)
Debug "CipherKey(i) = "+Str(CipherKey.q(i))
fkey(i)=CipherKey.q(i)
; For (i=0;i<Nk;i++) fkey[i]=CipherKey[i];
i+1
Wend
j=Nk
k=0
While (j<N)
; For (j=Nk,k=0;j<N;j+=Nk,k++)
; {
Debug "j:" + Str(j)
Debug "rco(k)" + Str(rco(k))
Debug "fkey(j-1) = "+Str(fkey(j-1))
Debug "ROTL24 = "+Str(ROTL24(fkey(j-1)))
Debug "SubByte"
Debug SubByte(ROTL24(fkey(j-1)))
Debug "fkey"
Debug fkey(j-Nk)
fkey(j)=fkey(j-Nk)!SubByte(ROTL24(fkey(j-1)))!rco(k)
; fkey[j]=fkey[j-Nk]^SubByte(ROTL24(fkey[j-1]))^rco[k];
If(nk<=6)
; If (Nk<=6)
; {
i=1
While (i<Nk And (i+j)<N)
; For (i=1;i<Nk && (i+j)<N;i++)
fkey(i+j)=fkey(i+j-Nk)!fkey(1+j-1)
; fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
; }
i+1
Wend
Else
; Else
; {
i=1
While(i<4 And (i+j)<N)
fkey(i+j)=fkey(i+j-Nk)!fkey(i+j-1)
i+1
Wend
; For (i=1;i<4 &&(i+j)<N;i++)
; fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
If ((j+4)<N)
fkey(j+4)=fkey(j+4-Nk)!SubByte(fkey(j+3))
EndIf
; If ((j+4)<N) fkey[j+4]=fkey[j+4-Nk]^SubByte(fkey[j+3]);
i=5
While (i<Nk And (i+j)<N)
; For (i=5;i<Nk && (i+j)<N;i++)
fkey(i+j)=fkey(i+j-Nk)!fkey(i+j-1)
; fkey[i+j]=fkey[i+j-Nk]^fkey[i+j-1];
i+1
Wend
; }
EndIf
;
; }
j+Nk
k+1
Wend
;
; /* now For the expanded decrypt key in reverse order */
;
j=0
While(j<Nk)
; For (j=0;j<Nb;j++) rkey[j+N-Nb]=fkey[j];
rkey(j+N-Nb)=fkey(j)
j+1
Wend
i=Nb
While(i<N-Nb)
; For (i=Nb;i<N-Nb;i+=Nb)
; {
k=N-Nb-i
; k=N-Nb-i;
j=0
While(j<Nb)
; For (j=0;j<Nb;j++) rkey[k+j]=InvMixCol(fkey[i+j]);
rkey(k+j)=InvMixCol(fkey(i+j))
j+1
Wend
; }
i+Nb
Wend
j=N-Nb
While(j<N)
rkey(j-N+Nb)=fkey(j)
; For (j=N-Nb;j<N;j++) rkey[j-N+Nb]=fkey[j];
j+1
Wend
; }
;
;
; /* There is an obvious time/space trade-off possible here. *
; * Instead of just one ftable[], I could have 4, the other *
; * 3 pre-rotated To save the ROTL8, ROTL16 And ROTL24 overhead */
;
EndProcedure
;- AES encrypt
; void encrypt(char *buff)
Procedure encrypt(buff.c(1))
; {
Define i.l, k.l, k.l, m.l
; int i,j,k,m;
; Anmerkung: Nach ANSI-C mindestens 2 Byte
Dim a.s(8)
Dim b.s(8)
Define *x.s,*y.s,*t.s
; WORD a[8],b[8],*x,*y,*t;
i=0
j=0
; For (i=j=0;i<Nb;i++,j+=4)
; {
; a[i]=pack((BYTE *)&buff[j]);
; a[i]^=fkey[i];
; }
; k=Nb;
; x=a; y=b;
;
; /* State alternates between a And b */
; For (i=1;i<Nr;i++)
; { /* Nr is number of rounds. May be odd. */
;
; /* If Nb is fixed - unroll this Next
; loop And hard-code in the values of fi[] */
;
; For (m=j=0;j<Nb;j++,m+=3)
; { /* deal With each 32-bit element of the State */
; /* This is the time-critical bit */
; y[j]=fkey[k++]^ftable[(BYTE)x[j]]^
; ROTL8(ftable[(BYTE)(x[fi[m]]>>8)])^
; ROTL16(ftable[(BYTE)(x[fi[m+1]]>>16)])^
; ROTL24(ftable[x[fi[m+2]]>>24]);
; }
; t=x; x=y; y=t; /* swap pointers */
; }
;
; /* Last Round - unroll If possible */
; For (m=j=0;j<Nb;j++,m+=3)
; {
; y[j]=fkey[k++]^(WORD)fbsub[(BYTE)x[j]]^
; ROTL8((WORD)fbsub[(BYTE)(x[fi[m]]>>8)])^
; ROTL16((WORD)fbsub[(BYTE)(x[fi[m+1]]>>16)])^
; ROTL24((WORD)fbsub[x[fi[m+2]]>>24]);
; }
; For (i=j=0;i<Nb;i++,j+=4)
; {
; unpack(y[i],(BYTE *)&buff[j]);
; x[i]=y[i]=0; /* clean up stack */
; }
; Return;
; }
EndProcedure
;
; void decrypt(char *buff)
; {
; int i,j,k,m;
; WORD a[8],b[8],*x,*y,*t;
;
; For (i=j=0;i<Nb;i++,j+=4)
; {
; a[i]=pack((BYTE *)&buff[j]);
; a[i]^=rkey[i];
; }
; k=Nb;
; x=a; y=b;
;
; /* State alternates between a And b */
; For (i=1;i<Nr;i++)
; { /* Nr is number of rounds. May be odd. */
;
; /* If Nb is fixed - unroll this Next
; loop And hard-code in the values of ri[] */
;
; For (m=j=0;j<Nb;j++,m+=3)
; { /* This is the time-critical bit */
; y[j]=rkey[k++]^rtable[(BYTE)x[j]]^
; ROTL8(rtable[(BYTE)(x[ri[m]]>>8)])^
; ROTL16(rtable[(BYTE)(x[ri[m+1]]>>16)])^
; ROTL24(rtable[x[ri[m+2]]>>24]);
; }
; t=x; x=y; y=t; /* swap pointers */
; }
;
; /* Last Round - unroll If possible */
; For (m=j=0;j<Nb;j++,m+=3)
; {
; y[j]=rkey[k++]^(WORD)rbsub[(BYTE)x[j]]^
; ROTL8((WORD)rbsub[(BYTE)(x[ri[m]]>>8)])^
; ROTL16((WORD)rbsub[(BYTE)(x[ri[m+1]]>>16)])^
; ROTL24((WORD)rbsub[x[ri[m+2]]>>24]);
; }
; For (i=j=0;i<Nb;i++,j+=4)
; {
; unpack(y[i],(BYTE *)&buff[j]);
; x[i]=y[i]=0; /* clean up stack */
; }
; Return;
; }
;
;********************************************************************
;
;- Hauptfunktion
;
;********************************************************************
; int main()
; { /* test driver */
Global i.l, Nb.l, Nk.l
; int i,nb,nk;
Global Dim key.c(32)
; char key[32];
Global Dim block.c(32)
; char block[32];
gentables()
; gentables();
For i.l=0 To 32 Step 1
key.c(i.l)=0
Next i.l
; For (i=0;i<32;i++) key[i]=0;
key.c(0)=1
; key[0]=1;
For i.l=0 To 32 Step 1
block.c(i.l)=i
Next i.l
; For (i=0;i<32;i++) block[i]=i;
For nb=4 To 8 Step 2
; For (nb=4;nb<=8;nb+=2)
For nk=4 To 8 Step 2
; For (nk=4;nk<=8;nk+=2)
Debug "Block Size="+StrU(Nb.l*32,#Long)+" bits, Key Size="+Str(nk*32)+"bits"
; printf("\nBlock Size= %d bits, Key Size= %d bits\n",nb*32,nk*32);
gkey(Nb.l,Nk.l,key())
; gkey(nb,nk,key);
Next nk
Next nb
;
; {
;
; printf("Plain= ");
; For (i=0;i<nb*4;i++) printf("%02x",block[i]);
; printf("\n");
; encrypt(block);
; printf("Encrypt= ");
; For (i=0;i<nb*4;i++) printf("%02x",(unsigned char)block[i]);
; printf("\n");
; decrypt(block);
; printf("Decrypt= ");
; For (i=0;i<nb*4;i++) printf("%02x",block[i]);
; printf("\n");
; }
; Return 0;
; }
;
; IDE Options = PureBasic v4.00 (Windows - x86)
; CursorPosition = 604
; FirstLine = 584
; Folding = ---
; Executable = aes.exe
; Watchlist = i