这是可以正常工作的原始PHP函数。
<?php
$const = [
'mod_q' => gmp_init("12341234123412341234"),
'jj_d' => gmp_init("23452345234523452345"),
'base00' => gmp_init("34563456345634563456"),
'base01' => gmp_init("45674567456745674567")];
function retc($key_bin, $mod_q_bin, $base){
global $const;
$ret0 = 0;
$ret1 = 1;
foreach(str_split($key_bin) as $c){
for($j = 0; $j <= $c; $j++){
$u2 = ($j == 1) ? $const["base{$base}0"] : $ret0;
$v2 = ($j == 1) ? $const["base{$base}1"] : $ret1;
$x = gmp_mod(gmp_mul($ret1, $v2), $const['mod_q']);
$y = gmp_mod(gmp_mul($const['jj_d'], gmp_mod(gmp_mul($ret0, gmp_mod(gmp_mul($u2, $x), $const['mod_q'])), $const['mod_q'])), $const['mod_q']);
$u3 = 1;
$v3 = 1;
foreach(str_split($mod_q_bin) as $d) {
$u3 = gmp_mod(gmp_mul($u3, $u3), $const['mod_q']);
$v3 = gmp_mod(gmp_mul($v3, $v3), $const['mod_q']);
if ($d == 1){
$u3 = gmp_mod(gmp_mul($u3, gmp_mod(gmp_add(1, $y), $const['mod_q'])), $const['mod_q']);
$v3 = gmp_mod(gmp_mul($v3, gmp_mod(gmp_sub(1, $y), $const['mod_q'])), $const['mod_q']);
}
}
$u3 = gmp_mod(gmp_mul(gmp_mod(gmp_add(gmp_mod(gmp_mul($ret0, $v2), $const['mod_q']), gmp_mod(gmp_mul($ret1, $u2), $const['mod_q'])), $const['mod_q']), $u3), $const['mod_q']);
$ret1 = gmp_mod(gmp_mul(gmp_mod(gmp_sub($x, gmp_mod(gmp_mul(-1, gmp_mod(gmp_mul($ret0, $u2), $const['mod_q'])), $const['mod_q'])), $const['mod_q']), $v3), $const['mod_q']);
$ret0 = $u3;
}
}
return [$ret0, $ret1];
}
这是一个Javascript函数(除了为全局常量使用不同的变量名外)在功能上相同,但是存在错误。
const params = {
mod_q : 12341234123412341234n,
jj_d : 23452345234523452345n,
base : [[34563456345634563456n,
45674567456745674567n]]};
function retc(key_bin, mod_q_bin, base){
var ret = [0n, 1n];
for(jj = 0; jj < key_bin.length; jj++){
for(j = 0; j <= key_bin[jj]; j++){
uv2 = ret;
if(j == 1) uv2 = params['base'][base];
x = (ret[1] * uv2[1]) % params['mod_q'];
var y = (params['jj_d'] * ((ret[0] * ((uv2[0] * x) % params['mod_q'])) % params['mod_q'])) % params['mod_q'];
var uv = [1n, 1n];
for(var ii = 0; ii < mod_q_bin.length; ii++){
uv[0] = (uv[0] ** 2n) % params['mod_q'];
uv[1] = (uv[1] ** 2n) % params['mod_q'];
if(mod_q_bin[ii] == '1'){
uv[0] = (uv[0] * ((1n + y) % params['mod_q'])) % params['mod_q'];
uv[1] = (uv[1] * ((1n - y) % params['mod_q'])) % params['mod_q'];
}
}
uv[0] = (((((ret[0] * uv2[1]) % params['mod_q']) + ((ret[1] * uv2[0]) % params['mod_q'])) % params['mod_q']) * uv[0]) % params['mod_q'];
ret[1] = (((x - ((-1n * ((ret[0] * uv2[0]) % params['mod_q'])) % params['mod_q'])) % params['mod_q']) * uv[1]) % params['mod_q'];
ret[0] = uv[0];
}
}
return ret;
}
要运行这两个代码段,请调用一个示例函数;输出应相同:
retc('0000110011000001000111001100110011100101000101100001101100110110111110100001010111111101110000101011000101000001110000101111110001010011101100111001111100111000100110111110101011110110100101001100100000010011011010010111110111101001011011100100001100101110', '0111001111101101101001110101001100101001100111010111110101001000001100110011100111011000000010000000100110100001110110000000010101010011101111011010010000000010111111111111111001011011111111101111111111111111111111111111111011111111111111111111111111111111', 0);
这个特定示例的PHP函数返回正确的[2960296029602960296, 4530453045304530453]
,而Javascript函数返回错误的[-9380938093809380938, -7810781078107810781]
。
我不确定我是否只是不了解其背后的数学原理,但一直在尝试修复它而没有运气,因此感谢任何帮助。