public function testPow()
 {
     $this->assertEquals(gmp_strval(gmp_pow($this->a, $this->a)), $this->math->pow($this->a, $this->a));
     $this->assertEquals(gmp_strval(gmp_pow($this->b, $this->b)), $this->math->pow($this->b, $this->b));
     $this->assertEquals(gmp_strval(gmp_pow($this->c, $this->c)), $this->math->pow($this->c, $this->c));
     $this->assertEquals(1, $this->math->pow(1, 1));
 }
예제 #2
0
 public function testBaseConvertDigits()
 {
     $converter = new BaseConvertConverter(new Base62Symbols());
     $this->assertSame(explode(':', '4:16:12:8:33:15:15:6:34:11:20:0:20:28:32:4:24:0:32:4:12:16:12:28:32'), $converter->convert(gmp_strval(gmp_pow(10, 38), 10), 10, 36));
     $this->assertSame(str_split('100000000000', 1), $converter->convert('100000000000', 10, 10));
     $this->assertSame(explode(':', '3:18:2:10:0:0:0:0:0'), $converter->convert('100000000000', 10, 20));
 }
예제 #3
0
 /**
  * Exponential expression / raise number into power
  *
  * @param string $base         base to raise
  * @param string $exp          exponent to use
  * @param string $use_function pow function to use, or false for auto-detect
  *
  * @return mixed string or float
  */
 public static function pow($base, $exp, $use_function = '')
 {
     static $pow_function = null;
     if ($pow_function == null) {
         $pow_function = self::detectPow();
     }
     if (!$use_function) {
         if ($exp < 0) {
             $use_function = 'pow';
         } else {
             $use_function = $pow_function;
         }
     }
     if ($exp < 0 && $use_function != 'pow') {
         return false;
     }
     switch ($use_function) {
         case 'bcpow':
             // bcscale() needed for testing pow() with base values < 1
             bcscale(10);
             $pow = bcpow($base, $exp);
             break;
         case 'gmp_pow':
             $pow = gmp_strval(gmp_pow($base, $exp));
             break;
         case 'pow':
             $base = (double) $base;
             $exp = (int) $exp;
             $pow = pow($base, $exp);
             break;
         default:
             $pow = $use_function($base, $exp);
     }
     return $pow;
 }
예제 #4
0
 /**
  * Return the modulus, also known as absolute value or magnitude of this number
  * = sqrt(r^2 + i^2);
  *
  * @return \Chippyash\Type\Number\Rational\GMPRationalType
  */
 public function modulus()
 {
     if ($this->isReal()) {
         //sqrt(r^2 + 0^2) = sqrt(r^2) = abs(r)
         /** @noinspection PhpUndefinedMethodInspection */
         return $this->value['real']->abs();
     }
     //get r^2 and i^2
     $sqrR = array('n' => gmp_pow($this->value['real']->numerator()->gmp(), 2), 'd' => gmp_pow($this->value['real']->denominator()->gmp(), 2));
     $sqrI = array('n' => gmp_pow($this->value['imaginary']->numerator()->gmp(), 2), 'd' => gmp_pow($this->value['imaginary']->denominator()->gmp(), 2));
     //r^2 + i^2
     $den = $this->lcm($sqrR['d'], $sqrI['d']);
     $numRaw = gmp_strval(gmp_add(gmp_div_q(gmp_mul($sqrR['n'], $den), $sqrR['d']), gmp_div_q(gmp_mul($sqrI['n'], $den), $sqrI['d'])));
     $num = TypeFactory::createInt($numRaw);
     //sqrt(num/den) = sqrt(num)/sqrt(den)
     //now this a fudge - we ought to be able to get a proper square root using
     //factors etc but what we do instead is to do an approximation by converting
     //to intermediate rationals using as much precision as we can i.e.
     // rNum = GMPRationaType(sqrt(num))
     // rDen = GMPRationalType(sqrt(den))
     // mod = rN/1 * 1/rD
     $rNum = RationalTypeFactory::fromFloat(sqrt($num()));
     $rDen = RationalTypeFactory::fromFloat(sqrt(gmp_strval($den)));
     $modN = gmp_mul($rNum->numerator()->gmp(), $rDen->denominator()->gmp());
     $modD = gmp_mul($rNum->denominator()->gmp(), $rDen->numerator()->gmp());
     return RationalTypeFactory::create((int) gmp_strval($modN), (int) gmp_strval($modD));
 }
예제 #5
0
/**
 * Exponential expression / raise number into power
 *
 * @param string $base         base to raise
 * @param string $exp          exponent to use
 * @param mixed  $use_function pow function to use, or false for auto-detect
 *
 * @return mixed string or float
 */
function PMA_pow($base, $exp, $use_function = false)
{
    static $pow_function = null;
    if (null == $pow_function) {
        $pow_function = PMA_detect_pow();
    }
    if (!$use_function) {
        $use_function = $pow_function;
    }
    if ($exp < 0 && 'pow' != $use_function) {
        return false;
    }
    switch ($use_function) {
        case 'bcpow':
            // bcscale() needed for testing PMA_pow() with base values < 1
            bcscale(10);
            $pow = bcpow($base, $exp);
            break;
        case 'gmp_pow':
            $pow = gmp_strval(gmp_pow($base, $exp));
            break;
        case 'pow':
            $base = (double) $base;
            $exp = (int) $exp;
            $pow = pow($base, $exp);
            break;
        default:
            $pow = $use_function($base, $exp);
    }
    return $pow;
}
예제 #6
0
파일: index.php 프로젝트: baotroy/chal
function sumT($n)
{
    if (gmp_intval($n) == 1) {
        return gmp_init(1);
    }
    return gmp_add(gmp_sub(gmp_pow($n, 2), gmp_pow(gmp_init(gmp_intval($n) - 1), 2)), sumT(gmp_init(gmp_intval($n) - 1)));
    //return gmp_mod(gmp_add(gmp_sub(gmp_mod(gmp_pow($n, 2), '1000000007'), gmp_mod(gmp_pow(gmp_init(gmp_intval($n)-1), 2), '1000000007')), sumT(gmp_init(gmp_intval($n)-1))), '1000000007');
}
예제 #7
0
 private function makeId32($timestamp, $machine, $sequence)
 {
     $timestamp = gmp_mul((string) $timestamp, gmp_pow(2, 22));
     $machine = gmp_mul((string) $machine, gmp_pow(2, 12));
     $sequence = gmp_init((string) $sequence, 10);
     $value = gmp_or(gmp_or($timestamp, $machine), $sequence);
     return gmp_strval($value, 10);
 }
function gmp_shiftr($x, $n)
{
    if ($x < 0) {
        return gmp_strval(gmp_com(gmp_div(gmp_com($x), gmp_pow(2, $n))));
    } else {
        return gmp_strval(gmp_div($x, gmp_pow(2, $n)));
    }
}
예제 #9
0
 private function computeBaseNLength($number, $targetBase)
 {
     $digits = 0;
     while (gmp_cmp($number, gmp_pow($targetBase, $digits)) != -1) {
         $digits++;
     }
     return $digits ?: 1;
 }
예제 #10
0
파일: GCM.php 프로젝트: fpoirotte/pssht
 public static function inc($X, $n)
 {
     $s = gmp_strval($X, 2);
     $s1 = (string) substr($s, 0, -$n);
     $s = gmp_add(gmp_init(substr($s, -$n), 2), 1);
     $s = gmp_mod($s, gmp_pow(2, $n));
     $s2 = str_pad(gmp_strval($s, 2), $n, '0', STR_PAD_LEFT);
     return gmp_init($s1 . $s2, 2);
 }
예제 #11
0
파일: ED25519.php 프로젝트: fpoirotte/pssht
 protected function __construct()
 {
     $this->params['q'] = gmp_sub(gmp_pow(2, 255), 19);
     $this->params['l'] = gmp_add(gmp_pow(2, 252), '27742317777372353535851937790883648493');
     $this->params['d'] = gmp_mul(-121665, $this->inv(121666));
     $this->params['I'] = gmp_powm(2, gmp_div_q(gmp_sub($this->params['q'], 1), 4), $this->params['q']);
     $By = gmp_mul(4, $this->inv(5));
     $Bx = $this->xrecover($By);
     $this->params['B'] = array($Bx, $By);
 }
예제 #12
0
 /**
  * @dataProvider providerTestTAGLong
  */
 public function testPutTAGLong($value)
 {
     $fPtr = fopen($this->vFile->url(), 'wb');
     // 32-bit longs seem to be too long for pack() on 32-bit machines. Split into 4x16-bit instead.
     $quarters[0] = gmp_div(gmp_and($value, '0xFFFF000000000000'), gmp_pow(2, 48));
     $quarters[1] = gmp_div(gmp_and($value, '0x0000FFFF00000000'), gmp_pow(2, 32));
     $quarters[2] = gmp_div(gmp_and($value, '0x00000000FFFF0000'), gmp_pow(2, 16));
     $quarters[3] = gmp_and($value, '0xFFFF');
     $binary = pack('nnnn', gmp_intval($quarters[0]), gmp_intval($quarters[1]), gmp_intval($quarters[2]), gmp_intval($quarters[3]));
     $this->dataHandler->putTAGLong($fPtr, $value);
     $this->assertSame($binary, $this->vFile->getContent());
 }
예제 #13
0
 public function provideNumbase()
 {
     $symbols = '0123456789' . 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . 'abcdefghijklmnopqrstuvwxyz';
     $numbases = array(array(Numbase::createDefault()), array(Numbase::createDefault(new StringSymbols($symbols))), array(Numbase::createDefault(new ArraySymbols(str_split($symbols, 1)))));
     $numbers = array(array(gmp_strval(gmp_pow(10, 9), 10), 10, 1000000000, '10'), array(gmp_strval(gmp_pow(10, 1000), 10), 10, 100, '1' . str_pad('', 500, '0', STR_PAD_RIGHT)), array('10000000000000000000000', 10, 100, '100000000000'), array('15', 10, 16, 'F'), array('zz', 62, 10, '3843'), array('3843', 10, 62, 'zz'), array('-3843', 10, 62, '-zz'), array('100000', 10, 62, 'Q0u'), array('3843', 10, 16, 'F03'), array('65', 10, 2, '1000001'), array('1', 10, 10, '1'), array('0', 16, 2, '0'), array('64000', 10, 32000, '20'));
     $result = array();
     foreach ($numbers as $number) {
         foreach ($numbases as $numbase) {
             $result[] = array_merge($numbase, $number);
         }
     }
     return $result;
 }
