.. _library_crypto:

``crypto``
==========

This library provides transport-neutral cryptographic predicates. It
currently exports the ``crypto`` object with the predicates:

- ``random_below/2``
- ``random_bytes/2``
- ``hex_bytes/2``
- ``token_hex/2``
- ``token_urlsafe/2``
- ``secure_compare/2``
- ``hkdf/5``
- ``pbkdf2/6``
- ``apr1/3``
- ``password_hash/4``
- ``password_hash_needs_rehash/3``
- ``verify_password_hash/2``

The ``random_below/2`` predicate returns a uniformly distributed random
integer greater than or equal to zero and less than the given exclusive
upper bound.

The ``random_bytes/2`` predicate returns a list with the requested
number of random bytes. It tries to read bytes from ``/dev/urandom``
first and falls back to a pseudo-random generator when that source is
unavailable.

The ``hex_bytes/2`` predicate relates hexadecimal atoms with lists of
bytes.

The ``token_hex/2`` and ``token_urlsafe/2`` predicates return either a
lowercase hexadecimal token or a unpadded Base64URL token generated from
the requested number of random bytes.

The ``secure_compare/2`` predicate provides constant-time comparison for
byte sequences represented either as byte lists or atoms.

The ``hkdf/5`` and ``pbkdf2/6`` predicates provide portable key
derivation implemented on top of the existing ``hashes`` and ``hmac``
libraries.

The ``apr1/3`` predicate computes Apache APR1 encoded checksums for
password and salt byte sequences using a portable MD5-based
implementation.

The ``password_hash/4`` predicate builds on top of ``pbkdf2/6`` to
generate structured password-hash terms. The
``password_hash_needs_rehash/3`` predicate checks stored password-hash
terms against the current PBKDF2 policy. The ``verify_password_hash/2``
predicate verifies ``pbkdf2(Hash, Iterations, Salt, DerivedKey)``,
``digest(Hash, StoredDigest)``, and ``apr1(Salt, Checksum)`` terms.

API documentation
-----------------

Open the
`../../apis/library_index.html#crypto <../../apis/library_index.html#crypto>`__
link in a web browser.

Loading
-------

To load the library, load the ``loader.lgt`` file:

::

   | ?- logtalk_load(crypto(loader)).

Testing
-------

To test this library, load the ``tester.lgt`` file:

::

   | ?- logtalk_load(crypto(tester)).

Examples
--------

Generate sixteen random bytes:

::

   | ?- crypto::random_bytes(16, Bytes).
   Bytes = [42,17,203,91,16,88,121,4,238,75,63,142,7,210,119,55]
   yes

Convert bytes to a hexadecimal atom:

::

   | ?- crypto::hex_bytes(Hex, [80,26,206]).
   Hex = '501ace'
   yes

Derive 32 bytes using HKDF-SHA-256:

::

   | ?- crypto::hkdf(sha256, [1,2,3,4], 32, Bytes, [salt([5,6,7,8]),info([9,10])]).
   Bytes = [...]
   yes

Compute an Apache APR1 checksum:

::

   | ?- crypto::apr1([112,97,115,115,119,111,114,100], [112,111,114,116,97,98,108,101], Checksum).
   Checksum = [107,117,110,70,78,90,57,114,48,81,57,54,51,88,98,115,116,101,79,79,87,46]
   yes
