> read(`public/Maple/RSA.mpl`); `convert/toASCII` := proc(string) local addr,lst,op3,code,i; if string = `.` then RETURN(46) fi; for i to 128 do if substring(ctrlstring,i .. i) = string then RETURN(i-1) fi od; print(`Try to convert unprintable character to ASCII`); RETURN(0) end Warning, string contains newline character. Close strings with ` quote. ctrlstring := .......... ..................... !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKL\ MNOPQRSTUVWXYZ(\)^_`abcdefghijklmnopqrstuvwxyz{|}~. `convert/fromASCII` := proc(ascii_val) substring(ctrlstring,ascii_val+1 .. ascii_val+1) end encode := proc(ClearText,PublicKey) local b,i,ints,codedints; b := blocking_factor(PublicKey); ints := pack(ClearText,b); codedints := []; for i to nops(ints) do codedints := [op(codedints),scramble(ints[i],PublicKey)] od; RETURN(codedints) end Warning, `publickey` is implicitly declared local decode := proc(CodedInts,PrivateKeys) local b,i,ints,P,Q,magicexp,publickey; P := PrivateKeys[1]; Q := PrivateKeys[2]; magicexp := iquo(2*(P-1)*(Q-1)+1,3); publickey := P*Q; ints := []; for i to nops(CodedInts) do ints := [op(ints),unscramble(CodedInts[i],magicexp,publickey)] od; b := blocking_factor(publickey); RETURN(unpack(ints,b)) end find_key := proc(Start) local int; int := Start; if irem(int,2) = 0 then int := int+1 fi; if irem(int,3) = 0 then int := int+2 fi; if irem(int,3) = 1 then int := int+4 fi; while not isprime(int) do int := int+6 od; RETURN(int) end blocking_factor := proc(Key) iquo(trunc(evalf(log(Key)/log(2))),8) end pack := proc(text,b) local chars,len,i,j,k,ints,code,c; len := round(length(text)/b+1/2); chars := text.` `. ` `. ` `; j := 0; ints := []; for i to len do code := 0; for k to b do j := j+1; code := 256*code+convert(substring(chars,j .. j),toASCII) od; ints := [op(ints),code] od; RETURN(ints) end Warning, `k` is implicitly declared local unpack := proc(intlist,b) local len,i,j,block,text,k; len := nops(intlist); text := ``; for i to len do block := ``; j := intlist[i]; for k to b do block := cat(convert(irem(j,256),fromASCII),block); j := iquo(j,256) od; text := cat(text,block) od; RETURN(text) end scramble := proc(Int,PublicKey) irem(irem(Int^2,PublicKey)*Int,PublicKey) end unscramble := proc(CodedInt,MagicExp,PublicKey) power_mod(CodedInt,MagicExp,PublicKey) end power_mod := proc(a,e,m) local half; if e = 0 then RETURN(1) fi; if e = 1 then RETURN(irem(a,m)) fi; half := power_mod(a,iquo(e,2),m); if type(e,even) then RETURN(Expand(half^2) mod m) else RETURN(Expand(half^2*a) mod m) fi end -------------------------------------------------------------------------------- > convert(`H`, toASCII); 72 -------------------------------------------------------------------------------- > convert(", binary); 1001000 -------------------------------------------------------------------------------- > P := find_key(1047309741920874129087); P := 1047309741920874129143 -------------------------------------------------------------------------------- > Q := find_key(174512903490182374); Q := 174512903490182447 -------------------------------------------------------------------------------- > K := P*Q;\ K := 182769063916165392636054393131309752921 -------------------------------------------------------------------------------- > convert(K, binary); 1000100110000000000010101001001101010001000111010010100000011000111001011000101\ 0010001011011101100101100011000000110001001011001 -------------------------------------------------------------------------------- > evalf(log[2](K)); 127.1032895 -------------------------------------------------------------------------------- > blocking_factor(K); 15 -------------------------------------------------------------------------------- > pack(`Hello, how are you today?`, 15); [375902487384808157144386877911098656, 630528547088015391132806231474839584] -------------------------------------------------------------------------------- > unpack(", 15); Hello, how are you today? -------------------------------------------------------------------------------- > encode(`Hello, how are you today?`, K); [106721224137614351582281885445412317874, 67467725784683723348414505373754317001 ] -------------------------------------------------------------------------------- > decode(", [P, Q]); Hello, how are you today? -------------------------------------------------------------------------------- > ints := pack(`Erich Kaltofen`, 15); ints := [360589027655680158358836091235429920] -------------------------------------------------------------------------------- > sgn := [unscramble(op(1,ints), (2*(P-1)*(Q-1)+1)/3, K)]; sgn := [175447822430736748602544060112260396636] -------------------------------------------------------------------------------- > lst := [scramble(op(1, sgn), K)]; lst := [360589027655680158358836091235429920] -------------------------------------------------------------------------------- > unpack(lst, 15); Erich Kaltofen -------------------------------------------------------------------------------- > # factors of RSA-129 found in 1994\ P := 3490529510847650949147849619903898133417764638493387843990820577;\ \ Q := 32769132993266709549961988190834461413177642967992942539798288533;\ \ # RSA-129\ K := P*Q;\ \ # encode(m) = m^s mod K\ s := 9007;\ \ # decode(e) = e^t mod K, where t = s^(-1) mod phi(K)\ t := s^(-1) mod ((P-1)*(Q-1));\ \ # this procedure does the special number to text conversion used\ sciamer_unpack := proc(int)\ local ctrlstring, text, pos, code;\ ctrlstring := ` ABCDEFGHIJKLMNOPQRSTUVWXYZ`;\ code := int;\ text := ``;\ while(code > 0) do\ pos := code mod 100; code := iquo(code, 100);\ text := cat(substring(ctrlstring, pos+1..pos+1), text);\ od;\ RETURN(text);\ end;\ P := 3490529510847650949147849619903898133417764638493387843990820577 Q := 32769132993266709549961988190834461413177642967992942539798288533 K := 1143816257578888676692357799761466120102182967212423625625618429357069352457338\ 97830597123563958705058989075147599290026879543541 s := 9007 t := 1066986143685780244428687713289201547807099066339378628012262244966310631259117\ 74470873340168597462306553968544513277109053606095 sciamer_unpack := proc(int) local ctrlstring,text,pos,code; ctrlstring := ` ABCDEFGHIJKLMNOPQRSTUVWXYZ`; code := int; text := ``; while 0 < code do pos := code mod 100; code := iquo(code,100); text := cat(substring(ctrlstring,pos+1 .. pos+1),text) od; RETURN(text) end -------------------------------------------------------------------------------- > # test sciamer_unpack on example p. 123\ sciamer_unpack(09201900011212000718050511002015001305);\ ITS ALL GREEK TO ME -------------------------------------------------------------------------------- > # this was the secret text on p. 121\ challenge := 9686961375462206;\ challenge := challenge*10^16 + 1477140922254355;\ challenge := challenge*10^16 + 8829057599911245;\ challenge := challenge*10^16 + 7431987469512093;\ challenge := challenge*10^16 + 0816298225145708;\ challenge := challenge*10^16 + 3569314766228839;\ challenge := challenge*10^16 + 8962801339199055;\ challenge := challenge*10^16 + 1829945157815154;\ \ power_mod(challenge, t, K);\ sciamer_unpack(");\ challenge := 9686961375462206 challenge := 96869613754622061477140922254355 challenge := 968696137546220614771409222543558829057599911245 challenge := 9686961375462206147714092225435588290575999112457431987469512093 challenge := 96869613754622061477140922254355882905759991124574319874695120930816298225145708 challenge := 9686961375462206147714092225435588290575999112457431987469512093081629822514570\ 83569314766228839 challenge := 9686961375462206147714092225435588290575999112457431987469512093081629822514570\ 835693147662288398962801339199055 challenge := 9686961375462206147714092225435588290575999112457431987469512093081629822514570\ 8356931476622883989628013391990551829945157815154 200805001301070903002315180419000118050019172105011309190800151919090618010705 THE MAGIC WORDS ARE SQUEAMISH OSSIFRAGE -------------------------------------------------------------------------------- >