Advanced Encryption Standard (AES) Source [unvollständig]

Für allgemeine Fragen zur Programmierung mit PureBasic.
dussel
Beiträge: 49
Registriert: 15.09.2004 12:52
Wohnort: Bei Frankfurt/Main

Advanced Encryption Standard (AES) Source [unvollständig]

Beitrag von dussel »

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

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
  

Zuletzt geändert von dussel am 02.08.2006 12:13, insgesamt 3-mal geändert.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

was ist AES?
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
dussel
Beiträge: 49
Registriert: 15.09.2004 12:52
Wohnort: Bei Frankfurt/Main

Beitrag von dussel »

Der Advanced Encryption Standard (AES) ist ein symmetrisches Verschlüsselungsverfahren, das als Nachfolger für DES bzw. 3DES im Oktober 2000 nach einem Wettbewerb vom National Institute of Standards and Technology (NIST) als Standard bekannt gegeben wurde.
Benutzeravatar
Andre
PureBasic Team
Beiträge: 1765
Registriert: 11.09.2004 16:35
Computerausstattung: MacBook Core2Duo mit MacOS 10.6.8
Lenovo Y50 i7 mit Windows 10
Wohnort: Saxony / Deutscheinsiedel
Kontaktdaten:

Beitrag von Andre »

Kaeru Gaman hat geschrieben:was ist AES?
Verschlüsselungssystem: http://de.wikipedia.org/wiki/Advanced_E ... n_Standard


[Mist! 15 sek zu spät ;-)]
Bye,
...André
(PureBasicTeam::Docs - PureArea.net | Bestellen:: PureBasic | PureVisionXP)
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

@dussel: cool, sowas hab ich in PB (auch im engl. Forum) schon gesucht. Leider war ich bisher zu träge, das von C zu übersetzen. Vielleicht kann ich Dich aber dabei irgendwie unterstützen? Worauf Du aufpassen musst: im C Quellcode ist WORD als "unsigned long" definiert. In PB kannst Du das nicht einfach als .l übersetzen, denn Longs in PB sind zwar 32 Bit, aber signed!

Interessant ist AES insb. in Zusammenhang mit Diffie-Hellman zum sicheren Schlüsselaustausch (siehe http://en.wikipedia.org/wiki/Diffie-Hellman). AES und Diffe-Hellman als Userlib für PB 4 wär genial!!! Dazu bräuchte man nichtmal den Code in PB übersetzen, sondern könnte ihn direkt mit LCCwin32 zur Userlib kompilieren. :D
Benutzeravatar
Karl
Beiträge: 520
Registriert: 21.07.2005 13:57
Wohnort: zu Hause

Beitrag von Karl »

Wie compiliert man mit LCCWin eine Userlibrary?

Das würde mich auch sehr interessieren.

Gruß Karl
The Kopyright Liberation Front also known as the justified ancients of Mumu!
PB 5.X
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

@Karl: Schau Dir mal den LibraryDesigner an. Mehr kann ich dazu auch nicht sagen, hab ihn erst für eine Userlib genutzt.
dussel
Beiträge: 49
Registriert: 15.09.2004 12:52
Wohnort: Bei Frankfurt/Main

Beitrag von dussel »

@real:
Vielleicht kann ich Dich aber dabei irgendwie unterstützen?
Gerne. Ich würde gerne im ersten Schritt eine Portierung erreichen und erst im zweiten Schritt eine Optimierung auf PB durchführen. Anhand meiner Kommentare kannst Du hoffenlich erkennen welche Teile übersetzt wurden; ein intensiver Code-Audit wird ebenfalls erforderlich sein da einige Funktionen noch nicht das erwünschte Ergebnis liefern.

Achja, Diffe-Hellman steht als nächstes an :)
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Ich kann zwar den C-Code nicht aber:

Code: Alles auswählen

691->Dim a.s(8)
zu

Code: Alles auswählen

691->Dim a.l(8)
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

:allright:
dussel hat geschrieben:Ich würde gerne im ersten Schritt eine Portierung erreichen und erst im zweiten Schritt eine Optimierung auf PB durchführen. Anhand meiner Kommentare kannst Du hoffenlich erkennen welche Teile übersetzt wurden; ein intensiver Code-Audit wird ebenfalls erforderlich sein da einige Funktionen noch nicht das erwünschte Ergebnis liefern.
Okay... Ich werd parallel dazu mal eine kleine Userlib draus machen, um erstmal die Funktionsweise (auch zum Vergleich mit dem PB-Code) zu testen. Das ist meiner Meinung nach sinnvoll, um einen direkten Vergleich zum Original zu haben.

Deine Kommentarge sind nicht schlecht, könnten aber in den unvollständigen bzw. noch nicht komplett getesteten Funktionen umfangreicher sein. :wink:
Antworten