protected static function sealData(
        ReadOnlyFile $input,
        MutableFile $output,
        EncryptionPublicKey $publicKey
    ): int {
        // Generate a new keypair for this encryption
        $ephemeralKeyPair = KeyFactory::generateEncryptionKeyPair();
        $ephSecret = $ephemeralKeyPair->getSecretKey();
        $ephPublic = $ephemeralKeyPair->getPublicKey();
        unset($ephemeralKeyPair);

        // Calculate the shared secret key
        $sharedSecretKey = AsymmetricCrypto::getSharedSecret($ephSecret, $publicKey, true);
        // @codeCoverageIgnoreStart
        if (!($sharedSecretKey instanceof EncryptionKey)) {
            throw new \TypeError('Shared secret is the wrong key type.');
        }
        // @codeCoverageIgnoreEnd

        // Destroy the secret key after we have the shared secret
        unset($ephSecret);

        // Load the configuration
        $config = self::getConfig(Halite::HALITE_VERSION_FILE, 'seal');

        // Generate a nonce as per crypto_box_seal
        $nonce = \sodium_crypto_generichash(
            $ephPublic->getRawKeyMaterial() . $publicKey->getRawKeyMaterial(),
            '',
            \SODIUM_CRYPTO_STREAM_NONCEBYTES
        );

        // Generate a random HKDF salt
        $hkdfSalt = \random_bytes((int) $config->HKDF_SALT_LEN);

        // Split the keys
        /**
         * @var string $encKey
         * @var string $authKey
         */
        list ($encKey, $authKey) = self::splitKeys($sharedSecretKey, $hkdfSalt, $config);

        // Write the header:
        $output->writeBytes(
            Halite::HALITE_VERSION_FILE,
            Halite::VERSION_TAG_LEN
        );
        $output->writeBytes(
            $ephPublic->getRawKeyMaterial(),
            \SODIUM_CRYPTO_BOX_PUBLICKEYBYTES
        );
        $output->writeBytes(
            $hkdfSalt,
            (int) $config->HKDF_SALT_LEN
        );

        // VERSION 2+
        $mac = \sodium_crypto_generichash_init($authKey);

        // We no longer need $authKey after we set up the hash context
        \sodium_memzero($authKey);

        \sodium_crypto_generichash_update($mac, Halite::HALITE_VERSION_FILE);
        \sodium_crypto_generichash_update($mac, $ephPublic->getRawKeyMaterial());
        \sodium_crypto_generichash_update($mac, $hkdfSalt);

        unset($ephPublic);
        \sodium_memzero($hkdfSalt);

        $ret = self::streamEncrypt(
            $input,
            $output,
            new EncryptionKey(
                new HiddenString($encKey)
            ),
            (string) $nonce,
            (string) $mac,
            $config
        );
        \sodium_memzero($encKey);
        unset($encKey);
        unset($nonce);
        return $ret;
    }
protected static function sealData(
        ReadOnlyFile $input,
        MutableFile $output,
        EncryptionPublicKey $publicKey
    ): int {
        // Generate a new keypair for this encryption
        $ephemeralKeyPair = KeyFactory::generateEncryptionKeyPair();
        $ephSecret = $ephemeralKeyPair->getSecretKey();
        $ephPublic = $ephemeralKeyPair->getPublicKey();
        unset($ephemeralKeyPair);

        // Calculate the shared secret key
        $sharedSecretKey = AsymmetricCrypto::getSharedSecret($ephSecret, $publicKey, true);
        // @codeCoverageIgnoreStart
        if (!($sharedSecretKey instanceof EncryptionKey)) {
            throw new \TypeError('Shared secret is the wrong key type.');
        }
        // @codeCoverageIgnoreEnd

        // Destroy the secret key after we have the shared secret
        unset($ephSecret);

        // Load the configuration
        $config = self::getConfig(Halite::HALITE_VERSION_FILE, 'seal');

        // Generate a nonce as per crypto_box_seal
        $nonce = \sodium_crypto_generichash(
            $ephPublic->getRawKeyMaterial() . $publicKey->getRawKeyMaterial(),
            '',
            \SODIUM_CRYPTO_STREAM_NONCEBYTES
        );

        // Generate a random HKDF salt
        $hkdfSalt = \random_bytes((int) $config->HKDF_SALT_LEN);

        // Split the keys
        /**
         * @var string $encKey
         * @var string $authKey
         */
        list ($encKey, $authKey) = self::splitKeys($sharedSecretKey, $hkdfSalt, $config);

        // Write the header:
        $output->writeBytes(
            Halite::HALITE_VERSION_FILE,
            Halite::VERSION_TAG_LEN
        );
        $output->writeBytes(
            $ephPublic->getRawKeyMaterial(),
            \SODIUM_CRYPTO_BOX_PUBLICKEYBYTES
        );
        $output->writeBytes(
            $hkdfSalt,
            (int) $config->HKDF_SALT_LEN
        );

        // VERSION 2+
        $mac = \sodium_crypto_generichash_init($authKey);

        // We no longer need $authKey after we set up the hash context
        \sodium_memzero($authKey);

        \sodium_crypto_generichash_update($mac, Halite::HALITE_VERSION_FILE);
        \sodium_crypto_generichash_update($mac, $ephPublic->getRawKeyMaterial());
        \sodium_crypto_generichash_update($mac, $hkdfSalt);

        unset($ephPublic);
        \sodium_memzero($hkdfSalt);

        $ret = self::streamEncrypt(
            $input,
            $output,
            new EncryptionKey(
                new HiddenString($encKey)
            ),
            (string) $nonce,
            (string) $mac,
            $config
        );
        \sodium_memzero($encKey);
        unset($encKey);
        unset($nonce);
        return $ret;
    }
