Example #1
0
 /**
  * @expectedException \InvalidArgumentException
  * @expectedExceptionMessage Integer too large, exceeds 64 bit
  */
 public function testSolveReadTooLong()
 {
     $math = EccFactory::getAdapter();
     $varint = new VarInt($math);
     $disallowed = $math->add($math->pow(2, 64), 1);
     $varint->solveReadSize($disallowed);
 }
Example #2
0
 public function testMultiPartyKeyGeneration()
 {
     $adapter = EccFactory::getAdapter();
     $generator = EccFactory::getNistCurves($adapter)->generator256();
     $messages = new MessageFactory($adapter);
     $alice = $generator->createPrivateKey();
     $bob = $generator->createPrivateKey();
     $carol = $generator->createPrivateKey();
     // Alice computes g^a and sends it to Bob.
     $bobX = $alice->createExchange($messages, $bob->getPublicKey());
     // Bob computes (g^a)^b = g^{ab} and sends it to Carol.
     $carolX = $carol->createExchange($messages, $bobX->createMultiPartyKey());
     // Carol computes (g^{ab})^c = g^{abc} and uses it as her secret.
     $carolSharedKey = $carolX->calculateSharedKey();
     // Bob computes g^b and sends it to Carol.
     $carolX = $carol->createExchange($messages, $bob->getPublicKey());
     // Carol computes (g^b)^c = g^{bc} and sends it to Alice.
     $aliceX = $alice->createExchange($messages, $carolX->createMultiPartyKey());
     // Alice computes (g^{bc})^a = g^{bca} = g^{abc} and uses it as her secret.
     $aliceSharedKey = $aliceX->calculateSharedKey();
     // Carol computes g^c and sends it to Alice.
     $aliceX = $carol->createExchange($messages, $alice->getPublicKey());
     // Alice computes (g^c)^a = g^{ca} and sends it to Bob.
     $bobX = $bob->createExchange($messages, $aliceX->createMultiPartyKey());
     // Bob computes (g^{ca})^b = g^{cab} = g^{abc} and uses it as his secret.
     $bobSharedKey = $bobX->calculateSharedKey();
     $this->assertTrue($bobSharedKey == $aliceSharedKey);
     $this->assertTrue($aliceSharedKey == $carolSharedKey);
     $this->assertTrue($carolSharedKey == $bobSharedKey);
 }
 /**
  * @expectedException \InvalidArgumentException
  * @expectedExceptionMessage Invalid base64
  */
 public function testInvalidBase64Data()
 {
     $data = "ab\$";
     $adapter = EccFactory::getAdapter();
     $serializer = new SshPublicKeySerializer($adapter, new UncompressedPointSerializer($adapter));
     $serializer->unserialize($data);
 }
 public function testGMP()
 {
     $math = \Mdanter\Ecc\EccFactory::getAdapter();
     $I_l = "e97a4d6be13f8f5804c0a76080428fc6d51260f74801678c4127045d2640af14";
     $private_key = "142018c66b43a95de58c1cf603446fc0da322bc15fb4df068b844b57c706dd05";
     $n = "115792089237316195423570985008687907852837564279074904382605163141518161494337";
     $gmp_I_l = gmp_init($I_l, 16);
     $gmp_private_key = gmp_init($private_key, 16);
     $gmp_add = gmp_add($gmp_I_l, $gmp_private_key);
     $gmp_add_res = gmp_strval($gmp_add, 10);
     $this->assertEquals("105604983404708440304568772161069255144976878830542744455590282065741265022740", gmp_strval($gmp_I_l));
     $this->assertEquals("9102967069016248707169900673545386030247334423973996501079368232055584775429", gmp_strval($gmp_private_key));
     $this->assertEquals("114707950473724689011738672834614641175224213254516740956669650297796849798169", gmp_strval($gmp_add));
     $this->assertEquals("114707950473724689011738672834614641175224213254516740956669650297796849798169", gmp_strval(gmp_div_r($gmp_add, gmp_init($n))));
     $this->assertEquals("-4", gmp_strval(gmp_cmp(0, gmp_div_r($gmp_add, $n))));
     $this->assertEquals("230500039711040884435309657843302549028061777533591645339274813439315011292506", gmp_strval(gmp_add(gmp_init($n), gmp_div_r($gmp_add, gmp_init($n)))));
     $gmp_mod2 = $math->mod($gmp_add_res, $n);
     $this->assertTrue(is_string($gmp_mod2));
     $this->assertEquals("114707950473724689011738672834614641175224213254516740956669650297796849798169", $gmp_mod2);
     $this->assertEquals("114707950473724689011738672834614641175224213254516740956669650297796849798169", $gmp_mod2);
     // when no base is provided both a resource and string work
     $this->assertEquals("114707950473724689011738672834614641175224213254516740956669650297796849798169", gmp_strval(gmp_init($gmp_mod2)));
     $this->assertEquals("114707950473724689011738672834614641175224213254516740956669650297796849798169", gmp_strval($gmp_mod2));
     // when base is provided it fails on HHVM when inputting a string
     $this->assertEquals("fd9a66324c8338b5ea4cc4568386ff87af448cb8a7b64692ccab4fb4ed478c19", gmp_strval(gmp_init($gmp_mod2), 16));
     // $this->assertEquals("fd9a66324c8338b5ea4cc4568386ff87af448cb8a7b64692ccab4fb4ed478c19", gmp_strval($gmp_mod2, 16));
     $this->assertEquals("fd9a66324c8338b5ea4cc4568386ff87af448cb8a7b64692ccab4fb4ed478c19", str_pad(gmp_strval(gmp_init($gmp_mod2), 16), 64, '0', STR_PAD_LEFT));
 }
