<commit_before><?php

namespace Afk11\Bitcoin\Key;

use \Afk11\Bitcoin\Bitcoin;
use \Afk11\Bitcoin\Exceptions\Base58ChecksumFailure;
use \Afk11\Bitcoin\Exceptions\InvalidPrivateKey;
use \Afk11\Bitcoin\NetworkInterface;
use \Afk11\Bitcoin\SerializableInterface;
use \Afk11\Bitcoin\Signature\Signature;
use \Afk11\Bitcoin\Signature\K\KInterface;
use \Afk11\Bitcoin\Math\Math;
use \Afk11\Bitcoin\Buffer;
use \Afk11\Bitcoin\Base58;
use \Afk11\Bitcoin\Crypto\Random\Random;
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\GeneratorPoint;

class PrivateKey implements KeyInterface, PrivateKeyInterface, SerializableInterface
{
    /**
     * @var int
     */
    protected $secretMultiplier;

    /**
     * @var \Mdanter\Ecc\CurveFp
     */
    protected $curve;

    /**
     * @var PublicKey
     */
    protected $publicKey = null;
    /**
     * @var
     */
    private $math;

    /**
     * @param Math $math
     * @param GeneratorPoint $generator
     * @param $hex
     * @param bool $compressed
     * @throws InvalidPrivateKey
     */
    public function __construct(
        Math $math,
        GeneratorPoint $generator,
        $hex,
        $compressed = false
    ) {
        if ($hex instanceof Buffer) {
            $hex = $hex->serialize('hex');
        }

        if (! self::isValidKey($hex)) {
            throw new InvalidPrivateKey('Invalid private key - must be less than curve order.');
        }

        $this->math = $math;
        $this->generator = $generator;
        $this->secretMultiplier = $this->math->hexDec($hex);
        $this->compressed       = $compressed;

        return $this;
    }

    /**
     * Instantiate the class when given a WIF private key.
     *
     * @param string $wif
     * @return PrivateKey
     * @throws Base58ChecksumFailure
     */
    public static function fromWIF($wif)
    {
        try {
            $data = Base58::decodeCheck($wif);
            $hex  = substr($data, 2, 64);
            $key  = new PrivateKey(Bitcoin::getMath(), Bitcoin::getGenerator(), $hex, (strlen($data) == 68));

        } catch (Base58ChecksumFailure $e) {
            throw new Base58ChecksumFailure('Failed to decode WIF - was it copied correctly?');
        }

        return $key;
    }

    /**
     * Generate a new private key from entropy
     *
     * @param bool $compressed
     * @return PrivateKey
     */
    public static function generateNew($compressed = false)
    {
        $keyBuffer = self::generateKey();
        $private   = new PrivateKey(Bitcoin::getMath(), Bitcoin::getGenerator(), $keyBuffer->serialize('hex'), $compressed);
        return $private;
    }

    /**
     * Check if the $hex string is a valid key, ie, less than the order of the curve.
     *
     * @param $hex
     * @return bool
     */
    public static function isValidKey($hex)
    {
        $math        = Bitcoin::getMath();
        $generator   = Bitcoin::getGenerator();

        // Less than the order of the curve
        $withinRange = $math->cmp($math->hexDec($hex), $generator->getOrder()) < 0;

        // Not zero
        $notZero     = ! ($math->cmp($math->hexDec($hex), 0) == 0);

        return $withinRange and $notZero;
    }
    /**
     * Generate a buffer containing a valid key
     *
     * @return Buffer
     * @throws \Afk11\Bitcoin\Exceptions\RandomBytesFailure
     */
    public static function generateKey()
    {
        $random = new Random();<commit_msg>PrivateKey::isValidKey: use && instead of and<commit_after><?php

namespace Afk11\Bitcoin\Key;

use \Afk11\Bitcoin\Bitcoin;
use \Afk11\Bitcoin\Exceptions\Base58ChecksumFailure;
use \Afk11\Bitcoin\Exceptions\InvalidPrivateKey;
use \Afk11\Bitcoin\NetworkInterface;
use \Afk11\Bitcoin\SerializableInterface;
use \Afk11\Bitcoin\Signature\Signature;
use \Afk11\Bitcoin\Signature\K\KInterface;
use \Afk11\Bitcoin\Math\Math;
use \Afk11\Bitcoin\Buffer;
use \Afk11\Bitcoin\Base58;
use \Afk11\Bitcoin\Crypto\Random\Random;
use Mdanter\Ecc\EccFactory;
use Mdanter\Ecc\GeneratorPoint;

class PrivateKey implements KeyInterface, PrivateKeyInterface, SerializableInterface
{
    /**
     * @var int
     */
    protected $secretMultiplier;

    /**
     * @var \Mdanter\Ecc\CurveFp
     */
    protected $curve;

    /**
     * @var PublicKey
     */
    protected $publicKey = null;
    /**
     * @var
     */
    private $math;

    /**
     * @param Math $math
     * @param GeneratorPoint $generator
     * @param $hex
     * @param bool $compressed
     * @throws InvalidPrivateKey
     */
    public function __construct(
        Math $math,
        GeneratorPoint $generator,
        $hex,
        $compressed = false
    ) {
        if ($hex instanceof Buffer) {
            $hex = $hex->serialize('hex');
        }

        if (! self::isValidKey($hex)) {
            throw new InvalidPrivateKey('Invalid private key - must be less than curve order.');
        }

        $this->math = $math;
        $this->generator = $generator;
        $this->secretMultiplier = $this->math->hexDec($hex);
        $this->compressed       = $compressed;

        return $this;
    }

    /**
     * Instantiate the class when given a WIF private key.
     *
     * @param string $wif
     * @return PrivateKey
     * @throws Base58ChecksumFailure
     */
    public static function fromWIF($wif)
    {
        try {
            $data = Base58::decodeCheck($wif);
            $hex  = substr($data, 2, 64);
            $key  = new PrivateKey(Bitcoin::getMath(), Bitcoin::getGenerator(), $hex, (strlen($data) == 68));

        } catch (Base58ChecksumFailure $e) {
            throw new Base58ChecksumFailure('Failed to decode WIF - was it copied correctly?');
        }

        return $key;
    }

    /**
     * Generate a new private key from entropy
     *
     * @param bool $compressed
     * @return PrivateKey
     */
    public static function generateNew($compressed = false)
    {
        $keyBuffer = self::generateKey();
        $private   = new PrivateKey(Bitcoin::getMath(), Bitcoin::getGenerator(), $keyBuffer->serialize('hex'), $compressed);
        return $private;
    }

    /**
     * Check if the $hex string is a valid key, ie, less than the order of the curve.
     *
     * @param $hex
     * @return bool
     */
    public static function isValidKey($hex)
    {
        $math        = Bitcoin::getMath();
        $generator   = Bitcoin::getGenerator();

        // Less than the order of the curve
        $withinRange = $math->cmp($math->hexDec($hex), $generator->getOrder()) < 0;

        // Not zero
        $notZero     = ! ($math->cmp($math->hexDec($hex), 0) == 0);

        return $withinRange && $notZero;
    }
    /**
     * Generate a buffer containing a valid key
     *
     * @return Buffer
     * @throws \Afk11\Bitcoin\Exceptions\RandomBytesFailure
     */
    public static function generateKey()
    {
        $random = new Random();
{'fraction_non_alphanumeric': 0.12832437145763698, 'fraction_numerical': 0.013370149687545414, 'mean_word_length': 2.2709125475285172, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5863848', 'n_tokens_mistral': 2153, 'n_tokens_neox': 2083, 'n_words': 496}