NAME
    Sodium::FFI - Sodium is a modern, easy-to-use software library for
    encryption, decryption, signatures, password hashing, and more.

SYNOPSIS
      use strict;
      use warnings;
      use v5.34;

      use Sodium::FFI ();

      my $text = "1234";
      my $padded = Sodium::FFI::pad($text, 16);
      say Sodium::FFI::unpad($padded);

DESCRIPTION
    Sodium::FFI is a set of Perl bindings for the LibSodium
    <https://doc.libsodium.org/> C library. Sodium is a modern, easy-to-use
    software library for encryption, decryption, signatures, password
    hashing, and more. These bindings have been created using FFI via
    FFI::Platypus.

    We also intend to eventually fix Crypt::NaCl::Sodium so that it can use
    newer versions of LibSodium.

Crypto Auth Functions
    LibSodium provides a few Crypto Auth Functions
    <https://doc.libsodium.org/secret-key_cryptography/secret-key_authentica
    tion> to encrypt and verify messages with a key.

  crypto_auth
        use Sodium::FFI qw(randombytes_buf crypto_auth crypto_auth_keygen);
        # First, let's create a key
        my $key = crypto_auth_keygen();
        # let's encrypt 12 bytes of random data... for fun
        my $message = randombytes_buf(12);
        my $encrypted_bytes = crypto_auth($message, $key);
        say $encrypted_bytes;

    The crypto_auth
    <https://doc.libsodium.org/secret-key_cryptography/secret-key_authentica
    tion#usage> function encrypts a message using a secret key and returns
    that message as a string of bytes.

  crypto_auth_verify
        use Sodium::FFI qw(randombytes_buf crypto_auth_verify crypto_auth_keygen);

        my $message = randombytes_buf(12);
        # you'd really need to already have the key, but here
        my $key = crypto_auth_keygen();
        # your encrypted data would come from a call to crypto_auth
        my $encrypted; # assume this is full of bytes
        # let's verify
        my $boolean = crypto_auth_verify($encrypted, $message, $key);
        say $boolean;

    The crypto_auth_verify
    <https://doc.libsodium.org/secret-key_cryptography/secret-key_authentica
    tion#usage> function returns a boolean letting us know if the encrypted
    message and the original message are verified with the secret key.

  crypto_auth_keygen
        use Sodium::FFI qw(crypto_auth_keygen);
        my $key = crypto_auth_keygen();
        # this could also be written:
        use Sodium::FFI qw(randombytes_buf crypto_auth_KEYBYTES);
        my $key = randombytes_buf(crypto_auth_KEYBYTES);

    The crypto_auth_keygen
    <https://doc.libsodium.org/secret-key_cryptography/secret-key_authentica
    tion#usage> function returns a byte string of "crypto_auth_KEYBYTES"
    bytes.

AES256-GCM Crypto Functions
    LibSodium provides a few AES256-GCM functions
    <https://doc.libsodium.org/secret-key_cryptography/aead/aes-256-gcm> to
    encrypt or decrypt a message with a nonce and key. Note that these
    functions may not be available on your hardware and will "croak" in such
    a case.

  crypto_aead_aes256gcm_decrypt
        use Sodium::FFI qw(
            randombytes_buf crypto_aead_aes256gcm_decrypt
            crypto_aead_aes256gcm_is_available
            crypto_aead_aes256gcm_keygen crypto_aead_aes256gcm_NPUBBYTES
        );

        if (crypto_aead_aes256gcm_is_available()) {
            # you'd really need to already have the nonce and key, but here
            my $key = crypto_aead_aes256gcm_keygen();
            my $nonce = randombytes_buf(crypto_aead_aes256gcm_NPUBBYTES);
            # your encrypted data would come from a call to crypto_aead_aes256gcm_encrypt
            my $encrypted; # assume this is full of bytes
            # any additional data bytes that were encrypted should also be included
            # they can be undef
            my $additional_data = undef; # we don't care to add anything extra
            # let's decrypt!
            my $decrypted_bytes = crypto_aead_aes256gcm_decrypt(
                $encrypted, $additional_data, $nonce, $key
            );
            say $decrypted_bytes;
        }

    The crypto_aead_aes256gcm_decrypt
    <https://doc.libsodium.org/secret-key_cryptography/aead/aes-256-gcm#comb
    ined-mode> function returns a string of bytes after verifying that the
    ciphertext includes a valid tag using a secret key, a public nonce, and
    additional data.

  crypto_aead_aes256gcm_encrypt
        use Sodium::FFI qw(
            randombytes_buf crypto_aead_aes256gcm_encrypt
            crypto_aead_aes256gcm_is_available
            crypto_aead_aes256gcm_keygen crypto_aead_aes256gcm_NPUBBYTES
        );
        if (crypto_aead_aes256gcm_is_available()) {
            # First, let's create a key and nonce
            my $key = crypto_aead_aes256gcm_keygen();
            my $nonce = randombytes_buf(crypto_aead_aes256gcm_NPUBBYTES);
            # let's encrypt 12 bytes of random data... for fun
            my $message = randombytes_buf(12);
            # any additional data bytes that were encrypted should also be included
            # they can be undef
            my $additional_data = undef; # we don't care to add anything extra
            $additional_data = randombytes_buf(12); # or some random byte string
            my $encrypted_bytes = crypto_aead_aes256gcm_encrypt(
                $message, $additional_data, $nonce, $key
            );
            say $encrypted_bytes;
        }

    The crypto_aead_aes256gcm_encrypt
    <https://doc.libsodium.org/secret-key_cryptography/aead/aes-256-gcm#comb
    ined-mode> function encrypts a message using a secret key and a public
    nonce and returns that message as a string of bytes.

  crypto_aead_aes256gcm_is_available
        use Sodium::FFI qw(crypto_aead_aes256gcm_is_available);
        if (crypto_aead_aes256gcm_is_available()) {
            # ... encrypt and decrypt some data here
        }

    The crypto_aead_aes256gcm_is_available
    <https://doc.libsodium.org/secret-key_cryptography/aead/aes-256-gcm#limi
    tations> function returns 1 if the current CPU supports the AES256-GCM
    implementation, 0 otherwise.

  crypto_aead_aes256gcm_keygen
        use Sodium::FFI qw(
            crypto_aead_aes256gcm_keygen crypto_aead_aes256gcm_is_available
        );
        if (crypto_aead_aes256gcm_is_available()) {
            my $key = crypto_aead_aes256gcm_keygen();
            # this could also be written:
            use Sodium::FFI qw(randombytes_buf crypto_aead_aes256gcm_KEYBYTES);
            my $key = randombytes_buf(crypto_aead_aes256gcm_KEYBYTES);
        }

    The crypto_aead_aes256gcm_keygen
    <https://doc.libsodium.org/secret-key_cryptography/aead/aes-256-gcm#deta
    ched-mode> function returns a byte string of
    "crypto_aead_aes256gcm_KEYBYTES" bytes.

chacha20poly1305 Crypto Functions
    LibSodium provides a few chacha20poly1305 functions
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/original_chacha20-poly1305_construction> to encrypt or decrypt a
    message with a nonce and key.

  crypto_aead_chacha20poly1305_decrypt
        use Sodium::FFI qw(
            randombytes_buf crypto_aead_chacha20poly1305_decrypt
            crypto_aead_chacha20poly1305_keygen crypto_aead_chacha20poly1305_NPUBBYTES
        );

        # you'd really need to already have the nonce and key, but here
        my $key = crypto_aead_chacha20poly1305_keygen();
        my $nonce = randombytes_buf(crypto_aead_chacha20poly1305_NPUBBYTES);
        # your encrypted data would come from a call to crypto_aead_chacha20poly1305_encrypt
        my $encrypted; # assume this is full of bytes
        # any additional data bytes that were encrypted should also be included
        # they can be undef
        my $additional_data = undef; # we don't care to add anything extra
        # let's decrypt!
        my $decrypted_bytes = crypto_aead_chacha20poly1305_decrypt(
            $encrypted, $additional_data, $nonce, $key
        );
        say $decrypted_bytes;

    The crypto_aead_chacha20poly1305_decrypt
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/original_chacha20-poly1305_construction#combined-mode> function
    returns a string of bytes after verifying that the ciphertext includes a
    valid tag using a secret key, a public nonce, and additional data.

  crypto_aead_chacha20poly1305_encrypt
        use Sodium::FFI qw(
            randombytes_buf crypto_aead_chacha20poly1305_encrypt
            crypto_aead_chacha20poly1305_keygen crypto_aead_chacha20poly1305_NPUBBYTES
        );
        # First, let's create a key and nonce
        my $key = crypto_aead_chacha20poly1305_keygen();
        my $nonce = randombytes_buf(crypto_aead_chacha20poly1305_NPUBBYTES);
        # let's encrypt 12 bytes of random data... for fun
        my $message = randombytes_buf(12);
        # any additional data bytes that were encrypted should also be included
        # they can be undef
        my $additional_data = undef; # we don't care to add anything extra
        $additional_data = randombytes_buf(12); # or some random byte string
        my $encrypted_bytes = crypto_aead_chacha20poly1305_encrypt(
            $message, $additional_data, $nonce, $key
        );
        say $encrypted_bytes;

    The crypto_aead_chacha20poly1305_encrypt
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/original_chacha20-poly1305_construction#combined-mode> function
    encrypts a message using a secret key and a public nonce and returns
    that message as a string of bytes.

  crypto_aead_chacha20poly1305_keygen
        use Sodium::FFI qw(
            crypto_aead_chacha20poly1305_keygen
        );
        my $key = crypto_aead_chacha20poly1305_keygen();
        # this could also be written:
        use Sodium::FFI qw(randombytes_buf crypto_aead_chacha20poly1305_KEYBYTES);
        my $key = randombytes_buf(crypto_aead_chacha20poly1305_KEYBYTES);

    The crypto_aead_chacha20poly1305_keygen
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/original_chacha20-poly1305_construction#detached-mode> function
    returns a byte string of "crypto_aead_chacha20poly1305_KEYBYTES" bytes.

chacha20poly1305_ietf Crypto Functions
    LibSodium provides a few chacha20poly1305 IETF functions
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/ietf_chacha20-poly1305_construction> to encrypt or decrypt a message
    with a nonce and key.

    The "IETF" variant of the "ChaCha20-Poly1305" construction can safely
    encrypt a practically unlimited number of messages, but individual
    messages cannot exceed approximately "256 GiB".

  crypto_aead_chacha20poly1305_ietf_decrypt
        use Sodium::FFI qw(
            randombytes_buf crypto_aead_chacha20poly1305_ietf_decrypt
            crypto_aead_chacha20poly1305_ietf_keygen crypto_aead_chacha20poly1305_IETF_NPUBBYTES
        );

        # you'd really need to already have the nonce and key, but here
        my $key = crypto_aead_chacha20poly1305_ietf_keygen();
        my $nonce = randombytes_buf(crypto_aead_chacha20poly1305_IETF_NPUBBYTES);
        # your encrypted data would come from a call to crypto_aead_chacha20poly1305_ietf_encrypt
        my $encrypted; # assume this is full of bytes
        # any additional data bytes that were encrypted should also be included
        # they can be undef
        my $additional_data = undef; # we don't care to add anything extra
        # let's decrypt!
        my $decrypted_bytes = crypto_aead_chacha20poly1305_ietf_decrypt(
            $encrypted, $additional_data, $nonce, $key
        );
        say $decrypted_bytes;

    The crypto_aead_chacha20poly1305_ietf_decrypt
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/ietf_chacha20-poly1305_construction#combined-mode> function returns a
    string of bytes after verifying that the ciphertext includes a valid tag
    using a secret key, a public nonce, and additional data.

  crypto_aead_chacha20poly1305_ietf_encrypt
        use Sodium::FFI qw(
            randombytes_buf crypto_aead_chacha20poly1305_ietf_encrypt
            crypto_aead_chacha20poly1305_ietf_keygen crypto_aead_chacha20poly1305_IETF_NPUBBYTES
        );
        # First, let's create a key and nonce
        my $key = crypto_aead_chacha20poly1305_ietf_keygen();
        my $nonce = randombytes_buf(crypto_aead_chacha20poly1305_IETF_NPUBBYTES);
        # let's encrypt 12 bytes of random data... for fun
        my $message = randombytes_buf(12);
        # any additional data bytes that were encrypted should also be included
        # they can be undef
        my $additional_data = undef; # we don't care to add anything extra
        $additional_data = randombytes_buf(12); # or some random byte string
        my $encrypted_bytes = crypto_aead_chacha20poly1305_ietf_encrypt(
            $message, $additional_data, $nonce, $key
        );
        say $encrypted_bytes;

    The crypto_aead_chacha20poly1305_ietf_encrypt
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/ietf_chacha20-poly1305_construction#combined-mode> function encrypts a
    message using a secret key and a public nonce and returns that message
    as a string of bytes.

  crypto_aead_chacha20poly1305_ietf_keygen
        use Sodium::FFI qw(
            crypto_aead_chacha20poly1305_ietf_keygen
        );
        my $key = crypto_aead_chacha20poly1305_ietf_keygen();
        # this could also be written:
        use Sodium::FFI qw(randombytes_buf crypto_aead_chacha20poly1305_IETF_KEYBYTES);
        my $key = randombytes_buf(crypto_aead_chacha20poly1305_IETF_KEYBYTES);

    The crypto_aead_chacha20poly1305_ietf_keygen
    <https://doc.libsodium.org/secret-key_cryptography/aead/chacha20-poly130
    5/ietf_chacha20-poly1305_construction#detached-mode> function returns a
    byte string of "crypto_aead_chacha20poly1305_IETF_KEYBYTES" bytes.

