这些代码段应该是等效的,这怎么了?

时间:2019-12-27 13:31:22

标签: javascript php

这是可以正常工作的原始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]

我不确定我是否只是不了解其背后的数学原理,但一直在尝试修复它而没有运气,因此感谢任何帮助。

0 个答案:

没有答案