[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/ -> libsodium.php (source)

   1  <?php
   2  
   3  /**
   4   * libsodium Key Handler
   5   *
   6   * Different NaCl implementations store the key differently.
   7   * https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ elaborates.
   8   * libsodium appears to use the same format as SUPERCOP.
   9   *
  10   * PHP version 5
  11   *
  12   * @author    Jim Wigginton <terrafrost@php.net>
  13   * @copyright 2015 Jim Wigginton
  14   * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
  15   * @link      http://phpseclib.sourceforge.net
  16   */
  17  
  18  namespace phpseclib3\Crypt\EC\Formats\Keys;
  19  
  20  use phpseclib3\Crypt\EC\Curves\Ed25519;
  21  use phpseclib3\Exception\UnsupportedFormatException;
  22  use phpseclib3\Math\BigInteger;
  23  
  24  /**
  25   * libsodium Key Handler
  26   *
  27   * @author  Jim Wigginton <terrafrost@php.net>
  28   */
  29  abstract class libsodium
  30  {
  31      use Common;
  32  
  33      /**
  34       * Is invisible flag
  35       *
  36       */
  37      const IS_INVISIBLE = true;
  38  
  39      /**
  40       * Break a public or private key down into its constituent components
  41       *
  42       * @param string $key
  43       * @param string $password optional
  44       * @return array
  45       */
  46      public static function load($key, $password = '')
  47      {
  48          switch (strlen($key)) {
  49              case 32:
  50                  $public = $key;
  51                  break;
  52              case 64:
  53                  $private = substr($key, 0, 32);
  54                  $public = substr($key, -32);
  55                  break;
  56              case 96:
  57                  $public = substr($key, -32);
  58                  if (substr($key, 32, 32) != $public) {
  59                      throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match');
  60                  }
  61                  $private = substr($key, 0, 32);
  62                  break;
  63              default:
  64                  throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long');
  65          }
  66  
  67          $curve = new Ed25519();
  68          $components = ['curve' => $curve];
  69          if (isset($private)) {
  70              $arr = $curve->extractSecret($private);
  71              $components['dA'] = $arr['dA'];
  72              $components['secret'] = $arr['secret'];
  73          }
  74          $components['QA'] = isset($public) ?
  75              self::extractPoint($public, $curve) :
  76              $curve->multiplyPoint($curve->getBasePoint(), $components['dA']);
  77  
  78          return $components;
  79      }
  80  
  81      /**
  82       * Convert an EC public key to the appropriate format
  83       *
  84       * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve
  85       * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
  86       * @return string
  87       */
  88      public static function savePublicKey(Ed25519 $curve, array $publicKey)
  89      {
  90          return $curve->encodePoint($publicKey);
  91      }
  92  
  93      /**
  94       * Convert a private key to the appropriate format.
  95       *
  96       * @param \phpseclib3\Math\BigInteger $privateKey
  97       * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve
  98       * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey
  99       * @param string $secret optional
 100       * @param string $password optional
 101       * @return string
 102       */
 103      public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $secret = null, $password = '')
 104      {
 105          if (!isset($secret)) {
 106              throw new \RuntimeException('Private Key does not have a secret set');
 107          }
 108          if (strlen($secret) != 32) {
 109              throw new \RuntimeException('Private Key secret is not of the correct length');
 110          }
 111          if (!empty($password) && is_string($password)) {
 112              throw new UnsupportedFormatException('libsodium private keys do not support encryption');
 113          }
 114          return $secret . $curve->encodePoint($publicKey);
 115      }
 116  }