> 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 -------------------------------------------------------------------------------- > P := find_key(398472398472398472398472); P := 398472398472398472398543 -------------------------------------------------------------------------------- > > Q := find_key(1097398479874297); Q := 1097398479874331 -------------------------------------------------------------------------------- > K := P*Q;\ K := 437283004355488777720855198786787499733 -------------------------------------------------------------------------------- > Code := encode(`This is my secret: E = mc^2`, K); Code := [ 209108607200813361678156013520174275758, 431546554612854482981534544834871831775 ] -------------------------------------------------------------------------------- > decode(Code, [P, Q]); This is my secret: E = mc^2 -------------------------------------------------------------------------------- > b := blocking_factor(K); b := 16 -------------------------------------------------------------------------------- > M := pack(`This is my secret: E = mc^2`, b); M := [ 112197289293498629158752592933480002149, 154492255242673209519851554059151482912 ] -------------------------------------------------------------------------------- > m := op(1, M); m := 112197289293498629158752592933480002149 -------------------------------------------------------------------------------- > e := m^3 mod K; e := 209108607200813361678156013520174275758 -------------------------------------------------------------------------------- > irem(P, 3); 2 -------------------------------------------------------------------------------- > irem(Q, 3); 2 -------------------------------------------------------------------------------- > secret := (2*(P-1)*(Q-1) + 1)/3; secret := 291522002903658919498970419326556817907 -------------------------------------------------------------------------------- > power_mod(e, secret, K); 112197289293498629158752592933480002149 -------------------------------------------------------------------------------- > m; 112197289293498629158752592933480002149 -------------------------------------------------------------------------------- >