Systemprogrammierung (37-023) Arithmetik Modulo p Verschiedene Zahlenmengen (M) Assemblerprogrammierung Betriebssystemgrundlagen Maschinenmodelle N = Natürliche Zahlen (1..n) N0= Natürliche Zahlen mit 0 Z = Ganze Zahlen Dozenten: Zn = Ganze Zahlen mod n Prof. Thomas Stricker Unterrichtssprache: Q / R = rationale / reelle Zahlen Deutsch (gespickt mit Englisch) C = komplexe Zahlen Begleit-/Textbuch: R. P. Paul: SPARC Architecture, Assembly Language Programming and C, Prentice Hall, 1994 GFp = Ganze Zahlen mod p (prime) (Z, +, *) kommutativer Ring Heute: • 32bit Arithmetik modulo p (Zn, +, *) kommutativer Ring mod n • Optimierung eines Codes (Q, + , *), (R, + , *) Körper • WLAN Beteiligung von Studenten 5.2.01 - 1 37-023 Systemprogrammierung (C, +, * ), (GFp, +, *) Körper © Stricker Eigenschaften einer Gruppe 5.2.01 - 2 37-023 Systemprogrammierung © Stricker Eigenschaften eines Körpers Algebraische Struktur (M, + , * ) Abgeschlossenheit (M, *) • a,b ∈ M ⇒ a * b ∈ M Addition Assoziativität (M, *) • (a*b)*c = a*(b*c) ∀a,b,c ∈ M • (M, +) ist kommutative Gruppe mit neutralem Element 0. Neutrales Element Multiplikation • n*a = a*n = a ∃n ∀ a ∈ M • (M / {0}, *) ist kommutative Gruppe mit neutralem Element 1 Inverses Element • a‘ * a = a * a‘ = n ∃n ∀ a ∈ M Distributivität kommutative Gruppe • a * (b + c) = a*b + a*c ∀a,b,c ∈ M • a*b= b*a ∀a,b ∈ M Integritätsbereich zyklische Gruppe • jedes von 0 verschiedene Element hat ein inverses Element bzl. Multiplikation • a = a‘ k ∃k,a‘∀a ∈ M endliche Gruppe • M ist endliche Menge 5.2.01 - 3 37-023 Systemprogrammierung © Stricker 5.2.01 - 4 37-023 Systemprogrammierung © Stricker Endlicher Körper GF(p) Spezielles Thema Heute Körper Modulo p = 231-1 • Der kommutative Ring (Zp, +, *) ist genau dann ein Körper wenn p eine Primzahl ist. • p ist eine Mersennsche Primzahl d.h. 2k-1 mit k=31 • Beweist man u.a. mit dem kleinen Fermatschen Satz, siehe Buch. • Bildet einen Körper mit ähnlichen Eigenschaften wie C (komplexe Zahlen) • Haben einige besondere Eigenschaften. Z.B. zyklotomische Generatoren • Braucht nur Arithmetische Operationen Integer Rechenwerk. zn != 1 mod p zn = 1 mod p 0<n<p-1 n=p-1 • Kein Fliesspunkt nötig. • In der Analysis wurden dazu immer die komplexen Zahlen herangezogen, doch auch endliche Körper modulo p haben alle benötigten Eigenschaften. • Viele Anwendungen in der Codierung, Kryptographie und u.a. auch die Basis der schnellen Fourier Transformation FFT. • Passt gut in die 32bit Arithmetik der SPARC bzw. MIPS. Buchtip: Endliche Körper heissen Galois Fields. M.R. Schroeder: Number Theory in Science and Communication, Springer, ISBN 0-387-15800-6 5.2.01 - 5 5.2.01 - 6 37-023 Systemprogrammierung © Stricker Addition 37-023 Systemprogrammierung © Stricker Multiplikation Addition mod p=231-1 ist einfach Multiplikation mod p=231-1 ist c = a + b mod p c = a * b mod p a, b,c < p a, b,c < p • Summe 0 < c < 2*p <= 232-4 • Produkt 0<a*b<=(p-1)2 <= 262- 2*231+1 • Modulus Bildung durch Test und eventueller Subtraktion von p. • Modulus Bildung schwieriger. • Passt nicht mehr ohne weiteres in 32 bit Arithmetik. Subtraktion Bildung der negativen Zahl als inversen Elementes bzl. 0: i=p-a=0-a da p mod p = 0 • Subtraktion durch Addition des inversen Elementes • Wichtige Identitäten: • 2^31 mod p = 1 • 2^32 mod p = 2 • a * b mod p = (a mod p * b mod p) mod p Division Bildung der reziproken Zahl als inverses Elementes bzl. 1: alles in 32bit Arithmetik! i = 1/a 5.2.01 - 7 37-023 Systemprogrammierung © Stricker 5.2.01 - 8 mittels Euklid GCD Algorith. 37-023 Systemprogrammierung © Stricker Basis Algorithmus / 32bit Ops 32x32 bit Multiplikation in vier 16x16bit Multiplikationen zerlegen: c = (u1*216+ u0) * (v1*216+ v0) c = u1*v1*232+(u1*v0+v1*u0)*216+u0*v0 c = c2 * 232+ c0 c2 = u1*v1 + (u1*v0+v1*u0) / 216 c0 = u0*v0 + (u1*v0+v1*u0) * 216 Modulo in die Produkte reinnehmen c%p = ((c2%p) * (232%p) Basis Algorithmus / 32bit Ops 1 unsigned int pmult(u,v,p) 2 unsigned int u,v,p; 3 { 4 unsigned int u0,u1,v0,v1; 5 unsigned int w0,w1,wi,wi0,wi1,x0,x1; 6 7 u1=u / 65536; u0=u % 65536; 8 v1=v / 65536; v0=v % 65536; 9 10 w0= u0*v0; 11 wi= u0*v1+u1*v0; 12 wi1= wi / 65536; wi0= wi % 65536; 13 w1= u1*v1; 14 15 x0=(w0 % p + (wi0 * 65536) % p) % p; 16 x1=(w1 % p + wi1 % p) % p; 17 18 return (x0 + x1 * 2) % p; 19 } Assembler: 75 inst. mit vielen mult-div + (c0%p)) %p Daraus ergibt sich eine pure 32bit Basis Lösung... 1 2 3 4 5 6 7 8 5.2.01 - 9 5.2.01 - 10 232 mod p = 232 mod (231-1) = 2 37-023 Systemprogrammierung © Stricker ... Basis Algorithmus / 64bit Ops SPARC auf dem Weg zur 64bit CPU, daher ab V8einige 64bit Op vorhanden... Mit Datentyp: unsigned long long; 1 2 3 4 5 6 7 8 unsigned pmult(u,v,p) unsigned u,v,p; { unsigned long long x; %o3, %o2, %g2 %g2, %o2, %g2 %o3, %g2, %o3 ... 37-023 Systemprogrammierung © Stricker Optimierungselemente Additionen kein Problem: zweimal Range von 0..(231-2) reicht fuer eine Addition im 32bit Range 0..(232-1) Ersatz durch 64 bit Operation Distribution von “mod p” beim MSW (w*232) und MSB (v*231): } 232 mod (231-1) = 2 231 mod (231-1) = 1 Assembler: save smul mov mov mov call mov ret restore %g3, %o4, %g3 %g0, %g0, %y Multiplikation ein Problem: x= u * v; return x % p; 1 pmult: 2 3 4 5 6 7 8 9 10 smul wr nop nop nop udiv smul sub %sp, -112, %sp %i0, %i1, %o0 %o0, %o1 0, %o0 0, %o2 __urem64, 0 %i2, %o3 Wertebereichstransformation: a mod (231-1) = ((a+1) mod 231) -1 %g0, %o1, %o0 aber Vorsicht der Compiler! 5.2.01 - 11 37-023 Systemprogrammierung © Stricker 5.2.01 - 12 37-023 Systemprogrammierung © Stricker Wertebereichsbetrachtungen: mod 231-1 Operation ziemlich komplex für vollen 32bit Bereich [0..231-1]. 1 2 3 4 5 6 7 8 static inline unsigned mod_p(u) register unsigned u; { return(((u+1) & p) - (((u+1)>>31)^1)); } bzw. als Macro 6 Extended Euclid GCD Algorithm d=gcd(a,b)=ax + by finds d,x,y For a mult. inverse mod p just compute d=gcd(a,p)=1=ax + 0 finds x=a-1 static inline unsigned mod_p(u) register unsigned u; { register unsigned x; x=(u & p) + (u>>31) + 1; return((x & p) - ((x>>31)^1)); } Einfacher für reduzierten Bereich [0..231-2] 1 2 3 4 5 Reziproker Wert / Division 1 unsigned reciprocal(unsigned x) 2 { 1 unsigned q, r, y; 2 signed t_1, t_2, tmp; 3 4 y = p; 5 t_2 = 0; t_1 = 1; 6 while ( x != 1 ) { 7 q = y / x; 8 r = y % x; 9 tmp = t_2; 10 t_2 = t_1; 11 y = x; 12 x = r; 13 t_1 = tmp - t_1 * q; 14 } 15 if ( t_1 > 0 ) return t_1; 16 else return t_1 + p; 17 } #define modp(u,p) ((((u)+1) & p) ((((u)+1)>>31)^1)) 5.2.01 - 13 37-023 Systemprogrammierung © Stricker 5.2.01 - 14 37-023 Systemprogrammierung © Stricker