rsa.l (2621B)
1 # 10nov04abu 2 # (c) Software Lab. Alexander Burger 3 4 # *InND 5 6 # Generate long random number 7 (de longRand (N) 8 (use (R D) 9 (while (=0 (setq R (abs (rand))))) 10 (until (> R N) 11 (unless (=0 (setq D (abs (rand)))) 12 (setq R (* R D)) ) ) 13 (% R N) ) ) 14 15 # X power Y modulus N 16 (de **Mod (X Y N) 17 (let M 1 18 (loop 19 (when (bit? 1 Y) 20 (setq M (% (* M X) N)) ) 21 (T (=0 (setq Y (>> 1 Y))) 22 M ) 23 (setq X (% (* X X) N)) ) ) ) 24 25 # Probabilistic prime check 26 (de prime? (N) 27 (and 28 (> N 1) 29 (bit? 1 N) 30 (let (Q (dec N) K 0) 31 (until (bit? 1 Q) 32 (setq 33 Q (>> 1 Q) 34 K (inc K) ) ) 35 (do 50 36 (NIL (_prim? N Q K)) 37 T ) ) ) ) 38 39 # (Knuth Vol.2, p.379) 40 (de _prim? (N Q K) 41 (use (X J Y) 42 (while (> 2 (setq X (longRand N)))) 43 (setq 44 J 0 45 Y (**Mod X Q N) ) 46 (loop 47 (T 48 (or 49 (and (=0 J) (= 1 Y)) 50 (= Y (dec N)) ) 51 T ) 52 (T 53 (or 54 (and (> J 0) (= 1 Y)) 55 (<= K (inc 'J)) ) 56 NIL ) 57 (setq Y (% (* Y Y) N)) ) ) ) 58 59 # Find a prime number with `Len' digits 60 (de prime (Len) 61 (let P (longRand (** 10 (*/ Len 2 3))) 62 (unless (bit? 1 P) 63 (inc 'P) ) 64 (until (prime? P) # P: Prime number of size 2/3 Len 65 (inc 'P 2) ) 66 # R: Random number of size 1/3 Len 67 (let (R (longRand (** 10 (/ Len 3))) K (+ R (% (- P R) 3))) 68 (when (bit? 1 K) 69 (inc 'K 3) ) 70 (until (prime? (setq R (inc (* K P)))) 71 (inc 'K 6) ) 72 R ) ) ) 73 74 # Generate RSA key 75 (de rsaKey (N) #> (Encrypt . Decrypt) 76 (let (P (prime (*/ N 5 10)) Q (prime (*/ N 6 10))) 77 (cons 78 (* P Q) 79 (/ 80 (inc (* 2 (dec P) (dec Q))) 81 3 ) ) ) ) 82 83 # Encrypt a list of characters 84 (de encrypt (Key Lst) 85 (let Siz (>> 1 (size Key)) 86 (make 87 (while Lst 88 (let N (char (pop 'Lst)) 89 (while (> Siz (size N)) 90 (setq N (>> -16 N)) 91 (inc 'N (char (pop 'Lst))) ) 92 (link (**Mod N 3 Key)) ) ) ) ) ) 93 94 # Decrypt a list of numbers 95 (de decrypt (Keys Lst) 96 (mapcan 97 '((N) 98 (let Res NIL 99 (setq N (**Mod N (cdr Keys) (car Keys))) 100 (until (=0 N) 101 (push 'Res (char (& `(dec (** 2 16)) N))) 102 (setq N (>> 16 N)) ) 103 Res ) ) 104 Lst ) ) 105 106 # Init crypt 107 (de rsa (N) 108 (seed (in "/dev/urandom" (rd 20))) 109 (setq *InND (rsaKey N)) )