/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Invalid base64 */ public function testInvalidBase64Data() { $data = "ab\$"; $adapter = EccFactory::getAdapter(); $serializer = new SshPublicKeySerializer($adapter, new UncompressedPointSerializer($adapter)); $serializer->unserialize($data); }
/** * @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); }
/** * */ public function __construct() { if (!class_exists('\\Mdanter\\Ecc\\EccFactory')) { throw new \RuntimeException("The library 'mdanter/ecc' is required to use Elliptic Curves based algorithm algorithms"); } $this->adapter = EccFactory::getAdapter(); }
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)); }
/** * Constructor * * @param $service * @param $private_key * @param $public_key * @param bool $debug */ public function __construct($service, $private_key, $public_key, $debug = FALSE) { $this->math_adapter = EccFactory::getAdapter(); $this->service_name = $service; $this->private_key = $private_key; $this->public_key = $public_key; $this->debug = $debug; }
/** * @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.'); }
/** * 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()))); }
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 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); }
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)); } }
<?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
public function IntVectors() { $math = EccFactory::getAdapter(); return array(array('1', 1, '01', $math), array('1', null, '01', $math), array('20', 1, '14', $math)); }
/** * @param InputInterface $input * @param OutputInterface $output * @param QuestionHelper $helper * @param string $curveName * @param bool $useEncryption * @return array */ public function generateKeyData(InputInterface $input, OutputInterface $output, QuestionHelper $helper, $curveName, $useEncryption) { if (!is_bool($useEncryption)) { throw new \InvalidArgumentException('useEncryption parameter must be a boolean'); } /** * @var GeneratorPoint $generator */ list(, $generator) = Curves::load($curveName); $key = $generator->createPrivateKey(); if ($useEncryption) { $password = $this->promptForPassword($input, $output, $helper); $encrypted = new EncryptedPrivateKey($key, 'AES-128-CBC', random_bytes(16)); $serializer = new EncryptedPrivateKeySerializer(new DerPrivateKeySerializer()); $keyData = $serializer->serialize($encrypted, $password); } else { $serializer = new PemPrivateKeySerializer(new DerPrivateKeySerializer()); $keyData = $serializer->serialize($key); } $adapter = EccFactory::getAdapter(); $publicKey = $key->getPublicKey(); $publicSerializer = new SshPublicKeySerializer($adapter, new UncompressedPointSerializer($adapter)); $publicData = $publicSerializer->serialize($curveName, $publicKey); $localUser = posix_getpwuid(posix_geteuid()); $localHost = gethostname(); $publicData = sprintf("ecdsa-sha2-%s %s %s@%s\n", $curveName, $publicData, $localUser['name'], $localHost); return [$keyData, $publicData]; }
/** * @param $value * * @return string */ private function convertDecToBin($value) { $value = gmp_strval($value, 10); $adapter = EccFactory::getAdapter(); return hex2bin($adapter->decHex($value)); }
/** * @param $value * * @return string */ private function convertDecToHex($value) { $value = gmp_strval($value, 10); return EccFactory::getAdapter()->decHex($value); }
private static function getUncompressedKeys(PrivateKeyInterface $privateKeyObject) { $pointSerializer = new UncompressedPointSerializer(EccFactory::getAdapter()); $vapid['publicKey'] = base64_encode(hex2bin($pointSerializer->serialize($privateKeyObject->getPublicKey()->getPoint()))); $vapid['privateKey'] = base64_encode(hex2bin(str_pad(gmp_strval($privateKeyObject->getSecret(), 16), 2 * self::PRIVATE_KEY_LENGTH, '0', STR_PAD_LEFT))); return $vapid; }
/** * @expectedException \Exception * @expectedExceptionMessage Bit string length must be a multiple of 8 */ public function testInvalidFlipLength() { $math = EccFactory::getAdapter(); $u = new Uint8($math, 1); $u->flipBits('0'); }
private function getAdapter() { if (!is_null($this->adapter)) { return $this->adapter; } $this->adapter = EccFactory::getAdapter(); return $this->adapter; }
<?php require "../vendor/autoload.php"; use Mdanter\Ecc\Serializer\PublicKey\DerPublicKeySerializer; use Mdanter\X509\Serializer\Certificates\CertificateSubjectSerializer; use Mdanter\X509\Serializer\Signature\DerSignatureSerializer; $curveName = 'secp256k1'; $hasherName = 'sha512'; $serialNo = 0; $math = \Mdanter\Ecc\EccFactory::getAdapter(); $f = new \Mdanter\X509\Factory(); $domain = $f->getDomain($math, $curveName, $hasherName); $G = $domain->getGenerator(); $randomInt = \Mdanter\Ecc\Random\RandomGeneratorFactory::getUrandomGenerator()->generate($G->getOrder()); $k = $G->getPrivateKeyFrom($randomInt); $issuerDetails = ['commonName' => 'test CA']; $issuerSubject = new \Mdanter\X509\Certificates\CertificateSubject($issuerDetails); $ca = $f->getCA($math, $domain, $issuerSubject); $serializer = new \Mdanter\X509\Serializer\Certificates\CertificateSerializer(new CertificateSubjectSerializer(), new DerPublicKeySerializer(), new DerSignatureSerializer()); $validityStart = new DateTime('now'); $validityEnd = new DateTime('now'); $validityEnd->modify("+1 year"); $info = new \Mdanter\X509\Certificates\CertificateInfo(0, $domain->getSigAlgorithm(), $issuerSubject, $issuerSubject, $k->getPublicKey(), $validityStart, $validityEnd); $usage = new \Mdanter\X509\Extensions\Extension\KeyUsage(null); $usage->addKeyUsage(0); $usage->addKeyUsage(1); $usage->addKeyUsage(5); var_dump($usage->getBitString()); $certificate = $ca->createCertificate($serializer, $info, $k); echo $serializer->serialize($certificate);
/** * 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 string $value * * @return string */ private static function convertDecToBin($value) { $adapter = EccFactory::getAdapter(); return hex2bin($adapter->decHex($value)); }
/** * @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); }
/** * @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); }
/** * @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); }
/** * Decode Signature * * This function extracts the r and s parameters from a DER encoded * signature. No checking on the validity of the numbers. * * @param string $signature * @return array */ public static function decode_signature($signature) { $math = EccFactory::getAdapter(); $r_start = 8; $r_length = $math->hexDec(substr($signature, 6, 2)) * 2; $r_end = $r_start + $r_length; $r = substr($signature, $r_start, $r_length); $s_start = $r_end + 4; $s_length = $math->hexDec(substr($signature, $r_end + 2, 2)) * 2; $s = substr($signature, $s_start, $s_length); return array('r' => $r, 's' => $s, 'hash_type' => substr($signature, -2), 'last_byte_s' => substr($s, -2)); }