;;; -*- Mode:LISP; Package:USER; Base:10; Readtable:CL -*- #|| Copyright LISP Machine, Inc. 1985, 1986 See filename "Copyright.Text" for licensing and release information. ********************************************************* ********************************************************* *** NOTE: This is an EXAMPLE, not LMI supported code. *** *** information contained in this example is subject *** *** to change without notice. The ways of doing *** *** the things contained in the example may change *** *** between system releases. Some techniques which *** *** are mere examples in one release may become built *** *** in system features in the next release. Use good *** *** judgement when copying these techniques. Most *** *** examples have been motivated by specific customer *** *** requests, and may not be the best engineered *** *** or most efficient solution for someone else. *** ********************************************************* ********************************************************* Encryption/Decryption functions. We might find these useful sometime. 2-Mar-86 11:22:32 -GJC ||# (defun crypt (message key) "Message is a list of integers, key is a pair ( . )" (mapcar (function (lambda (mblock) (crypt-block mblock key))) message)) (defun crypt-block (message-block key) (exponent-modulo message-block (car key) (cdr key))) (defun exponent-modulo (a b c) (do ((foo 1) (imax (1+ (haulong b))) (i 1 (1+ i))) ((= i imax) foo) (setq foo ((lambda (temp) (cond ((oddp (haipart b i)) (remainder (times temp a) c)) (t temp))) (remainder (times foo foo) c))))) ;;; ;;; Functions for defining keys. ;;; (defun make-keys (max-digits) (do ((p (make-suitable-prime max-digits)) (q (make-suitable-prime (+ max-digits (random 10) 1)) (make-suitable-prime (+ max-digits (random 10) 1)))) ((lessp (gcd (sub1 p) (sub1 q)) 1000) (prog (e d n phi) (setq n (times p q) phi (difference n p q -1)) loop (setq d (make-prime-bignum (* max-digits 2)) e ((lambda (trial-e) (cond ((minusp trial-e) (plus phi trial-e)) (t trial-e))) (inverse-modulo d phi))) (and (lessp e (haulong n)) (go loop)) (return (cons (cons e n) (cons d n))))))) (defun inverse-modulo (a b) (do ((olderx 0 oldx) (oldx b x) (x a (remainder oldx x)) (oldb 0 b) (b 1 (plus oldb (times b (quotient (difference (remainder oldx x) oldx) x))))) ((zerop x) oldb))) (defun congruentp (a b c) (equal (remainder b c) (remainder a c))) (defun make-suitable-prime (max-digits) (do ((u (make-prime-bignum max-digits)) (i 2 (+ i 2)) (foo 4 (add1 (times i u)))) ((test-primality foo) foo))) (defun make-prime-bignum (max-digits) (do ((bignum-to-test (make-bignum-to-test max-digits) (make-bignum-to-test max-digits))) ((test-primality bignum-to-test) bignum-to-test))) (defun test-primality (prime-candidate) (do ((i 1 (1+ i)) (a (big-random prime-candidate) (big-random prime-candidate))) ((= i 30) t) ;;2^30 is about 1 billion (or (and (equal (gcd a prime-candidate) 1) (equal (cond ((= (Jacobi a prime-candidate) -1) (sub1 prime-candidate)) (t 1)) (exponent-modulo a (quotient (sub1 prime-candidate) 2) prime-candidate))) (return nil)))) (defun big-random (limit) ;;1<=big-random<=limit-1 (do ((foo (quotient (times limit (random 10000)) 10000) (quotient (times limit (random 10000)) 10000))) ((not (zerop foo)) foo))) (defun Jacobi (a b) (cond ((equal a 1) 1) ((not (oddp a)) (times (Jacobi (quotient a 2) b) (sign-power (quotient (sub1 (times b b)) 8)))) (t (times (Jacobi (remainder b a) a) (sign-power (quotient (times (sub1 a) (sub1 b)) 4)))))) (defun sign-power (n) (cond ((oddp n) -1) (t 1))) (defun make-bignum-to-test (max-digits) (do ((i 1 (1+ i)) (next-digit (random-first-digit) (random-digit)) (foo 0 (plus (times foo 10) next-digit))) ((= i max-digits) (plus (times foo 10) (random-final-digit))))) (defun random-digit () (random 10)) (defun random-first-digit () (do ((foo (random-digit) (random-digit))) ((not (zerop foo)) foo))) (defun random-final-digit () (do ((foo (random-digit) (random-digit))) ((member foo '(1 3 7 9)) foo)))