【新月実装】需【Clojure・ClojureScript】

2ddc3727 :Anonymous 2016-01-15 03:11
@markdown
一応署名機能の実装のめどがたちました。

```clojure
(require 'clojure.math.numeric-tower)
(require 'digest)
(require 'clojure.data.codec.base64)
(let [siganture-key "test"
hashs (str (digest/md5 siganture-key)
(digest/md5 (str siganture-key "pad1"))
(digest/md5 (str siganture-key "pad2"))
(digest/md5 (str siganture-key "pad3")))
match (re-find #"^(.{56})(.{72})$" hashs)
str-to-bigint (fn [s]
(apply +
(map
(fn [[x y] n] (* (bigint (Integer/parseInt (str x y) 16)) (clojure.math.numeric-tower/expt 256 n)))
(partition 2 s)
(range (/ (count s) 2)))))
p (str-to-bigint (nth match 1))
q (str-to-bigint (nth match 2))
is-nth-bit-on? (fn [num n] (pos? (rem (quot num (clojure.math.numeric-tower/expt 2 (dec n))) 2)))
p (if (is-nth-bit-on? p 216) p (+ p (clojure.math.numeric-tower/expt 2 215)))
q (if (is-nth-bit-on? p 280) q (+ q (clojure.math.numeric-tower/expt 2 279)))
p (bigint (.nextProbablePrime (biginteger p)))
q (bigint (.nextProbablePrime (biginteger q)))
t 30531
e 65537
expt-mod (fn [b e n] (bigint (.modPow (biginteger b) (biginteger e) (biginteger n))))
base64-table
{0 "A" 16 "Q" 32 "g" 48 "w"
1 "B" 17 "R" 33 "h" 49 "x"
2 "C" 18 "S" 34 "i" 50 "y"
3 "D" 19 "T" 35 "j" 51 "z"
4 "E" 20 "U" 36 "k" 52 "0"
5 "F" 21 "V" 37 "l" 53 "1"
6 "G" 22 "W" 38 "m" 54 "2"
7 "H" 23 "X" 39 "n" 55 "3"
8 "I" 24 "Y" 40 "o" 56 "4"
9 "J" 25 "Z" 41 "p" 57 "5"
10 "K" 26 "a" 42 "q" 58 "6"
11 "L" 27 "b" 43 "r" 59 "7"
12 "M" 28 "c" 44 "s" 60 "8"
13 "N" 29 "d" 45 "t" 61 "9"
14 "O" 30 "e" 46 "u" 62 "+"
15 "P" 31 "f" 47 "v" 63 "/" }
bigint-to-base64 (fn bigint-to-base64
[n]
(if (>= n 64)
(concat (list (get base64-table (rem n 64))) (bigint-to-base64 (quot n 64)))
(list (get base64-table n))))
add-padding (fn [s] (str s (apply str (repeat (- 86 (count s)) "A"))))]
(loop [p p
q q]
(let [n (* p q)
d (bigint (.modInverse (biginteger e) (biginteger (* (dec p) (dec q)))))]
(if (= (expt-mod t (* e d) n) t)
[(add-padding (apply str (bigint-to-base64 n))) (add-padding (apply str (bigint-to-base64 d)))]
(recur (+ p 2) (+ q 2))))))
```

これを実行すると公開鍵と秘密鍵が生成されます。

```
=>
["DpmzfQSOhbpxE7xuaiEao3ztv9NAJi/loTs2N43f5hC3XpT3z9VhApcrYy94XhMBKONo5H14c8STrriPJnCcVA"
"BAcp0SUgUOSY+TrLhy/MEszzq0Obadi3EhXDEUUD9FmOkv7vhPiNrgg2HR8DmuFiPcXNHdqu44wyGRX5bmdcQA"]
```

コードの整理はまだですが、とりあえずこれで一安心です。
Powered by shinGETsu.