| 
<?phpdeclare(strict_types=1);
 namespace ParagonIE\Halite;
 
 use ParagonIE\Halite\{
 Alerts as CryptoException,
 Asymmetric\EncryptionPublicKey,
 Asymmetric\EncryptionSecretKey
 };
 
 /**
 * Describes a pair of secret and public keys
 */
 final class EncryptionKeyPair extends KeyPair
 {
 /**
 *
 * Pass it a secret key, it will automatically generate a public key
 *
 * @param ...Key $keys
 */
 public function __construct(Key ...$keys)
 {
 switch (\count($keys)) {
 /**
 * If we received two keys, it must be an asymmetric secret key and
 * an asymmetric public key, in either order.
 */
 case 2:
 if (!$keys[0]->isAsymmetricKey() || !$keys[1]->isAsymmetricKey()) {
 throw new CryptoException\InvalidKey(
 'Only keys intended for asymmetric cryptography can be used in a KeyPair object'
 );
 }
 if ($keys[0]->isPublicKey()) {
 if ($keys[1]->isPublicKey()) {
 throw new CryptoException\InvalidKey(
 'Both keys cannot be public keys'
 );
 }
 $this->setupKeyPair(
 $keys[1] instanceof EncryptionSecretKey
 ? $keys[1]
 : new EncryptionSecretKey($keys[1]->get())
 );
 } elseif ($keys[1]->isPublicKey()) {
 $this->setupKeyPair(
 $keys[0] instanceof EncryptionSecretKey
 ? $keys[0]
 : new EncryptionSecretKey($keys[0]->get())
 );
 } else {
 throw new CryptoException\InvalidKey(
 'Both keys cannot be secret keys'
 );
 }
 break;
 /**
 * If we only received one key, it must be an asymmetric secret key!
 */
 case 1:
 if (!$keys[0]->isAsymmetricKey()) {
 throw new CryptoException\InvalidKey(
 'Only keys intended for asymmetric cryptography can be used in a KeyPair object'
 );
 }
 if ($keys[0]->isPublicKey()) {
 // Ever heard of the Elliptic Curve Discrete Logarithm Problem?
 throw new CryptoException\InvalidKey(
 'We cannot generate a valid keypair given only a public key; we can given only a secret key, however.'
 );
 }
 $this->setupKeyPair(
 $keys[0] instanceof EncryptionSecretKey
 ? $keys[0]
 : new EncryptionSecretKey($keys[0]->get())
 );
 break;
 default:
 throw new \InvalidArgumentException(
 'Halite\\EncryptionKeyPair expects 1 or 2 keys'
 );
 }
 }
 
 /**
 * Set up our key pair
 *
 * @param EncryptionSecretKey $secret
 */
 protected function setupKeyPair(EncryptionSecretKey $secret)
 {
 $this->secret_key = $secret;
 $this->public_key = $this->secret_key->derivePublicKey();
 }
 }
 
 |