; Functions for generating and using PGP keys. ; Written by Shane Sniffen. ; Encrypt/decrypt message 'm with public/private key 'key. (require 'stdlib) (puts "needs porting to rep") (exit) (defun crypt-message (m key) (setq n (first key)) (setq a (second key)) (mod (expt m a) n)) ; Generate key pair in the form '(pub priv) (defun generate-key-pair () (setq p (random-prime)) (setq q (random-prime)) (setq n (* p q)) (setq phi (* (1- p) (1- q))) (setq e (random-e phi)) (setq d (inv-mod e phi)) `((,n ,e) (,n ,d))) ; The inverse modular multiplication function (defun inv-mod2 (e phi) (let ((d 1)) (repet d e phi))) (defun repet (d e phi) (cond ((= (mod (* e d) phi) 1) d) (t (repet (1+ d) e phi)))) ; Alternative inv-mod function, probably better (defun inv-mod (e phi) (let ((d 1)) (loop (when (= (mod (* e d) phi) 1) (return d)) (setq d (1+ d))))) ; Old inv-mod function. Still fast. (defun inv (e phi &optional n) (if (eq n nil) (setq n 0)) (let ((j (/ phi e))) (if (equal (mod (* (setq d (1+ (* n j))) e) phi) 1) d (inv e phi (1+ n))))) ; Random prime (defun random-prime2 () (let ((prime 100000)) (setq prime-num (random 10000)) (dotimes (x prime-num prime) (setq prime (next-prime prime))))) ; Faster, less random prime generator (defun random-prime () (next-prime (+ 100 (random 1000)))) ; Return random number less than and coprime with 'phi. (defun random-e (phi) (loop (setq ar (let ((re (random phi))) (loop (unless (< re phi) (return nil)) (when (are-coprime re phi) (return re)) (setq re (1+ re))))) (unless (null ar) (return ar)))) ; Return the next prime number that appears after 'num. (defun next-prime (num) (cond ((is-prime (1+ num)) (1+ num)) (t (next-prime (1+ num))))) ; Is 'num prime? (defun is-prime (num) (cond ((or (= num 0) (= num 1)) nil) (t (let ((x 2) (s (sqrt num))) (loop (when (> x s) (return t)) (when (= (/ num x) (floor (/ num x))) (return nil)) (setq x (1+ x))))))) ; Are 'numbers coprime? (defun are-coprime (&rest numbers) (let ((x 2)) (loop (when (eval (append '(or) (mapcar (lambda (z) (> x z)) numbers))) (return t)) (when (eval (append '(and) (mapcar (lambda (z) (= (/ z x) (floor (/ z x)))) numbers))) (return nil)) (setq x (1+ x)))))