goldrat/vendor/simplito/elliptic-php/lib/Utils.php
2025-10-09 17:41:57 +00:00

177 lines
4.2 KiB
PHP

<?php
namespace Elliptic;
use \Exception;
use BN\BN;
if (!function_exists("random_int")) {
function random_int($a, $b) {
return rand($a, $b);
}
}
class Utils
{
public static $ASSERT_ENABLED;
public static function toArray($msg, $enc = false)
{
if( is_array($msg) )
return array_slice($msg, 0);
if( !$msg )
return array();
if( !is_string($msg) )
throw new Exception("Not implemented");
if( !$enc )
return array_slice(unpack("C*", $msg), 0);
if( $enc === "hex" )
return array_slice(unpack("C*", hex2bin($msg)), 0);
return $msg;
}
public static function toHex($msg)
{
if( is_string($msg) )
return bin2hex($msg);
if( !is_array($msg) )
throw new Exception("Not implemented");
$binary = call_user_func_array("pack", array_merge(["C*"], $msg));
return bin2hex($binary);
}
public static function toBin($msg, $enc = false)
{
if( is_array($msg) )
return call_user_func_array("pack", array_merge(["C*"], $msg));
if( $enc === "hex" )
return hex2bin($msg);
return $msg;
}
public static function encode($arr, $enc)
{
if( $enc === "hex" )
return self::toHex($arr);
return $arr;
}
// Represent num in a w-NAF form
public static function getNAF($num, $w)
{
$naf = array();
$ws = 1 << ($w + 1);
$k = clone($num);
while( $k->cmpn(1) >= 0 )
{
if( !$k->isOdd() )
array_push($naf, 0);
else
{
$mod = $k->andln($ws - 1);
$z = $mod;
if( $mod > (($ws >> 1) - 1))
$z = ($ws >> 1) - $mod;
$k->isubn($z);
array_push($naf, $z);
}
// Optimization, shift by word if possible
$shift = (!$k->isZero() && $k->andln($ws - 1) === 0) ? ($w + 1) : 1;
for($i = 1; $i < $shift; $i++)
array_push($naf, 0);
$k->iushrn($shift);
}
return $naf;
}
// Represent k1, k2 in a Joint Sparse Form
public static function getJSF($k1, $k2)
{
$jsf = array( array(), array() );
$k1 = $k1->_clone();
$k2 = $k2->_clone();
$d1 = 0;
$d2 = 0;
while( $k1->cmpn(-$d1) > 0 || $k2->cmpn(-$d2) > 0 )
{
// First phase
$m14 = ($k1->andln(3) + $d1) & 3;
$m24 = ($k2->andln(3) + $d2) & 3;
if( $m14 === 3 )
$m14 = -1;
if( $m24 === 3 )
$m24 = -1;
$u1 = 0;
if( ($m14 & 1) !== 0 )
{
$m8 = ($k1->andln(7) + $d1) & 7;
$u1 = ( ($m8 === 3 || $m8 === 5) && $m24 === 2 ) ? -$m14 : $m14;
}
array_push($jsf[0], $u1);
$u2 = 0;
if( ($m24 & 1) !== 0 )
{
$m8 = ($k2->andln(7) + $d2) & 7;
$u2 = ( ($m8 === 3 || $m8 === 5) && $m14 === 2 ) ? -$m24 : $m24;
}
array_push($jsf[1], $u2);
// Second phase
if( (2 * $d1) === ($u1 + 1) )
$d1 = 1 - $d1;
if( (2 * $d2) === ($u2 + 1) )
$d2 = 1 - $d2;
$k1->iushrn(1);
$k2->iushrn(1);
}
return $jsf;
}
public static function intFromLE($bytes) {
return new BN($bytes, 'hex', 'le');
}
public static function parseBytes($bytes) {
if (is_string($bytes))
return self::toArray($bytes, 'hex');
return $bytes;
}
public static function randBytes($count)
{
$res = "";
for($i = 0; $i < $count; $i++)
$res .= chr(random_int(0, 255));
return $res;
}
public static function optionAssert(&$array, $key, $value = false, $required = false)
{
if( isset($array[$key]) )
return;
if( $required )
throw new Exception("Missing option " . $key);
$array[$key] = $value;
}
}
Utils::$ASSERT_ENABLED = ini_get("zend.assertions") === "1";
?>