其實在RSA裡面藏了很多很多的困難,一般來說AES、DES、RC5其實寫程式都沒說很困難。
但RSA中有些東西就真的很困難了。
上一次我們提到幾個點:
當 RSA 的位元數 1024、2048、4096,這樣的級別的時候,一般的質數掃描法,幾乎就沒有用了。
因此用一般的方式幾乎沒有辦法處理,必需要使用特定的算法。
而這些算法上我希望能大大家完成自己的RSA系統。
畢竟我們都是工程師,工程師除了用之外,有的時候還要知道一下內部的處理方式。
有些東西就能在必要的時後拆出來用。
好,廢話不多說,接下來將會分幾天提到:
那我們先從質數類開始吧~~
我們簡單地來說明一下數學上的原理好了,這樣才能把程式寫出來。
得先知道一個數學上的定理:
n=7
7-1 = 6 = 2^1*3
s = 1
d = 3
更詳細的數學我會放在補充資料。
我們簡單地來算一下:
n = 601
n-1 = 600 = 2^3 * 75
可得 s = 3 , d = 75
取任意數為 a 跟 0<=r<=s-1。
a = 212
這邊大家可能要知道一下模算數的運算法則。
兩者之間,有一則滿足,要就是 601 是質數,要不然就是 212 是「強偽證」。
手算完之後,我們將這東西寫成程式。
想必大家應該心裡有底了。
那我們在判斷質數之前,我們先做幾個加速的程式:
def test_prime_in_100(n: int) -> bool:
prime_list = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37,
41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
for i in prime_list:
if n % i == 0:
return True
else:
return False
def convert_n_to_sd(n: int) -> Tuple[int, int]:
# n-1 convert to (2^s)*d
s = 0
d = n - 1
while True:
quotient, remainder = divmod(d, 2)
if remainder == 1:
return s, d
s += 1
d = quotient
def test_prime_in_miller_rabin(a: int, d: int, n: int, s: int):
if pow(a, d, n) == 1:
return False
for i in range(s):
if pow(a, 2**i*d, n) == n-1:
return False
return True
def is_prime_of_miller_rabin_test(n: int, trials_time: int = 5) -> bool:
if test_prime_in_100(n):
return False
s, d = convert_n_to_sd(n)
for _ in range(trials_time):
a = random.randint(100, n)
if test_prime_in_miller_rabin(a, d, n, s):
return False
return True
def get_prime(lens: int = 30):
while True:
prime = random.randint(10**(lens-1), 10**lens-1)
if len(str(prime)) != lens:
continue
elif prime&1 == 0:
prime += 1
if is_prime_of_miller_rabin_test(prime):
return prime
def main():
print(get_prime(100))
從這邊看來,Miller Rabin速度很快,正確率也很高。
但!Miller Rabin的測試最終還是有機率的問題,因此接下來要介紹一個跟機率沒關係的。
並非使用猜想的方法:AKS質數測試。
最後,其實Miller Rabin也十分好用了。
沒想到寫個已經很麻煩的文章還要看數學,還要寫程式。
好累阿~~~
我明明看到好多人參加比賽,但為什麼大家都還沒開賽?
難道是!存稿!說實話,寫這個好累,好懶得寫阿~