计算机程序的构造和解释(SICP) Assignment 5 RSA encryption
这次回顾Assignment 5 RSA encryption。
学习资料:
https://github.com/DeathKing/Learning-SICP
https://mitpress.mit.edu/sites/default/files/sicp/index.html
https://www.bilibili.com/video/BV1Xx41117tr?from=search&seid=14983483066585274454
作业地址:
https://mitpress.mit.edu/sites/default/files/sicp/psets/index.html
2. Exercises
Exercise 1
没有区别。
Exercise 2
略过。
Exercise 3
先加密更好;因为如果先sign,相当于只加密了一次,但是先加密再sign相当于加密了多次。
Exercise 4
代码:
(define (RSA-encrypt intlist key1)
(map (lambda (int) (RSA-transform int key1))
intlist))
(define (RSA-decrypt intlist key1)
(map (lambda (int) (RSA-transform int key1))
intlist))
3. Programming assignment
Exercise 1
计算公式:
encrypt:
decrypt:
代码:
(define (RSA-unconvert-list intlist key)
(let ((n (key-modulus key)))
(define (unconvert l sum)
(if (null? l)
'()
(let ((x (modulo (+ (RSA-transform (car l) key)
sum) n)))
(cons x (unconvert (cdr l) (car l))))))
(unconvert intlist 0)))
(load "rsa.scm")
(define result1 (rsa-encrypt "This is a test message." test-public-key1))
(display result1)
(RSA-decrypt result1 test-private-key1)
(define result2 (rsa-encrypt "This is a another test message." test-public-key2))
(display result2)
(RSA-decrypt result2 test-private-key2)
运行结果:
1 ]=> (display result1)(209185193 793765302 124842465 169313344 117194397 237972864)
;Unspecified return value
1 ]=> (RSA-decrypt result1 test-private-key1)
;Value 13: "This is a test message. "
1 ]=> (define result2 (rsa-encrypt "This is a another test message." test-public-key2))
;Value: result2
1 ]=> (display result2)(102436216 322617498 188506539 149103786 325444552 190854590 397182031 313797695)
;Unspecified return value
1 ]=> (RSA-decrypt result2 test-private-key2)
;Value 14: "This is a another test message. "
Exercise 2
代码:
; e2
(define signed-message cons)
(define message car)
(define signature cdr)
(define (encrypt-and-sign message sender-private-key recip-public-key)
(let ((encry-message (RSA-encrypt message recip-public-key)))
(let ((unencry-signature (list (compress encry-message))))
(let ((encry-signature (car (RSA-convert-list unencry-signature sender-private-key))))
(signed-message message encry-signature)))))
(load "rsa.scm")
(define result2
(encrypt-and-sign "Test message from user 1 to user 2"
test-private-key1
test-public-key2))
(message result2)
(signature result2)
实验结果:
1 ]=> (message result2)
;Value 13: "Test message from user 1 to user 2"
1 ]=> (signature result2)
;Value: 15378444
Exercise 3
流程:
遍历pulic-key,来找到对应的发送者。
代码:
(load "rsa.scm")
(define message (intlist->string received-mystery-message))
(display message)
(define unencry-message (RSA-decrypt received-mystery-message newt-gingrich-private-key))
(display unencry-message)
(define encry-message (rsa-encrypt unencry-message newt-gingrich-public-key))
(define unencrypted-signature (compress encry-message))
(display unencrypted-signature)
(define (encry-to-unencry encrypted-signature public-key)
(car (RSA-convert-list (list encrypted-signature) public-key)))
(define public-keys (list
(list 'bill-clinton bill-clinton-public-key)
(list 'al-gore al-gore-public-key )
(list 'bob-dole bob-dole-public-key )
(list 'ross-perot ross-perot-public-key )
(list 'hillary-clinton hillary-clinton-public-key )
(list 'tipper-gore tipper-gore-public-key )
(list 'chuck-vest chuck-vest-public-key)
(list 'rupert-murdoch rupert-murdoch-public-key)
(list 'newt-gingrich newt-gingrich-public-key)))
(define (get-res unencrypted-signature encrypted-signature public-keys)
(cond ((null? public-keys) "No result!")
((= (encry-to-unencry encrypted-signature (cadar public-keys)) unencrypted-signature)
(caar public-keys))
(else (get-res unencrypted-signature encrypted-signature (cdr public-keys)))))
(get-res unencrypted-signature received-mystery-signature public-keys)
实验结果:
1 ]=> (get-res unencrypted-signature received-mystery-signature public-keys)
;Value: rupert-murdoch
Exercise 4
为了求解:
假设:
那么:
记
那么
此时新方程为
注意到
所以经过有限步后一定有$r=0$,此时
特别的,这里取
代码:
(define (solve-ax+by=1 a b)
(if (= b 0)
(cons 1 0)
(let ((q (quotient a b))
(r (remainder a b)))
(let ((x1y1 (solve-ax+by=1 b r)))
(cons (cdr x1y1) (- (car x1y1) (* q (cdr x1y1))))))))
(load "rsa.scm")
(define a 233987973)
(define b 41111687)
(define (test a b)
(let ((xy (solve-ax+by=1 a b)))
(let ((x (car xy))
(y (cdr xy)))
(if (= (+ (* a x) (* b y)) 1)
(display "Pass test!")
(display "Fail test!")))))
(test a b)
(solve-ax+by=1 a b)
; test
(define key-pair (generate-RSA-key-pair))
(define public-key (key-pair-public key-pair))
(define private-key (key-pair-private key-pair))
(define result (rsa-encrypt "This is a test message." public-key))
(RSA-decrypt result private-key)
实验结果:
1 ]=> (test a b)Pass test!
;Unspecified return value
1 ]=> (solve-ax+by=1 a b)
;Value 13: (-11827825 . 67318298)
1 ]=> ; test
(define key-pair (generate-RSA-key-pair))
;Value: key-pair
1 ]=> (define public-key (key-pair-public key-pair))
;Value: public-key
1 ]=> (define private-key (key-pair-private key-pair))
;Value: private-key
1 ]=> (define result (rsa-encrypt "This is a test message." public-key))
;Value: result
1 ]=> (RSA-decrypt result private-key)
;Value 14: "This is a test message. "
Exercise 5
要通过公钥$(n,e)$求出私钥$(n,d)$,只要求出$e$,满足下式即可:
即
其中
所以一个可行的算法是枚举小于$n$的素数,找到整除$n$的素数$p$,然后求出
由此计算出$m$,最后通过Exercise 5的算法求出$e$即可,完整的代码如下:
(load "rsa.scm")
; n, e
; n = pq, m = (p - 1) * (q - 1)
; de = 1 mod m
; n, d
(define (crack-rsa public-key)
(let ((n (key-modulus public-key))
(e (key-exponent public-key)))
(let ((p (smallest-divisor n)))
(let ((q (/ n p)))
(let ((m (* (- p 1) (- q 1))))
(let ((xy (solve-ax+by=1 m e)))
(make-key-pair n (modulo (cdr xy) m))))))))
(define (key-eq? k1 k2)
(and (eq? (car k1) (car k2))
(eq? (cdr k1) (cdr k2))))
(define (test-crack public-key private-key)
(let ((crack-private-key (crack-rsa public-key)))
(cond ((key-eq? crack-private-key private-key)
(newline)
(display "Crack succeed"))
(else (newline) (display "Crack fail")))))
(test-crack test-public-key1 test-private-key1)
(test-crack test-public-key2 test-private-key2)
实验结果:
1 ]=> (test-crack test-public-key1 test-private-key1)
Crack succeed
;Unspecified return value
1 ]=> (test-crack test-public-key2 test-private-key2)
Crack succeed
;Unspecified return value
Exercise 6
代码:
(load "rsa.scm")
(define fake-message "fake message")
(define bill-clinton-private-key (crack-rsa bill-clinton-public-key))
(define al-gore-private-key (crack-rsa al-gore-public-key))
(define encrypt-and-sign-msg (encrypt-and-sign fake-message bill-clinton-private-key al-gore-public-key))
(display encrypt-and-sign-msg)
; message
(define encry-message (rsa-encrypt fake-message al-gore-public-key))
(define decry-message (rsa-decrypt encry-message al-gore-private-key))
(display encry-message)
(display decry-message)
; signature
(define unencry-signature (compress encry-message))
(define unencry-signature-v1 (car (rsa-convert-list (list (cdr encrypt-and-sign-msg)) bill-clinton-public-key)))
(display unencry-signature)
(display unencry-signature-v1)
实验结果:
1 ]=> (display encrypt-and-sign-msg)(fake message . 219078547)
;Unspecified return value
1 ]=> ; message
(define encry-message (rsa-encrypt fake-message al-gore-public-key))
;Value: encry-message
1 ]=> (define decry-message (rsa-decrypt encry-message al-gore-private-key))
;Value: decry-message
1 ]=> (display encry-message)(314791012 219982518 198773833)
;Unspecified return value
1 ]=> (display decry-message)fake message
;Unspecified return value
1 ]=> ; signature
(define unencry-signature (compress encry-message))
;Value: unencry-signature
1 ]=> (define unencry-signature-v1 (car (rsa-convert-list (list (cdr encrypt-and-sign-msg)) bill-clinton-public-key)))
;Value: unencry-signature-v1
1 ]=> (display unencry-signature)196676451
;Unspecified return value
1 ]=> (display unencry-signature-v1)196676451
;Unspecified return value
Exercise 7
同6,略过。
Exercise 8
参考资料:
https://zh.wikipedia.org/wiki/%E8%B3%AA%E6%95%B8%E5%88%97%E8%A1%A8
代码:
(load "rsa.scm")
(define n1 (* 2971 3529))
(define n2 780450379)
(define n3 (* 39916801 479001599))
(display n1)
(display n2)
(display n3)
(timed smallest-divisor n1)
(timed smallest-divisor n2)
(timed smallest-divisor n3)
指数时间复杂度:
1 ]=> (display n1)10484659
;Unspecified return value
1 ]=> (display n2)780450379
;Unspecified return value
1 ]=> (display n3)19120211505964799
;Unspecified return value
1 ]=> (timed smallest-divisor n1)(time: 0.)
;Value: 2971
1 ]=> (timed smallest-divisor n2)(time: 1.0000000000000002e-2)
;Value: 25057
1 ]=> (timed smallest-divisor n3)(time: 17.86)
;Value: 39916801
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere