/** * Returns the compressed public key value * * @return string */ public function __toString() { if (is_null($this->x)) { return ''; } if (Math::mod('0x' . $this->y, '0x02') == '1') { return sprintf('03%s', $this->x); } else { return sprintf('02%s', $this->x); } }
/** * Decodes $data from BASE-58 format * * @param string $data * * @return string */ public static function decode($data) { for ($return = '0', $i = 0; $i < strlen($data); $i++) { $current = strpos(self::BASE58_CHARS, $data[$i]); $return = Math::mul($return, '58'); $return = Math::add($return, $current); } $return = Util::encodeHex($return); for ($i = 0; $i < strlen($data) && substr($data, $i, 1) == '1'; $i++) { $return = '00' . $return; } if (strlen($return) % 2 != 0) { $return = '0' . $return; } return $return; }
public function testGenerate() { if (extension_loaded('gmp')) { \Bitpay\Math\Math::setEngine(new \Bitpay\Math\GmpEngine()); } elseif (extension_loaded('bcmath')) { \Bitpay\Math\Math::setEngine(new \Bitpay\Math\BcEngine()); } else { \Bitpay\Math\Math::setEngine(new \Bitpay\Math\RpEngine()); } $priKey = new PrivateKey(); $this->assertNotNull($priKey); $this->assertNull($priKey->getHex()); $this->assertNull($priKey->getDec()); $priKey->generate(); $this->assertEquals(64, strlen($priKey->getHex())); $this->assertGreaterThanOrEqual(72, strlen($priKey->getDec())); }
/** * Converts hex value into octet (byte) string * * @param string * * @return string */ public static function binConv($hex) { $rem = ''; $dv = ''; $byte = ''; $digits = array(); for ($x = 0; $x < 256; $x++) { $digits[$x] = chr($x); } if (substr(strtolower($hex), 0, 2) != '0x') { $hex = '0x' . strtolower($hex); } while (Math::cmp($hex, 0) > 0) { $dv = Math::div($hex, 256); $rem = Math::mod($hex, 256); $hex = $dv; $byte = $byte . $digits[$rem]; } return strrev($byte); }
/** * Encodes keypair data to PEM format. * * @param array $keypair The keypair info. * @return string The data to decode. * @throws \Exception */ public function pemEncode($keypair) { if (is_array($keypair) && (strlen($keypair[0]) < 64 || strlen($keypair[1]) < 128)) { throw new \Exception('Invalid or corrupt secp256k1 keypair provided. Cannot decode the supplied PEM data.'); } $dec = ''; $byte = ''; $beg_ec_text = ''; $end_ec_text = ''; $ecpemstruct = array(); $digits = array(); for ($x = 0; $x < 256; $x++) { $digits[$x] = chr($x); } $ecpemstruct = array('sequence_beg' => '30', 'total_len' => '74', 'int_sec_beg' => '02', 'int_sec_len' => '01', 'int_sec_val' => '01', 'oct_sec_beg' => '04', 'oct_sec_len' => '20', 'oct_sec_val' => $keypair[0], 'a0_ele_beg' => 'a0', 'a0_ele_len' => '07', 'obj_id_beg' => '06', 'obj_id_len' => '05', 'obj_id_val' => '2b8104000a', 'a1_ele_beg' => 'a1', 'a1_ele_len' => '44', 'bit_str_beg' => '03', 'bit_str_len' => '42', 'bit_str_val' => '00' . $keypair[1]); $beg_ec_text = '-----BEGIN EC PRIVATE KEY-----'; $end_ec_text = '-----END EC PRIVATE KEY-----'; $dec = trim(implode($ecpemstruct)); if (strlen($dec) < 230) { throw new \Exception('Invalid or corrupt secp256k1 keypair provided. Cannot encode the supplied data.'); } $dec = Util::decodeHex('0x' . $dec); while (Math::cmp($dec, '0') > 0) { $dv = Math::div($dec, '256'); $rem = Math::mod($dec, '256'); $dec = $dv; $byte = $byte . $digits[$rem]; } $byte = $beg_ec_text . "\r\n" . chunk_split(base64_encode(strrev($byte)), 64) . $end_ec_text; $this->pemEncoded = $byte; return $byte; }