C++ Bizzare在RSA montgomery乘法的不同MWR2MM算法中得出相同的错误结果 背景
我正在尝试使用各种不同的蒙哥马利方法在硬件(xilinx ZYNQ FPGA)中实现RSA 2048。我使用Xilinx HLS(基本上是C++代码,被合成为硬件)来实现算法。p> < P>注意:为了这个帖子,把它当作标准C++实现,除了我可以有一些变量,这些变量像位向量一样宽4096位,使用C++ Bizzare在RSA montgomery乘法的不同MWR2MM算法中得出相同的错误结果 背景,c++,algorithm,cryptography,rsa,montgomery-multiplication,C++,Algorithm,Cryptography,Rsa,Montgomery Multiplication,我正在尝试使用各种不同的蒙哥马利方法在硬件(xilinx ZYNQ FPGA)中实现RSA 2048。我使用Xilinx HLS(基本上是C++代码,被合成为硬件)来实现算法。p> < P>注意:为了这个帖子,把它当作标准C++实现,除了我可以有一些变量,这些变量像位向量一样宽4096位,使用 Fo[BIT] < /COD>或Fo.Real[7/0 ] 语法访问各个位。我还没有并行化它,所以它应该像标准C++代码一样运行。请不要害怕,停止阅读,因为我说了FPGA和HLS这个词。只需将此处理为C+
- S是部分和
- M是模量
- Y是被乘数
- X是乘法器,X_i(下标)是单个位(例如X=(X_n,…,X_1,X_0)
- 上标是单词向量(例如M=(0,M^{e-1},…,M^1,M^0)
- (A,B)是两个位向量的串联
- m是操作数宽度
- w是所选单词的宽度
- e是完成向量所需的w位字数(例如e=ceil((m+1)/w))
MWR2MM\u m=2048(操作数大小,从上方开始为m)
MWR2MM_w=8(字号,从上往下看)
MWR2MM_e=ceil((e+1)/w)=257(每个操作数的字数+1,从上面开始的e)
是如何在HLS中声明位向量的ap\u uint
void mwr2mm_csa( ap_uint<MWR2MM_m> X,
ap_uint<MWR2MM_w> Y[MWR2MM_e+1],
ap_uint<MWR2MM_w> M[MWR2MM_e+1],
ap_uint<MWR2MM_m> *out)
{
// Declare and zero partial sum S
ap_uint<MWR2MM_w> S[MWR2MM_e] = 0;
for (int i=0; i<MWR2MM_e; i++)
S[i] = 0;
// Two Carry bits
ap_uint<1> Ca=0, Cb=0;
for (int i=0; i<MWR2MM_m; i++)
{
(Ca,S[0]) = X[i]*Y[0] + S[0]; // this is how HLS concatenates vectors, just like in the paper!
if (S[0][0] == 1) // if the 0th bit of the 0th word is 1
{
(Cb,S[0]) = S[0] + M[0];
for (int j=1; j<=MWR2MM_e; j++)
{
(Ca, S[j]) = Ca + X[i]*Y[j] + S[j];
(Cb, S[j]) = Cb + M[j] + S[j];
S[j-1] = ( S[j][0], S[j-1].range(MWR2MM_w-1,1) );
}
}
else
{
for (int j=1; j<=MWR2MM_e; j++)
{
(Ca, S[j]) = Ca + X[i]*Y[j] + S[j];
S[j-1] = ( S[j][0], S[j-1].range(MWR2MM_w-1,1) );
}
}
}
// copy the result to the output pointer
for (int i=0; i<MWR2MM_e-1; i++)
out->range(MWR2MM_w*i+(MWR2MM_w-1), MWR2MM_w*i) = S[i].to_uchar();
}
但是,我的算法返回
MWR2MM_csa(X,Y,M) = 0x16C27CBC37C109B048B0F8B860C3501DB2E90F07D9BF9F6A63839453AC6603776C8CBD7AE8974544C52F078AD035AF1AC58CBBD5DB5801CDF3CF876C43F29FC1719ADF46804928D8BB621FCD48988160602C47812299603181FD97AEC74B7BE563EA0B0CB9EC9B2559191D8EE6AE8092FF9E50ADC1B874BC40C9256D785A4920DC1C1A5DF2B8492B181D16841EEA5377524BDF9BCC8A6DC3919DD4FDF6BBD7BB9D8FC35D06D7A4135363A2AA7FA6AE43B335A2704B007E405731A0D5D352EF7C51AD58241D201E07FA86AA395BB8F5AB3C9B966D5DB966777B45FE47B1838B97AFED23907D7AF61CF809D0B934FC3899998BFEF5B11516CA76C62D999CED8840
例2
好的,那么可能这个实现是错误的。让我们尝试另一个修改版本,MWR2MM_CPA算法(以硬件中使用的进位推进加法器命名):
以及我对MWR2M_CSA的实施:
void mwr2mm_cpa(rsaSize_t X, rsaSize_t Yin, rsaSize_t Min, rsaSize_t* out)
{
// extend operands to 2 extra words longer
ap_uint<MWR2MM_m+2*MWR2MM_w> Y = Yin;
ap_uint<MWR2MM_m+2*MWR2MM_w> M = Min;
ap_uint<MWR2MM_m+2*MWR2MM_w> S = 0;
ap_uint<2> C = 0;
bit_t qi = 0;
// unlike the previous example, we store the concatenations in a temporary variable
ap_uint<10> temp_concat=0;
for (int i=0; i<MWR2MM_m; i++)
{
qi = (X[i]*Y[0]) xor S[0];
// C gets top two bits of temp_concat, j'th word of S gets bottom 8 bits of temp_concat
temp_concat = X[i]*Y.range(MWR2MM_w-1,0) + qi*M.range(MWR2MM_w-1,0) + S.range(MWR2MM_w-1,0);
C = temp_concat.range(9,8);
S.range(MWR2MM_w-1,0) = temp_concat.range(7,0);
for (int j=1; j<=MWR2MM_e; j++)
{
temp_concat = C + X[i]*Y.range(MWR2MM_w*j+(MWR2MM_w-1), MWR2MM_w*j) + qi*M.range(MWR2MM_w*j+(MWR2MM_w-1), MWR2MM_w*j) + S.range(MWR2MM_w*j+(MWR2MM_w-1), MWR2MM_w*j);
C = temp_concat.range(9,8);
S.range(MWR2MM_w*j+(MWR2MM_w-1), MWR2MM_w*j) = temp_concat.range(7,0);
S.range(MWR2MM_w*(j-1)+(MWR2MM_w-1), MWR2MM_w*(j-1)) = (S.bit(MWR2MM_w*j), S.range( MWR2MM_w*(j-1)+(MWR2MM_w-1), MWR2MM_w*(j-1)+1));
}
S.range(S.length()-1, S.length()-MWR2MM_w) = 0;
C=0;
}
*out = S;
为简洁起见,我将不使用另外两种也返回相同错误结果的算法。我应该注意,当与4位操作数大小和2位字大小一起使用时,这两种算法都能正确工作。但是,任何其他操作数大小/字大小组合都是不正确的,但对于所有四个不同的位,它们的结果都是相同的-级别实现
我一辈子都搞不懂为什么这四种算法都返回相同的错误结果。我在第一个示例中的代码与tenca koc论文中提出的算法一字不差
我认为MWR2MM算法应该返回与标准基数-2mm算法相同的结果(在蒙哥马利域中)是错误的吗?它们具有相同的基数,因此无论字长如何,结果都应该是相同的。我是否应该不能相互交换这些算法
很抱歉,这篇文章太长了,但我想非常准确和连贯地解释问题所在。我不是在寻求调试代码的帮助,而是想弄清楚我是否误解了蒙哥马利乘法算法的一个基本功能。我也很好奇为什么要使用不同的实现g相同的错误的结果
谢谢!问题是您的算法实际上返回:
0x116c27cbc37...
^
它大于M。如果你从中减去M,你会得到预期的答案:
这两种算法都返回0到2*M的值,因此如果答案大于或等于M,则需要最后的减法阶段
换句话说,如果你用随机选择的X和Y测试你的算法,你会发现有一半的时间它给出了正确的答案
本文第2节:
因此,只需一次条件减法即可使S[n]达到所需的范围0≤ S[n]你确定你的e值是正确的吗?如果257个字的宽度是4,那么总共会有257*4=1028位,这就更少了
MWR2MM_cpa(X,Y,M) = 0x16C27CBC37C109B048B0F8B860C3501DB2E90F07D9BF9F6A63839453AC6603776C8CBD7AE8974544C52F078AD035AF1AC58CBBD5DB5801CDF3CF876C43F29FC1719ADF46804928D8BB621FCD48988160602C47812299603181FD97AEC74B7BE563EA0B0CB9EC9B2559191D8EE6AE8092FF9E50ADC1B874BC40C9256D785A4920DC1C1A5DF2B8492B181D16841EEA5377524BDF9BCC8A6DC3919DD4FDF6BBD7BB9D8FC35D06D7A4135363A2AA7FA6AE43B335A2704B007E405731A0D5D352EF7C51AD58241D201E07FA86AA395BB8F5AB3C9B966D5DB966777B45FE47B1838B97AFED23907D7AF61CF809D0B934FC3899998BFEF5B11516CA76C62D999CED8840
0x116c27cbc37...
^