예제 #14
0
파일: main.php 프로젝트: AlexanderGrom/knee
function number62_decode($string)
{
    if (preg_match('#^[a-zA-Z0-9]+$#iu', $string) == 0) {
        return 0;
    }
    $out = 0;
    $length = mb_strlen($string);
    $array = array_flip(str_split("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"));
    for ($i = 0; $i < $length; $i++) {
        $out = gmp_add($out, gmp_mul($array[$string[$length - $i - 1]], gmp_pow(62, $i)));
    }
    $out = gmp_strval($out, 10);
    return $out;
}
예제 #15
0
 public function contains($x, $y)
 {
     $eq_zero = null;
     if (extension_loaded('gmp') && USE_EXT == 'GMP') {
         $eq_zero = gmp_cmp(gmp_Utils::gmp_mod2(gmp_sub(gmp_pow($y, 2), gmp_add(gmp_add(gmp_pow($x, 3), gmp_mul($this->a, $x)), $this->b)), $this->prime), 0);
         if ($eq_zero == 0) {
             return true;
         } else {
             return false;
         }
     } else {
         throw new ErrorException("Please install GMP");
     }
 }
function recoverPubKey($r, $s, $e, $recoveryFlags, $G)
{
    $isYEven = ($recoveryFlags & 1) != 0;
    $isSecondKey = ($recoveryFlags & 2) != 0;
    $curve = $G->getCurve();
    $signature = new Signature($r, $s);
    // Precalculate (p + 1) / 4 where p is the field order
    static $p_over_four;
    // XXX just assuming only one curve/prime will be used
    if (!$p_over_four) {
        $p_over_four = gmp_div(gmp_add($curve->getPrime(), 1), 4);
    }
    // 1.1 Compute x
    if (!$isSecondKey) {
        $x = $r;
    } else {
        $x = gmp_add($r, $G->getOrder());
    }
    // 1.3 Convert x to point
    $alpha = gmp_mod(gmp_add(gmp_add(gmp_pow($x, 3), gmp_mul($curve->getA(), $x)), $curve->getB()), $curve->getPrime());
    $beta = NumberTheory::modular_exp($alpha, $p_over_four, $curve->getPrime());
    // If beta is even, but y isn't or vice versa, then convert it,
    // otherwise we're done and y == beta.
    if (isBignumEven($beta) == $isYEven) {
        $y = gmp_sub($curve->getPrime(), $beta);
    } else {
        $y = $beta;
    }
    // 1.4 Check that nR is at infinity (implicitly done in construtor)
    $R = new Point($curve, $x, $y, $G->getOrder());
    $point_negate = function ($p) {
        return new Point($p->curve, $p->x, gmp_neg($p->y), $p->order);
    };
    // 1.6.1 Compute a candidate public key Q = r^-1 (sR - eG)
    $rInv = NumberTheory::inverse_mod($r, $G->getOrder());
    $eGNeg = $point_negate(Point::mul($e, $G));
    $Q = Point::mul($rInv, Point::add(Point::mul($s, $R), $eGNeg));
    // 1.6.2 Test Q as a public key
    $Qk = new PublicKey($G, $Q);
    if ($Qk->verifies($e, $signature)) {
        return $Qk;
    }
    return false;
}
예제 #17
0
/**
 * Exponential expression / raise number into power
 *
 * @uses    function_exists()
 * @uses    bcpow()
 * @uses    gmp_pow()
 * @uses    gmp_strval()
 * @uses    pow()
 * @param   number  $base
 * @param   number  $exp
 * @param   string  pow function use, or false for auto-detect
 * @return  mixed  string or float
 */
function PMA_pow($base, $exp, $use_function = false)
{
    static $pow_function = null;

    if (null == $pow_function) {
        if (function_exists('bcpow')) {
            // BCMath Arbitrary Precision Mathematics Function
            $pow_function = 'bcpow';
        } elseif (function_exists('gmp_pow')) {
            // GMP Function
            $pow_function = 'gmp_pow';
        } else {
            // PHP function
            $pow_function = 'pow';
        }
    }

    if (! $use_function) {
        $use_function = $pow_function;
    }
    if ($exp < 0 && 'pow' != $use_function) {
        return false;
    }

    switch ($use_function) {
        case 'bcpow' :
            // bcscale() needed for testing PMA_pow() with base values < 1
            bcscale(10);
            $pow = bcpow($base, $exp);
            break;
        case 'gmp_pow' :
             $pow = gmp_strval(gmp_pow($base, $exp));
            break;
        case 'pow' :
            $base = (float) $base;
            $exp = (int) $exp;
            $pow = pow($base, $exp);
            break;
        default:
            $pow = $use_function($base, $exp);
    }

    return $pow;
}
예제 #18
0
파일: fungsiRSA.php 프로젝트: senusop/ci
function deskripsi($chiper, $d, $n)
{
    $time_start = microtime(true);
    //Pesan Enkripsi dipecah menjadi array dengan batasan "+"
    $hasildekrip = '';
    $hasil = '';
    $dekrip = explode(" ", $chiper);
    foreach ($dekrip as $nilai) {
        //Rumus Deskripsi ---> PlainTeks = <enkripsi>^<d>mod<n>
        $gm1 = gmp_pow($nilai, gmp_strval($d));
        $gm2 = gmp_mod($gm1, $n);
        $gm3 = gmp_strval($gm2);
        $hasildekrip .= chr($gm3);
    }
    $time_end = microtime(true);
    // Waktu Eksekusi
    $time = $time_end - $time_start;
    $hasil = array($time, $hasildekrip);
    return $hasil;
}
예제 #19
0
function base58_decode($string)
{
    $table = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
    static $table_rev = null;
    if (is_null($table_rev)) {
        $table_rev = array();
        for ($i = 0; $i < 58; ++$i) {
            $table_rev[$table[$i]] = $i;
        }
    }
    $l = strlen($string);
    $long_value = gmp_init('0');
    for ($i = 0; $i < $l; ++$i) {
        $c = $string[$l - $i - 1];
        $long_value = gmp_add($long_value, gmp_mul($table_rev[$c], gmp_pow(58, $i)));
    }
    // php is lacking binary output for gmp
    $res = pack('H*', gmp_strval($long_value, 16));
    for ($nPad = 0; $string[$nPad] == $table[0]; ++$nPad) {
    }
    return str_repeat("", $nPad) . $res;
}
예제 #20
0
/**
 * Calculate Wang hash for 64bit unsigned integer using GMP library
 * PHP only supports signed integers even with 64bit version
 *
 * See <code/nel/include/nel/misc/wang_hash.h> on https://bitbucket.org/ryzom/ryzomcore
 *
 * @param string $key
 *
 * @return string hash
 */
function wang_hash64($key)
{
    // force $key to be base 10
    $key = gmp_init($key, 10);
    //$key = (~$key) + ($key << 21);
    $key = gmp_add(gmp_com($key), gmp_mul($key, 1 << 21));
    //$key = $key ^ ($key >> 24);
    $key = gmp_xor($key, gmp_div($key, 1 << 24));
    //$key = $key * 265;
    $key = gmp_mul($key, 265);
    //$key = $key ^ ($key >> 14);
    $key = gmp_xor($key, gmp_div($key, 1 << 14));
    //$key = $key * 21;
    $key = gmp_mul($key, 21);
    //$key = $key ^ ($key >> 28);
    $key = gmp_xor($key, gmp_div($key, 1 << 28));
    //$key = $key + ($key << 31);
    $key = gmp_add($key, gmp_mul($key, gmp_pow(2, 31)));
    // limit to 64bit
    $key = gmp_and($key, "0xFFFFFFFFFFFFFFFF");
    return gmp_strval($key, 10);
}
예제 #21
0
파일: Base128.php 프로젝트: afk11/phpasn1
 /**
  * @param string $octets
  *
  * @throws InvalidArgumentException if the given octets represent a malformed base-128 value or the decoded value would exceed the the maximum integer length
  *
  * @return int
  */
 public static function decode($octets)
 {
     $bitsPerOctet = 7;
     $value = gmp_init(0, 10);
     $i = 0;
     $leftShift = function ($number, $positions) {
         return gmp_mul($number, gmp_pow(2, $positions));
     };
     while (true) {
         if (!isset($octets[$i])) {
             throw new InvalidArgumentException(sprintf('Malformed base-128 encoded value (0x%s).', strtoupper(bin2hex($octets)) ?: '0'));
         }
         $octet = gmp_init(ord($octets[$i++]), 10);
         $l1 = $leftShift($value, $bitsPerOctet);
         $r1 = gmp_and($octet, 0x7f);
         $value = gmp_add($l1, $r1);
         if (0 === gmp_cmp(gmp_and($octet, 0x80), 0)) {
             break;
         }
     }
     return gmp_strval($value);
 }
예제 #22
0
파일: Gmp.php 프로젝트: wAmpIre/netmon
 /**
  * @param string $left_operand
  * @param string $right_operand
  * @return string
  */
 public function pow($left_operand, $right_operand)
 {
     $result = gmp_pow($left_operand, $right_operand);
     return gmp_strval($result);
 }
예제 #23
0
 public static function double(Point $p1)
 {
     $p = $p1->curve->prime;
     $a = $p1->curve->a;
     $inverse = gmp_invert(gmp_mul(2, $p1->y), $p);
     $three_x2 = gmp_mul(3, gmp_pow($p1->x, 2));
     $l = gmp_mod(gmp_mul(gmp_add($three_x2, $a), $inverse), $p);
     $x3 = gmp_mod(gmp_sub(gmp_pow($l, 2), gmp_mul(2, $p1->x)), $p);
     $y3 = gmp_mod(gmp_sub(gmp_mul($l, gmp_sub($p1->x, $x3)), $p1->y), $p);
     if (gmp_cmp(0, $y3) > 0) {
         $y3 = gmp_add($p, $y3);
     }
     return new Point($p1->curve, $x3, $y3);
 }
예제 #24
0
파일: misc.php 프로젝트: captincook/Pony
function gmp_shiftr($x, $n)
{
    return gmp_div($x, gmp_pow(2, $n));
}
예제 #25
0
 /**
  * Logical Left Shift
  *
  * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
  *
  * @param int $shift
  * @return Math_BigInteger
  * @access public
  * @internal The only version that yields any speed increases is the internal version.
  */
 function bitwise_leftShift($shift)
 {
     $temp = new Math_BigInteger();
     switch (MATH_BIGINTEGER_MODE) {
         case MATH_BIGINTEGER_MODE_GMP:
             static $two;
             if (!isset($two)) {
                 $two = gmp_init('2');
             }
             $temp->value = gmp_mul($this->value, gmp_pow($two, $shift));
             break;
         case MATH_BIGINTEGER_MODE_BCMATH:
             $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);
             break;
         default:
             // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten
             // and I don't want to do that...
             $temp->value = $this->value;
             $temp->_lshift($shift);
     }
     return $this->_normalize($temp);
 }
예제 #26
0
 /**
  * Raise one number to the power of the other, utilize Math extensions
  *
  * @param mixed a First operand
  * @param mixed b Second operand
  * @return mixed
  * @access private
  */
 function _pow($a, $b)
 {
     switch (MATH_BASEX_MATHEXTENSION) {
         case 'bcmath':
             return bcpow($a, $b);
         case 'gmp':
             return gmp_strval(gmp_pow($a, $b));
         case 'none':
             return pow($a, $b);
     }
 }
예제 #27
0
/**	
 * Reformat incomplete IPv6 address to decimal for search!
 */
function reformatIPv6forSearch($ip)
{
    //split network and subnet part
    $ip = explode("/", $ip);
    //if subnet is not provided we are looking for host!
    if (sizeof($ip) < 2) {
        $return['low'] = Transform2decimal($ip[0]);
        $return['high'] = Transform2decimal($ip[0]);
    }
    //if network part ends with :: we must search the complete provided subnet!
    $lastChars = substr($ip[0], -2);
    if ($lastChars == "::") {
        $return['low'] = Transform2decimal($ip[0]);
        //set highest IP address
        $subnet = substr($ip[0], 0, -2);
        $subnet = Transform2decimal($subnet);
        //calculate all possible hosts in subnet mask
        $maskHosts = gmp_strval(gmp_sub(gmp_pow(2, 128 - $ip[1]), 1));
        $return['high'] = gmp_strval(gmp_add($return['low'], $maskHosts));
    }
    return $return;
}
예제 #28
0
 protected function subtraction($A, $B, $radix)
 {
     $a = gmp_init($A, $radix);
     $b = gmp_init($B, $radix);
     // Prevent negative values
     if (gmp_cmp($a, $b) < 0) {
         $a = gmp_add($a, gmp_pow($radix, strlen($A)));
     }
     // Block-wise subtraction
     return $this->fixedLength(gmp_strval(gmp_sub($a, $b), $radix), strlen($A), '0');
 }
 public function import()
 {
     /*{{{*/
     if (extension_loaded('xhprof')) {
         // xhprof slows things down
         xhprof_disable();
     }
     if (!extension_loaded('gmp')) {
         throw new Exception('The blockchain importer requires the PHP GMP module to be installed and enabled');
     }
     echo "\nTodo:\n\n* add Output_Key join table to support multisig, convert data, then re-import all multisig transactions\n* detect if PHP is 64-bit, if not, check if GMP is installed, otherwise us BCMath\n  - ACTUALLY, just move to PHPSECLIB: http://phpseclib.sourceforge.net/math/intro.html \n* move RPC calls into separate class\n* move bitcoin specific utils into separate class\n* move conversion from satoshis to floats into view model\n* fix trailing decimal point on whole numbers in block and blockchain views\n\nMaybe:\n\n* move entities to model binder?\n";
     sleep(1);
     // this can take a long time
     set_time_limit(0);
     $client = new \Zend\Json\Server\Client($this->bitcoindServerUrl);
     $client->getHttpClient()->setOptions(array('timeout' => 30));
     $blockcount = $client->call('getblockcount');
     // Get the last block in the DB
     $query = $this->objectManager->createQuery('SELECT b FROM Blockchain\\Entity\\Block b WHERE b.id = (SELECT MAX(bm.id) FROM Blockchain\\Entity\\Block bm)');
     $result = $query->getResult();
     if (count($result) == 1) {
         $blockEntity = $result[0];
         $blockId = $blockEntity->getId();
         $blockhash = $blockEntity->getBlockhash();
         $blockNumber = $blockEntity->getBlockNumber();
         $block = $this->getBlockFromServer($blockhash);
         // remove last block and all associated transactions in case it wasn't loaded full or there was no "nextblockhash"
         $connection = $this->objectManager->getConnection();
         if ($connection->getDatabasePlatform()->getName() == 'mysql') {
             // The input and output tables have cyclical foreign keys, so rows can't be deleted
             $connection->query('SET FOREIGN_KEY_CHECKS=0');
         }
         $this->objectManager->remove($blockEntity);
         $this->objectManager->flush();
         if ($connection->getDatabasePlatform()->getName() == 'mysql') {
             $connection->query('SET FOREIGN_KEY_CHECKS=1');
         }
         $coinbaseExp = floor($blockNumber / 210000);
         $gmp_coinbaseValue = gmp_div_q(gmp_init("5000000000"), gmp_pow(gmp_init("2"), $coinbaseExp));
     } else {
         $blockNumber = 0;
         $blockhash = $client->call('getblockhash', array($blockNumber));
         $gmp_coinbaseValue = gmp_init("5000000000");
     }
     $batchSize = 25;
     $count = 0;
     // Start importing
     $lastTime = 0;
     $currTime = 0;
     $avgTime = 0;
     $blockCount = 0;
     while ($blockhash) {
         $currTime = microtime(true);
         if ($lastTime) {
             $diff = $currTime - $lastTime;
             // update average time between blocks
             $avgTime = ($avgTime * ($blockCount - 1) + $diff) / $blockCount;
             $blocksLeft = $blockcount - $blockNumber;
             $estimatedCompletion = $blocksLeft * $avgTime;
             echo sprintf("\n\nEstimated completion: %s (blocks left: %d, average block time: %s seconds\n", self::secondsToString($estimatedCompletion), $blocksLeft, number_format($avgTime, 2));
         }
         if ($blockNumber % 210000 == 0) {
             // only calculate this when necessary instead of every loop
             $coinbaseExp = floor($blockNumber / 210000);
             $gmp_coinbaseValue = gmp_div_q(gmp_init("5000000000"), gmp_pow(gmp_init("2"), $coinbaseExp));
         }
         echo "\nBlock {$blockNumber}, Transactions: ";
         $gmp_totalBlockValue = gmp_init("0");
         $block = $this->getBlockFromServer($blockhash);
         $blockEntity = new \Blockchain\Entity\Block();
         $blockEntity->setBlockNumber($blockNumber);
         $blockEntity->setBlockhash($block['hash']);
         $blockEntity->setSize($block['size']);
         $blockEntity->setHeight($block['height']);
         $blockEntity->setVersion($block['version']);
         $blockEntity->setMerkleroot($block['merkleroot']);
         $blockEntity->setTime(new \DateTime('@' . $block['time']));
         $blockEntity->setNonce($block['nonce']);
         $blockEntity->setBits($block['bits']);
         $blockEntity->setDifficulty($block['difficulty']);
         if (isset($block['nextblockhash'])) {
             $blockEntity->setNextblockhash($block['nextblockhash']);
         }
         if (isset($block['previousblockhash'])) {
             $blockEntity->setPreviousblockhash($block['previousblockhash']);
         }
         $this->objectManager->persist($blockEntity);
         $count++;
         $gmp_offeredFees = gmp_init("0");
         $gmp_takenFees = gmp_init("0");
         // First block is unique
         if ($blockNumber > 0) {
             $seenTxids = array();
             $seenAddresses = array();
             $txCount = 0;
             foreach ($block['tx'] as $txid) {
                 $txCount++;
                 if ($txCount > 1) {
                     echo ', ';
                 }
                 echo $txCount;
                 // the JSON RPC client appears to have a memory leak, so isolate it inside a function
                 $transaction = $this->getRawTransactionFromServer($txid);
                 if (!$transaction) {
                     die('failure retrieving transaction');
                 }
                 if ($blockNumber == 91842 && $transaction['txid'] == 'd5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599') {
                     // Special case where a transaction was duplicated in block 91812 and 91842 due to a bug in a mining client
                     // ignore the second instance
                     continue;
                 }
                 if ($blockNumber == 91880 && $transaction['txid'] == 'e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468') {
                     // Special case where a transaction was duplicated in block 91722 and 91880 due to a bug in a mining client
                     // ignore the second instance
                     continue;
                 }
                 $transactionEntity = new \Blockchain\Entity\Transaction();
                 $transactionEntity->setTxid($transaction['txid']);
                 $transactionEntity->setBlockhash($blockhash);
                 $transactionEntity->setBlock($blockEntity);
                 $transactionEntity->setVersion($transaction['version']);
                 $transactionEntity->setLocktime($transaction['locktime']);
                 $transactionEntity->setSize($transaction['size']);
                 $this->objectManager->persist($transactionEntity);
                 $count++;
                 $gmp_totalInputValue = gmp_init("0");
                 foreach ($transaction['vin'] as $input) {
                     $inputEntity = new \Blockchain\Entity\Input();
                     $inputEntity->setTxid($txid);
                     $inputEntity->setSequence($input['sequence']);
                     if (isset($input['coinbase'])) {
                         $inputEntity->setCoinbase($input['coinbase']);
                         $inputEntity->setValue(gmp_strval($gmp_coinbaseValue));
                         $gmp_totalInputValue = gmp_add($gmp_totalInputValue, $gmp_coinbaseValue);
                     } else {
                         if (isset($seenTxids[$input['txid']])) {
                             // input of one transaction is referencing the output of another transaction in the same block.  flush writes.
                             $this->objectManager->flush();
                             // clear objects to free memory
                             $this->objectManager->clear();
                             // reload associated entities
                             $blockEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Block')->findOneBy(array('blockhash' => $blockhash));
                             $transactionEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Transaction')->findOneBy(array('txid' => $txid));
                         }
                         $inputEntity->setRedeemedTxid($input['txid']);
                         $inputEntity->setScriptSigAsm($input['scriptSig']['asm']);
                         $inputEntity->setScriptSigHex($input['scriptSig']['hex']);
                         $inputEntity->setVout($input['vout']);
                         $redeemedOutputEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Output')->findOneBy(array('txid' => $input['txid'], 'n' => $input['vout']));
                         if (!$redeemedOutputEntity) {
                             die('could not find output');
                         }
                         $nonstandard = false;
                         $pubkey = null;
                         $hash160 = null;
                         $address = null;
                         $keyEntity = null;
                         if (preg_match('/(.+) (.+)/', $input['scriptSig']['asm'], $matches)) {
                             // Standard Transaction to Bitcoin address (pay-to-pubkey-hash)
                             // scriptPubKey: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
                             // scriptSig: <sig> <pubKey>
                             $signature = $matches[1];
                             $pubkey = $matches[2];
                             $hash160 = self::pubkeyToHash160($pubkey);
                             $address = self::hash160ToAddress($hash160);
                         } else {
                             if ($redeemedOutputEntity->getType() == 'nonstandard') {
                                 $nonstandard = true;
                                 echo "...nonstandard output, scriptsig: " . $input['scriptSig']['asm'] . "...";
                                 $redeemedOutputKeyEntity = $redeemedOutputEntity->getKey();
                                 if ($redeemedOutputKeyEntity) {
                                     $pubkey = $redeemedOutputKeyEntity->getPubkey();
                                     $hash160 = $redeemedOutputKeyEntity->getHash160();
                                     $address = $redeemedOutputKeyEntity->getAddress();
                                 }
                             } else {
                                 if (preg_match('/([\\S]+)/', $input['scriptSig']['asm'])) {
                                     // Standard Generation Transaction (pay-to-pubkey)
                                     // scriptPubKey: <pubKey> OP_CHECKSIG
                                     // scriptSig: <sig>
                                     $redeemedOutputKeyEntity = $redeemedOutputEntity->getKey();
                                     if ($redeemedOutputKeyEntity) {
                                         $pubkey = $redeemedOutputKeyEntity->getPubkey();
                                         $hash160 = $redeemedOutputKeyEntity->getHash160();
                                         $address = $redeemedOutputKeyEntity->getAddress();
                                     } else {
                                         echo "\n\n" . $input['scriptSig']['asm'] . "\n";
                                         die("\nStandard Generation without key\n");
                                     }
                                 } else {
                                     die("strange scriptSig: " . $input['scriptSig']['asm'] . "\n");
                                 }
                             }
                         }
                         $keyEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Key')->findOneBy(array('address' => $address));
                         if (!$keyEntity) {
                             if ($address && !isset($seenAddresses[$address])) {
                                 $keyEntity = new \Blockchain\Entity\Key();
                                 $keyEntity->setPubkey($pubkey);
                                 $keyEntity->setHash160($hash160);
                                 $keyEntity->setAddress($address);
                                 $keyEntity->setFirstblockhash($blockhash);
                                 $keyEntity->setFirstblock($blockEntity);
                                 $seenAddresses[$address] = array('pubkey' => $pubkey);
                             } else {
                                 $this->objectManager->flush();
                                 $keyEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Key')->findOneBy(array('address' => $address));
                             }
                         }
                         if (!$keyEntity && !$nonstandard) {
                             die("problem finding input key: {$address}\n");
                         }
                         if ($keyEntity) {
                             if ($pubkey && !$keyEntity->getPubkey()) {
                                 $keyEntity->setPubkey($pubkey);
                             }
                             $this->objectManager->persist($keyEntity);
                             $inputEntity->setKey($keyEntity);
                         }
                         $inputEntity->setHash160($hash160);
                         $inputEntity->setAddress($address);
                         $gmp_inputValue = gmp_init($redeemedOutputEntity->getValue());
                         $inputEntity->setValue(gmp_strval($gmp_inputValue));
                         $inputEntity->setAddress($redeemedOutputEntity->getAddress());
                         $inputEntity->setRedeemedOutput($redeemedOutputEntity);
                         $redeemedOutputEntity->setRedeemingInput($inputEntity);
                         $this->objectManager->persist($redeemedOutputEntity);
                         $gmp_totalInputValue = gmp_add($gmp_totalInputValue, gmp_init($inputEntity->getValue()));
                         // echo 'txid: '.$txid.', input txid: '.$input['txid'].', vout: '.$input['vout'].", val: ".gmp_strval($gmp_inputValue)."\n";
                         // Need to figure out how to extract hash160, if it is of any value...
                         // $inputEntity->setHash160();
                     }
                     $inputEntity->setTransaction($transactionEntity);
                     $this->objectManager->persist($inputEntity);
                     $count++;
                 }
                 $gmp_totalBlockValue = gmp_add($gmp_totalBlockValue, $gmp_totalInputValue);
                 $gmp_totalOutputValue = gmp_init("0");
                 foreach ($transaction['vout'] as $output) {
                     $outputEntity = new \Blockchain\Entity\Output();
                     $outputEntity->setTxid($txid);
                     $outputEntity->setN($output['n']);
                     $gmp_outputValue = self::floatBTCToGmpSatoshis($output['value']);
                     $outputEntity->setValue(gmp_strval($gmp_outputValue));
                     $gmp_totalOutputValue = gmp_add($gmp_totalOutputValue, $gmp_outputValue);
                     $outputEntity->setScriptPubKeyAsm($output['scriptPubKey']['asm']);
                     $outputEntity->setScriptPubKeyHex($output['scriptPubKey']['hex']);
                     $pubkey = null;
                     $hash160 = null;
                     $address = null;
                     if (preg_match('/OP_DUP OP_HASH160 ([\\S]+) OP_EQUALVERIFY OP_CHECKSIG/', $output['scriptPubKey']['asm'], $matches)) {
                         $hash160 = $matches[1];
                         $address = self::hash160ToAddress($hash160);
                     } else {
                         if (preg_match('/^([\\S]+) OP_CHECKSIG$/', $output['scriptPubKey']['asm'], $matches)) {
                             $pubkey = $matches[1];
                             $hash160 = self::pubkeyToHash160($pubkey);
                             $address = self::hash160ToAddress($hash160);
                         }
                     }
                     $keyEntity = null;
                     if ($address) {
                         $keyEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Key')->findOneBy(array('address' => $address));
                         if (!$keyEntity) {
                             if (!isset($seenAddresses[$address])) {
                                 $keyEntity = new \Blockchain\Entity\Key();
                                 $keyEntity->setPubkey($pubkey);
                                 $keyEntity->setHash160($hash160);
                                 $keyEntity->setAddress($address);
                                 $keyEntity->setFirstblockhash($blockhash);
                                 $keyEntity->setFirstblock($blockEntity);
                                 $seenAddresses[$address] = array('pubkey' => $pubkey);
                             } else {
                                 $this->objectManager->flush();
                                 $keyEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Key')->findOneBy(array('address' => $address));
                             }
                         }
                         if ($keyEntity) {
                             if ($pubkey && !$keyEntity->getPubkey()) {
                                 $keyEntity->setPubkey($pubkey);
                             }
                             $this->objectManager->persist($keyEntity);
                             $outputEntity->setKey($keyEntity);
                         }
                         if (!$keyEntity && $pubkey && !$seenAddresses[$address]['pubkey']) {
                             die("Situation: address seen multiple times in transaction, and pubkey available\n");
                         }
                     }
                     if ($address && !$keyEntity) {
                         die("Output key entity not generated: {$address}\n");
                     }
                     $outputEntity->setHash160($hash160);
                     if (isset($output['scriptPubKey']['reqSigs'])) {
                         $outputEntity->setReqSigs($output['scriptPubKey']['reqSigs']);
                     }
                     $outputEntity->setType($output['scriptPubKey']['type']);
                     if (count($output['scriptPubKey']['addresses']) > 1) {
                         echo "\n\noutput with multiple addresses found:\n";
                         echo print_r($output, true);
                         echo "\n";
                     } else {
                         if (isset($output['scriptPubKey']['addresses'][0]) && $address != $output['scriptPubKey']['addresses'][0]) {
                             echo $output['scriptPubKey']['asm'] . "\n";
                             die("inconsistent output addresses\n    parsed: {$address}\n    given: {$output['scriptPubKey']['addresses'][0]}\n");
                         }
                     }
                     $outputEntity->setAddress($output['scriptPubKey']['addresses'][0]);
                     $outputEntity->setHash160($hash160);
                     $outputEntity->setTransaction($transactionEntity);
                     $this->objectManager->persist($outputEntity);
                     $count++;
                 }
                 if (isset($input['coinbase'])) {
                     $gmp_takenFees = gmp_sub($gmp_totalOutputValue, $gmp_coinbaseValue);
                 }
                 if (!isset($input['coinbase'])) {
                     $gmp_fee = gmp_sub($gmp_totalInputValue, $gmp_totalOutputValue);
                     $gmp_offeredFees = gmp_add($gmp_offeredFees, $gmp_fee);
                 } else {
                     $gmp_fee = gmp_init("0");
                 }
                 $transactionEntity->setFee(gmp_strval($gmp_fee));
                 $transactionEntity->setTotalIn(gmp_strval($gmp_totalInputValue));
                 $transactionEntity->setTotalOut(gmp_strval($gmp_totalOutputValue));
                 $this->objectManager->persist($transactionEntity);
                 $count++;
                 $seenTxids[$txid] = true;
                 if ($count % $batchSize == 0) {
                     $this->objectManager->flush();
                     $this->objectManager->clear();
                     $blockEntity = $this->objectManager->getRepository('Blockchain\\Entity\\Block')->findOneBy(array('blockhash' => $blockhash));
                 }
             }
         }
         if (gmp_cmp($gmp_offeredFees, $gmp_takenFees) > 0) {
             echo "WARNING: Possible lost coins. Offered Fees: " . gmp_strval($gmp_offeredFees) . ", Taken Fees: " . gmp_strval($gmp_takenFees) . "\n";
         }
         if (gmp_cmp($gmp_takenFees, $gmp_offeredFees) > 0) {
             die("ERROR.  Impossible transaction: Offered Fees: " . gmp_strval($gmp_offeredFees) . ", Taken Fees: " . gmp_strval($gmp_takenFees) . "\n");
         }
         $blockEntity->setOfferedFees(gmp_strval($gmp_offeredFees));
         $blockEntity->setTakenFees(gmp_strval($gmp_takenFees));
         $blockEntity->setTotalvalue(gmp_strval($gmp_totalBlockValue));
         $gmp_lostValue = gmp_sub($gmp_offeredFees, $gmp_takenFees);
         $blockEntity->setLostvalue(gmp_strval($gmp_lostValue));
         $this->objectManager->persist($blockEntity);
         $count++;
         if (isset($block['nextblockhash'])) {
             $nextblockhash = $block['nextblockhash'];
         } else {
             $nextblockhash = null;
         }
         $this->objectManager->flush();
         $this->objectManager->clear();
         $blockhash = $nextblockhash;
         $blockNumber++;
         $blockCount++;
         $lastTime = $currTime;
     }
 }
예제 #30
0
 public static function double(Point $p1)
 {
     if (extension_loaded('gmp') && USE_EXT == 'GMP') {
         $p = $p1->curve->getPrime();
         $a = $p1->curve->getA();
         //                $inverse = NumberTheory::inverse_mod(gmp_strval(gmp_mul(2, $p1->y)), $p);
         $inverse = gmp_strval(gmp_invert(gmp_strval(gmp_mul(2, $p1->y)), $p));
         $three_x2 = gmp_mul(3, gmp_pow($p1->x, 2));
         $l = gmp_strval(gmp_Utils::gmp_mod2(gmp_mul(gmp_add($three_x2, $a), $inverse), $p));
         $x3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_pow($l, 2), gmp_mul(2, $p1->x)), $p));
         $y3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_mul($l, gmp_sub($p1->x, $x3)), $p1->y), $p));
         if (gmp_cmp(0, $y3) > 0) {
             $y3 = gmp_strval(gmp_add($p, $y3));
         }
         $p3 = new Point($p1->curve, $x3, $y3);
         return $p3;
     } else {
         throw new ErrorException("Please install GMP");
     }
 }