KeyPair.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace Elliptic\EC;
  3. use BN\BN;
  4. class KeyPair
  5. {
  6. public $ec;
  7. public $pub;
  8. public $priv;
  9. function __construct($ec, $options)
  10. {
  11. $this->ec = $ec;
  12. $this->priv = null;
  13. $this->pub = null;
  14. if( isset($options["priv"]) )
  15. $this->_importPrivate($options["priv"], $options["privEnc"]);
  16. if( isset($options["pub"]) )
  17. $this->_importPublic($options["pub"], $options["pubEnc"]);
  18. }
  19. public static function fromPublic($ec, $pub, $enc)
  20. {
  21. if( $pub instanceof KeyPair )
  22. return $pub;
  23. return new KeyPair($ec, array(
  24. "pub" => $pub,
  25. "pubEnc" => $enc
  26. ));
  27. }
  28. public static function fromPrivate($ec, $priv, $enc)
  29. {
  30. if( $priv instanceof KeyPair )
  31. return $priv;
  32. return new KeyPair($ec, array(
  33. "priv" => $priv,
  34. "privEnc" => $enc
  35. ));
  36. }
  37. public function validate()
  38. {
  39. $pub = $this->getPublic();
  40. if( $pub->isInfinity() )
  41. return array( "result" => false, "reason" => "Invalid public key" );
  42. if( !$pub->validate() )
  43. return array( "result" => false, "reason" => "Public key is not a point" );
  44. if( !$pub->mul($this->ec->curve->n)->isInfinity() )
  45. return array( "result" => false, "reason" => "Public key * N != O" );
  46. return array( "result" => true, "reason" => null );
  47. }
  48. public function getPublic($compact = false, $enc = "")
  49. {
  50. //compact is optional argument
  51. if( is_string($compact) )
  52. {
  53. $enc = $compact;
  54. $compact = false;
  55. }
  56. if( $this->pub === null )
  57. $this->pub = $this->ec->g->mul($this->priv);
  58. if( !$enc )
  59. return $this->pub;
  60. return $this->pub->encode($enc, $compact);
  61. }
  62. public function getPrivate($enc = false)
  63. {
  64. if( $enc === "hex" )
  65. return $this->priv->toString(16, 2);
  66. return $this->priv;
  67. }
  68. private function _importPrivate($key, $enc)
  69. {
  70. $this->priv = new BN($key, (isset($enc) && $enc) ? $enc : 16);
  71. // Ensure that the priv won't be bigger than n, otherwise we may fail
  72. // in fixed multiplication method
  73. $this->priv = $this->priv->umod($this->ec->curve->n);
  74. }
  75. private function _importPublic($key, $enc)
  76. {
  77. $x = $y = null;
  78. if ( is_object($key) ) {
  79. $x = $key->x;
  80. $y = $key->y;
  81. } elseif ( is_array($key) ) {
  82. $x = isset($key["x"]) ? $key["x"] : null;
  83. $y = isset($key["y"]) ? $key["y"] : null;
  84. }
  85. if( $x != null || $y != null )
  86. $this->pub = $this->ec->curve->point($x, $y);
  87. else
  88. $this->pub = $this->ec->curve->decodePoint($key, $enc);
  89. }
  90. //ECDH
  91. public function derive($pub) {
  92. return $pub->mul($this->priv)->getX();
  93. }
  94. //ECDSA
  95. public function sign($msg, $enc = false, $options = false) {
  96. return $this->ec->sign($msg, $this, $enc, $options);
  97. }
  98. public function verify($msg, $signature) {
  99. return $this->ec->verify($msg, $signature, $this);
  100. }
  101. public function inspect() {
  102. return "<Key priv: " . (isset($this->priv) ? $this->priv->toString(16, 2) : "") .
  103. " pub: " . (isset($this->pub) ? $this->pub->inspect() : "") . ">";
  104. }
  105. public function __debugInfo() {
  106. return ["priv" => $this->priv, "pub" => $this->pub];
  107. }
  108. }
  109. ?>