Public Key Cryptography - Crypto Boxes
    LibSodium provides a few Public Key Authenticated Encryption
    <https://doc.libsodium.org/public-key_cryptography/authenticated_encrypt
    ion> and Sealed Box Encryption
    <https://doc.libsodium.org/public-key_cryptography/sealed_boxes>
    functions to allow sending messages using authenticated encryption.

  crypto_box_easy
        use Sodium::FFI qw(crypto_box_keypair crypto_box_easy randombytes_buf crypto_box_NONCEBYTES);
        my $nonce = randombytes_buf(crypto_box_NONCEBYTES);
        my ($public_key, $secret_key) = crypto_box_keypair();
        my $msg = "test";
        my $cipher_text = crypto_box_easy($msg, $nonce, $public_key, $secret_key);

    The crypto_box_easy
    <https://doc.libsodium.org/public-key_cryptography/authenticated_encrypt
    ion#combined-mode> function encrypts a message using the recipient's
    public key, the sender's secret key, and a nonce.

  crypto_box_keypair
        use Sodium::FFI qw(crypto_box_keypair);
        my ($public_key, $secret_key) = crypto_box_keypair();

    The crypto_box_keypair
    <https://doc.libsodium.org/public-key_cryptography/authenticated_encrypt
    ion#key-pair-generation> function randomly generates a secret key and a
    corresponding public key.

  crypto_box_open_easy
        use Sodium::FFI qw(crypto_box_keypair crypto_box_easy crypto_box_open_easy randombytes_buf crypto_box_NONCEBYTES);
        my $nonce = randombytes_buf(crypto_box_NONCEBYTES);
        my ($public_key, $secret_key) = crypto_box_keypair();
        my $msg = "test";
        my $cipher_text = crypto_box_easy($msg, $nonce, $public_key, $secret_key);
        my $decrypted = crypto_box_open_easy($cipher_text, $nonce, $public_key, $secret_key);
        if ($decrypted eq $msg) {
            say "Yay!";
        }

    The crypto_box_open_easy
    <https://doc.libsodium.org/public-key_cryptography/authenticated_encrypt
    ion#combined-mode> function decrypts a cipher text produced by
    crypto_box_easy.

  crypto_box_seal
        use Sodium::FFI qw(crypto_box_keypair crypto_box_seal);
        my ($public_key, $secret_key) = crypto_box_keypair();
        my $msg = "test";
        my $cipher_text = crypto_box_seal($msg, $public_key);

    The crypto_box_seal
    <https://doc.libsodium.org/public-key_cryptography/sealed_boxes>
    function encrypts a message for a recipient whose public key is
    provided. The function creates a new key pair for each message and
    attaches the public key to the ciphertext. The secret key is overwritten
    and is not accessible after this function returns.

  crypto_box_seal_open
        use Sodium::FFI qw(crypto_box_keypair crypto_box_seal crypto_box_seal_open);
        my ($public_key, $secret_key) = crypto_box_keypair();
        my $msg = "test";
        my $cipher_text = crypto_box_seal($msg, $public_key);
        my $decrypted = crypto_box_seal_open($cipher_text, $public_key, $secret_key);
        if ($decrypted eq $msg) {
            say "Yay!";
        }

    The crypto_box_seal_open
    <https://doc.libsodium.org/public-key_cryptography/sealed_boxes>
    function decrypts a cipher text produced by crypto_box_seal.

  crypto_box_seed_keypair
        use Sodium::FFI qw(crypto_box_seed_keypair crypto_sign_SEEDBYTES randombytes_buf);
        my $seed = randombytes_buf(crypto_sign_SEEDBYTES);
        my ($public_key, $secret_key) = crypto_box_seed_keypair($seed);

    The crypto_box_seed_keypair
    <https://doc.libsodium.org/public-key_cryptography/authenticated_encrypt
    ion#key-pair-generation> function randomly generates a secret key
    deterministically derived from a single key seed.

  crypto_scalarmult_base
        use Sodium::FFI qw(crypto_box_keypair crypto_scalarmult_base);
        my ($public_key, $secret_key) = crypto_box_keypair();
        my $computed_public = crypto_scalarmult_base($secret_key);
        if ($public_key eq $computed_public) {
            say "Yay!";
        }

    The crypto_scalarmult_base
    <https://doc.libsodium.org/public-key_cryptography/authenticated_encrypt
    ion#key-pair-generation> function can be used to compute the public key
    given a secret key previously generated with crypto_box_keypair.

