File with support functions for RSA encryption and decryption > with(StringTools); Warning, the assigned name Group now has a global binding [AndMap, Capitalize, Char, CharacterMap, Chomp, CommonPrefix, CommonSuffix, Compare, CompareCI, Drop, Explode, FirstFromLeft, FirstFromRight, FormatMessage, Group, Implode, IsASCII, IsAlpha, IsAlphaNumeric, IsBinaryDigit, IsControlCharacter, IsDigit, IsGraphic, IsHexDigit, IsIdentifier, IsIdentifier1, IsLower, IsOctalDigit, IsPrefix, IsPrintable, IsPunctuation, IsSpace, IsSuffix, IsUpper, Join, LeftFold, Levenshtein, LongestCommonSubSequence, LongestCommonSubString, LowerCase, Map, OrMap, Ord, Random, RegMatch, RegSub, Remove, Reverse, RightFold, Search, SearchAll, Select, SelectRemove, Soundex, Split, Squeeze, SubString, Substitute, SubstituteAll, Take, Trim, TrimLeft, TrimRight, UpperCase] > listtonumber := L -> if L = [] then 0 else Ord(L[1]) + 1000*(listtonumber(L[2..nops(L)])) end if; listtonumber := proc(L) option operator, arrow; if L = [] then 0 else :-Ord(L[1]) + 1000*listtonumber(L[2 .. nops(L)]) end if end proc stringtonumber is a function which sends a string to a number. All ASCII characters are encoded. > stringtonumber := L -> listtonumber(Explode(L)); stringtonumber := L -> listtonumber(:-Explode(L)) > Example := "These are the times that try men's souls"; Example := "These are the times that try men's souls" > Example2 := stringtonumber(Example); Example2 := 1151081171111150321150391101011090321211141160321160\ 9710411603211510110910511603210110411603210111409703210111\ 5101104084 numbertostring converts numbers back to strings, as in the example. > numbertostring := n -> if n = 0 then "" else cat(Char(n mod 1000),numbertostring(trunc(n / 1000))) end if; numbertostring := proc(n) option operator, arrow; if n = 0 then "" else cat(:-Char(n mod 1000), numbertostring(trunc(1/1000*n))) end if end proc > numbertostring(Example2); "These are the times that try men's souls" blocknumber and unblocknumber convert numbers to and from lists of numbers less than the RSA key. > blocknumber := (N,n) -> if n < N then [n] else [n mod N,op(blocknumber(N,trunc(n/N)))] end if; > blocknumber := proc(N, n) option operator, arrow; if n < N then [n] else [n mod N, op(blocknumber(N, trunc(n/N)))] end if end proc > Example3:=blocknumber(1000,Example2); Example3 := [84, 104, 101, 115, 101, 32, 97, 114, 101, 32, 116, 104, 101, 32, 116, 105, 109, 101, 115, 32, 116, 104, 97, 116, 32, 116, 114, 121, 32, 109, 101, 110, 39, 115, 32, 115, 111, 117, 108, 115] > unblocknumber:= (N,L) ->if L = [] then 0 else L[1] + N*(unblocknumber(N,L[2..nops(L)])) end if; > unblocknumber := proc(N, L) option operator, arrow; if L = [] then 0 else L[1] + N*unblocknumber(N, L[2 .. nops(L)]) end if end proc > unblocknumber(1000,Example3); 1151081171111150321150391101011090321211141160321160971041160321\ 15101109105116032101104116032101114097032101115101104084 > evalb(%=Example2); true > shortencipher:=(N,e,T) -> Power(T,e) mod N; shortencipher := (N, e, T) -> Power(T, e) mod N > encipher := (N,e,T) -> unblocknumber(N,map (subs({NN=N,ee=e},(x->shortencipher(NN,ee,x))), (blocknumber (N,T)))); encipher := (N, e, T) -> unblocknumber(N, map( subs({NN = N, ee = e}, x -> shortencipher(NN, ee, x)), blocknumber(N, T))) > p:=nextprime (111111111111111111111111111111111111111111111111111111111111); p := 111111111111111111111111111111111111111111111111111111111151 > q := nextprime (p); q := 111111111111111111111111111111111111111111111111111111111253 > N:=p*q; N := 12345679012345679012345679012345679012345679012345679012365\ 8765432098765432098765432098765432098765432098765432098822\ 03 > gcd(1111,N); 1 > e:=1111;d:=(1/e)mod((p-1)*(q-1)); e := 1111 d := 55116622773388449956106721783289440055116622773388449956195\ 9004789367825671456034492338122701159004789367825671456279\ 1 > encipher(N,e,Example2); 8096297518078435012597803619738861962499185463974974600897507809\ 8983042251228052438856278917236590375920716449652816706342\ 7223634562505499508817762246117022935108816513415702289756\ 60863521339910387346112921482725867913162981553289758658 > numbertostring(encipher(N,d,%)); "These are the times that try men's souls" > stringencipher and stringdecipher do the whole job. stringencipher takes the RSA public key as its first two arguments, and a string as its third, and returns a ciphertext for that string. There is no length limitation on the string, because it is blocked suitably. stringdecipher takes the N component of the public key and your private decryption key as its first arguments, the ciphertest as its third, and returns a plaintext string. > stringencipher := (N,e,T) -> encipher(N,e,stringtonumber(T)); stringencipher := (N, e, T) -> encipher(N, e, stringtonumber(T)) > stringdecipher := (N,d,C) -> numbertostring(encipher(N,d,C)); stringdecipher := (N, d, C) -> numbertostring(encipher(N, d, C)) > stringencipher(N,e,"These are the times that try men's souls"); 8096297518078435012597803619738861962499185463974974600897507809\ 8983042251228052438856278917236590375920716449652816706342\ 7223634562505499508817762246117022935108816513415702289756\ 60863521339910387346112921482725867913162981553289758658 > stringdecipher(N,d,%); "These are the times that try men's souls" > >