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