protected static function sealData ( ReadOnlyFile $ input , MutableFile $ output , EncryptionPublicKey $ publicKey ) : int { // Generate a new keypair for this encryption $ ephemeralKeyPair = KeyFactory :: generateEncryptionKeyPair ( ) ; $ ephSecret = $ ephemeralKeyPair -> getSecretKey ( ) ; $ ephPublic = $ ephemeralKeyPair -> getPublicKey ( ) ; unset ( $ ephemeralKeyPair ) ; // Calculate the shared secret key $ sharedSecretKey = AsymmetricCrypto :: getSharedSecret ( $ ephSecret , $ publicKey , true ) ; // @codeCoverageIgnoreStart if ( ! ( $ sharedSecretKey instanceof EncryptionKey ) ) { throw new \ TypeError ( 'Shared secret is the wrong key type.' ) ; } // @codeCoverageIgnoreEnd // Destroy the secret key after we have the shared secret unset ( $ ephSecret ) ; // Load the configuration $ config = self :: getConfig ( Halite :: HALITE_VERSION_FILE , 'seal' ) ; // Generate a nonce as per crypto_box_seal $ nonce = \ sodium_crypto_generichash ( $ ephPublic -> getRawKeyMaterial ( ) . $ publicKey -> getRawKeyMaterial ( ) , '' , \ SODIUM_CRYPTO_STREAM_NONCEBYTES ) ; // Generate a random HKDF salt $ hkdfSalt = \ random_bytes ( ( int ) $ config -> HKDF_SALT_LEN ) ; // Split the keys /**
         * @var string $encKey
         * @var string $authKey
         */ list ( $ encKey , $ authKey ) = self :: splitKeys ( $ sharedSecretKey , $ hkdfSalt , $ config ) ; // Write the header: $ output -> writeBytes ( Halite :: HALITE_VERSION_FILE , Halite :: VERSION_TAG_LEN ) ; $ output -> writeBytes ( $ ephPublic -> getRawKeyMaterial ( ) , \ SODIUM_CRYPTO_BOX_PUBLICKEYBYTES ) ; $ output -> writeBytes ( $ hkdfSalt , ( int ) $ config -> HKDF_SALT_LEN ) ; // VERSION 2+ $ mac = \ sodium_crypto_generichash_init ( $ authKey ) ; // We no longer need $authKey after we set up the hash context \ sodium_memzero ( $ authKey ) ; \ sodium_crypto_generichash_update ( $ mac , Halite :: HALITE_VERSION_FILE ) ; \ sodium_crypto_generichash_update ( $ mac , $ ephPublic -> getRawKeyMaterial ( ) ) ; \ sodium_crypto_generichash_update ( $ mac , $ hkdfSalt ) ; unset ( $ ephPublic ) ; \ sodium_memzero ( $ hkdfSalt ) ; $ ret = self :: streamEncrypt ( $ input , $ output , new EncryptionKey ( new HiddenString ( $ encKey ) ) , ( string ) $ nonce , ( string ) $ mac , $ config ) ; \ sodium_memzero ( $ encKey ) ; unset ( $ encKey ) ; unset ( $ nonce ) ; return $ ret ; }
Seal the contents of a file.

@param ReadOnlyFile $input
@param MutableFile $output
@param EncryptionPublicKey $publicKey
@return int

@throws CannotPerformOperation
@throws FileAccessDenied
@throws FileModified
@throws InvalidDigestLength
@throws InvalidMessage
@throws InvalidType
@throws \Exception
@throws \TypeError
Seal the contents of a file .