Example #5
0
 public function testNetworkSerializer()
 {
     $network = Bitcoin::getDefaultNetwork();
     $parser = new NetworkMessageSerializer(Bitcoin::getDefaultNetwork());
     $factory = new Factory($network, new Random());
     $version = '1';
     $relayUntil = '9999999';
     $expiration = '9898989';
     $id = '123';
     $cancel = '0';
     $minVer = '0';
     $maxVer = '0';
     $priority = '50';
     $comment = new Buffer('comment');
     $statusBar = new Buffer('statusBar');
     $setCancel = [1, 2];
     $setSubVer = [50, 99];
     $detail = new AlertDetail($version, $relayUntil, $expiration, $id, $cancel, $minVer, $maxVer, $priority, $comment, $statusBar, $setCancel, $setSubVer);
     $adapter = EcAdapterFactory::getPhpEcc(new Math(), EccFactory::getSecgCurves()->generator256k1());
     $sig = new Signature($adapter, '1', '1');
     $alert = $factory->alert($detail, $sig);
     $serialized = $alert->getNetworkMessage()->getBuffer();
     $parsed = $parser->parse($serialized)->getPayload();
     /** @var \BitWasp\Bitcoin\Networking\Messages\Alert $parsed */
     $this->assertEquals($alert->getDetail(), $parsed->getDetail());
     $this->assertEquals($alert->getSignature()->getR(), $parsed->getSignature()->getR());
     $this->assertEquals($alert->getSignature()->getS(), $parsed->getSignature()->getS());
 }
Example #6
0
 /**
  * @param CertificateInfo $info
  * @return Sequence
  */
 public function getCertInfoAsn(CertificateInfo $info)
 {
     $curve = EccFactory::getSecgCurves()->curve256k1();
     if ($this->extension === null) {
         return new Sequence(new Integer($info->getSerialNo()), new Sequence(SigAlgorithmOidMapper::getSigAlgorithmOid($info->getSigAlgorithm())), $this->subjectSer->toAsn($info->getIssuerInfo()), new Sequence(new UTCTime($info->getValidityStart()->format(CertificateSerializer::UTCTIME_FORMAT)), new UTCTime($info->getValidityEnd()->format(CertificateSerializer::UTCTIME_FORMAT))), $this->subjectSer->toAsn($info->getSubjectInfo()), $this->getSubjectKeyASN($curve, $info->getPublicKey()));
     }
     return new Sequence(new Integer($info->getSerialNo()), new Sequence(SigAlgorithmOidMapper::getSigAlgorithmOid($info->getSigAlgorithm())), $this->subjectSer->toAsn($info->getIssuerInfo()), new Sequence(new UTCTime($info->getValidityStart()->format(CertificateSerializer::UTCTIME_FORMAT)), new UTCTime($info->getValidityEnd()->format(CertificateSerializer::UTCTIME_FORMAT))), $this->subjectSer->toAsn($info->getSubjectInfo()), $this->getSubjectKeyASN($curve, $info->getPublicKey()), $this->extension->apply($info));
 }
