The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

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 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.

Random Number Functions

LibSodium provides a few Random Number Generator Functions 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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.