请教RSA加密中大数运算中蒙哥马利算法

zxphxh 2013-12-01 08:34:03
从网上找了一些资料,可是看了蒙哥马利算法还是不清楚整个过程,请教一下这个算法的原理,望高手赐教!
...全文
454 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zxphxh 2013-12-02
  • 打赏
  • 举报
回复
引用 6 楼 zhiji 的回复:
我发现不会 数论 写这算法还是算了吧. 写出来了还是慢的没法用. 劝楼主找现成的 库 吧.
不是找现成的,我现在学习这个算法。慢不是问题,而是算法原理还没有理解。
zhiji 2013-12-02
  • 打赏
  • 举报
回复
我发现不会 数论 写这算法还是算了吧. 写出来了还是慢的没法用. 劝楼主找现成的 库 吧.
zxphxh 2013-12-02
  • 打赏
  • 举报
回复
以下我是根据网上的资料写的代码,可是执行总是不正确,找不到原因在哪,我仔细看了看算法,也看不出来错误的地方,哪位大侠帮助指点一下迷津?在下不胜感激! #include <iostream> #include <stdio.h> #include <stdlib.h> #include <conio.h> using namespace std; //----------------------------------------------------------------------------- #define DATA unsigned int #define r_BASE 10 // 10进制 #define vlong __int64 //----------------------------------------------------------------------------- long getBits(vlong A); DATA get0Num(vlong A); DATA getNNum(vlong A, long n); unsigned int get2Bits(const vlong N, DATA *A); vlong Pow(vlong A, vlong E); vlong ModInv( const vlong &A, const vlong &N ); //----------------------------------------------------------------------------- /* 返回A的位数 */ long getBits(const vlong A) { long n = 0; vlong X = A; while(X>0){X=X/r_BASE; n++;} return n; } //----------------------------------------------------------------------------- /* 返回A的零位数 */ DATA get0Num(const vlong A) { return A%r_BASE; } //----------------------------------------------------------------------------- /* 返回A的第n位数 */ DATA getNNum(const vlong A, long n) { long i=0; vlong X=A; while(A>0) { if(i==n) return X%r_BASE; else X=X/r_BASE; i++; } return r_BASE; } //----------------------------------------------------------------------------- /* 把r_BASE进制数N转换成2进制数,并数N的2进制下的位数, 2进制用数组A返回,A[0]表示低位,A[n]表示高位 */ unsigned int get2Bits(const vlong N, DATA *A) { long k=0; vlong E=N; while(E>0) { A[k]= E%2; E= E/2; k++; } return k; } //----------------------------------------------------------------------------- /* 求A^E的结果 */ vlong Pow(const vlong A, vlong E) { if (A == 0 || E < 0) return 0; // 0^n = 0 因为整数运算,负幂数运算结果为0 if (E == 0) return 1; // a^0 = 1 vlong t = 1; vlong X = A; while ( E > 0 ) { while ( E % 2 == 0) { X = X * X; E = (E / 2); } t = t * X; E = E - 1; } return t; } //----------------------------------------------------------------------------- /* 用蒙哥马利乘模算法求D=X×Y×r^(-k)%N的值 */ vlong MonPro(vlong X, vlong Y, vlong K, vlong N) { vlong q, D=0, D0, Y0, Yi; long m = getBits(Y); // Y的位数 // 从Y的低位到高位 for(int i=0; i<m; i++) { D0 = get0Num(D); Y0 = get0Num(Y); Yi = getNNum(Y, i); q = (D0 + X * Y0) * K % r_BASE; D = D + X * Yi + q * N; D = D/r_BASE; } if(D>=N) D = D-N; return D; } //----------------------------------------------------------------------------- /* 求A关于模N的逆模 */ vlong ModInv( const vlong &A, const vlong &N ) { vlong d=0, j=1, b=N, c=A, x, y; while ( c != 0 ) { x = b / c; y = b - x*c; b = c; c = y; y = j; j = d - j*x; d = y; } if ( d < 0 ) d += N; return d; } //----------------------------------------------------------------------------- /* 用蒙哥马利幂模算法求 M^E %N的值 */ vlong MonPowMod(vlong M , vlong E, vlong N) { long k = getBits(M); // M的位数 vlong R = Pow(r_BASE, k) % N; // 求R=r^k%N; vlong A = M * R % N; vlong D = R; DATA EA[1024]; // 存放E的二进制数 long t = get2Bits(E, EA); // 把E转换成二进制数,E的位数t vlong N01 = ModInv(get0Num(N), r_BASE); // 求N0关于r的模逆N01 vlong m = r_BASE - N01; for(int i=t-1; i>=0; i--) // 从高位到低位循环 { D = MonPro(D, D, m, N); if(EA[i] == 1) { D = MonPro(A, D, m, N); } } D = MonPro(D, 1, m, N); return D; } //----------------------------------------------------------------------------- int main() { vlong M = 13; vlong E = 11; vlong N = 77; vlong X = MonPowMod(M, E, N); cout<<"\n计算结果:X="<<X; _getch(); } //-----------------------------------------------------------------------------
zxphxh 2013-12-01
  • 打赏
  • 举报