Example #7
0
 /**
  * @param string $sigAlgo
  * @return Hasher
  */
 public static function getHasher($sigAlgo)
 {
     if (array_key_exists($sigAlgo, self::$oidMap)) {
         $algo = explode("+", $sigAlgo)[1];
         return new Hasher(EccFactory::getAdapter(), $algo);
     }
     throw new \RuntimeException('Unsupported hashing algorithm.');
 }
Example #8
0
 /**
  * @return Binary
  */
 public function generateKey()
 {
     $generator = EccFactory::getNistCurves()->generator256();
     $key = $generator->createPrivateKey();
     $serializer = new DerPrivateKeySerializer();
     $serialized = $serializer->serialize($key);
     return new Binary($serialized);
 }
Example #9
0
 /**
  * Instantiate class, optionally taking Buffer or HEX.
  *
  * @param null|string|Buffer $input
  * @param MathAdapterInterface|null $math
  */
 public function __construct($input = null, MathAdapterInterface $math = null)
 {
     $this->math = $math ?: EccFactory::getAdapter();
     if (!$input instanceof Buffer) {
         $input = Buffer::hex($input, null, $this->math);
     }
     $this->string = $input->getBinary();
     $this->position = 0;
 }
 public function testVector()
 {
     $math = EccFactory::getAdapter();
     $factory = new TemplateFactory(null, $math);
     $factory->vector(function () {
         return;
     });
     $template = $factory->getTemplate();
     $this->assertEquals(1, count($template));
     $template = $factory->getTemplate()->getItems();
     $this->assertInstanceOf('BitWasp\\Buffertools\\Types\\Vector', $template[0]);
 }
Example #11
0
 function setVAPIDInfo($privateKey, $audience, $subject)
 {
     if (!USE_VAPID || !$privateKey || !$audience || !$subject) {
         return;
     }
     $builder = new Builder();
     $token = $builder->setAudience($audience)->setExpiration(time() + 86400)->setSubject($subject)->sign(new Sha256(), new Key($privateKey))->getToken();
     $this->additionalHeaders['Authorization'] = 'Bearer ' . $token;
     $privKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer());
     $privateKeyObject = $privKeySerializer->parse($privateKey);
     $publicKeyObject = $privateKeyObject->getPublicKey();
     $pointSerializer = new UncompressedPointSerializer(EccFactory::getAdapter());
     $this->additionalHeaders['Crypto-Key'] = 'p256ecdsa=' . Base64Url::encode(hex2bin($pointSerializer->serialize($publicKeyObject->getPoint())));
 }
Example #12
0
 /**
  *
  * @dataProvider getAdapters
  */
 public function testSecp256r1EquivalenceToNistP192(MathAdapterInterface $adapter)
 {
     $secpFactory = EccFactory::getSecgCurves($adapter);
     $nistFactory = EccFactory::getNistCurves($adapter);
     $signer = new Signer($adapter);
     $secret = $adapter->hexDec('DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F');
     $secpKey = $secpFactory->generator256r1()->getPrivateKeyFrom($secret);
     $nistKey = $nistFactory->generator256()->getPrivateKeyFrom($secret);
     $randomK = RandomGeneratorFactory::getRandomGenerator()->generate($secpKey->getPoint()->getOrder());
     $message = RandomGeneratorFactory::getRandomGenerator()->generate($secpKey->getPoint()->getOrder());
     $sigSecp = $signer->sign($secpKey, $message, $randomK);
     $sigNist = $signer->sign($nistKey, $message, $randomK);
     $this->assertEquals($sigNist->getR(), $sigSecp->getR());
     $this->assertEquals($sigNist->getS(), $sigSecp->getS());
 }