Public Key Cryptography - Public Key Signatures
    LibSodium provides a few Public Key Signature Functions
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    > where a signer generates a key pair (public key and secret key) and
    appends the secret key to any number of messages. The one doing the
    verification will need to know and trust the public key before messages
    signed using it can be verified. This is not authenticated encryption.

  crypto_sign
        use Sodium::FFI qw(crypto_sign_keypair crypto_sign);
        my $msg = "Let's sign this and stuff!";
        my ($public_key, $secret_key) = crypto_sign_keypair();
        my $signed_msg = crypto_sign($msg, $secret_key);

    The crypto_sign
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    #combined-mode> function prepends a signature to an unaltered message.

  crypto_sign_detached
        use Sodium::FFI qw(crypto_sign_keypair crypto_sign_detached);
        my $msg = "Let's sign this and stuff!";
        my ($public_key, $secret_key) = crypto_sign_keypair();
        my $signature = crypto_sign_detached($msg, $secret_key);

    The crypto_sign_detached
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    #detached-mode> function signs the message with the secret key and
    returns the signature.

  crypto_sign_keypair
        use Sodium::FFI qw(crypto_sign_keypair);
        my ($public_key, $secret_key) = crypto_sign_keypair();

    The crypto_sign_keypair
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    #key-pair-generation> function randomly generates a secret key and a
    corresponding public key.

  crypto_sign_open
        use Sodium::FFI qw(crypto_sign_open);
        # we should have the public key and signed message to open
        my $signed_msg = ...;
        my $public_key = ...;
        my $msg = crypto_sign_open($signed_msg, $public_key);

    The crypto_sign_open
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    #combined-mode> function checks that a signed message has a valid
    signature for the public key. If so, it returns that message and if not,
    it will throw.

  crypto_sign_seed_keypair
        use Sodium::FFI qw(crypto_sign_seed_keypair crypto_sign_SEEDBYTES randombytes_buf);
        my $seed = randombytes_buf(crypto_sign_SEEDBYTES);
        my ($public_key, $secret_key) = crypto_sign_seed_keypair($seed);

    The crypto_sign_seed_keypair
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    #key-pair-generation> function randomly generates a secret key
    deterministically derived from a single key seed and a corresponding
    public key.

  crypto_sign_verify_detached
        use Sodium::FFI qw(crypto_sign_verify_detached);
        my $signature = ...;
        my $message = ...;
        my $public_key = ...;
        my $boolean = crypto_sign_verify_detached($signature, $message, $public_key);

    The crypto_sign_verify_detached
    <https://doc.libsodium.org/public-key_cryptography/public-key_signatures
    #detached-mode> function verifies that a signature is valid for the
    supplied message with public key. It returns a boolean value, 1 for
    true, 0 for false.

