NAME
    Sodium::FFI - FFI implementation of libsodium

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. These bindings have been created
    using FFI via FFI::Platypus to make building and maintaining the
    bindings easier than was done via Crypt::NaCl::Sodium. While we also
    intend to fix up Crypt::NaCl::Sodium so that it can use newer versions
    of LibSodium, the FFI method is faster to build and release.

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.

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.

