init
This commit is contained in:
+128
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
namespace Elliptic\EdDSA;
|
||||
|
||||
use Elliptic\Utils;
|
||||
|
||||
class KeyPair {
|
||||
public $eddsa;
|
||||
public $_pubBytes;
|
||||
/**
|
||||
* @param {\Elliptic\EdDSA} eddsa - instance
|
||||
* @param {Object} params - public/private key parameters
|
||||
*
|
||||
* @param {Array<Byte>} [params.secret] - secret seed bytes
|
||||
* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
|
||||
* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
|
||||
*
|
||||
*/
|
||||
function __construct($eddsa, #[\SensitiveParameter]
|
||||
$params) {
|
||||
$this->eddsa = $eddsa;
|
||||
$this->_secret = isset($params["secret"]) ? Utils::parseBytes($params["secret"]) : null;
|
||||
if (!isset($params["pub"])) {
|
||||
$this->_pub = null;
|
||||
$this->_pubBytes = null;
|
||||
return;
|
||||
}
|
||||
if ($eddsa->isPoint($params["pub"]))
|
||||
$this->_pub = $params["pub"];
|
||||
else
|
||||
$this->_pubBytes = Utils::parseBytes($params["pub"]);
|
||||
}
|
||||
|
||||
public static function fromPublic($eddsa, $pub) {
|
||||
if ($pub instanceof KeyPair)
|
||||
return $pub;
|
||||
return new KeyPair($eddsa, [ "pub" => $pub ]);
|
||||
}
|
||||
|
||||
public static function fromSecret($eddsa, #[\SensitiveParameter]
|
||||
$secret) {
|
||||
if ($secret instanceof KeyPair)
|
||||
return $secret;
|
||||
return new KeyPair($eddsa, [ "secret" => $secret ]);
|
||||
}
|
||||
|
||||
private $_secret;
|
||||
public function secret() {
|
||||
return $this->_secret;
|
||||
}
|
||||
|
||||
public function pubBytes() {
|
||||
if (!$this->_pubBytes)
|
||||
$this->_pubBytes = $this->eddsa->encodePoint($this->pub());
|
||||
return $this->_pubBytes;
|
||||
}
|
||||
|
||||
private $_pub;
|
||||
public function pub() {
|
||||
if (!$this->_pub) {
|
||||
if ($this->_pubBytes)
|
||||
$this->_pub = $this->eddsa->decodePoint($this->_pubBytes);
|
||||
else
|
||||
$this->_pub = $this->eddsa->g->mul($this->priv());
|
||||
}
|
||||
return $this->_pub;
|
||||
}
|
||||
|
||||
private $_privBytes;
|
||||
public function privBytes() {
|
||||
if (!$this->_privBytes) {
|
||||
$eddsa = $this->eddsa;
|
||||
$hash = $this->hash();
|
||||
$lastIx = $eddsa->encodingLength - 1;
|
||||
|
||||
$a = array_slice($hash, 0, $eddsa->encodingLength);
|
||||
$a[0] &= 248;
|
||||
$a[$lastIx] &= 127;
|
||||
$a[$lastIx] |= 64;
|
||||
$this->_privBytes = $a;
|
||||
}
|
||||
return $this->_privBytes;
|
||||
}
|
||||
|
||||
private $_priv;
|
||||
public function priv() {
|
||||
if (!$this->_priv) {
|
||||
$this->_priv = $this->eddsa->decodeInt($this->privBytes());
|
||||
}
|
||||
return $this->_priv;
|
||||
}
|
||||
|
||||
private $_hash;
|
||||
public function hash() {
|
||||
if (!$this->_hash) {
|
||||
// TODO: !!!
|
||||
$hash = hash_init('sha512');
|
||||
hash_update($hash, Utils::toBin($this->secret()));
|
||||
$this->_hash = Utils::toArray( hash_final($hash), 'hex' );
|
||||
}
|
||||
return $this->_hash;
|
||||
}
|
||||
|
||||
private $_messagePrefix;
|
||||
public function messagePrefix() {
|
||||
if (!$this->_messagePrefix) {
|
||||
$this->_messagePrefix = array_slice($this->hash(), $this->eddsa->encodingLength);
|
||||
}
|
||||
return $this->_messagePrefix;
|
||||
}
|
||||
|
||||
public function sign($message) {
|
||||
assert($this->_secret); //, 'KeyPair can only verify');
|
||||
return $this->eddsa->sign($message, $this);
|
||||
}
|
||||
|
||||
public function verify($message, $sig) {
|
||||
return $this->eddsa->verify($message, $sig, $this);
|
||||
}
|
||||
|
||||
public function getSecret($enc = false) {
|
||||
assert($this->_secret); //, 'KeyPair is public only');
|
||||
return Utils::encode($this->secret(), $enc);
|
||||
}
|
||||
|
||||
public function getPublic($enc = false) {
|
||||
return Utils::encode($this->pubBytes(), $enc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace Elliptic\EdDSA;
|
||||
|
||||
use Elliptic\Utils;
|
||||
use BN\BN;
|
||||
|
||||
class Signature {
|
||||
|
||||
public $eddsa;
|
||||
|
||||
/**
|
||||
* @param {EdDSA} eddsa - eddsa instance
|
||||
* @param {Array<Bytes>|Object} sig -
|
||||
* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
|
||||
* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
|
||||
* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
|
||||
* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
|
||||
*/
|
||||
function __construct($eddsa, $sig) {
|
||||
$this->eddsa = $eddsa;
|
||||
|
||||
if (is_string($sig))
|
||||
$sig = Utils::parseBytes($sig);
|
||||
|
||||
if (is_array($sig) && !isset($sig["R"])) {
|
||||
$sig = [
|
||||
"R" => array_slice($sig, 0, $eddsa->encodingLength),
|
||||
"S" => array_slice($sig, $eddsa->encodingLength)
|
||||
];
|
||||
}
|
||||
|
||||
assert($sig["R"] && $sig["S"]); //, 'Signature without R or S');
|
||||
|
||||
if ($eddsa->isPoint($sig["R"]))
|
||||
$this->_R = $sig["R"];
|
||||
if ($sig["S"] instanceof BN)
|
||||
$this->_S = $sig["S"];
|
||||
|
||||
$this->_Rencoded = is_array($sig["R"]) ? $sig["R"] : (isset($sig["Rencoded"]) ?$sig["Rencoded"] : null);
|
||||
$this->_Sencoded = is_array($sig["S"]) ? $sig["S"] : (isset($sig["Sencoded"]) ?$sig["Sencoded"] : null);
|
||||
}
|
||||
|
||||
private $_S;
|
||||
public function S() {
|
||||
if (!$this->_S) {
|
||||
$this->_S = $this->eddsa->decodeInt($this->Sencoded());
|
||||
}
|
||||
return $this->_S;
|
||||
}
|
||||
|
||||
private $_R;
|
||||
public function R() {
|
||||
if (!$this->_R) {
|
||||
$this->_R = $this->eddsa->decodePoint($this->Rencoded());
|
||||
}
|
||||
return $this->_R;
|
||||
}
|
||||
|
||||
private $_Rencoded;
|
||||
public function Rencoded() {
|
||||
if (!$this->_Rencoded) {
|
||||
$this->_Rencoded = $this->eddsa->encodePoint($this->R());
|
||||
}
|
||||
return $this->_Rencoded;
|
||||
}
|
||||
|
||||
private $_Sencoded;
|
||||
public function Sencoded() {
|
||||
if (!$this->_Sencoded) {
|
||||
$this->_Sencoded = $this->eddsa->encodeInt($this->S());
|
||||
}
|
||||
return $this->_Sencoded;
|
||||
}
|
||||
|
||||
public function toBytes() {
|
||||
return array_merge($this->Rencoded(), $this->Sencoded());
|
||||
}
|
||||
|
||||
public function toHex() {
|
||||
return strtoupper(Utils::encode($this->toBytes(), 'hex'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user