Skip to content

Commit

Permalink
Merge pull request #4 from kadena-php/feature/add-fromstring-methods-…
Browse files Browse the repository at this point in the history
…to-keyfactory

Add fromstring methods to keyfactory
  • Loading branch information
HergenD authored Jan 10, 2023
2 parents 2b6bd7a + 5a51339 commit d8b3110
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 2 deletions.
3 changes: 1 addition & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ Commands have to be signed before sending them to the Kadena API. To support thi

Let's create a signer with a public key of `example-key` and the `coin.transfer` capability. As a signer can have multiple or no capabilities, all `Capability` objects should be wrapped in a `CapabilityCollection` object:
```php
// Just as an example, keys should be created using the KeyFactory
$publicKey = new PublicKey(new SignaturePublicKey(new HiddenString('example-key')));
$publicKey = KeyFactory::publicKeyFromHex('not-a-real-key');

$transferCapability = new Capability(
name: 'coin.transfer',
Expand Down
7 changes: 7 additions & 0 deletions src/Contracts/Crypto/KeyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
namespace Kadena\Contracts\Crypto;

use Kadena\ValueObjects\Signer\KeyPair;
use Kadena\ValueObjects\Signer\PublicKey;
use Kadena\ValueObjects\Signer\SecretKey;

interface KeyFactory
{
public static function generate(): KeyPair;

public static function publicKeyFromBytes(string $publicKey): PublicKey;
public static function publicKeyFromHex(string $publicKey): PublicKey;
public static function secretKeyFromBytes(string $secretKey): SecretKey;
public static function secretKeyFromHex(string $secretKey): SecretKey;
}
36 changes: 36 additions & 0 deletions src/Crypto/KeyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@
use Kadena\ValueObjects\Signer\KeyPair;
use Kadena\ValueObjects\Signer\PublicKey;
use Kadena\ValueObjects\Signer\SecretKey;
use ParagonIE\ConstantTime\Hex;
use ParagonIE\Halite\Alerts\CannotPerformOperation;
use ParagonIE\Halite\Alerts\InvalidKey;
use ParagonIE\Halite\Asymmetric\SignaturePublicKey;
use ParagonIE\Halite\Asymmetric\SignatureSecretKey;
use ParagonIE\HiddenString\HiddenString;
use SodiumException;

final class KeyFactory implements KeyFactoryContract
Expand All @@ -26,4 +30,36 @@ public static function generate(): KeyPair
secretKey: new SecretKey($keyPair->getSecretKey())
);
}

/**
* @throws InvalidKey
*/
public static function publicKeyFromBytes(string $publicKey): PublicKey
{
return new PublicKey(new SignaturePublicKey(new HiddenString($publicKey)));
}

/**
* @throws InvalidKey
*/
public static function publicKeyFromHex(string $publicKey): PublicKey
{
return self::publicKeyFromBytes(Hex::decode($publicKey));
}

/**
* @throws InvalidKey
*/
public static function secretKeyFromBytes(string $secretKey): SecretKey
{
return new SecretKey(new SignatureSecretKey(new HiddenString($secretKey)));
}

/**
* @throws InvalidKey
*/
public static function secretKeyFromHex(string $secretKey): SecretKey
{
return self::secretKeyFromBytes(Hex::decode($secretKey));
}
}
49 changes: 49 additions & 0 deletions tests/Unit/Crypto/KeyFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Kadena\ValueObjects\Signer\KeyPair;
use Kadena\ValueObjects\Signer\PublicKey;
use Kadena\ValueObjects\Signer\SecretKey;
use ParagonIE\ConstantTime\Hex;
use PHPUnit\Framework\TestCase;

final class KeyFactoryTest extends TestCase
Expand All @@ -19,4 +20,52 @@ public function it_should_generate_a_key_pair(): void
$this->assertInstanceOf(PublicKey::class, $keyPair->publicKey);
$this->assertInstanceOf(SecretKey::class, $keyPair->secretKey);
}

/** @test */
public function it_should_create_a_public_key_from_a_binary_string(): void
{
$keyPair = KeyFactory::generate();

$binaryString = $keyPair->publicKey->key->getRawKeyMaterial();

$actual = KeyFactory::publicKeyFromBytes($binaryString);

$this->assertEquals($keyPair->publicKey->key->getRawKeyMaterial(), $actual->key->getRawKeyMaterial());
}

/** @test */
public function it_should_create_a_public_key_from_a_hex_encoded_string(): void
{
$keyPair = KeyFactory::generate();

$hexString = Hex::encode($keyPair->publicKey->key->getRawKeyMaterial());

$actual = KeyFactory::publicKeyFromHex($hexString);

$this->assertEquals($keyPair->publicKey->key->getRawKeyMaterial(), $actual->key->getRawKeyMaterial());
}

/** @test */
public function it_should_create_a_secret_key_from_a_binary_string(): void
{
$keyPair = KeyFactory::generate();

$binaryString = $keyPair->secretKey->key->getRawKeyMaterial();

$actual = KeyFactory::secretKeyFromBytes($binaryString);

$this->assertEquals($keyPair->secretKey->key->getRawKeyMaterial(), $actual->key->getRawKeyMaterial());
}

/** @test */
public function it_should_create_a_secret_key_from_a_hex_encoded_string(): void
{
$keyPair = KeyFactory::generate();

$hexString = Hex::encode($keyPair->secretKey->key->getRawKeyMaterial());

$actual = KeyFactory::secretKeyFromHex($hexString);

$this->assertEquals($keyPair->secretKey->key->getRawKeyMaterial(), $actual->key->getRawKeyMaterial());
}
}

0 comments on commit d8b3110

Please sign in to comment.