Groepen, ringen en velden Groep Een groep G is een verzameling van elementen en een binaire operator ° met volgende eigenschappen: 1. closure (gesloten): als a en b tot G behoren, doet a°b dat ook. 2. associativiteit: voor alle a, b en c in G geldt: a°(b°c)=(a°b)°c 3. neutraal element: voor elke a van G bestaat er een e in G zodat a°e=e°a=a 4. invers element: voor elke a van G bestaat er een a' zodat a°a'=a'°a=e De groep is abelian (commutatief) als ook geldt: 5. commutativiteit: voor elke a en b van G geldt: a°b=b°a Een voorbeeld van een groep is de verzameling van de gehele getallen met als operator de optelling.
Ring Een (commutatieve) ring R is een commutatieve groep met twee operatoren: optelling + en vermenigvuldiging * met volgende eigenschappen: 1.-5. R moet een commutatieve groep zijn met de optelling als operator. Het neutrale element is 0 en het inverse element van a is -a. 6. closure (gesloten): voor elke a en b van R geldt dat a*b ook een element van R is. 7. associativiteit: voor elke a, b en c van R geldt: a*(b*c)=(a*b)*c 8. distributiviteit: voor elke a, b en c van R geldt: a*(b+c)=a*b+a*c en (a+b)*c=a*c+a*b De ring is commutatief als bovendien voldaan is aan: 9. commutativiteit: voor elke a en b van R geldt: a*b=b*a
Integraal domein Een integraal domein is een commutatieve ring met volgende extra eigenschappen: 10. neutraal element voor de *: er bestaat een element 1 in R zodat a*1=1*a=a 11. geen delers van 0: voor alle a en b in R geldt er: als a*b=0 dan is a=0 of b=0
Velden Een veld F is een integraal domein met volgende extra eigenschap: 12. invers element: voor elke a in F (behalve 0) bestaat er een a-1 zodat a * a-1 = a-1 *a=1
Anders gesommeerd: een veld F is een verzameling met twee operatoren + en * die aan volgende eisen voldoen: 1. closure (gesloten): als a en b tot F behoren, doet a+b dat ook. 2. associativiteit: voor alle a, b en c in F geldt: a+(b+c)=(a+b)+c 3. neutraal element: voor elke a van F bestaat er een 0 in F zodat a+0=0+a=a 4. invers element: voor elke a van F bestaat er een -a zodat a+(-a)=(-a)+a=0 5. commutativiteit: voor elke a en b van F geldt: a+b=b+a 6. closure (gesloten): voor elke a en b van F geldt dat a*b ook een element van F is. 7. associativiteit: voor elke a, b en c van F geldt: a*(b*c)=(a*b)*c 10. neutraal element voor de *: er bestaat een element 1 in F zodat a*1=1*a=a 12. invers element: voor elke a in F (behalve 0) bestaat er een a-1 zodat a * a-1 = a-1 *a=1 9. commutativiteit: voor elke a en b van F geldt: a*b=b*a 8. distributiviteit: voor elke a, b en c van F geldt: a*(b+c)=a*b+a*c en (a+b)*c=a*c+a*b 11. geen delers van 0: voor alle a en b in F geldt er: als a*b=0 dan is a=0 of b=0
Men kan stellen dat een veld F een verzameling elementen is waarin men kan optellen, aftrekken, vermenigvuldigen en delen zonder de verzameling te verlaten.
Voorbeelden van velden F kunnen zijn: de verzameling van breuken reële getallen complexe getallen telkens met de operatoren + en *.
Modulair rekenen Wanneer we een getal a delen door n, krijgt men een quotiënt q en een rest r, zodat: a = q*n + r waarbij de rest r steeds positief is. Een voorbeeld: -11 = -2*7 + 3 dus (-11) mod 7 = 3 11 = 1*7 + 4 dus (11) mod 7 = 4
Eigenschappen van de modulo operator: 1. ((a mod n) + (b mod n)) mod n = (a + b) mod n 2. ((a mod n) - (b mod n)) mod n = (a - b) mod n 3. ((a mod n) * (b mod n)) mod n = (a * b) mod n Men kan dus besluiten dat de rekenkundige regels ook gelden voor modulair rekenen. Men kan dan een verzameling Zn gaan definiëren als alle gehele getallen tussen 0 en n-1. Men kan een mapping gaan doen van alle gehele getallen op deze verzameling Z n door de modulo operator. Voor Z8 zou bijvoorbeeld het getal 11 'geprojecteerd worden' op 3, zijnde de rest van de deling van 11 door 8 Soms moet men op zoek gaan naar de grootste gemene deler c van a en b. Hiervoor moet c voldoen aan: 1. c moet een deler zijn van a en b 2. elke deler van a en b moet ook een deler zijn van c. Een handig computeralgoritme is: ggd(a,b)=ggd(b, a mod b) en ggd(c,0)=c
Men zou dus in C kunnen schrijven: int ggd (int a, int b) { if (b = = 0) return a; else return (ggd(b, a%b)); /* in C is % de mod operator */ } /* Hierbij veronderstellen we dat: - a groter is dan b - a en b positieve getallen zijn - Dit laatste is geen beperking, want voor de ggd is het teken van de getallen a en b irrelevant. */
Galois velden GF(pn) Deze velden zijn belangrijk in cryptografiesystemen. Meer specifiek wanneer men gaat rekenen modulo pn, waarbij p een priemgetal is en n om het even welk positief geheel getal. Deze eindige velden (modulo pn) noemt men Galois velden. Men noteert ze als GP(pn) Hiervan zijn er twee speciale soorten: - p1, of p: GF(p) - 2n of GF(2n)
GF(p) Nemen we als voorbeeld p gelijk aan 7. Men kan de verzameling van alle natuurlijke getallen projecteren op de verzameling {0, 1, 2, 3, 4, 5, 6} door de rest van de deling door 7 te gebruiken. Men heeft dan minstens een commutatieve ring. Maar wanneer men modulo een priemgetal gaat rekenen bestaat er ook een invers element voor elk element voor de vermenigvuldiging. Men heeft dan een veld. Een voorbeeld:
GF(2n) Wanneer men modulo pn gaat rekenen, heeft men geen veld. Voor p=8 en n = 1 heeft men namelijk:
De inverse elementen bestaan dus niet altijd! Stel dat we encryptie willen doen op bytes, dit zijn 8 bits. Men heeft dan alle combinaties van 0 tot 255. 255 is echter geen priemgetal, 251 is het wel. Men zou dan modulo 251 kunnen rekenen en alle goede eigenschappen kunnen gebruiken van velden. Het nadeel is dan echter dat we enkele combinaties (251 .. 255) niet gebruiken. Er bestaan echter wel velden van de vorm: GF(2p).
Nemen we als voorbeeld 23. Men gebruikt dan volgende rekenregels:
De aandachtige lezer zal opmerken dat de sommatie eigenlijk op een EXOR functie van de verschillende bits neerkomt. Voor de vermenigvuldiging zijn de rekenregels op het eerste zicht niet zo duidelijk. We komen er iets verder op terug...
Rekenen met veeltermen Men kan gaan rekenen met veeltermen (optellen en vermenigvuldigen) waarvan de coëfficienten 0 of 1 zijn. (0 en 1 zijn de elementen modulo 2). AES gebruikt rekenkunde in GF(28) met als veelterm: m(x) = x8 + x4 + x3 + x + 1 Een voorbeeld: f(x) = x6 + x4 + x2 + x + 1 g(x) = x7 + x + 1 dan is: f(x) + g(x) = x7 + x6 + x4 + x2 want 1 + 1 = 0 en dan is: f(x) * g(x) = x13 + x11 + x9 + x8 + x6 + x5 + x4 + x3 + 1 en : f(x) * g(x) mod m(x) = x7 + x6 + 1 door te delen door m(x). Om het veld GF(23) op te stellen moeten we een analoge berekening doen, maar dan met een veelterm van macht 3. Er zijn 2 goede kandidaten: x3 + x2 + 1 x3 + x + 1. Met deze laatste krijgen we:
Vergelijk de coëfficiënten van de veeltermen met de tabel voor rekenen in GF(2 3). Dit is de verklaring voor de ‘eigenaardige’ rekenregels voor het vermenigvuldigen.
Praktisch in AES
Zoals volgende figuur laat zien moet men kunnen vermenigvuldigen met 1, 2 en 3.
Men kan opmerken dat een matrixvermenigvuldiging neerkomt op een reeks producten die gesommeerd worden. De optelling is een eenvoudige EXOR functie. Maar we moeten ook met 2 en 3 kunnen vermenigvuldigen. Met 3 vermenigvuldigen komt neer op vermenigvuldigen met 2 en dan nog eens het origineel sommeren. (3=2+1). We moeten dus met 2 kunnen vermenigvuldigen! Hiervoor kan men bewijzen dat : 2 * (b7 b6 b5 b4 b3 b2 b1 b0) = (b6 b5 b4 b3 b2 b1 b0 0) als b7 = 0 en dat: 2 * (b7 b6 b5 b4 b3 b2 b1 b0) = (b6 b5 b4 b3 b2 b1 b0 0) EXOR (00011011) als b7 = 1
AES sleutelexpansie
Deze functie g doet in hoofdzaak 3 bewerkingen: een 'shift left' van 1 volledige byte. Dit wil zeggen dat 4 bytes: [b0 b1 b2 b3] worden vertaald in: [b1 b2 b3 b0] een bytesubstitutie op dezelfde manier en dezelfde matrix als het AES algoritme zelf. EXOR met een constante, die functie is van het rondenummer. De drie meest rechtse bytes zijn steeds 00. De andere, meest beduidende, byte is: ronde constante
1
2
3
4
5
6
7
8
9
10
01
02
04
08
10
20
40
80
1B
36