% This LaTeX document was generated using the LaTeX backend of PlDoc, % The SWI-Prolog documentation system \subsection{Introduction} \label{sec:crypto-introduction} This library provides bindings to functionality of OpenSSL that is related to cryptography and authentication, not necessarily involving connections, sockets or streams. \subsection{Design principle: Secure default algorithms} \label{sec:crypto-secure-defaults} A basic design principle of this library is that its \textit{default algorithms are cryptographically secure} at the time of this writing. We will \textit{change} the default algorithms if an attack on them becomes known, and replace them by new defaults that are deemed appropriate at that time. This may mean, for example, that where \const{sha256} is currently the default algorithm, \const{blake2s256} or some other algorithm may become the default in the future. To preserve interoperability and compatibility and at the same time allow us to transparently update default algorithms of this library, the following conventions are used: \begin{enumerate} \item If an explicit algorithm is specified as an option, then that algorithm is used. \item If \textit{no} algorithm is specified, then a cryptographically secure algorithm is used. \item If an option that normally specifies an algorithm is present, and a \textit{logical variable} appears instead of a concrete algorithm, then that variable is unified with the secure default value. \end{enumerate} This allows application programmers to inspect \textit{which} algorithm was actually used, and store it for later reference. For example: \begin{code} ?- crypto_data_hash(test, Hash, [algorithm(A)]). Hash = '9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08', A = sha256. \end{code} This shows that at the time of this writing, \const{sha256} was deemed sufficiently secure, and was used as default algorithm for hashing. You therefore must not rely on \textit{which} concrete algorithm is being used by default. However, you can rely on the fact that the default algorithms are secure. In other words, if they are \textit{not} secure, then this is a mistake in this library, and we ask you to please report such a situation as an urgent security issue. \subsection{Representing binary data} \label{sec:crypto-binary-data} In the context of this library, \textit{bytes} can be represented as lists of integers between 0 and 255. Such lists can be converted to and from \textit{hexadecimal notation} with the following bidirectional relation: \begin{description} \predicate[det]{hex_bytes}{2}{?Hex, ?List} Relation between a hexadecimal sequence and a list of bytes. \arg{Hex} is an atom, string, list of characters or list of codes in hexadecimal encoding. This is the format that is used by \predref{crypto_data_hash}{3} and related predicates to represent \textit{hashes}. Bytes is a list of \textit{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 \arg{List} \textit{to} \arg{Hex}, an \textit{atom} is used to represent the sequence of hexadecimal digits. Example: \begin{code} ?- hex_bytes('501ACE', Bs). Bs = [80, 26, 206]. \end{code} \begin{tags} \tag{See also} \predref{base64_encoded}{3} for Base64 encoding, which is often used to transfer or embed binary data in applications. \end{tags} \end{description} \subsection{Cryptographically secure random numbers} \label{sec:crypto-random} Almost all cryptographic applications require the availability of numbers that are sufficiently unpredictable. Examples are the creation of keys, nonces and salts. With this library, you can generate cryptographically strong pseudo-random numbers for such use cases: \begin{description} \predicate[det]{crypto_n_random_bytes}{2}{+N, -Bytes} \arg{Bytes} is unified with a list of \arg{N} cryptographically secure pseudo-random bytes. Each byte is an integer between 0 and 255. If the internal pseudo-random number generator (PRNG) has not been seeded with enough entropy to ensure an unpredictable byte sequence, an exception is thrown. One way to relate such a list of bytes to an \textit{integer} is to use CLP(FD) constraints as follows: \begin{code} :- use_module(library(clpfd)). bytes_integer(Bs, N) :- foldl(pow, Bs, 0-0, N-_). pow(B, N0-I0, N-I) :- B in 0..255, N #= N0 + B*256^I0, I #= I0 + 1. \end{code} With this definition, you can generate a random 256-bit integer \textit{from} a list of 32 random \textit{bytes}: \begin{code} ?- crypto_n_random_bytes(32, Bs), bytes_integer(Bs, I). Bs = [98, 9, 35, 100, 126, 174, 48, 176, 246|...], I = 109798276762338328820827...(53 digits omitted). \end{code} The above relation also works in the other direction, letting you translate an integer \textit{to} a list of bytes. In addition, you can use \predref{hex_bytes}{2} to convert bytes to \textit{tokens} that can be easily exchanged in your applications. This also works if you have compiled SWI-Prolog without support for large integers. \end{description} \subsection{Hashes} \label{sec:crypto-hash} A \textbf{hash}, also called \textbf{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 \verb$library(sha)$, \verb$library(hash_stream)$ and \verb$library(md5)$ by providing a unified interface to all available digest algorithms. The underlying OpenSSL library (\const{libcrypto}) is dynamically loaded if \textit{either} \verb$library(crypto)$ or \verb$library(ssl)$ are loaded. Therefore, if your application uses \verb$library(ssl)$, you can use \verb$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 \verb$library(crypto)$. \subsubsection{Hashes of data and files} \label{sec:crypto-hash-basic} The most important predicates to compute hashes are: \begin{description} \predicate[det]{crypto_data_hash}{3}{+Data, -Hash, +Options} \arg{Hash} is the hash of \arg{Data}. The conversion is controlled by \arg{Options}: \begin{description} \termitem{algorithm}{+Algorithm} One of \const{md5} (\textit{insecure}), \const{sha1} (\textit{insecure}), \const{ripemd160}, \const{sha224}, \const{sha256}, \const{sha384}, \const{sha512}, \verb$sha3_224$, \verb$sha3_256$, \verb$sha3_384$, \verb$sha3_512$, \const{blake2s256} or \const{blake2b512}. The BLAKE digest algorithms require OpenSSL 1.1.0 or greater, and the SHA-3 algorithms require OpenSSL 1.1.1 or greater. The default is a cryptographically secure algorithm. If you specify a variable, then that variable is unified with the algorithm that was used. \termitem{encoding}{+Encoding} If \arg{Data} is a sequence of character \textit{codes}, this must be translated into a sequence of \textit{bytes}, because that is what the hashing requires. The default encoding is \const{utf8}. The other meaningful value is \const{octet}, claiming that \arg{Data} contains raw bytes. \termitem{hmac}{+Key} If this option is specified, a \textit{hash-based message authentication code} (HMAC) is computed, using the specified \arg{Key} which is either an atom, string or list of \textit{bytes}. 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. \end{description} \begin{arguments} \arg{Data} & is either an atom, string or code-list \\ \arg{Hash} & is an atom that represents the hash in hexadecimal encoding. \\ \end{arguments} \begin{tags} \mtag{See also}- \predref{hex_bytes}{2} for conversion between hexadecimal encoding and lists of bytes. \\- \predref{crypto_password_hash}{2} for the important use case of passwords. \end{tags} \predicate[det]{crypto_file_hash}{3}{+File, -Hash, +Options} True if \arg{Hash} is the hash of the content of \arg{File}. For \arg{Options}, see \predref{crypto_data_hash}{3}. \end{description} \subsubsection{Hashes of passwords} \label{sec:crypto-hash-password} For the important case of deriving hashes from \textit{passwords}, the following specialised predicates are provided: \begin{description} \predicate[semidet]{crypto_password_hash}{2}{+Password, ?Hash} If \arg{Hash} is instantiated, the predicate succeeds \textit{iff} the hash matches the given password. Otherwise, the call is equivalent to \verb$crypto_password_hash(Password, Hash, [])$ and computes a password-based hash using the default options. \predicate[det]{crypto_password_hash}{3}{+Password, -Hash, +Options} Derive \arg{Hash} based on \arg{Password}. This predicate is similar to \predref{crypto_data_hash}{3} in that it derives a hash from given data. However, it is tailored for the specific use case of \textit{passwords}. One essential distinction is that for this use case, the derivation of a hash should be \textit{as slow as possible} to counteract brute-force attacks over possible passwords. Another important distinction is that equal passwords must yield, with very high probability, \textit{different} hashes. For this reason, cryptographically strong random numbers are automatically added to the password before a hash is derived. \arg{Hash} is unified with an atom that contains the computed hash and all parameters that were used, except for the password. Instead of storing passwords, store these hashes. Later, you can verify the validity of a password with \predref{crypto_password_hash}{2}, comparing the then entered password to the stored hash. If you need to export this atom, you should treat it as opaque ASCII data with up to 255 bytes of length. The maximal length may increase in the future. Admissible options are: \begin{description} \termitem{algorithm}{+Algorithm} The algorithm to use. Currently, the only available algorithms are \verb$pbkdf2-sha512$ (the default) and \const{bcrypt}. \termitem{cost}{+C} \arg{C} is an integer, denoting the binary logarithm of the number of \textit{iterations} used for the derivation of the hash. This means that the number of iterations is set to 2\Shat{}\arg{C}. Currently, the default is 17, and thus more than one hundred \textit{thousand} iterations. You should set this option as high as your server and users can tolerate. The default is subject to change and will likely increase in the future or adapt to new algorithms. \termitem{salt}{+Salt} Use the given list of bytes as salt. By default, cryptographically secure random numbers are generated for this purpose. The default is intended to be secure, and constitutes the typical use case of this predicate. \end{description} Currently, PBKDF2 with SHA-512 is used as the hash derivation function, using 128 bits of salt. All default parameters, including the algorithm, are subject to change, and other algorithms will also become available in the future. Since computed hashes store all parameters that were used during their derivation, such changes will not affect the operation of existing deployments. Note though that new hashes will then be computed with the new default parameters. \begin{tags} \tag{See also} \predref{crypto_data_hkdf}{4} for generating keys from \arg{Hash}. \end{tags} \end{description} \subsubsection{HMAC-based key derivation function (HKDF)} \label{sec:crypto-hkdf} The following predicate implements the \textit{Hashed Message Authentication Code (HMAC)-based key derivation function}, abbreviated as HKDF. It supports a wide range of applications and requirements by concentrating possibly dispersed entropy of the input keying material and then expanding it to the desired length. The number and lengths of the output keys depend on the specific cryptographic algorithms for which the keys are needed. \begin{description} \predicate[det]{crypto_data_hkdf}{4}{+Data, +Length, -Bytes, +Options} Concentrate possibly dispersed entropy of \arg{Data} and then expand it to the desired length. \arg{Bytes} is unified with a list of \textit{bytes} of length \arg{Length}, and is suitable as input keying material and initialization vectors to the symmetric encryption predicates. Admissible options are: \begin{description} \termitem{algorithm}{+Algorithm} A hashing algorithm as specified to \predref{crypto_data_hash}{3}. The default is a cryptographically secure algorithm. If you specify a variable, then it is unified with the algorithm that was used. \termitem{info}{+Info} Optional context and application specific information, specified as an atom, string or list of \textit{bytes}. The default is the zero length atom ''. \termitem{salt}{+List} Optionally, a list of \textit{bytes} that are used as salt. The default is all zeroes. \termitem{encoding}{+Atom} Either \verb$utf8$ (default) or \verb$octet$, denoting the representation of \arg{Data} as in \predref{crypto_data_hash}{3}. \end{description} The \predref{info}{1} option can be used to generate multiple keys from a single master key, using for example values such as \verb$key$ and \verb$iv$, or the name of a file that is to be encrypted. This predicate requires OpenSSL 1.1.0 or greater. \begin{tags} \tag{See also} \predref{crypto_n_random_bytes}{2} to obtain a suitable salt. \end{tags} \end{description} \subsubsection{Hashing incrementally} \label{sec:crypto-hash-incremental} The following predicates are provided for building hashes \textit{incrementally}. This works by first creating a \textbf{context} with \predref{crypto_context_new}{2}, then using this context with \predref{crypto_data_context}{3} to incrementally obtain further contexts, and finally extract the resulting hash with \predref{crypto_context_hash}{2}. \begin{description} \predicate[det]{crypto_context_new}{2}{-Context, +Options} \arg{Context} is unified with the empty context, taking into account \arg{Options}. The context can be used in \predref{crypto_data_context}{3}. For \arg{Options}, see \predref{crypto_data_hash}{3}. \begin{arguments} \arg{Context} & is an opaque pure Prolog term that is subject to garbage collection. \\ \end{arguments} \predicate[det]{crypto_data_context}{3}{+Data, +Context0, -Context} \arg{Context0} is an existing computation context, and \arg{Context} is the new context after hashing \arg{Data} in addition to the previously hashed data. \arg{Context0} may be produced by a prior invocation of either \predref{crypto_context_new}{2} or \predref{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. \predicate{crypto_context_hash}{2}{+Context, -Hash} Obtain the hash code of \arg{Context}. \arg{Hash} is an atom representing the hash code that is associated with the current state of the computation context \arg{Context}. \end{description} The following hashing predicates work over \textit{streams}: \begin{description} \predicate[det]{crypto_open_hash_stream}{3}{+OrgStream, -HashStream, +Options} Open a filter stream on \arg{OrgStream} that maintains a hash. The hash can be retrieved at any time using \predref{crypto_stream_hash}{2}. Available \arg{Options} in addition to those of \predref{crypto_data_hash}{3} are: \begin{description} \termitem{close_parent}{+Bool} If \const{true} (default), closing the filter stream also closes the original (parent) stream. \end{description} \predicate[det]{crypto_stream_hash}{2}{+HashStream, -Hash} Unify \arg{Hash} with a hash for the bytes sent to or read from \arg{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. \end{description} \subsection{Digital signatures} \label{sec:crypto-signatures} A digital \textbf{signature} is a relation between a key and data that only someone who knows the key can compute. \textit{Signing} uses a \textit{private} key, and \textit{verifying} a signature uses the corresponding \textit{public} key of the signing entity. This library supports both RSA and ECDSA signatures. You can use \predref{load_private_key}{3} and \predref{load_public_key}{2} to load keys from files and streams. In typical cases, we use this mechanism to sign the \textit{hash} of data. See hashing (\secref{crypto-hash}). For this reason, the following predicates work on the \textit{hexadecimal} representation of hashes that is also used by \predref{crypto_data_hash}{3} and related predicates. Signatures are also represented in hexadecimal notation, and you can use \predref{hex_bytes}{2} to convert them to and from lists of bytes (integers). \subsubsection{ECDSA} \label{sec:crypto-ECDSA} \begin{description} \predicate{ecdsa_sign}{4}{+Key, +Data, -Signature, +Options} Create an ECDSA signature for \arg{Data} with EC private key \arg{Key}. Among the most common cases is signing a hash that was created with \predref{crypto_data_hash}{3} or other predicates of this library. For this reason, the default encoding (\const{hex}) assumes that \arg{Data} is an atom, string, character list or code list representing the data in hexadecimal notation. See \predref{rsa_sign}{4} for an example. \arg{Options}: \begin{description} \termitem{encoding}{+Encoding} \arg{Encoding} to use for \arg{Data}. Default is \const{hex}. Alternatives are \const{octet}, \const{utf8} and \const{text}. \end{description} \predicate[semidet]{ecdsa_verify}{4}{+Key, +Data, +Signature, +Options} True iff \arg{Signature} can be verified as the ECDSA signature for \arg{Data}, using the EC public key \arg{Key}. \arg{Options}: \begin{description} \termitem{encoding}{+Encoding} \arg{Encoding} to use for \arg{Data}. Default is \const{hex}. Alternatives are \const{octet}, \const{utf8} and \const{text}. \end{description} \end{description} \subsubsection{RSA} \label{sec:crypto-RSA} \begin{description} \predicate[det]{rsa_sign}{4}{+Key, +Data, -Signature, +Options} Create an RSA signature for \arg{Data} with private key \arg{Key}. \arg{Options}: \begin{description} \termitem{type}{+Type} SHA algorithm used to compute the digest. Values are \const{sha1}, \const{sha224}, \const{sha256}, \const{sha384} or \const{sha512}. The default is a cryptographically secure algorithm. If you specify a variable, then it is unified with the algorithm that was used. \termitem{encoding}{+Encoding} \arg{Encoding} to use for \arg{Data}. Default is \const{hex}. Alternatives are \const{octet}, \const{utf8} and \const{text}. \end{description} This predicate can be used to compute a \verb$sha256WithRSAEncryption$ signature as follows: \begin{code} sha256_with_rsa(PemKeyFile, Password, Data, Signature) :- Algorithm = sha256, read_key(PemKeyFile, Password, Key), crypto_data_hash(Data, Hash, [algorithm(Algorithm), encoding(octet)]), rsa_sign(Key, Hash, Signature, [type(Algorithm)]). read_key(File, Password, Key) :- setup_call_cleanup( open(File, read, In, [type(binary)]), load_private_key(In, Password, Key), close(In)). \end{code} Note that a hash that is computed by \predref{crypto_data_hash}{3} can be directly used in \predref{rsa_sign}{4} as well as \predref{ecdsa_sign}{4}. \predicate[semidet]{rsa_verify}{4}{+Key, +Data, +Signature, +Options} Verify an RSA signature for \arg{Data} with public key \arg{Key}. \arg{Options}: \begin{description} \termitem{type}{+Type} SHA algorithm used to compute the digest. Values are \const{sha1}, \const{sha224}, \const{sha256}, \const{sha384} or \const{sha512}. The default is the same as for \predref{rsa_sign}{4}. This option must match the algorithm that was used for signing. When operating with different parties, the used algorithm must be communicated over an authenticated channel. \termitem{encoding}{+Encoding} \arg{Encoding} to use for \arg{Data}. Default is \const{hex}. Alternatives are \const{octet}, \const{utf8} and \const{text}. \end{description} \end{description} \subsection{Asymmetric encryption and decryption} \label{sec:crypto-asymmetric} The following predicates provide \textit{asymmetric} RSA encryption and decryption. This means that the key that is used for \textit{encryption} is different from the one used to \textit{decrypt} the data: \begin{description} \predicate[det]{rsa_private_decrypt}{4}{+PrivateKey, +CipherText, -PlainText, +Options} \nodescription \predicate[det]{rsa_private_encrypt}{4}{+PrivateKey, +PlainText, -CipherText, +Options} \nodescription \predicate[det]{rsa_public_decrypt}{4}{+PublicKey, +CipherText, -PlainText, +Options} \nodescription \predicate[det]{rsa_public_encrypt}{4}{+PublicKey, +PlainText, -CipherText, +Options} RSA Public key encryption and decryption primitives. A string can be safely communicated by first encrypting it and have the peer decrypt it with the matching key and predicate. The length of the string is limited by the key length. \arg{Options}: \begin{description} \termitem{encoding}{+Encoding} \arg{Encoding} to use for Data. Default is \const{utf8}. Alternatives are \const{utf8} and \const{octet}. \termitem{padding}{+PaddingScheme} Padding scheme to use. Default is \const{pkcs1}. Alternatives are \verb$pkcs1_oaep$, \const{sslv23} and \const{none}. Note that \const{none} should only be used if you implement cryptographically sound padding modes in your application code as encrypting unpadded data with RSA is insecure \end{description} \begin{tags} \tag{Errors} \verb$ssl_error(Code, LibName, FuncName, Reason)$ is raised if there is an error, e.g., if the text is too long for the key. \tag{See also} \predref{load_private_key}{3}, \predref{load_public_key}{2} can be use to load keys from a file. The predicate \predref{load_certificate}{2} can be used to obtain the public key from a certificate. \end{tags} \end{description} \subsection{Symmetric encryption and decryption} \label{sec:crypto-symmetric} The following predicates provide \textit{symmetric} encryption and decryption. This means that the \textit{same} key is used in both cases. \begin{description} \predicate{crypto_data_encrypt}{6}{+PlainText, +Algorithm, +Key, +IV, -CipherText, +Options} Encrypt the given \arg{PlainText}, using the symmetric algorithm \arg{Algorithm}, key \arg{Key}, and initialization vector (or nonce) \arg{IV}, to give \arg{CipherText}. \arg{PlainText} must be a string, atom or list of codes or characters, and \arg{CipherText} is created as a string. \arg{Key} and \arg{IV} are typically lists of \textit{bytes}, though atoms and strings are also permitted. \arg{Algorithm} must be an algorithm which your copy of OpenSSL knows about. Keys and IVs can be chosen at random (using for example \predref{crypto_n_random_bytes}{2}) or derived from input keying material (IKM) using for example \predref{crypto_data_hkdf}{4}. This input is often a shared secret, such as a negotiated point on an elliptic curve, or the hash that was computed from a password via \predref{crypto_password_hash}{3} with a freshly generated and specified \textit{salt}. Reusing the same combination of \arg{Key} and \arg{IV} typically leaks at least \textit{some} information about the plaintext. For example, identical plaintexts will then correspond to identical ciphertexts. For some algorithms, reusing an \arg{IV} with the same \arg{Key} has disastrous results and can cause the loss of all properties that are otherwise guaranteed. Especially in such cases, an \arg{IV} is also called a \textit{nonce} (number used once). If an \arg{IV} is not needed for your algorithm (such as \verb$'aes-128-ecb'$) then any value can be provided as it will be ignored by the underlying implementation. Note that such algorithms do not provide \textit{semantic security} and are thus insecure. You should use stronger algorithms instead. It is safe to store and transfer the used initialization vector (or nonce) in plain text, but the key \textit{must be kept secret}. Commonly used algorithms include: \begin{description} \item[\const{'chacha20-poly1305'}] A powerful and efficient \textit{authenticated} encryption scheme, providing secrecy and at the same time reliable protection against undetected \textit{modifications} of the encrypted data. This is a very good choice for virtually all use cases. It is a \textit{stream cipher} and can encrypt data of any length up to 256 GB. Further, the encrypted data has exactly the same length as the original, and no padding is used. It requires OpenSSL 1.1.0 or greater. See below for an example. \item[\const{'aes-128-gcm'}] Also an authenticated encryption scheme. It uses a 128-bit (i.e., 16 bytes) key and a 96-bit (i.e., 12 bytes) nonce. It requires OpenSSL 1.1.0 or greater. \item[\const{'aes-128-cbc'}] A \textit{block cipher} that provides secrecy, but does not protect against unintended modifications of the cipher text. This algorithm uses 128-bit (16 bytes) keys and initialization vectors. It works with all supported versions of OpenSSL. If possible, consider using an authenticated encryption scheme instead. \end{description} \arg{Options}: \begin{description} \termitem{encoding}{+Encoding} \arg{Encoding} to use for \arg{PlainText}. Default is \const{utf8}. Alternatives are \const{utf8} and \const{octet}. \termitem{padding}{+PaddingScheme} For block ciphers, the padding scheme to use. Default is \const{block}. You can disable padding by supplying \const{none} here. If padding is disabled for block ciphers, then the length of the ciphertext must be a multiple of the block size. \termitem{tag}{-List} For authenticated encryption schemes, \arg{List} is unified with a list of \textit{bytes} holding the tag. This tag must be provided for decryption. Authenticated encryption requires OpenSSL 1.1.0 or greater. \termitem{tag_length}{+Length} For authenticated encryption schemes, the desired length of the tag, specified as the number of bytes. The default is 16. Smaller numbers are not recommended. \end{description} For example, with OpenSSL 1.1.0 and greater, we can use the ChaCha20 stream cipher with the Poly1305 authenticator. This cipher uses a 256-bit key and a 96-bit \textit{nonce}, i.e., 32 and 12 \textit{bytes}, respectively: \begin{code} ?- Algorithm = 'chacha20-poly1305', crypto_n_random_bytes(32, Key), crypto_n_random_bytes(12, IV), crypto_data_encrypt("this is some input", Algorithm, Key, IV, CipherText, [tag(Tag)]), crypto_data_decrypt(CipherText, Algorithm, Key, IV, RecoveredText, [tag(Tag)]). Algorithm = 'chacha20-poly1305', Key = [65, 147, 140, 197, 27, 60, 198, 50, 218|...], IV = [253, 232, 174, 84, 168, 208, 218, 168, 228|...], CipherText = , Tag = [248, 220, 46, 62, 255, 9, 178, 130, 250|...], RecoveredText = "this is some input". \end{code} In this example, we use \predref{crypto_n_random_bytes}{2} to generate a key and nonce from cryptographically secure random numbers. For repeated applications, you must ensure that a nonce is only used \textit{once} together with the same key. Note that for \textit{authenticated} encryption schemes, the \textit{tag} that was computed during encryption is necessary for decryption. It is safe to store and transfer the tag in plain text. \begin{tags} \mtag{See also}- \predref{crypto_data_decrypt}{6}. \\- \predref{hex_bytes}{2} for conversion between bytes and hex encoding. \end{tags} \predicate{crypto_data_decrypt}{6}{+CipherText, +Algorithm, +Key, +IV, -PlainText, +Options} Decrypt the given \arg{CipherText}, using the symmetric algorithm \arg{Algorithm}, key \arg{Key}, and initialization vector \arg{IV}, to give \arg{PlainText}. \arg{CipherText} must be a string, atom or list of codes or characters, and \arg{PlainText} is created as a string. \arg{Key} and \arg{IV} are typically lists of \textit{bytes}, though atoms and strings are also permitted. \arg{Algorithm} must be an algorithm which your copy of OpenSSL knows. See \predref{crypto_data_encrypt}{6} for an example. \begin{description} \termitem{encoding}{+Encoding} \arg{Encoding} to use for \arg{CipherText}. Default is \const{utf8}. Alternatives are \const{utf8} and \const{octet}. \termitem{padding}{+PaddingScheme} For block ciphers, the padding scheme to use. Default is \const{block}. You can disable padding by supplying \const{none} here. \termitem{tag}{+Tag} For authenticated encryption schemes, the tag must be specified as a list of bytes exactly as they were generated upon encryption. This option requires OpenSSL 1.1.0 or greater. \termitem{min_tag_length}{+Length} If the tag length is smaller than 16, this option must be used to permit such shorter tags. This is used as a safeguard against truncation attacks, where an attacker provides a short tag that is easier to guess. \end{description} \end{description} \subsection{Number theory} \label{sec:crypto-numbertheory} This library provides operations from number theory that frequently arise in cryptographic applications, complementing the existing built-ins and GMP bindings: \begin{description} \predicate[det]{crypto_modular_inverse}{3}{+X, +M, -Y} Compute the modular multiplicative inverse of the integer \arg{X}. \arg{Y} is unified with an integer such that \arg{X}*\arg{Y} is congruent to 1 modulo \arg{M}. \predicate[det]{crypto_generate_prime}{3}{+N, -P, +Options} Generate a prime \arg{P} with at least \arg{N} bits. \arg{Options} is a list of options. Currently, the only supported option is: \begin{description} \termitem{safe}{Boolean} If \arg{Boolean} is \const{true} (default is \const{false}), then a \textit{safe} prime is generated. This means that \arg{P} is of the form 2*Q + 1 where Q is also prime. \end{description} \predicate[semidet]{crypto_is_prime}{2}{+P, +Options} True iff \arg{P} passes a probabilistic primality test. \arg{Options} is a list of options. Currently, the only supported option is: \begin{description} \termitem{iterations}{N} \arg{N} is the number of iterations that are performed. If this option is not specified, a number of iterations is used such that the probability of a false positive is at most 2\Shat{}(-80). \end{description} \end{description} \subsection{Elliptic curves} \label{sec:crypto-ec} This library provides functionality for reasoning over \textit{elliptic curves}. Elliptic curves are represented as opaque objects. You acquire a handle for an elliptic curve via \predref{crypto_name_curve}{2}. A \textit{point} on a curve is represented by the Prolog term \verb$point(X, Y)$, where \arg{X} and \arg{Y} are integers that represent the point's affine coordinates. The following predicates are provided for reasoning over elliptic curves: \begin{description} \predicate[det]{crypto_name_curve}{2}{+Name, -Curve} Obtain a handle for a \textit{named} elliptic curve. \arg{Name} is an atom, and \arg{Curve} is unified with an opaque object that represents the curve. Currently, only elliptic curves over prime fields are supported. Examples of such curves are \const{prime256v1} and \const{secp256k1}. If you have OpenSSL installed, you can get a list of supported curves via: \begin{code} $ openssl ecparam -list_curves \end{code} \predicate[det]{crypto_curve_order}{2}{+Curve, -Order} Obtain the order of an elliptic curve. \arg{Order} is an integer, denoting how many points on the curve can be reached by multiplying the curve's generator with a scalar. \predicate[det]{crypto_curve_generator}{2}{+Curve, -Point} \arg{Point} is the \textit{generator} of the elliptic curve \arg{Curve}. \predicate[det]{crypto_curve_scalar_mult}{4}{+Curve, +N, +Point, -R} \arg{R} is the result of \arg{N} times \arg{Point} on the elliptic curve \arg{Curve}. \arg{N} must be an integer, and \arg{Point} must be a point on the curve. \end{description} \subsection{Example: Establishing a shared secret} \label{sec:crypto-shared-secret} As one example that involves most predicates of this library, we explain a way to establish a \textit{shared secret} over an insecure channel. We shall use \textit{elliptic curves} for this purpose. Suppose Alice wants to establish an encrypted connection with Bob. To achieve this even over a channel that may be subject to eavesdrooping and man-in-the-middle attacks, Bob performs the following steps: \begin{enumerate} \item Choose an elliptic curve \arg{C}, using \predref{crypto_name_curve}{2}. \item Pick a random integer \textit{k} such that \textit{k} is greater than 0 and smaller than the order of \arg{C}. This can be done using \predref{crypto_curve_order}{2} and \predref{crypto_n_random_bytes}{2}. \item Use \predref{crypto_curve_generator}{2} to obtain the generator \arg{G} of \arg{C}, and use \predref{crypto_curve_scalar_mult}{4} to compute the scalar product \textit{k*G}. We call this result \arg{R}, denoting a point on the curve. \item Sign \arg{R} (using for example \predref{rsa_sign}{4} or \predref{ecdsa_sign}{4}) and send this to Alice. \end{enumerate} This mechanism hinges on a way for Alice to establish the \textit{authenticity} of the signed message (using predicates like \predref{rsa_verify}{4} and \predref{ecdsa_verify}{4}), for example by means of a public key that was previously exchanged or is signed by a trusted party in such a way that Alice can be sufficiently certain that it belongs to Bob. However, none of these steps require any encryption! Alice in turn performs the following steps: \begin{enumerate} \item Create a random integer \textit{j} such that \textit{j} is greater than 0 and smaller than the order of C. Alice can also use \predref{crypto_curve_order}{2} and \predref{crypto_n_random_bytes}{2} for this. \item Compute the scalar product \textit{j*G}, where \arg{G} is again the generator of \arg{C} as obtained via \predref{crypto_curve_generator}{2}. \item Further, compute the scalar product \textit{j*R}, which is a point on the curve that we shall call Q. We can derive a \textit{shared secret} from \arg{Q}, using for example \predref{crypto_data_hkdf}{4}, and encrypt any message with it (using for example \predref{crypto_data_encrypt}{6}). \item Send the point \textit{j*G} and the encrypted message to Bob. \end{enumerate} Bob receives \textit{j*G} in plain text and can arrive at the same shared secret by performing the calculation \textit{k*(j*G)}, which is - by associativity and commutativity of scalar multiplication - identical to the point \textit{j*(k*G)}, which is again Q from which the shared secret can be derived, and the message can be decrypted with \predref{crypto_data_decrypt}{6}. This method is known as Diffie-Hellman-Merkle key exchange over elliptic curves, abbreviated as ECDH. It provides forward secrecy (FS): Even if the private key that was used to establish the \textit{authenticity} of Bob is later compromised, the encrypted messages cannot be decrypted with it. A major attraction of using elliptic curves for this purpose is found in the comparatively small key size that suffices to make any attacks unrealistic as far as we currently know. In particular, given any point on the curve, we currently have no efficient way to determine by which scalar the generator was multiplied to obtain that point. The method described above relies on the hardness of this so-called \textit{elliptic curve discrete logarithm problem} (ECDLP). On the other hand, some of the named curves have been suspected to be chosen in such a way that they could be prone to attacks that are not publicly known. As an alternative to ECDH, you can use the original DH key exchange scheme, where the prime field GF(p) is used instead of an elliptic curve, and \textit{exponentiation} of a suitable generator is used instead of scalar multiplication. You can use \predref{crypto_generate_prime}{3} to generate a sufficiently large prime for this purpose.