当在模幂运算算法中使用时,我对如何绕过radix-2 montgomery 模乘中的模的最终减法感到困惑。以下两篇论文提出了绕过减法的条件。
我不明白在“预处理和后处理”方面需要什么来消除在蒙哥马利乘法结束时重复减去模数的需要。
阅读上述论文后,我的理解是,要消除最后的减法,您必须:
将每个输入操作数零扩展为模幂乘二
e.g. new[2049 downto 0] = (0, 0, old[2047 downto 0])
- 将蒙哥马利乘法内的循环边界增加 2,以便执行循环的另外两次迭代
我已经对工作算法进行了这些修改,但是结果与我预期的不一样,我不明白为什么。因此,我认为我误解了这些论文中的某些内容,或者遗漏了关键步骤。
让我们参考(类似 C 的伪代码)中的(工作)基数 2 蒙哥马利模幂函数。请注意,我已将操作数宽度扩展了两个最重要的零位(只是为了确保我没有溢出)。它们过去只有 2048 位。
let NUM_BITS = 2048
let rsaSize_t be a 2050-bit vector type
// Montgomery multiplication: outData = XYr^(-1) modulo M,
// where the radix r=2^n (n=NUM_BITS)
function montMult( rsaSize_t X, // Multiplier
rsaSize_t Y, // Multiplicand
rsaSize_t M, // Modulus
rsaSize_t outData) // Result
{
rsaSize_t S = 0; // Running sum
for (i=0; i<NUM_BITS; i++)
{
if (X.bit(i)==1) // Check ith bit of X
S += Y;
if (S.bit(0)==1) // check LSB of S
S += M;
S = S >> 1; // Rightshift 1 bit
}
// HERE IS THE FINAL SUBTRACTION I WANT (NEED) TO AVOID
if (S >= M)
{
S -= M;
}
outData = S.range(NUM_BITS-1,0);
}
// montgomery modular exponentiation using square and multiply algorithm
// computes M^e modulo n, where we precompute the transformation of the
// base and running-partial sum into the montgomery domain
function rsaModExp( rsaSize_t e, // exponent
rsaSize_t n, // modulus
rsaSize_t Mbar, // precomputed: montgomery residue of the base w.r.t. the radix--> (2^2048)*base mod n
rsaSize_t xbar, // precomputed: montgomery residue of 1 w.r.t. the radix--> 2^2048 mod n
rsaSize_t *out) // result
{
for (i=NUM_BITS-1; i>=0; i--)
{
montMult(xbar, xbar, n, xbar); // square
if (e.bit(i)==1)
montMult(Mbar, xbar, n, xbar); // multiply
}
// undo montgomery transform
montMult(xbar, 1, n, out);
}
我在报纸上遗漏了什么吗?我不认为这是一个实现错误,因为我的代码与论文中提出的完全一致。我相信我可能是一个概念错误。任何和所有的帮助表示赞赏。
谢谢!