3.2 Hashes and digests
A hash, also called digest, is a way to verify the integrity of data. In typical cases, a hash is significantly shorter than the data itself, and already miniscule changes in the data lead to different hashes.
The hash functionality of this library subsumes and extends that of
library(sha), library(hash_stream) and library(md5)
by providing a unified interface to all available digest algorithms.
The underlying OpenSSL library (libcrypto) is
dynamically loaded if
either library(crypto) or library(ssl)
are loaded. Therefore, if your application uses library(ssl),
you can use library(crypto) for hashing without increasing
the memory footprint of your application. In other cases, the
specialised hashing libraries are more lightweight but less general
alternatives to library(crypto).
The most important predicates to compute hashes are:
- [det]crypto_data_hash(+Data, -Hash, +Options)
- Hash is the hash of Data. The conversion is
controlled by Options:
- algorithm(+Algorithm)
- One of
md5,sha1,sha224,sha256(default),sha384,sha512,blake2s256orblake2b512. TheBLAKEdigest algorithms require OpenSSL 1.1.0 or greater. - encoding(+Encoding)
- If Data is a sequence of character codes, this must be
translated into a sequence of bytes, because that is what the
hashing requires. The default encoding is
utf8. The other meaningful value isoctet, claiming that Data contains raw bytes. - hmac(+Key)
- If this option is specified, a hash-based message authentication code (HMAC) is computed, using the specified Key which is either an atom or string. Any of the available digest algorithms can be used with this option. The cryptographic strength of the HMAC depends on that of the chosen algorithm and also on the key. This option requires OpenSSL 1.1.0 or greater.
Data is either an atom, string or code-list Hash is an atom that represents the hash. - See also
- hex_bytes/2 for conversion between hashes and lists.
- [det]crypto_file_hash(+File, -Hash, +Options)
- True if Hash is the hash of the content of File. For Options, see crypto_data_hash/3.
For further reasoning and conversion of digests in hexadecimal notation, the following bidirectional relation is provided:
- [det]hex_bytes(?Hex, ?List)
- Relation between a hexadecimal sequence and a list of bytes. Hex
is an atom, string, list of characters or list of codes in hexadecimal
encoding. This is the format that is used by
crypto_data_hash/3 and
related predicates to represent hashes. Bytes is a list of integers
between 0 and 255 that represent the sequence as a list of bytes. At
least one of the arguments must be instantiated. When converting List to Hex,
an atom is used to represent the sequence of hexadecimal digits.
Example:
?- hex_bytes('501ACE', Bs). Bs = [80, 26, 206].
In addition, the following predicates are provided for building hashes incrementally. This works by first creating a context with crypto_context_new/2, then using this context with crypto_data_context/3 to incrementally obtain further contexts, and finally extract the resulting hash with crypto_context_hash/2.
- [det]crypto_context_new(-Context, +Options)
- Context is unified with the empty context, taking into
account
Options. The context can be used in crypto_data_context/3.
For
Options, see crypto_data_hash/3.
Context is an opaque pure Prolog term that is subject to garbage collection. - [det]crypto_data_context(+Data, +Context0, -Context)
- Context0 is an existing computation context, and Context
is the new context after hashing Data in addition to the
previously hashed data. Context0 may be produced by a prior
invocation of either crypto_context_new/2
or crypto_data_context/3
itself.
This predicate allows a hash to be computed in chunks, which may be important while working with Metalink (RFC 5854), BitTorrent or similar technologies, or simply with big files.
- crypto_context_hash(+Context, -Hash)
- Obtain the hash code of Context. Hash is an atom representing the hash code that is associated with the current state of the computation context Context.
The following hashing predicates work over streams:
- [det]crypto_open_hash_stream(+OrgStream, -HashStream, +Options)
- Open a filter stream on OrgStream that maintains a hash. The
hash can be retrieved at any time using crypto_stream_hash/2.
Available
Options in addition to those of crypto_data_hash/3
are:
- close_parent(+Bool)
- If
true(default), closing the filter stream also closes the original (parent) stream.
- [det]crypto_stream_hash(+HashStream, -Hash)
- Unify Hash with a hash for the bytes sent to or read from HashStream. Note that the hash is computed on the stream buffers. If the stream is an output stream, it is first flushed and the Digest represents the hash at the current location. If the stream is an input stream the Digest represents the hash of the processed input including the already buffered data.