Example #13
0
 protected function setUp()
 {
     // file containing a json array of {compressed=>'', decompressed=>''} values
     // of compressed and uncompressed ECDSA public keys (testing secp256k1 curve)
     $file_comp = TEST_DATA_DIR . '/compression.json';
     if (!file_exists($file_comp)) {
         $this->fail('Key compression input data not found');
     }
     $file_sqrt = TEST_DATA_DIR . '/square_root_mod_p.json';
     if (!file_exists($file_sqrt)) {
         $this->fail('Square root input data not found');
     }
     $this->generator = EccFactory::getSecgCurves()->generator256k1();
     $this->compression_data = json_decode(file_get_contents($file_comp));
     $this->sqrt_data = json_decode(file_get_contents($file_sqrt));
 }
Example #14
0
 function get_public_key($privateKey)
 {
     $publicKeyVal = __('Your private key is invalid.', 'web-push');
     error_reporting(E_ERROR);
     try {
         $privKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer());
         $privateKeyObject = $privKeySerializer->parse($privateKey);
         $publicKeyObject = $privateKeyObject->getPublicKey();
         $pointSerializer = new UncompressedPointSerializer(EccFactory::getAdapter());
         $publicKeyVal = Base64Url::encode(hex2bin($pointSerializer->serialize($publicKeyObject->getPoint())));
     } catch (Exception $e) {
         // Ignore exceptions while getting the public key from the private key.
     }
     error_reporting(E_ALL);
     return $publicKeyVal;
 }
Example #15
0
 public function testReadVector()
 {
     $math = EccFactory::getAdapter();
     $varint = new VarInt($math);
     $vector = new Vector($varint, function (Parser &$parser) {
         return $parser->readBytes(16);
     });
     $eBuffer = Buffer::hex('010203040506070809000a0b0c0d0e0f');
     $hex = '03010203040506070809000a0b0c0d0e0f010203040506070809000a0b0c0d0e0f010203040506070809000a0b0c0d0e0f';
     $buffer = Buffer::hex($hex);
     $parser = new Parser($buffer);
     $array = $vector->read($parser);
     foreach ($array as $item) {
         $this->assertEquals($eBuffer->getBinary(), $item->getBinary());
     }
 }
Example #16
0
 public static function generate_vapid_options()
 {
     if (USE_VAPID) {
         if (!get_option('webpush_vapid_key')) {
             $generator = EccFactory::getNistCurves()->generator256();
             $privKeySerializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer());
             update_option('webpush_vapid_key', $privKeySerializer->serialize($generator->createPrivateKey()));
         }
         if (!get_option('webpush_vapid_subject')) {
             update_option('webpush_vapid_subject', 'mailto:' . get_option('admin_email'));
         }
         if (!get_option('webpush_vapid_audience')) {
             $parsedURL = parse_url(home_url('/', 'https'));
             update_option('webpush_vapid_audience', $parsedURL['scheme'] . '://' . $parsedURL['host'] . (isset($parsedURL['port']) ? ':' . $parsedURL['port'] : ''));
         }
     }
 }
