Utils.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <?php
  2. namespace Elliptic;
  3. use \Exception;
  4. use BN\BN;
  5. if (!function_exists("random_int")) {
  6. function random_int($a, $b) {
  7. return rand($a, $b);
  8. }
  9. }
  10. class Utils
  11. {
  12. public static $ASSERT_ENABLED;
  13. public static function toArray($msg, $enc = false)
  14. {
  15. if( is_array($msg) )
  16. return array_slice($msg, 0);
  17. if( !$msg )
  18. return array();
  19. if( !is_string($msg) )
  20. throw new Exception("Not implemented");
  21. if( !$enc )
  22. return array_slice(unpack("C*", $msg), 0);
  23. if( $enc === "hex" )
  24. return array_slice(unpack("C*", hex2bin($msg)), 0);
  25. return $msg;
  26. }
  27. public static function toHex($msg)
  28. {
  29. if( is_string($msg) )
  30. return bin2hex($msg);
  31. if( !is_array($msg) )
  32. throw new Exception("Not implemented");
  33. $binary = call_user_func_array("pack", array_merge(["C*"], $msg));
  34. return bin2hex($binary);
  35. }
  36. public static function toBin($msg, $enc = false)
  37. {
  38. if( is_array($msg) )
  39. return call_user_func_array("pack", array_merge(["C*"], $msg));
  40. if( $enc === "hex" )
  41. return hex2bin($msg);
  42. return $msg;
  43. }
  44. public static function encode($arr, $enc)
  45. {
  46. if( $enc === "hex" )
  47. return self::toHex($arr);
  48. return $arr;
  49. }
  50. // Represent num in a w-NAF form
  51. public static function getNAF($num, $w)
  52. {
  53. $naf = array();
  54. $ws = 1 << ($w + 1);
  55. $k = clone($num);
  56. while( $k->cmpn(1) >= 0 )
  57. {
  58. if( !$k->isOdd() )
  59. array_push($naf, 0);
  60. else
  61. {
  62. $mod = $k->andln($ws - 1);
  63. $z = $mod;
  64. if( $mod > (($ws >> 1) - 1))
  65. $z = ($ws >> 1) - $mod;
  66. $k->isubn($z);
  67. array_push($naf, $z);
  68. }
  69. // Optimization, shift by word if possible
  70. $shift = (!$k->isZero() && $k->andln($ws - 1) === 0) ? ($w + 1) : 1;
  71. for($i = 1; $i < $shift; $i++)
  72. array_push($naf, 0);
  73. $k->iushrn($shift);
  74. }
  75. return $naf;
  76. }
  77. // Represent k1, k2 in a Joint Sparse Form
  78. public static function getJSF($k1, $k2)
  79. {
  80. $jsf = array( array(), array() );
  81. $k1 = $k1->_clone();
  82. $k2 = $k2->_clone();
  83. $d1 = 0;
  84. $d2 = 0;
  85. while( $k1->cmpn(-$d1) > 0 || $k2->cmpn(-$d2) > 0 )
  86. {
  87. // First phase
  88. $m14 = ($k1->andln(3) + $d1) & 3;
  89. $m24 = ($k2->andln(3) + $d2) & 3;
  90. if( $m14 === 3 )
  91. $m14 = -1;
  92. if( $m24 === 3 )
  93. $m24 = -1;
  94. $u1 = 0;
  95. if( ($m14 & 1) !== 0 )
  96. {
  97. $m8 = ($k1->andln(7) + $d1) & 7;
  98. $u1 = ( ($m8 === 3 || $m8 === 5) && $m24 === 2 ) ? -$m14 : $m14;
  99. }
  100. array_push($jsf[0], $u1);
  101. $u2 = 0;
  102. if( ($m24 & 1) !== 0 )
  103. {
  104. $m8 = ($k2->andln(7) + $d2) & 7;
  105. $u2 = ( ($m8 === 3 || $m8 === 5) && $m14 === 2 ) ? -$m24 : $m24;
  106. }
  107. array_push($jsf[1], $u2);
  108. // Second phase
  109. if( (2 * $d1) === ($u1 + 1) )
  110. $d1 = 1 - $d1;
  111. if( (2 * $d2) === ($u2 + 1) )
  112. $d2 = 1 - $d2;
  113. $k1->iushrn(1);
  114. $k2->iushrn(1);
  115. }
  116. return $jsf;
  117. }
  118. public static function intFromLE($bytes) {
  119. return new BN($bytes, 'hex', 'le');
  120. }
  121. public static function parseBytes($bytes) {
  122. if (is_string($bytes))
  123. return self::toArray($bytes, 'hex');
  124. return $bytes;
  125. }
  126. public static function randBytes($count)
  127. {
  128. $res = "";
  129. for($i = 0; $i < $count; $i++)
  130. $res .= chr(random_int(0, 255));
  131. return $res;
  132. }
  133. public static function optionAssert(&$array, $key, $value = false, $required = false)
  134. {
  135. if( isset($array[$key]) )
  136. return;
  137. if( $required )
  138. throw new Exception("Missing option " . $key);
  139. $array[$key] = $value;
  140. }
  141. }
  142. Utils::$ASSERT_ENABLED = ini_get("zend.assertions") === "1";
  143. ?>