标题:请大侠帮忙:RSA加密算法
只看楼主
Kabie
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:69
专家分:185
注 册:2009-8-21
得分:10 
1:int是存不下RSA用的质数的……RSA的强度完全取决于p和q的位数……32位整数很快就会被破解了……当然你只为了研究算法就无所谓了。。。
2:a≡c^d(mod n)应当用一些数学方法计算而不是强求c^d……

如果你只为测试RSA算法……不想自己写大数计算的话……可以直接选取小素数……这样n可以用int来存储……
或者使用现有的大数计算库……
2010-12-01 15:09
Crocodile_JX
Rank: 5Rank: 5
等 级:职业侠客
帖 子:161
专家分:335
注 册:2010-9-13
得分:0 
回复 21楼 Kabie
unsigned long high_exp(unsigned long c,unsigned long d,unsigned long n) /*计算a 满足 a≡c^d(mod n)*/
{
  unsigned long e,f;
  f=c%n;
  while(d!=1)
  {
    e=c*f;
    f=e%n;
    d--;
  }
  return f;
}
这个是我的朋友给我的代码。他不解释,让我自己去折磨。都没有看明白呢。数学不好啊。其实我想弄明白如何才可以满足大数计算的
2010-12-01 16:27
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:0 
你去查查 “同余” 相关的理论,讲的多和这方面相关。

以前虽然稍微研究过一点加密相关的东西,但学得不深。看题目还以为 100 分没什么分得的机会呢。結果,冒的全是数学问题,呵,分有的接了~~

[ 本帖最后由 pangding 于 2010-12-1 17:20 编辑 ]
2010-12-01 16:55
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:40 
稍微推导了一下。

我用 ~ 来代替 ≡。
有个重要的定理,是说如果 a ~ b (mod m) 则 a^n ~ b^n (mod m)。
这个很好证:
由因式分解易知 (a-b)|(a^n - b^n),所以 m | (a-b) => m | (a^n-b^n) 定理得证。

下面来看你朋友的算法。
由第一步:f ~ c (mod n)
所以只要求 f^d 则必有 f^d ~ c^d (mod n)
而实际上,f^d 也不用求,只要能求 f^d % n 就行了。
c = kn + f
e = cf = knf + f^2
e % n = f^2 % n
这就得到了 f^2 % n,往后继续迭代出 f^d % n 就行了。
2010-12-01 17:17
Crocodile_JX
Rank: 5Rank: 5
等 级:职业侠客
帖 子:161
专家分:335
注 册:2010-9-13
得分:0 
回复 24楼 pangding
所以只要求 f^d 则必有 f^d ~ c^d (mod n)
而实际上,f^d 也不用求,只要能求 f^d % n 就行了。/*这一步为什么可以这样呢*/
c = kn + f  /*这一步也看不懂呢...嘻嘻。。。请大侠再说详细一点吧。我的数学领悟能力太差!谢谢哦~*/
e = cf = knf + f^2
e % n = f^2 % n
这就得到了 f^2 % n,往后继续迭代出 f^d % n 就行了。
2010-12-01 22:12
Crocodile_JX
Rank: 5Rank: 5
等 级:职业侠客
帖 子:161
专家分:335
注 册:2010-9-13
得分:0 
所以只要求 f^d 则必有 f^d ~ c^d (mod n)
而实际上,f^d 也不用求,只要能求 f^d % n 就行了。/*这一步为什么可以这样呢,还没有看懂*/
c = kn + f  /*这一步看懂了...嘻嘻。。。~*/
e = cf = knf + f^2
e % n = f^2 % n
这就得到了 f^2 % n,往后继续迭代出 f^d % n 就行了。
2010-12-01 23:23
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
得分:0 
回复 26楼 Crocodile_JX
那天说的是不太清楚,我又整理了一下思路。

