/** * @inheritdoc */ public function load($id) { if (!is_file($id)) { throw new \Exception(sprintf('Could not find "%s"', $id)); } if (!is_readable($id)) { throw new \Exception(sprintf('"%s" cannot be read, check permissions', $id)); } $encoded = file_get_contents($id); $decoded = openssl_decrypt(\Bitpay\Util\Util::binConv($encoded), self::METHOD, $this->password, 1, self::IV); if (false === $decoded) { throw new \Exception('Could not decode key'); } return unserialize($decoded); }
/** * 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; }
/** * Generates a Service Identification Number (SIN), see: * https://en.bitcoin.it/wiki/Identity_protocol_v1 * * @return SinKey * @throws \Exception */ public function generate() { if (is_null($this->publicKey)) { throw new \Exception('Public Key has not been set'); } $compressedValue = $this->publicKey; if (empty($compressedValue)) { throw new \Exception('The Public Key needs to be generated.'); } $step1 = Util::sha256(Util::binConv($compressedValue), true); $step2 = Util::ripe160($step1); $step3 = sprintf('%s%s%s', self::SIN_VERSION, self::SIN_TYPE, $step2); $step4 = Util::twoSha256(Util::binConv($step3), true); $step5 = substr(bin2hex($step4), 0, 8); $step6 = $step3 . $step5; $this->value = Base58::encode($step6); return $this; }
/** * 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; }
/** * @inheritdoc */ public function createToken(array $payload = array()) { if (isset($payload['pairingCode']) && 1 !== preg_match('/^[a-zA-Z0-9]{7}$/', $payload['pairingCode'])) { throw new \Exception('[ERROR] In Client::createToken(): The pairing code provided is not legal.'); } $this->request = $this->createNewRequest(); $this->request->setMethod(Request::METHOD_POST); $this->request->setPath('tokens'); $payload['guid'] = Util::guid(); $this->request->setBody(json_encode($payload)); $this->response = $this->sendRequest($this->request); $body = json_decode($this->response->getBody(), true); if (isset($body['error'])) { throw new \Bitpay\Client\BitpayException($this->response->getStatusCode() . ': ' . $body['error']); } $tkn = $body['data'][0]; $createdAt = new \DateTime(); $pairingExpiration = new \DateTime(); $token = new \Bitpay\Token(); $token->setPolicies($tkn['policies'])->setToken($tkn['token'])->setFacade($tkn['facade'])->setCreatedAt($createdAt->setTimestamp(floor($tkn['dateCreated'] / 1000))); if (isset($tkn['resource'])) { $token->setResource($tkn['resource']); } if (isset($tkn['pairingCode'])) { $token->setPairingCode($tkn['pairingCode']); $token->setPairingExpiration($pairingExpiration->setTimestamp(floor($tkn['pairingExpiration'] / 1000))); } return $token; }
public function testCheckRequirements() { $requirements = Util::checkRequirements(); // PHP Version if (!defined('PHP_VERSION_ID')) { $version = explode('.', PHP_VERSION); define('PHP_VERSION_ID', $version[0] * 10000 + $version[1] * 100 + $version[2]); } if (PHP_VERSION_ID >= 50400) { $this->assertTrue($requirements['PHP']); } else { $this->assertTrue(is_string($requirements['PHP'])); } // Mcrypt Extension if (extension_loaded('mcrypt')) { $this->assertTrue($requirements['Mcrypt']); } else { $this->assertTrue(is_string($requirements['Mcrypt'])); } // OpenSSL Extension if (extension_loaded('openssl')) { $this->assertTrue($requirements['OpenSSL']); } else { $this->assertTrue(is_string($requirements['OpenSSL'])); } // JSON Extension if (extension_loaded('json')) { $this->assertTrue($requirements['JSON']); } else { $this->assertTrue(is_string($requirements['JSON'])); } // cURL Extension if (extension_loaded('curl')) { $this->assertTrue($requirements['cURL']); $curl_version = curl_version(); $ssl_supported = $curl_version['features'] & CURL_VERSION_SSL; if ($ssl_supported) { $this->assertTrue($requirements['cURL.SSL']); } else { $this->assertTrue(is_string($requirements['cURL.SSL'])); } } else { $this->assertTrue(is_string($requirements['cURL'])); $this->assertTrue(is_string($requirements['cURL'])); } // Math if (extension_loaded('bcmath') || extension_loaded('gmp')) { $this->assertTrue($requirements['Math']); } else { $this->assertTrue(is_string($requirements['Math'])); } }
/** * Generates an uncompressed and compressed EC public key. * * @param \Bitpay\PrivateKey $privateKey * @return \Bitpay\PublicKey * @throws \Exception */ public function generate(PrivateKey $privateKey = null) { if ($privateKey instanceof PrivateKey) { $this->setPrivateKey($privateKey); } if (!empty($this->hex)) { return $this; } if (is_null($this->privateKey)) { throw new \Exception('Please `setPrivateKey` before you generate a public key'); } if (!$this->privateKey->isGenerated()) { $this->privateKey->generate(); } if (!$this->privateKey->isValid()) { throw new \Exception('Private Key is invalid and cannot be used to generate a public key'); } $point = new Point('0x' . substr(Secp256k1::G, 2, 64), '0x' . substr(Secp256k1::G, 66, 64)); $R = Util::doubleAndAdd('0x' . $this->privateKey->getHex(), $point); $RxHex = Util::encodeHex($R->getX()); $RyHex = Util::encodeHex($R->getY()); $RxHex = str_pad($RxHex, 64, '0', STR_PAD_LEFT); $RyHex = str_pad($RyHex, 64, '0', STR_PAD_LEFT); $this->x = $RxHex; $this->y = $RyHex; $this->hex = sprintf('%s%s', $RxHex, $RyHex); $this->dec = Util::decodeHex($this->hex); return $this; }