回复
以下是我写的部分代码,不知道错误在哪里,计算结果不正确。 其中vlong是大数表示,A[0]表示vlong的最高位 A[Len-1]表示vlong的个位。 #define r_BASE 10 // 10进制 #define DATATYPE long /* 用蒙哥马利乘模算法求C=A×B×r^(-k)%N的值 */ vlong MonPro(vlong X, vlong Y, vlong K, vlong N) { vlong D = 0; vlong q; DATATYPE D0, Y0; long m = Y.GetLen();// Y的位数 // 从低位到高位 for(int i=m-1; i>=0; i--) { D0 = D[D.GetLen()-1]; Y0 = Y[Y.GetLen()-1]; q = (D0 + X * Y0) * K % r_BASE; D = D + X * Y[i] + q * N; D = D>>1; // 相当于 D= D/r_BASE; } if(D>=N) D= D-N; return D; } /* 用蒙哥马利幂模算法求 M^E %N的值 */ vlong MonPowMod(vlong M , vlong E, vlong N) { long k = M.GetLen(); // M的位数 vlong R = Power(r_BASE, k)%N; // 求R=r^k%N; vlong A = M * R % N; vlong D = R; E=E.Conver(2); // 把E转换成二进制数 long t = E.GetLen(); //E的位数 // 求N0的模逆 vlong N01 = ModInv(N[N.GetLen()-1], r_BASE); vlong m = r_BASE - N01; for(int i=0; i<t; i++) // 从高位到低位循环 { D = MonPro(D, D, m, N); if(E[i] == 1) { D = MonPro(A, D, m, N); } } D = MonPro(D, 1, m, N); return D; } int main() { vlong M = 13; vlong E = 5; vlong N = 77; vlong X = MonPowMod(M, E, N); X.ShowData("计算结果:X="); _getch(); } 最后的输出结果X=19 而13^5%77=371293%77=76
worldy 2013-12-01
  • 打赏
  • 举报
回复
http://wenku.baidu.com/link?url=AzPO6BJcgqUlgpXZjpuV0OO7ACvkus1Jzp-aIgFy7FR29nO3Sz70QbXhh3-2D3xZX6a-XAW6Vo1Zz90kkwPkTAb56Pa0sHHmv9Ozw20pb0O
zxphxh 2013-12-01
  • 打赏
  • 举报
回复
引用 2 楼 max_min_ 的回复:
http://www.cnblogs.com/zhtxwd/archive/2012/02/09/2344165.html 参考下
这个算法也看过了,就是有几个地方不懂: (1)语句A'=A*R %N 这中的R=2^k%N 请问k指的是什么如何求?求的? (2)语句X=A' 我认为应该是X=R,这样才能推出A^E%N。是不是这样呢?

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