{VERSION 5 0 "IBM INTEL LINUX" "5.0" } {USTYLETAB {CSTYLE "Maple Input" -1 0 "Courier" 0 1 255 0 0 1 0 1 0 0 1 0 0 0 0 1 }{PSTYLE "Normal" -1 0 1 {CSTYLE "" -1 -1 "" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }0 0 0 -1 -1 -1 0 0 0 0 0 0 -1 0 }{PSTYLE "Heading 1" 0 3 1 {CSTYLE "" -1 -1 "" 1 18 0 0 0 0 0 1 0 0 0 0 0 0 0 0 }1 0 0 0 8 4 0 0 0 0 0 0 -1 0 }{PSTYLE "Heading 2" 3 4 1 {CSTYLE "" -1 -1 "" 1 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }0 0 0 -1 8 2 0 0 0 0 0 0 -1 0 }} {SECT 0 {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 8 "restart;" }}}{SECT 1 {PARA 3 "" 0 "" {TEXT -1 45 "Some procedures for testing for good pri mes." }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 198 "In this section I will pr esent a few simple procedures. They are written for clarity, not for typing efficiency. I am sure that you could write a more compact ver sion of each of the procedures. " }}{PARA 0 "" 0 "" {TEXT -1 0 "" }} {PARA 0 "" 0 "" {TEXT -1 248 "In the RSA cryptosystem, it is useful to have a prime number p such that (p-1)/2 has large prime factors. For example if (p-1)/2 is itself prime that would be ideal. Let us write a simple test for a prime to see if it satisfies this condition. " }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 141 "goodprime := proc(p)\nlo cal pp, bool;\n\npp := (p-1)/2;\nif isprime(pp) \n then bool := true ;\n else bool := false;\nfi;\nRETURN(bool);\nend proc;" }}{PARA 0 " " 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 58 "There are \+ a few things to notice in this simple example. " }}{PARA 0 "" 0 "" {TEXT -1 87 "1) The if statement must be terminated with either \"en d if\" or its abbreviation \"fi\"." }}{PARA 0 "" 0 "" {TEXT -1 105 "2) The else statement is optional. You can also have a sequence of el se if statements, written \"elif\"." }}{PARA 0 "" 0 "" {TEXT -1 118 "3 ) If you hold down the key when typing you don't get a new cursor and the annoying warning message." }}{PARA 0 "" 0 "" {TEXT -1 89 "4) I like to explicitly say what the procedure should re turn, using RETURN() as shown. " }}{PARA 0 "" 0 "" {TEXT -1 65 "I'm n ot completely clear on the rules if RETURN is not specified." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 57 "Now let 's make a list of all good primes between m and n." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 187 "goodprimelist := proc(m,n)\nlocal i, plist ;\n\nplist := [];\nfor i from m to n do\n if (isprime(i) and goodpri me(i))\n then plist := [op(plist), i];\n fi;\nod;\nRETURN(plis t);\nend proc;\n" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 191 "Notes: 1) W e closed both the if and the do statements. 2) The indentation is \+ my choice for legibility. 3) I had to initialize plist . 4) Extendi ng a list is done via the op() command." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 24 "goodprimelist(100,1000 );" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 70 "Now let's count how many go od primes there are less than 2^(i+1) and " }}{PARA 0 "" 0 "" {TEXT -1 141 "graph the result. This indicate tell how easy it is to find such primes, and thus the feasibility of finding them for an RSA cryp tosystem." }}{PARA 0 "" 0 "" {TEXT -1 125 "For comparison, the Prine N umber Theorem says that the number of primes less than 2^i is approxim ately ((2^i / i * log(2) )." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 281 "numgoodprimes := \+ proc(pow)\nlocal i, tot_cnt, new_cnt, countlist;\n\ncountlist := [];\n tot_cnt := 0;\nfor i from 2 to pow do\n new_cnt := nops(goodprimelis t(2^i, 2^(i+1)));\n tot_cnt := tot_cnt + new_cnt;\n countlist := [ op(countlist), [i,tot_cnt]];\nod;\nRETURN(countlist);\nend proc;\n" }} }{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 30 "datalist := numgoodprimes(1 5);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 234 "Now go back to the numgoo dprimes function and change it so that it prints out the number of goo dprimes in each range 2^i .... 2^(i+1), so that we can keep track of h ow long it takes to do range (it should increase exponentially). Use " }}{PARA 0 "" 0 "" {TEXT -1 17 "print(\"i is \" i);" }}{PARA 0 "" 0 " " {TEXT -1 92 "print( \"the number of goodprimes in the range\" (2^i, 2^(i+1)) );\nprint( \"is \" (new_+cnt));" }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 12 "with(plots);" }}} {EXCHG {PARA 0 "" 0 "" {TEXT -1 290 "Now we will plot the datalist wit h the number of good primes and compare it to what we might expect acc ording to the prime number theorem. There number of primes less than \+ t is roughly t/ln(t). We might expect that t and (t-1)/2 would bo th be prime for t/ (ln(t)*ln(t/2)) values of t." }}}{EXCHG {PARA 0 "> \+ " 0 "" {MPLTEXT 1 0 37 "plot1 := plot(datalist, color = red);" }}} {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 66 "plot2 := plot(2^t/(log(2^t)* log(2^(t-1))), t=2..15, color = blue):" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 21 "display(plot1,plot2);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 0 "" }}}}{SECT 1 {PARA 3 "" 0 "" {TEXT -1 33 "Some aids for w riting procedures" }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 50 "Here are a \+ few Maple commands that may be of use." }}{PARA 0 "" 0 "" {TEXT -1 0 " " }}{PARA 0 "" 0 "" {TEXT -1 194 "Setting printlevel to 10 will force \+ Maple to print out intermediate data computed within a given procedure . Setting it to 20 will also printout data in procedures called by th e given procedure." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 16 "printlevel := 1;" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 21 "goodprimelist(10,50);" }}}{EXCHG {PARA 0 "> " 0 " " {MPLTEXT 1 0 17 "printlevel := 20;" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 21 "goodprimelist(10,50);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 94 "Another interesting thing is to look at the Maple code fo r some of the functions that you use." }}{PARA 0 "" 0 "" {TEXT -1 75 " The rather cryptic command sequence is to set verboseproc =2 and use p rint." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 17 "printlevel := 1; \+ " }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 25 "interface(verboseproc=3 );" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 15 "print(isprime);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 15 "print(ifactor);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 90 "Finally the function showtime() allows will tell you how long a fu nction takes to perform." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 11 "showtime();" }}}{EXCHG {PARA 0 "O1 := " 0 "" {MPLTEXT 1 0 22 "isprime ((2^(2^11)+1));" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 4 "off;" }}} {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}}{SECT 0 {PARA 3 "" 0 " " {TEXT -1 12 "Prime Fields" }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 99 "Bas ic arithmetic operations work as usual, except that exponentiation sho uld be written as follows " }}{PARA 0 "" 0 "" {TEXT -1 68 "to make it \+ more efficient. (This only matters for large exponents.)" }}{PARA 0 " " 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 13 "2&^6 3 mod 71;" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 85 "The function Primiti ve(a(x)) mod p checks whether the polynomial a(x) is primitive. " }} {PARA 0 "" 0 "" {TEXT -1 90 "That is, whether 1) it is irreducible a nd 2) x is primitive in the field Z_p[x]/a(x) ." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 87 "When a(x) = x-b is linear it tells whether the integer b is primitive in the field Z/p." }}} {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 22 "Primitive(x-2) mod 71;" }}} {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 12 "2^35 mod 71;" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 22 "Primitive(x-7) mod 71;" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 37 "7^6 mod 71; 7^10 mod 71; 7^35 mod 7 1;" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}}{SECT 0 {PARA 3 "" 0 "" {TEXT -1 39 "Cre ating an extension of a Prime Field" }}{PARA 3 "" 0 "" {TEXT -1 86 "N ote to crypto class. There is an easier way to create a field, I will post it later." }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 197 "In this sectio n we define the functions used to create a finite field with p^d elem ents. We will use the Maple function GF which creates an array of fun ctions and constants relevant to the field." }}{PARA 0 "" 0 "" {TEXT -1 98 "I will illustrate them below. GF(p,d) chooses an irreducile po lynomial, but I had trouble making " }}{PARA 0 "" 0 "" {TEXT -1 92 "th e arithmetic work. So I use the version GF(p,d,f) where I choose f to be irreducible and " }}{PARA 0 "" 0 "" {TEXT -1 10 "primitive." }} {PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 86 "So we nee d to find a polynomial, f(T), which is irreducible and of degree d ov er F_p." }}{PARA 0 "" 0 "" {TEXT -1 135 "We will also insist that the \+ polynomial be primitive. That is, in the multiplicative group of F_p[ T]/f(T), the order of T is p^d - 1." }}{PARA 0 "" 0 "" {TEXT -1 213 " You'll notice I check that degree(f)=d. Randpoly(d,t) should produce \+ a polynomial of degree d, but for some reason when d>40 it sometimes r eturns a polynomial of lower degree. So I inserted the check to be su re." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 224 "GetIrrPoly := proc(p,d)\nlocal bool, f;\n\nbool:=fal se;\nwhile bool = false do\n f:= Randpoly(d,T) mod p;\n if Irreduc(f ) mod p and Primitive(f) mod p \n and (degree(f)= d) then bo ol :=true fi;\nod;\nRETURN(f);\nend proc;\n" }}}{SECT 0 {PARA 4 "" 0 " " {TEXT -1 18 "The field GF(2^50)" }}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 19 "p:=2; d:= 50;p := 2" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 22 "f := GetIrrPoly(p,d);\n" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 155 "Next we use the Maple function GF to create the field. \+ GF returns an array of constants and functions that do most of what w e want with the finite field." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}} {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 15 "FF:= GF(p,d,f);" }}{PARA 0 " > " 0 "" {MPLTEXT 1 0 0 "" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 220 "Now we define our primitive element of the finite field. It is the image of T in the quotient space F_p[T]/f(T).\nMaple won't let you use T it self, but it will always express things in terms of T not al. I don't get it." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 23 "al := FF[ConvertIn](T);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 96 "I find the Maple syntax f or the field operations tedious to type, so I made pseudonyms for them ." }}{PARA 0 "" 0 "" {TEXT -1 120 "I chose to set Fzero := FF[zero] in stead of using an alias. If you use an alias Fmul(Fzero,al) will retu rn Fzero not 0." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> \+ " 0 "" {MPLTEXT 1 0 89 "alias( Fadd=FF[`+`], Fmul=FF[`*`], Fexp = FF[ `^`] );\nFzero := FF[zero]; Fone := FF[one];" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 15 "Fadd(Fzero,al);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 14 "Fadd(Fone,al);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 16 "Fmul(Fzero, al);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 98 "Wow, \+ it really works! And it does the following computation quickly, so it thinks before it acts." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 16 " Fexp(al,2^50-1);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 19 "Fexp(al ,111342347);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 7 "Amazing" }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 94 "The next two c oncern primitive elements. The first produces a primitive element ran domly. " }}{PARA 0 "" 0 "" {TEXT -1 61 "The second checks whether a \+ given field element is primitive." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 23 "FF[PrimitiveElement]();" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 18 "h:= Fadd(Fone,al);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 26 "FF[isPrimitiveElement](h);" }}}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}{SECT 0 {PARA 4 "" 0 "" {TEXT -1 24 "The fin ite field GF(5^2)" }{MPLTEXT 1 0 0 "" }}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 20 "H:= GF(5,2,T^2+T+1);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 22 "gam:= H[ConvertIn](T);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 50 "alias (Hadd=H[`+`], Hmul=H[`*`], Hexp = H[`^`] );\n" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 95 "Unfortunately, it is a bit clum sy to write elements of our field H. For example this is how we" }} {PARA 0 "" 0 "" {TEXT -1 42 "have to write the elements 3 and 3 +4T. \+ " }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 25 "H[input](3);H[input](2 3);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 51 "In general, the integer a+ b5 for a, b =0,1,2,3,or 4" }}{PARA 0 "" 0 "" {TEXT -1 38 "corresponds \+ to the field element a+bT." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 21 "Here is (4+ gam)*gam." }}}{EXCHG {PARA 0 "> " 0 " " {MPLTEXT 1 0 32 "Hmul(Hadd(gam,H[input](4)),gam);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 77 "We could alias H[input] and it's inverse H[outp ut] and, while we're at it...." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}} {EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 99 "alias( Hin = H[input], Hout \+ = H[output], HPrim=H[PrimitiveElement], HisPrim=H[isPrimitiveElement]) ;" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 17 "HisPrim(Hin(23));" }} {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}}}{SECT 1 {PARA 3 "" 0 "" {TEXT -1 9 "Exercises" }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 152 "1) Write a new version of good prime which uses the criteria that p is a good prime if (p-1) has a pr ime factor exceeding p/(log_2(p)). Use ifactors()." }}{PARA 0 "" 0 " " {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 172 "2) Examine the asympto tics of good primes: Write a procedure that will test what proportion \+ of primes in the range 2^i....2^(i+1) are good, as i varies. Graph t he result." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 103 "3) Create a finite field of 7^2 elements. Try to find all of \+ the primitive elements. There should be " }}{PARA 0 "" 0 "" {TEXT -1 16 "phi(49-1) = 16;" }}}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" } }}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}}{MARK "4 1 0" 80 } {VIEWOPTS 1 1 0 1 1 1803 1 1 1 1 }{PAGENUMBERS 0 1 2 33 1 1 }