# Raku Gcrypt - Bindings for GNU Libgcrypt [![Build Status](https://travis-ci.org/CurtTilmes/raku-libgcrypt.svg)](https://travis-ci.org/CurtTilmes/raku-libgcrypt) * [Introduction](#introduction) * [Message Digest (Hash)](#message-digest-hash) * [Symmetric cryptography ciphers](#symmetric-cryptography-ciphers) * [Random](#random) * [Passphrase](#passphrase) * [libgcrypt versions/features](#libgcrypt-versionsfeatures) * [Multi-threading](#multi-threading) * [Installation](#installation) * [License](#license) ## Introduction A [Raku](https://raku.org/) interface to [libgcrypt](https://gnupg.org/software/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. **Note, this is still a work in progress, more features may or may not be forthcoming!! Patches welcome!!** # Usage ## Message Digest (Hash) A [message digest or cryptographic hash function](https://en.wikipedia.org/wiki/Cryptographic_hash_function) is a function that maps data of arbitrary size to a bit string of fixed size, the hash or digest. ``` use Gcrypt::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: MD5 SHA1 RIPEMD160 TIGER SHA256 SHA384 SHA512 SHA224 MD4 CRC32 CRC32_RFC1510 CRC24_RFC2440 WHIRLPOOL TIGER1 TIGER2 GOSTR3411_94 STRIBOG256 STRIBOG512 SHA3_224 SHA3_256 SHA3_384 SHA3_512 SHAKE128 SHAKE256 BLAKE2B_512 BLAKE2B_384 BLAKE2B_256 BLAKE2B_160 BLAKE2S_256 BLAKE2S_224 BLAKE2S_160 BLAKE2S_128 See [Available hash algorithms](https://gnupg.org/documentation/manuals/gcrypt/Available-hash-algorithms.html) 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 Gcrypt::Simple :SHAKE128; say SHAKE128('Some text').hex(16); ``` ## Message Authentication Codes (MAC) A [message authentication code](https://en.wikipedia.org/wiki/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 Gcrypt::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: HMAC_SHA256 HMAC_SHA224 HMAC_SHA512 HMAC_SHA384 HMAC_SHA1 HMAC_MD5 HMAC_MD4 HMAC_RIPEMD160 HMAC_TIGER HMAC_WHIRLPOOL HMAC_GOSTR3411_94 HMAC_STRIBOG256 HMAC_STRIBOG512 HMAC_SHA3_224 HMAC_SHA3_256 HMAC_SHA3_384 HMAC_SHA3_512 CMAC_AES CMAC_3DES CMAC_Camellia CMAC_CAST5 CMAC_Blowfish CMAC_Twofish CMAC_Serpent CMAC_SEED CMAC_RFC2268 CMAC_IDEA CMAC_GOST28147 GMAC_AES GMAC_Camellia GMAC_Twofish GMAC_Serpent GMAC_SEED POLY1305 See [Available MAC algorithms](https://gnupg.org/documentation/manuals/gcrypt/Available-MAC-algorithms.html) for more details on each algorithm. ## Symmetric cryptography ciphers ``` use Gcrypt::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: IDEA DES3 CAST5 Blowfish AES AES192 AES256 Twofish RC4 DES Twofish128 Serpent128 Serpent192 RFC2268_40 SEED Camellia128 Camellia192 Camellia256 Salsa20 Salsa20R12 GOST28147 ChaCha20 See [Available ciphers](https://gnupg.org/documentation/manuals/gcrypt/Available-ciphers.html) for more details on each algorithm. ## Random ``` use Gcrypt::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](https://gnupg.org/documentation/manuals/gcrypt/Quality-of-random-numbers.html) for more information. ## Passphrase Derive a key from a string ``` use Gcrypt::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](https://gnupg.org/documentation/manuals/gcrypt/Key-Derivation.html) for more information. # libgcrypt versions/features You can check the version by calling `Gcrypt.version` which returns the version as a string: ``` use Gcrypt; say Gcrypt.version; # '1.7.6beta' or '1.8.1' or whatever ``` You can query the library for its capabilities with `Gcrypt.config`: ``` use Gcrypt; say Gcrypt.config; # Get all configuration say Gcrypt.config('ciphers'); # List available ciphers say Gcrypt.config('digests'); # List available digests ``` NOTE: `config` has a known problem on CentOS and is likely not to work. # Multi-threading Most Gcrypt 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: * For debian or ubuntu: `apt install libgcrypt20` * For alpine: `apk add libgcrypt` * For CentOS: `yum install libgcrypt` Then `zef install Gcrypt` # License This work is subject to the Artistic License 2.0. See [LICENSE](LICENSE) for more information.