/** * Encodes $data into BASE-58 format * * @param string $data * * @return string */ public static function encode($data) { if (strlen($data) % 2 != 0 || strlen($data) == 0) { throw new \Exception('Invalid Length'); } $code_string = self::BASE58_CHARS; $x = Util::decodeHex($data); $output_string = ''; while (Math::cmp($x, '0') > 0) { $q = Math::div($x, 58); $r = Math::mod($x, 58); $output_string .= substr($code_string, intval($r), 1); $x = $q; } for ($i = 0; $i < strlen($data) && substr($data, $i, 2) == '00'; $i += 2) { $output_string .= substr($code_string, 0, 1); } $output_string = strrev($output_string); return $output_string; }
/** * Encodes a numeric string into BASE-58 format. * * @param string $data * @return string $output_string * @throws \Exception */ public static function encode($data) { $dataLen = strlen($data); if ($dataLen % 2 != 0 || $dataLen == 0) { throw new \Exception('Invalid length data string provided to Base58::encode() method.'); } $code_string = self::BASE58_CHARS; $x = Util::decodeHex($data); $output_string = ''; while (Math::cmp($x, '0') > 0) { $q = Math::div($x, '58'); $r = Math::mod($x, '58'); $output_string .= substr($code_string, intval($r), 1); $x = $q; } for ($i = 0; $i < $dataLen && substr($data, $i, 2) == '00'; $i += 2) { $output_string .= substr($code_string, 0, 1); } $output_string = strrev($output_string); return $output_string; }
/** * 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; }
/** * @expectedException Exception */ public function testDecodeHexException() { Util::decodeHex(new \StdClass()); }
/** * 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; }