public function testHexEncode() { $cnt = (getenv('BITCOINLIB_EXTENSIVE_TESTING') ?: 1) * 50; for ($this->testHexEncode_i = 0; $this->testHexEncode_i < $cnt; $this->testHexEncode_i++) { $hex = BitcoinLib::hex_encode((string) $this->testHexEncode_i); $this->_testHexEncode_result($hex); $this->_testHexEncode_length($hex); } }
/** * Decode Mnemonic * * This function decodes a string of 12 words to convert to the electrum * seed. This is an implementation of http://tools.ietf.org/html/rfc1751, * which is how electrum generates a 128-bit key from 12 words. * * @param string $words * @return string */ public static function decode_mnemonic($words) { $math = EccFactory::getAdapter(); $words = explode(" ", $words); $out = ''; $n = 1626; for ($i = 0; $i < count($words) / 3; $i++) { $a = 3 * $i; list($word1, $word2, $word3) = array($words[$a], $words[$a + 1], $words[$a + 2]); $index_w1 = array_search($word1, self::$words); $index_w2 = array_search($word2, self::$words) % $n; $index_w3 = array_search($word3, self::$words) % $n; $x = $index_w1 + $n * $math->mod($index_w2 - $index_w1, $n) + $n * $n * $math->mod($index_w3 - $index_w2, $n); $out .= BitcoinLib::hex_encode($x); } return $out; }
/** * Encode Signature * * This function accepts a signature object, and information about * the txout being spent, and the relevant key for signing, and * encodes the signature in DER format. * * @param Signature $signature * @return string */ public static function encode_signature(Signature $signature) { $rBin = pack("H*", BitcoinLib::hex_encode($signature->getR())); $sBin = pack("H*", BitcoinLib::hex_encode($signature->getS())); // Pad R and S if their highest bit is flipped, ie, // they are negative. $rt = $rBin[0] & pack('H*', '80'); if (ord($rt) == 128) { $rBin = pack('H*', '00') . $rBin; } $st = $sBin[0] & pack('H*', '80'); if (ord($st) == 128) { $sBin = pack('H*', '00') . $sBin; } $r = bin2hex($rBin); $s = bin2hex($sBin); // Create the signature. $der_sig = '30' . self::_dec_to_bytes(4 + (strlen($r) + strlen($s)) / 2, 1) . '02' . self::pushdata($r) . '02' . self::pushdata($s) . '01'; return $der_sig; }
/** * Encode Signature * * This function accepts a signature object, and information about * the txout being spent, and the relevant key for signing, and * encodes the signature in DER format. * * @param Signature $signature * @return string */ public static function encode_signature(Signature $signature) { $math = EccFactory::getAdapter(); $generator = EccFactory::getSecgCurves($math)->generator256k1(); // if S is > half then we substract from N if (self::check_signature_is_high_s($signature)) { $n = $generator->getOrder(); $signature = new Signature($signature->getR(), $math->sub($n, $signature->getS())); } $rBin = pack("H*", BitcoinLib::hex_encode($signature->getR())); $sBin = pack("H*", BitcoinLib::hex_encode($signature->getS())); // Pad R and S if their highest bit is flipped, ie, // they are negative. $rt = $rBin[0] & pack('H*', '80'); if (ord($rt) == 128) { $rBin = pack('H*', '00') . $rBin; } $st = $sBin[0] & pack('H*', '80'); if (ord($st) == 128) { $sBin = pack('H*', '00') . $sBin; } $r = bin2hex($rBin); $s = bin2hex($sBin); // Create the signature. $der_sig = '30' . self::_dec_to_bytes(4 + (strlen($r) + strlen($s)) / 2, 1) . '02' . self::pushdata($r) . '02' . self::pushdata($s) . '01'; return $der_sig; }
/** * Encode * * This function accepts an array of information describing the * extended key. It will determine the magic bytes depending on the * network, testnet, and type indexes. The fingerprint is accepted * as-is, because the CKD() and master_key() functions work that out * themselves. The child number is fixed at '00000000'. Private key's * are padded with \x00 to ensure they are 33 bytes. This information * is concatenated and converted to base58check encoding. * The input array has the same indexes as the output from the import() * function to ensure compatibility. * * @param array $data * @return string */ public static function encode($data) { // Magic Byte - 4 bytes / 8 characters - left out for now $magic_byte_var = strtolower($data['network']) . "_" . ($data['testnet'] == true ? 'testnet' : 'mainnet') . "_{$data['type']}"; $magic_byte = self::${$magic_byte_var}; $fingerprint = $data['fingerprint']; $child_number = $data['i']; $depth = BitcoinLib::hex_encode($data['depth']); $chain_code = $data['chain_code']; $key_data = $data['type'] == 'public' ? $data['key'] : '00' . $data['key']; $string = $magic_byte . $depth . $fingerprint . $child_number . $chain_code . $key_data; return BitcoinLib::base58_encode_checksum($string); }
/** * encode a message signature * * @param Signature $signature * @param $i * @param bool $compressed * @return string * @throws \Exception */ private static function encodeMessageSignature(Signature $signature, $i, $compressed = false) { if (!$compressed) { throw new \Exception("Uncompressed message signing not supported!"); } $val = $i + 27; if ($compressed) { $val += 4; } return hex2bin(implode("", [BitcoinLib::hex_encode($val), str_pad(BitcoinLib::hex_encode($signature->getR()), 64, '0', STR_PAD_LEFT), str_pad(BitcoinLib::hex_encode($signature->getS()), 64, '0', STR_PAD_LEFT)])); }