Random Number Functions
    LibSodium provides a few Random Number Generator Functions
    <https://doc.libsodium.org/generating_random_data> to assist you in
    getting your data ready for encryption, decryption, or hashing.

  randombytes_buf
        use Sodium::FFI qw(randombytes_buf);
        my $bytes = randombytes_buf(2);
        say $bytes; # contains two bytes of random data

    The randombytes_buf
    <https://doc.libsodium.org/generating_random_data#usage> function
    returns string of random bytes limited by a provided length.

  randombytes_buf_deterministic
        use Sodium::FFI qw(randombytes_buf_deterministic);
        # create some seed string of length Sodium::FFI::randombytes_SEEDBYTES
        my $seed = 'x' x Sodium::FFI::randombytes_SEEDBYTES;
        # use that seed to create a random string
        my $length = 2;
        my $bytes = randombytes_buf_deterministic($length, $seed);
        say $bytes; # contains two bytes of random data

    The randombytes_buf_deterministic
    <https://doc.libsodium.org/generating_random_data#usage> function
    returns string of random bytes limited by a provided length.

    It returns a byte string indistinguishable from random bytes without
    knowing the $seed. For a given seed, this function will always output
    the same sequence. The seed string you create should be
    "randombytes_SEEDBYTES" bytes long. Up to 256 GB can be produced with a
    single seed.

  randombytes_random
        use Sodium::FFI qw(randombytes_random);
        my $random = randombytes_random();
        say $random;

    The randombytes_random
    <https://doc.libsodium.org/generating_random_data#usage> function
    returns an unpredictable value between 0 and 0xffffffff (included).

  randombytes_uniform
        use Sodium::FFI qw(randombytes_uniform);
        my $upper_limit = 0xffffffff;
        my $random = randombytes_uniform($upper_limit);
        say $random;

    The randombytes_uniform
    <https://doc.libsodium.org/generating_random_data#usage> function
    returns an unpredictable value between 0 and $upper_bound (excluded).
    Unlike "randombytes_random() % $upper_bound", it guarantees a uniform
    distribution of the possible output values even when $upper_bound is not
    a power of 2. Note that an $upper_bound less than 2 leaves only a single
    element to be chosen, namely 0.