Example #17
0
 /**
  * {@inheritdoc}
  */
 public function verify(JWKInterface $key, $data, $signature)
 {
     $this->checkKey($key);
     $signature = $this->convertBinToHex($signature);
     $part_length = $this->getSignaturePartLength();
     if (strlen($signature) !== 2 * $part_length) {
         return false;
     }
     $p = $this->getGenerator();
     $x = $this->convertBase64ToDec($key->getValue('x'));
     $y = $this->convertBase64ToDec($key->getValue('y'));
     $R = $this->convertHexToDec(substr($signature, 0, $part_length));
     $S = $this->convertHexToDec(substr($signature, $part_length));
     $hash = $this->convertHexToDec(hash($this->getHashAlgorithm(), $data));
     $public_key = $p->getPublicKeyFrom($x, $y);
     $signer = EccFactory::getSigner();
     return $signer->verify($public_key, new Signature($R, $S), $hash);
 }
 public function testCurve()
 {
     $math = EccFactory::getAdapter();
     $G = CurveFactory::getGeneratorByName("nist-p224");
     $algo = 'sha256';
     // Initialize private key and message hash (decimal)
     $privateKey = $G->getPrivateKeyFrom($this->math->hexDec('F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1'));
     $messageHash = $this->math->hexDec(hash($algo, "sample"));
     // Derive K
     $drbg = RandomGeneratorFactory::getHmacRandomGenerator($privateKey, $messageHash, $algo);
     $k = $drbg->generate($this->G->getOrder());
     //$this->assertEquals($this->math->hexdec($test->expectedK), $k);
     $signer = new Signer($this->math);
     $sig = $signer->sign($privateKey, $messageHash, $k);
     // R and S should be correct
     //$sR = $this->math->hexDec(substr(strtolower($test->expectedRS), 0, 64));
     //$sS = $this->math->hexDec(substr(strtolower($test->expectedRS), 64, 64));
     //$this->assertSame($sR, $sig->getR());
     //$this->assertSame($sS, $sig->getS());
 }
Example #19
0
 /**
  * @param string $payload          With padding
  * @param string $userPublicKey    Base 64 encoded (MIME or URL-safe)
  * @param string $userAuthToken    Base 64 encoded (MIME or URL-safe)
  * @param bool   $nativeEncryption Use OpenSSL (>PHP7.1)
  *
  * @return array
  */
 public static function encrypt($payload, $userPublicKey, $userAuthToken, $nativeEncryption)
 {
     $userPublicKey = Base64Url::decode($userPublicKey);
     $userAuthToken = Base64Url::decode($userAuthToken);
     // initialize utilities
     $math = EccFactory::getAdapter();
     $pointSerializer = new UncompressedPointSerializer($math);
     $generator = EccFactory::getNistCurves()->generator256();
     $curve = EccFactory::getNistCurves()->curve256();
     // get local key pair
     $localPrivateKeyObject = $generator->createPrivateKey();
     $localPublicKeyObject = $localPrivateKeyObject->getPublicKey();
     $localPublicKey = hex2bin($pointSerializer->serialize($localPublicKeyObject->getPoint()));
     // get user public key object
     $pointUserPublicKey = $pointSerializer->unserialize($curve, bin2hex($userPublicKey));
     $userPublicKeyObject = $generator->getPublicKeyFrom($pointUserPublicKey->getX(), $pointUserPublicKey->getY(), $generator->getOrder());
     // get shared secret from user public key and local private key
     $sharedSecret = hex2bin($math->decHex(gmp_strval($userPublicKeyObject->getPoint()->mul($localPrivateKeyObject->getSecret())->getX())));
     // generate salt
     $salt = openssl_random_pseudo_bytes(16);
     // section 4.3
     $ikm = !empty($userAuthToken) ? self::hkdf($userAuthToken, $sharedSecret, 'Content-Encoding: auth' . chr(0), 32) : $sharedSecret;
     // section 4.2
     $context = self::createContext($userPublicKey, $localPublicKey);
     // derive the Content Encryption Key
     $contentEncryptionKeyInfo = self::createInfo('aesgcm', $context);
     $contentEncryptionKey = self::hkdf($salt, $ikm, $contentEncryptionKeyInfo, 16);
     // section 3.3, derive the nonce
     $nonceInfo = self::createInfo('nonce', $context);
     $nonce = self::hkdf($salt, $ikm, $nonceInfo, 12);
     // encrypt
     // "The additional data passed to each invocation of AEAD_AES_128_GCM is a zero-length octet sequence."
     if (!$nativeEncryption) {
         list($encryptedText, $tag) = \AESGCM\AESGCM::encrypt($contentEncryptionKey, $nonce, $payload, '');
     } else {
         $encryptedText = openssl_encrypt($payload, 'aes-128-gcm', $contentEncryptionKey, OPENSSL_RAW_DATA, $nonce, $tag);
         // base 64 encoded
     }
     // return values in url safe base64
     return array('localPublicKey' => Base64Url::encode($localPublicKey), 'salt' => Base64Url::encode($salt), 'cipherText' => $encryptedText . $tag);
 }
