Rand Stats

Crypt::LibGcrypt

zef:knarkhov

Raku Crypt::LibGcrypt - Yet another bindings for GNU Libgcrypt

Introduction

This module was initially developed by Curt Tilmes, original repository might be found at: https://github.com/CurtTilmes/raku-libgcrypt.

A Raku interface to libgcrypt.

Libgcrypt is a general purpose cryptographic library originally based on code from GnuPG. It provides functions for all cryptograhic building blocks: symmetric cipher algorithms (AES, Arcfour, Blowfish, Camellia, CAST5, ChaCha20 DES, GOST28147, Salsa20, SEED, Serpent, Twofish) and modes (ECB,CFB,CBC,OFB,CTR,CCM,GCM,OCB,POLY1305,AESWRAP), hash algorithms (MD2, MD4, MD5, GOST R 34.11, RIPE-MD160, SHA-1, SHA2-224, SHA2-256, SHA2-384, SHA2-512, SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE-128, SHAKE-256, TIGER-192, Whirlpool), MACs (HMAC for all hash algorithms, CMAC for all cipher algorithms, GMAC-AES, GMAC-CAMELLIA, GMAC-TWOFISH, GMAC-SERPENT, GMAC-SEED, Poly1305, Poly1305-AES, Poly1305-CAMELLIA, Poly1305-TWOFISH, Poly1305-SERPENT, Poly1305-SEED), and random numbers.

Usage

Message Digest (Hash)

A message digest or cryptographic hash function is a function that maps data of arbitrary size to a bit string of fixed size, the hash or digest.

use Crypt::LibGcrypt::Simple :MD5;       # Import routines you specify, or use :ALL for all

say MD5('Some text').hex;      # 9db5682a4d778ca2cb79580bdb67083f

say MD5(slurp).hex;            # print md5sum of STDIN

my $obj = MD5;                 # Get a new object
$obj.write("$_\n") for lines;  # Incremental calculation

say $obj.digest;               # Blob
say $obj.hex;                  # Hex string
say $obj.dec;                  # Decimal
say $obj.hex(:reset);          # Each of these can take :reset to reset the obj

$obj.reset;                    # or call reset to Reuse object on another message

Available Hashes:

See Available hash algorithms for more details on each algorithm.

Note that SHAKE128 and SHAKE256 are extendable-output functions (XOF), and can produce variable amounts of output. Pass in the number of bytes you want to digest, hex or dec:

use Crypt::LibGcrypt::Simple :SHAKE128;
say SHAKE128('Some text').hex(16);

Message Authentication Codes (MAC)

A message authentication code is a short code used to authenticate that a message came from the stated sender (its authenticity) and has not been changed.

To create one, you need a key and the message.

use Crypt::LibGcrypt::Simple :HMAC_MD5;       # Select algorithm, or :ALL for all

say HMAC_MD5('mykey', 'my message').hex;
# f50357b6299b741cf6b1c63073e54112

my $obj = HMAC_MD5('mykey');        # Create object
$obj.write('my message');           # Add data
say $obj.MAC;                       # Blob
say $obj.hex;                       # Hex string
say $obj.hex(:reset);               # Can also pass :reset to MAC or hex
$obj.reset;                         # or reset to reuse object on another message

Key is truncated or 0 extended to the size for the algorithm. ($obj.keylen will tell you the algorithm's key size).

Available MAC algorithms:

See Available MAC algorithms for more details on each algorithm.

Symmetric cryptography ciphers

use Crypt::LibGcrypt::Simple :IDEA;

my $key = 'foobar';
my $encrypted = IDEA($key).encrypt('Some text');
say IDEA($key).decrypt($encrypted);

my $obj = IDEA($key);                       # Create object
my $encrypted = $obj.encrypt('Some text');
$obj.reset;                                 # Reuse object
say $obj.decrypt($encrypted);

Available Ciphers:

See Available ciphers for more details on each algorithm.

Random

use Crypt::LibGcrypt::Random;

my $rand = random(10);
# Buf[uint8].new(148,229,159,236,230,13,154,226,245,23)
my $rand = random(10, :weak);           # actually the same as strong
my $rand = random(10, :strong);         # default
my $rand = random(10, :very-strong);    # stronger
my $rand = nonce(10);                   # Actually weak, but unpredictable

Returns a buffer of random bytes.

See Quality of random numbers for more information.

Passphrase

Derive a key from a string

use Crypt::LibGcrypt::Passphrase;

my $passphrase = "This is a long and complicated passphrase.";

my $key = key-from-passphrase($passphrase,
                              keysize => 16,
                              algorithm => 'SIMPLE_S2K',
                              subalgorithm => 'SHA1');

$key = key-from-passphrase($passphrase,
                           keysize => 64,
                           algorithm => 'ITERSALTED_S2K',
                           subalgorithm => 'SHA512',
                           iterations => 12,
                           salt => 'abcdefgh');

See Key Derivation for more information.

libgcrypt versions/features

You can check the version by calling Crypt::LibGcrypt.version which returns the version as a string:

use Crypt::LibGcrypt;
say Crypt::LibGcrypt.version;   # '1.7.6beta' or '1.8.1' or whatever

You can query the library for its capabilities with Gcrypt.config:

use Crypt::LibGcrypt;
say Crypt::LibGcrypt.config;               # Get all configuration
say Crypt::LibGcrypt.config('ciphers');    # List available ciphers
say Crypt::LibGcrypt.config('digests');    # List available digests

NOTE: config has a known problem on CentOS and is likely not to work.

Multi-threading

Most Crypt::LibGcrypt actions are thread-safe.

The error strings use a static memory buffer, so make sure only one thread is printing out an Exception message at a time. You can use the exception's integer code safely.

Installation

Many distributions already have libgcrypt installed, but if not, get it first:

Then zef install Crypt::LibGcrypt

License

This work is subject to the Artistic License 2.0.

See LICENSE for more information.

Maintaner

Please contact me via Matrix or LinkedIn. Your feedback is welcome at narkhov.pro.