Пример #1
0
function isMessageSignatureValid($address, $signature, $message)
{
    $address = base58check_decode($address);
    if (strlen($address) != 21 || $address[0] != "") {
        throw new InvalidArgumentException('Invalid Bitcoin address.');
    }
    $derivedAddress = getVerifiedAddress160Bin($signature, $message);
    $derivedAddress = "" . $derivedAddress;
    return $address === $derivedAddress;
}
 public function buildDataAddr($toaddr, $currency, $amount)
 {
     $decoded = base58check_decode($toaddr);
     $seqnum = hexdec(bin2hex($decoded[1])) - 1;
     if ($seqnum < 0) {
         $seqnum = $seqnum + 256;
     }
     $datahex = dechex($seqnum);
     // seqence number
     $datahex = $datahex . $this->int32ToHexLittle(0);
     // tx type
     $datahex = $datahex . $this->int32ToHexLittle($currency);
     // currency id
     $datahex = $datahex . $this->int64ToHexLittle($amount);
     // amount
     $datahex = $datahex . "000000";
     $encoded = base58check_encode(hex2bin($datahex));
     return $encoded;
 }
Пример #3
0
function isMessageSignatureValid($address, $signature, $message)
{
    // curve definition
    // http://www.secg.org/download/aid-784/sec2-v2.pdf
    static $secp256k1 = null;
    static $secp256k1_G = null;
    $secp256k1 == null && ($secp256k1 = new CurveFp('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', '0', '7'));
    $secp256k1_G == null && ($secp256k1_G = new Point($secp256k1, '0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', '0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141'));
    // extract parameters
    $address = base58check_decode($address);
    if (strlen($address) != 21 || $address[0] != "") {
        throw new InvalidArgumentException('invalid Bitcoin address');
    }
    $signature = base64_decode($signature, true);
    if ($signature === false) {
        throw new InvalidArgumentException('invalid base64 signature');
    }
    if (strlen($signature) != 65) {
        throw new InvalidArgumentException('invalid signature length');
    }
    $recoveryFlags = ord($signature[0]) - 27;
    if ($recoveryFlags < 0 || $recoveryFlags > 7) {
        throw new InvalidArgumentException('invalid signature type');
    }
    $isCompressed = ($recoveryFlags & 4) != 0;
    // hash message, recover key
    $messageHash = hash('sha256', hash('sha256', "Bitcoin Signed Message:\n" . numToVarIntString(strlen($message)) . $message, true), true);
    $pubkey = recoverPubKey(bin2gmp(substr($signature, 1, 32)), bin2gmp(substr($signature, 33, 32)), bin2gmp($messageHash), $recoveryFlags, $secp256k1_G);
    if ($pubkey === false) {
        throw new InvalidArgumentException('unable to recover key');
    }
    $point = $pubkey->getPoint();
    // see that the key we recovered is for the address given
    if (!$isCompressed) {
        $pubBinStr = "" . str_pad(gmp2bin($point->getX()), 32, "", STR_PAD_LEFT) . str_pad(gmp2bin($point->getY()), 32, "", STR_PAD_LEFT);
    } else {
        $pubBinStr = (isBignumEven($point->getY()) ? "" : "") . str_pad(gmp2bin($point->getX()), 32, "", STR_PAD_LEFT);
    }
    $derivedAddress = "" . hash('ripemd160', hash('sha256', $pubBinStr, true), true);
    return $address === $derivedAddress;
}
 protected function addressToRipemd160($address)
 {
     return bin2hex(substr(base58check_decode($address), 1, 20));
 }