1<?php 2 3/** 4 * Montgomery Private Key Handler 5 * 6 * "Naked" Curve25519 private keys can pretty much be any sequence of random 32x bytes so unless 7 * we have a "hidden" key handler pretty much every 32 byte string will be loaded as a curve25519 8 * private key even if it probably isn't one by PublicKeyLoader. 9 * 10 * "Naked" Curve25519 public keys also a string of 32 bytes so distinguishing between a "naked" 11 * curve25519 private key and a public key is nigh impossible, hence separate plugins for each 12 * 13 * PHP version 5 14 * 15 * @category Crypt 16 * @package EC 17 * @author Jim Wigginton <terrafrost@php.net> 18 * @copyright 2015 Jim Wigginton 19 * @license http://www.opensource.org/licenses/mit-license.html MIT License 20 * @link http://phpseclib.sourceforge.net 21 */ 22 23namespace phpseclib3\Crypt\EC\Formats\Keys; 24 25use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; 26use phpseclib3\Crypt\EC\Curves\Curve25519; 27use phpseclib3\Crypt\EC\Curves\Curve448; 28use phpseclib3\Exception\UnsupportedFormatException; 29use phpseclib3\Math\BigInteger; 30 31/** 32 * Montgomery Curve Private Key Handler 33 * 34 * @package EC 35 * @author Jim Wigginton <terrafrost@php.net> 36 * @access public 37 */ 38abstract class MontgomeryPrivate 39{ 40 /** 41 * Is invisible flag 42 * 43 * @access private 44 */ 45 const IS_INVISIBLE = true; 46 47 /** 48 * Break a public or private key down into its constituent components 49 * 50 * @access public 51 * @param string $key 52 * @param string $password optional 53 * @return array 54 */ 55 public static function load($key, $password = '') 56 { 57 switch (strlen($key)) { 58 case 32: 59 $curve = new Curve25519(); 60 break; 61 case 56: 62 $curve = new Curve448(); 63 break; 64 default: 65 throw new \LengthException('The only supported lengths are 32 and 56'); 66 } 67 68 $components = ['curve' => $curve]; 69 $components['dA'] = new BigInteger($key, 256); 70 $curve->rangeCheck($components['dA']); 71 // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) 72 $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); 73 74 return $components; 75 } 76 77 /** 78 * Convert an EC public key to the appropriate format 79 * 80 * @access public 81 * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve 82 * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey 83 * @return string 84 */ 85 public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) 86 { 87 return strrev($publicKey[0]->toBytes()); 88 } 89 90 /** 91 * Convert a private key to the appropriate format. 92 * 93 * @access public 94 * @param \phpseclib3\Math\BigInteger $privateKey 95 * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve 96 * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey 97 * @param string $password optional 98 * @return string 99 */ 100 public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $password = '') 101 { 102 if (!empty($password) && is_string($password)) { 103 throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); 104 } 105 106 return $privateKey->toBytes(); 107 } 108} 109