Utility/Helper Functions
    LibSodium provides a few Utility/Helper Functions
    <https://doc.libsodium.org/helpers> to assist you in getting your data
    ready for encryption, decryption, or hashing.

  sodium_add
        use Sodium::FFI qw(sodium_add);
        my $left = "111";
        $left = sodium_add($left, 111);
        say $left; # bbb

    The sodium_add <https://doc.libsodium.org/helpers#adding-large-numbers>
    function adds 2 large numbers.

  sodium_base642bin
        use Sodium::FFI qw(sodium_base642bin);
        say sodium_base642bin('/wA='); # \377\000
        my $variant = Sodium::FFI::sodium_base64_VARIANT_ORIGINAL;
        say sodium_base642bin('/wA=', $variant); # \377\000
        $variant = Sodium::FFI::sodium_base64_VARIANT_ORIGINAL_NO_PADDING;
        say sodium_base642bin('/wA', $variant); # \377\000
        $variant = Sodium::FFI::sodium_base64_VARIANT_URLSAFE;
        say sodium_base642bin('_wA=', $variant); # \377\000
        $variant = Sodium::FFI::sodium_base64_VARIANT_URLSAFE_NO_PADDING;
        say sodium_base642bin('_wA', $variant); # \377\000

    The sodium_base642bin
    <https://doc.libsodium.org/helpers#base64-encoding-decoding> function
    takes a base64 encoded string and turns it back into a binary string.

  sodium_bin2base64
        use Sodium::FFI qw(sodium_bin2base64);
        say sodium_bin2base64("\377\000"); # /wA=
        my $variant = Sodium::FFI::sodium_base64_VARIANT_ORIGINAL;
        say sodium_bin2base64("\377\000", $variant); # /wA=
        $variant = Sodium::FFI::sodium_base64_VARIANT_ORIGINAL_NO_PADDING;
        say sodium_bin2base64("\377\000", $variant); # /wA
        $variant = Sodium::FFI::sodium_base64_VARIANT_URLSAFE;
        say sodium_bin2base64("\377\000", $variant); # _wA=
        $variant = Sodium::FFI::sodium_base64_VARIANT_URLSAFE_NO_PADDING;
        say sodium_bin2base64("\377\000", $variant); # _wA

    The sodium_bin2base64
    <https://doc.libsodium.org/helpers#base64-encoding-decoding> function
    takes a binary string and turns it into a base64 encoded string.

  sodium_bin2hex
        use Sodium::FFI qw(sodium_bin2hex);
        my $binary = "ABC";
        my $hex = sodium_bin2hex($binary);
        say $hex; # 414243

    The sodium_bin2hex
    <https://doc.libsodium.org/helpers#hexadecimal-encoding-decoding>
    function takes a binary string and turns it into a hex string.

  sodium_compare
        use Sodium::FFI qw(sodium_compare);
        say sodium_compare("\x01", "\x02"); # -1
        say sodium_compare("\x02", "\x01"); # 1
        say sodium_compare("\x01", "\x01"); # 0

    The sodium_compare
    <https://doc.libsodium.org/helpers#comparing-large-numbers> function
    compares two large numbers encoded in little endian format. Results in
    -1 when "$left < $right" Results in 0 when "$left eq $right" Results in
    1 when "$left > $right"

  sodium_hex2bin
        use Sodium::FFI qw(sodium_hex2bin);
        my $hex = "414243";
        my $bin = sodium_hex2bin($hex);
        say $bin; # ABC

    The sodium_hex2bin
    <https://doc.libsodium.org/helpers#hexadecimal-encoding-decoding>
    function takes a hex string and turns it into a binary string.

  sodium_increment
        use Sodium::FFI qw(sodium_increment);
        my $x = "\x01";
        $x = sodium_increment($x); # "\x02";

    The sodium_increment
    <https://doc.libsodium.org/helpers#incrementing-large-numbers> function
    takes an arbitrarily long unsigned number and increments it.

  sodium_is_zero
        use Sodium::FFI qw(sodium_is_zero);
        my $string = "\x00\x00\x01"; # zero zero 1
        # entire string not zeros
        say sodium_is_zero($string); # 0
        # first byte of string is zero
        say sodium_is_zero($string, 1); # 1
        # first two bytes of string is zero
        say sodium_is_zero($string, 2); # 1

    The sodium_is_zero
    <https://doc.libsodium.org/helpers#testing-for-all-zeros> function tests
    a string for all zeros.

  sodium_library_minimal
        use Sodium::FFI qw(sodium_library_minimal);
        say sodium_library_minimal; # 0 or 1

    The "sodium_library_minimal" function lets you know if this is a minimal
    version.

  sodium_library_version_major
        use Sodium::FFI qw(sodium_library_version_major);
        say sodium_library_version_major; # 10

    The "sodium_library_version_major" function returns the major version of
    the library.

  sodium_library_version_minor
        use Sodium::FFI qw(sodium_library_version_minor);
        say sodium_library_version_minor; # 3

    The "sodium_library_version_minor" function returns the minor version of
    the library.

  sodium_memcmp
        use Sodium::FFI qw(sodium_memcmp);
        my $string1 = "abcdef";
        my $string2 = "abc";
        my $match_length = 3;
        # string 1 and 2 are equal for the first 3
        say sodium_memcmp($string1, $string2, $match_length); # 0
        # they are not equal for 4 slots
        say sodium_memcmp("abcdef", "abc", 4); # -1

    The sodium_memcmp
    <https://doc.libsodium.org/helpers#constant-time-test-for-equality>
    function compares two strings in constant time. Results in -1 when
    strings 1 and 2 aren't equal. Results in 0 when strings 1 and 2 are
    equal.

  sodium_pad
        use Sodium::FFI qw(sodium_pad);
        my $bin_string = "\x01";
        my $block_size = 4;
        say sodium_pad($bin_string, $block_size); # 01800000

    The sodium_pad <https://doc.libsodium.org/padding> function adds padding
    data to a buffer in order to extend its total length to a multiple of
    the block size.

  sodium_sub
        use Sodium::FFI qw(sodium_sub);
        my $x = "\x02";
        my $y = "\x01";
        my $z = sodium_sub($x, $y);
        say $x; # \x01

    The sodium_sub
    <https://doc.libsodium.org/helpers#subtracting-large-numbers> function
    subtracts 2 large, unsigned numbers encoded in little-endian format.

  sodium_unpad
        use Sodium::FFI qw(sodium_unpad);
        my $bin_string = "\x01\x80\x00\x00\x0";
        my $block_size = 4;
        say sodium_unpad($bin_string, $block_size); # 01

    The sodium_unpad <https://doc.libsodium.org/padding> function computes
    the original, unpadded length of a message previously padded using
    "sodium_pad".

  sodium_version_string
        use Sodium::FFI qw(sodium_version_string);
        say sodium_version_string; # 1.0.18

    The "sodium_version_string" function returns the stringified version
    information for the version of LibSodium that you have installed.

COPYRIGHT
     Copyright 2020 Chase Whitener. All rights reserved.

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.