Example #20
0
 /**
  * @return \Mdanter\Ecc\Primitives\GeneratorPoint
  */
 protected function getGenerator()
 {
     return EccFactory::getNistCurves()->generator521();
 }
Example #21
0
 private function getAdapter()
 {
     if (!is_null($this->adapter)) {
         return $this->adapter;
     }
     $this->adapter = EccFactory::getAdapter();
     return $this->adapter;
 }
Example #22
0
 /**
  * Load the generator to be used throughout
  */
 public static function getGenerator()
 {
     return EccFactory::getSecgCurves(self::getMath())->generator256k1();
 }
Example #23
0
 /**
  * @param int|string $integer
  * @param null|int $byteSize
  * @param MathAdapterInterface|null $math
  * @return Buffer
  */
 public static function int($integer, $byteSize = null, MathAdapterInterface $math = null)
 {
     $math = $math ?: EccFactory::getAdapter();
     $binary = pack("H*", $math->decHex($integer));
     return new self($binary, $byteSize, $math);
 }
 /**
  * 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;
 }
Example #25
0
 /**
  * @param $value
  *
  * @return string
  */
 private function convertDecToBin($value)
 {
     $value = gmp_strval($value, 10);
     $adapter = EccFactory::getAdapter();
     return hex2bin($adapter->decHex($value));
 }
Example #26
0
 public function IntVectors()
 {
     $math = EccFactory::getAdapter();
     return array(array('1', 1, '01', $math), array('1', null, '01', $math), array('20', 1, '14', $math));
 }
 /**
  * @expectedException \Exception
  */
 public function testNumToVarIntOutOfRange()
 {
     // Check that this is out of range (PHP's fault)
     $decimal = EccFactory::getAdapter()->pow(2, 32) + 1;
     Buffertools::numToVarInt($decimal);
 }
Example #28
0
<?php

// ------------------------------------------
// Step 0 - Create the application keys
// ------------------------------------------
// include composer autoloader
require '../vendor/autoload.php';
use Mdanter\Ecc\EccFactory;
$generator = EccFactory::getNistCurves()->generator256();
$private = $generator->createPrivateKey();
$public = $private->getPublicKey();
$adaptor = EccFactory::getAdapter();
$public_point = $public->getPoint();
// hexlify the integers
$private_hex = $adaptor->decHex($private->getSecret());
$public_hex = $adaptor->decHex($public_point->getX()) . $adaptor->decHex($public_point->getY());
// keys!
$keys = ['public' => $public_hex, 'private' => $private_hex];
var_dump($keys);
// Once we have EC Keys, we continue on step1.php file and fill in the data in config.php
Example #29
0
 /**
  * @param Adapter|null $adapter
  * @param EcdsaSigner|null $signer
  * @param KeyParser|null $parser
  */
 public function __construct(Adapter $adapter = null, Signer $signer = null, KeyParser $parser = null)
 {
     $this->adapter = $adapter ?: EccFactory::getAdapter();
     $this->signer = $signer ?: EccFactory::getSigner($this->adapter);
     $this->parser = $parser ?: new KeyParser($this->adapter);
 }
 public function testSignAndIsCanonical()
 {
     $cnt = (getenv('BITCOINLIB_EXTENSIVE_TESTING') ?: 1) * 10;
     $math = EccFactory::getAdapter();
     $G = EccFactory::getSecgCurves()->generator256k1();
     $private = $G->createPrivateKey();
     for ($i = 0; $i < $cnt; $i++) {
         $randomMsgHash = $math->hexDec((string) hash('sha256', 'random' . $i));
         $randomK = $math->hexDec((string) bin2hex(mcrypt_create_iv(32, \MCRYPT_DEV_URANDOM)));
         $signer = new \Mdanter\Ecc\Crypto\Signature\Signer($math);
         $sign = $signer->sign($private, $randomMsgHash, $randomK);
         $this->assertInstanceOf('Mdanter\\Ecc\\Crypto\\Signature\\Signature', $sign);
         $sig = RawTransaction::encode_signature($sign);
         $this->assertTrue(RawTransaction::is_canonical_signature($sig));
     }
 }