{VERSION 4 0 "IBM INTEL LINUX" "4.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 7 "We wi ll" }}{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 pr ime that would be ideal. Let us write a simple test for a prime to se e if it satisfies this condition. " }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 141 "goodprime := proc(p)\nlocal pp, bool;\n\npp := (p-1) /2;\nif isprime(pp) \n then bool := true;\n else bool := false;\nf i;\nRETURN(bool);\nend proc;" }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}} {EXCHG {PARA 0 "" 0 "" {TEXT -1 58 "There are a few things to notice i n this simple example. " }}{PARA 0 "" 0 "" {TEXT -1 87 "1) The if st atement must be terminated with either \"end if\" or its abbreviation \"fi\"." }}{PARA 0 "" 0 "" {TEXT -1 105 "2) The else statement is op tional. You can also have a sequence of else 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 anno ying warning message." }}{PARA 0 "" 0 "" {TEXT -1 89 "4) I like to ex plicitly say what the procedure should return, using RETURN() as shown . " }}{PARA 0 "" 0 "" {TEXT -1 65 "I'm not completely clear on the ru les 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 fr om m to n do\n if (isprime(i) and goodprime(i))\n then plist : = [op(plist), i];\n fi;\nod;\nRETURN(plist);\nend proc;\n" }}} {EXCHG {PARA 0 "" 0 "" {TEXT -1 191 "Notes: 1) We closed both the if \+ and the do statements. 2) The indentation is my choice for legibil ity. 3) I had to initialize plist . 4) Extending 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 good primes there are \+ less than 2^(i+1) and " }}{PARA 0 "" 0 "" {TEXT -1 141 "graph the res ult. This indicate tell how easy it is to find such primes, and thu s the feasibility of finding them for an RSA cryptosystem." }}{PARA 0 "" 0 "" {TEXT -1 125 "For comparison, the Prine Number Theorem says th at the number of primes less than 2^i is approximately ((2^i / i * lo g(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 := [];\ntot_cnt := 0;\nfo r i from 2 to pow do\n new_cnt := nops(goodprimelist(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(15);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 234 "Now go back to the numgoodprimes functio n and change it so that it prints out the number of goodprimes in each range 2^i .... 2^(i+1), so that we can keep track of how long it take s 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)) );\n print( \"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 with the n umber of good primes and compare it to what we might expect according \+ to the prime number theorem. There number of primes less than t is r oughly t/ln(t). We might expect that t and (t-1)/2 would both be p rime 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 writing proc edures" }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 50 "Here are a few Maple co mmands 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 pri nt out intermediate data computed within a given procedure. Setting i t to 20 will also printout data in procedures called by the given proc edure." }}{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 1 {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 1 {PARA 3 "" 0 "" {TEXT -1 39 "Cre ating an extension of a Prime Field" }}{PARA 3 "" 0 "" {TEXT -1 0 "" }}{EXCHG {PARA 0 "" 0 "" {TEXT -1 197 "In this section we define the \+ functions used to create a finite field with p^d elements. We will us e the Maple function GF which creates an array of functions and consta nts relevant to the field." }}{PARA 0 "" 0 "" {TEXT -1 98 "I will illu strate them below. GF(p,d) chooses an irreducile polynomial, but I ha d trouble making " }}{PARA 0 "" 0 "" {TEXT -1 92 "the arithmetic work. So I use the version GF(p,d,f) where I choose f to be irreducible an d " }}{PARA 0 "" 0 "" {TEXT -1 10 "primitive." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 86 "So we need to find a pol ynomial, f(T), which is irreducible and of degree d over 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), t he order of T is p^d - 1." }}{PARA 0 "" 0 "" {TEXT -1 213 "You'll noti ce I check that degree(f)=d. Randpoly(d,t) should produce a polynomia l of degree d, but for some reason when d>40 it sometimes returns a po lynomial of lower degree. So I inserted the check to be sure." }} {PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 224 "GetIrrPoly := proc(p,d)\nlocal bool, f;\n\nbool:=false;\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 bool :=true f i;\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 := G etIrrPoly(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 c onstants and functions that do most of what we want with the finite fi eld." }}{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 spa ce F_p[T]/f(T).\nMaple won't let you use T itself, 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 for the field operations ted ious to type, so I made pseudonyms for them." }}{PARA 0 "" 0 "" {TEXT -1 120 "I chose to set Fzero := FF[zero] instead of using an alias. I f you use an alias Fmul(Fzero,al) will return Fzero not 0." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 89 "ali as( Fadd=FF[`+`], Fmul=FF[`*`], Fexp = FF[`^`] );\nFzero := FF[zero]; Fone := FF[one];" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 15 "Fadd(F zero,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 concern primitive elements . The first produces a primitive element randomly. " }}{PARA 0 "" 0 "" {TEXT -1 61 "The second checks whether a given field element is p rimitive." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 23 "FF[PrimitiveEl ement]();" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 18 "h:= Fadd(Fone, al);" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 26 "FF[isPrimitiveEleme nt](h);" }}}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 0 "" }}}{SECT 0 {PARA 4 "" 0 "" {TEXT -1 24 "The finite 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[`+`], Hmu l=H[`*`], Hexp = H[`^`] );\n" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 95 "U nfortunately, it is a bit clumsy to write elements of our field H. Fo r 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](23);" }}}{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)*g am." }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 32 "Hmul(Hadd(gam,H[inpu t](4)),gam);" }}}{EXCHG {PARA 0 "" 0 "" {TEXT -1 77 "We could alias H[ input] and it's inverse H[output] and, while we're at it...." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}}{EXCHG {PARA 0 "> " 0 "" {MPLTEXT 1 0 99 "a lias( Hin = H[input], Hout = H[output], HPrim=H[PrimitiveElement], His Prim=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) Wr ite a new version of goodprime which uses the criteria that p is a goo d prime if (p-1) has a prime factor exceeding p/(log_2(p)). Use ifact ors()." }}{PARA 0 "" 0 "" {TEXT -1 0 "" }}{PARA 0 "" 0 "" {TEXT -1 172 "2) Examine the asymptotics of good primes: Write a procedure that will test what proportion of primes in the range 2^i....2^(i+1) are g ood, as i varies. Graph the result." }}{PARA 0 "" 0 "" {TEXT -1 0 " " }}{PARA 0 "" 0 "" {TEXT -1 103 "3) Create a finite field of 7^2 elem ents. 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 "7 0 0" 0 }{VIEWOPTS 1 1 0 1 1 1803 1 1 1 1 }{PAGENUMBERS 0 1 2 33 1 1 }