/** * @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); }
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)); }
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()); }
/** * @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)); }
/** * @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.'); }
/** * @return Binary */ public function generateKey() { $generator = EccFactory::getNistCurves()->generator256(); $key = $generator->createPrivateKey(); $serializer = new DerPrivateKeySerializer(); $serialized = $serializer->serialize($key); return new Binary($serialized); }
/** * 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]); }
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()))); }
/** * * @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()); }
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)); }
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; }
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()); } }
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'] : '')); } } }
/** * {@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()); }
/** * @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); }
/** * @return \Mdanter\Ecc\Primitives\GeneratorPoint */ protected function getGenerator() { return EccFactory::getNistCurves()->generator521(); }
private function getAdapter() { if (!is_null($this->adapter)) { return $this->adapter; } $this->adapter = EccFactory::getAdapter(); return $this->adapter; }
/** * Load the generator to be used throughout */ public static function getGenerator() { return EccFactory::getSecgCurves(self::getMath())->generator256k1(); }
/** * @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; }
/** * @param $value * * @return string */ private function convertDecToBin($value) { $value = gmp_strval($value, 10); $adapter = EccFactory::getAdapter(); return hex2bin($adapter->decHex($value)); }
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); }
<?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
/** * @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)); } }