public function test() { $privKey = hash('sha256', 'private key', true); $msg32 = hash('sha256', 'msg', true); $pub_t = ''; /** @var resource $pub_t */ $context = TestCase::getContext(); // Create public key of our private key $this->assertEquals(1, secp256k1_ec_pubkey_create($context, $pub_t, $privKey)); // Create recoverable signature $r_sig_t = ''; /** @var resource $r_sig_t */ $this->assertEquals(1, secp256k1_ecdsa_sign_recoverable($context, $r_sig_t, $msg32, $privKey)); $this->assertEquals(SECP256K1_TYPE_RECOVERABLE_SIG, get_resource_type($r_sig_t)); // Recover public key from the signature $r_pubkey_t = ''; /** @var resource $r_pubkey_t */ $this->assertEquals(1, secp256k1_ecdsa_recover($context, $r_pubkey_t, $r_sig_t, $msg32)); // Compare the two public keys $sPubkey = ''; $srPubkey = ''; $this->assertEquals(1, secp256k1_ec_pubkey_serialize($context, $sPubkey, $pub_t, 0)); $this->assertEquals(1, secp256k1_ec_pubkey_serialize($context, $srPubkey, $r_pubkey_t, 0)); $this->assertEquals($sPubkey, $srPubkey); // Double check that serialize(sig) == serialize(parse(serialize(sig)) $sSig = ''; /** @var resource $sSig */ $recid = ''; secp256k1_ecdsa_recoverable_signature_serialize_compact($context, $r_sig_t, $sSig, $recid); $parsedSig = ''; /** @var resource $parsedSig */ $this->assertEquals(1, secp256k1_ecdsa_recoverable_signature_parse_compact($context, $parsedSig, $sSig, $recid)); $sSigAgain = ''; $recidAgain = ''; secp256k1_ecdsa_recoverable_signature_serialize_compact($context, $parsedSig, $sSigAgain, $recidAgain); // Prepare expected DER sig $rl = 32; $r = substr($sSig, 0, 32); if (ord($sSig[0]) > 0x80) { $rl++; $r = "" . $r; } $sl = 32; $s = substr($sSig, 32, 32); if (ord($sSig[32]) > 0x80) { $sl++; $s = "" . $s; } $t = 4 + $rl + $sl; $der = "0" . chr($t) . "" . chr($rl) . $r . "" . chr($sl) . $s; $plain = ''; /** @var resource $plain */ // Test that conversion is successful $this->assertEquals(1, secp256k1_ecdsa_recoverable_signature_convert($context, $plain, $r_sig_t)); // Test the converted sig's DER output matches what we expect $derSer = ''; $this->assertEquals(1, secp256k1_ecdsa_signature_serialize_der($context, $derSer, $plain)); $this->assertEquals($der, $derSer); }
/** * @param PublicKey $publicKey * @return BufferInterface */ private function doSerialize(PublicKey $publicKey) { $serialized = ''; $isCompressed = $publicKey->isCompressed(); if (!secp256k1_ec_pubkey_serialize($this->ecAdapter->getContext(), $publicKey->getResource(), $isCompressed, $serialized)) { throw new \RuntimeException('Secp256k1: Failed to serialize public key'); } return new Buffer($serialized, $isCompressed ? PublicKey::LENGTH_COMPRESSED : PublicKey::LENGTH_UNCOMPRESSED, $this->ecAdapter->getMath()); }
/** * @param $hexPrivkey * @param $fcompressed * @param $expectedKey * @param $eResult */ public function genericTest($context, $hexPrivkey, $fcompressed, $expectedKey, $eResult) { $secretKey = $this->toBinary32($hexPrivkey); /** @var resource $pubkey */ $pubkey = ''; $this->assertEquals($eResult, secp256k1_ec_pubkey_create($context, $secretKey, $pubkey)); $this->assertEquals(SECP256K1_TYPE_PUBKEY, get_resource_type($pubkey)); $serialized = ''; secp256k1_ec_pubkey_serialize($context, $pubkey, $fcompressed, $serialized); $this->assertEquals($expectedKey, bin2hex($serialized)); $this->assertEquals($fcompressed ? 33 : 65, strlen($serialized)); }
/** * @param $publicKey * @param $tweak * @param $expectedPublicKey * @param $eMul */ private function genericTest($context, $publicKey, $tweak, $expectedPublicKey, $eMul, $compressed) { $publicKey = $this->toBinary32($publicKey); $tweak = $this->toBinary32($tweak); $p = ''; secp256k1_ec_pubkey_parse($context, $publicKey, $p); $result = secp256k1_ec_pubkey_tweak_mul($context, $p, $tweak); $this->assertEquals($eMul, $result); $ser = ''; secp256k1_ec_pubkey_serialize($context, $p, $compressed, $ser); $this->assertEquals($expectedPublicKey, bin2hex($ser)); }
/** * @param $publicKey * @param $tweak * @param $expectedPublicKey * @param $eAdd */ private function genericTest($context, $publicKey, $tweak, $expectedPublicKey, $eAdd, $compressed) { $publicKey = $this->toBinary32($publicKey); /** @var resource $p */ $p = ''; secp256k1_ec_pubkey_parse($context, $p, $publicKey); $tweak = $this->toBinary32($tweak); $result = secp256k1_ec_pubkey_tweak_add($context, $p, $tweak); $this->assertEquals($eAdd, $result); $pSer = ''; secp256k1_ec_pubkey_serialize($context, $pSer, $p, $compressed); $this->assertEquals(bin2hex($pSer), $expectedPublicKey); }
/** * @return resource * @throws \Exception */ private function clonePubkey() { $context = $this->ecAdapter->getContext(); /** @var resource $serialized */ $serialized = ''; if (1 !== secp256k1_ec_pubkey_serialize($context, $this->pubkey_t, $this->compressed, $serialized)) { throw new \Exception('Secp256k1: pubkey serialize'); } /** @var resource $clone */ $clone = ''; if (1 !== secp256k1_ec_pubkey_parse($context, $serialized, $clone)) { throw new \Exception('Secp256k1 pubkey parse'); } return $clone; }
public function testVerifyCompact() { $context = TestCase::getContext(); $recid = 1; $compressed = 0; $sig = pack("H*", 'fe5fe404f3d8c21e1204a08c38ff3912d43c5a22541d2f1cdc4977cbcad240015a3b6e9040f62cacf016df4fef9412091592e4908e5e3a7bd2a42a4d1be01951'); /** @var resource $s */ $s = ''; $this->assertEquals(1, secp256k1_ecdsa_recoverable_signature_parse_compact($context, $s, $sig, $recid)); $privateKey = pack("H*", 'fbb80e8a0f8af4fb52667e51963ac9860c192981f329debcc5d123a492a726af'); $publicKey = ''; $this->assertEquals(1, secp256k1_ec_pubkey_create($context, $publicKey, $privateKey)); $ePubKey = ''; $this->assertEquals(1, secp256k1_ec_pubkey_serialize($context, $ePubKey, $publicKey, $compressed)); $msg = pack("H*", '03acc83ba10066e791d51e8a8eb90ec325feea7251cb8f979996848fff551d13'); $recPubKey = ''; $this->assertEquals(1, secp256k1_ecdsa_recover($context, $recPubKey, $s, $msg)); $serPubKey = ''; $this->assertEquals(1, secp256k1_ec_pubkey_serialize($context, $serPubKey, $recPubKey, $compressed)); $this->assertEquals($ePubKey, $serPubKey); }
function generateKeyPair() { // Create a context: $ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY); do { // Generate random str: $privkey = mcrypt_create_iv(32, \MCRYPT_DEV_URANDOM); // Attempt to verify that it's a valid private key: } while (!(bool) secp256k1_ec_seckey_verify($ctx, $privkey)); $pubkey = null; $pubkeyRef = null; // Create the public key (note: For additional safety, check this equals 1): secp256k1_ec_pubkey_create($ctx, $privkey, $pubkeyRef); // Serialise it: secp256k1_ec_pubkey_serialize($ctx, $pubkeyRef, false, $pubkey); // Done: return array('private' => $privkey, 'public' => $pubkey); }