Bitpay\PrivateKey::sign PHP Method

sign() public method

Creates an ECDSA signature of $message
public sign ( $data ) : string
return string
    public function sign($data)
    {
        if (!ctype_xdigit($this->hex)) {
            throw new \Exception('The private key must be in hex format.');
        }
        if (empty($data)) {
            throw new \Exception('You did not provide any data to sign.');
        }
        $e = Util::decodeHex(hash('sha256', $data));
        do {
            if (substr(strtolower($this->hex), 0, 2) != '0x') {
                $d = '0x' . $this->hex;
            } else {
                $d = $this->hex;
            }
            $k = SecureRandom::generateRandom(32);
            $k_hex = '0x' . strtolower(bin2hex($k));
            $n_hex = '0x' . Secp256k1::N;
            $Gx = '0x' . substr(Secp256k1::G, 2, 64);
            $Gy = '0x' . substr(Secp256k1::G, 66, 64);
            $P = new Point($Gx, $Gy);
            // Calculate a new curve point from Q=k*G (x1,y1)
            $R = Util::doubleAndAdd($k_hex, $P);
            $Rx_hex = Util::encodeHex($R->getX());
            $Rx_hex = str_pad($Rx_hex, 64, '0', STR_PAD_LEFT);
            // r = x1 mod n
            $r = Math::mod('0x' . $Rx_hex, $n_hex);
            // s = k^-1 * (e+d*r) mod n
            $edr = Math::add($e, Math::mul($d, $r));
            $invk = Math::invertm($k_hex, $n_hex);
            $kedr = Math::mul($invk, $edr);
            $s = Math::mod($kedr, $n_hex);
            // The signature is the pair (r,s)
            $signature = array('r' => Util::encodeHex($r), 's' => Util::encodeHex($s));
            $signature['r'] = str_pad($signature['r'], 64, '0', STR_PAD_LEFT);
            $signature['s'] = str_pad($signature['s'], 64, '0', STR_PAD_LEFT);
        } while (Math::cmp($r, '0') <= 0 || Math::cmp($s, '0') <= 0);
        $sig = array('sig_rs' => $signature, 'sig_hex' => self::serializeSig($signature['r'], $signature['s']));
        return $sig['sig_hex']['seq'];
    }

Usage Example

 /**
  * @param RequestInterface $request
  * @throws \Exception
  */
 protected function addSignatureHeader(RequestInterface $request)
 {
     if (null === $this->privateKey) {
         throw new \Exception('Please set your Private Key');
     }
     if (true == property_exists($this->network, 'isPortRequiredInUrl')) {
         if ($this->network->isPortRequiredInUrl === true) {
             $url = $request->getUriWithPort();
         } else {
             $url = $request->getUri();
         }
     } else {
         $url = $request->getUri();
     }
     $message = sprintf('%s%s', $url, $request->getBody());
     $signature = $this->privateKey->sign($message);
     $request->setHeader('x-signature', $signature);
 }