可不可以把 “计算出满足 a ~ c^d(mod n) 的 a”理解成求 (c^d)%n 的值?
我当时就是这么理解的,因为和 c^d 关于模 n 同余的数非常多,但是介于 0 ~ n-1 之内的就只有一个,这个数就是 (c^d)%n 。

现在说怎么求 (c^d)%n。直接求 c^d 肯定会溢出,所以得换种求法。
假设已知 [c^(d-1)]%n = f,问能不能利用 f 求 (c^d)%n?方法如下:
因为 [c^(d-1)]%n = f,就是说 c^(d-1) 除以 n 的余数是 f。假设商是 k,那么根据带余除法:
c^(d-1) = kn + f。
于是:
c^d = c * c^(d-1) = ckn + cf。
现在要求 (c^d)%n,ckn 必是 n 的倍数。所以 c^d 与 cf 同余。
即 (c^d) % n = cf % n。

现在就可以往回推了,想求 [c^(d-1)]%n 就要求 [c^(d-2)]%n,……
最后是 c % n,这就是 f 的初始值。

其实就是说,在求 c^d 次方时,不是一直乘,而是每次乘完都取一次模,就可以在不溢出的情况下求出 c^d%n。这么解释是不是清楚一点?
所以我感觉代码写成下面这样可能可读性更好一点,它更像是表示每次乘完后取模:
程序代码:
f = 1;
while (--d) {
    f = f * c % n;
}



不过严格来看,还有几个值得商榷的问题。咱们这么算是为了避免计算 c^d 时溢出,但这么算会不会溢出呢?
做除法肯定没问题,主要是关心乘法。c*f 会不会溢出(就是超过 2^32)?
这里 f 是介于 0 ~ n-1 之间的一个数。可以认为它相对较小,但当 c 很大时,它还是有可能溢出。不过由于 c, f 都是小于32次方的,所以它们的积不会超过64次方。如果 e 用 long long 表示的话,就不用担心溢出了。
另一种想法是,可不可以先减小 c 的值,比如先把 c = c % n 一下?
我感觉可能是可以的。咱先记 c' = c % n,从而 c = ln + c'。
c^d = c*c^(d-1) = c(kn+f) ~ cf = (ln+c')f = lnf + c'f ~ c'f
只看最左一项和最右一项,就是 c^d ~ c'f,所以应该也是可以的。
这样一来 c'*f 肯定是小于 n^2 的,所以如果 n < 2^16 次方,就肯定不会溢出,而不用使用 long long 类型。


呵呵,不过上面说的都是凭空想的,包括给的那个代码也没试过。你可以写几个函数,用用不同的算法,看看实际算出来是不是一样的。理论的主说到底只是一种指导思想而已。

而且这个算法应该还能改进,比如如果知道了 c^2 是不是可以直接去算 c^4,而跳过求 c^3 这步?
我举个例子,c^7 = c^(4+2+1) = c^4 * c^2 * c。
由于同余是一种线性运算,即如果关于模 m,有: a ~ b, c ~ d 则 ac ~ bd。
(证明:由已知: m|(a-b), m|(c-d)。由于:ac-bd = ac-bc+bc-bd = c(a-b)+b(c-d)。从而 m|(ac-bd),即 ac~bd。)
所以事实上只要求出 2的幂次方 的各个同余的結果,最終的結果只要把它们再乘起来就够了。
如果这个方法可行,c^1024 次方,就只用算大约10余次乘法就够了,而不是一千多次。

同样是理论指导一下,具体是否可行,自己还得再推一推。不过要用到的数学技巧应该都在这了。
2010-12-02 19:50
Crocodile_JX
Rank: 5Rank: 5
等 级:职业侠客
帖 子:161
专家分:335
注 册:2010-9-13
得分:0 
回复 27楼 pangding
谢谢...感激不尽啊! 你的数学很好,厉害。
千言万语不知道该怎么谢谢你呢。让我学到了很多很多...谢谢!
2010-12-02 21:00



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-327270-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032503 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved