# Monocypher Bindings

## Synopsis

`(import monocypher)`

Bindings to the Monocypher library of cryptographic operations.

## Utilities

### parameter: `current-entropy-port`

A source of random bytes that defaults to built-in facilities from `(chicken random)`

.

### procedure: `(stream-xor! `*string*)

*string*)

### procedure: `(stream-xor! `*string* *port*)

*string*

*port*)

Destructively XOR the contents of the given string with data from the given input port or from the current input port. Returns the modified string.

### procedure: `(stream-xor `*string*)

*string*)

### procedure: `(stream-xor `*string* *port*)

*string*

*port*)

XOR the contents of the given string with data from the given input port or from the current input port. Returns the resulting string.

### procedure: `(blob=?/O1 `*blob-a* *blob-b*)

*blob-a*

*blob-b*)

Compares the contents of two blobs that must be 0, 16, 32, or 64 bytes long. The comparison takes the same amount of time no matter whether the contents differ or not.

### procedure: `(wipe! `*v*)

*v*)

Wipes the memory of the given key, envelope, string, blob, or SRFI-4 vector destroying any meaningful information inside it.

### parameter: `current-nonce-prefix`

A SRFI-4 byte vector used to prefix generated nonces or `#f`

.

### procedure: `(generate-nonce `*location* *noncebytes*)

*location*

*noncebytes*)

### procedure: `(generate-nonce `*location* *noncebytes* *port*)

*location*

*noncebytes*

*port*)

Generates a SRFI-4 byte vector of the given length for use as a nonce, based on the current nonce prefix and the current time. If `current-nonce-prefix`

is `#f`

, a new prefix is acquired from the given port, which defaults to the value of `current-entropy-port`

; the new nonce prefix is assigned to `current-nonce-prefix`

.

### procedure: `(nonce-seconds `*nonce*)

*nonce*)

For a nonce created with `generate-nonce`

, retrieve the time of its creation as a rational number of seconds since the unix epoch.

## Keys

### procedure: `(key? `*any*)

*any*)

### procedure: `(make-key `*algorithm* *public* *secret*)

*algorithm*

*public*

*secret*)

### procedure: `(key-algorithm `*key*)

*key*)

### procedure: `(public-key `*key*)

*key*)

### procedure: `(secret-key `*key*)

*key*)

Keys are represented by record instances that hold an algorithm name, a public key blob and a secret key blob. Depending on the algorithm and intended use of the key, either the public or secret component may be `#f`.

You may store a signed envelope in the public key component, which is unwrapped transparently. The procedures `symmetric-key-sign`

and `asymmetric-key-sign`

may be used to create such records. The procedures `symmetric-key-verify`

and `asymmetric-key-verify`

may be used to check the validity of such records.

You may store an encrypted envelope in the secret key component. Such a record can be used where only the public component is required. The procedures `symmetric-key-box`

and `asymmetric-key-box`

may be used to create such records. The procedures `symmetric-key-unbox`

and `asymmetric-key-unbox`

may be used to decrypt the secret component when needed.

### procedure: `(signed-key? `*v*)

*v*)

Check whether the given value is a key record with a signature on its public component.

### procedure: `(boxed-key? `*v*)

*v*)

Check whether the given value is a key record with an envelope as its secret component.

### procedure: `(make-public-key `*key*)

*key*)

Creates a new key that has the same algorithm and public key blob as the given one, but does not contain a secret component.

### procedure: `(public-key-envelope `*key*)

*key*)

If the given key has a public component with a signature, this procedure returns the envelope record. Otherwise, the result is `#f`

.

### procedure: `(check-key `*location* *algorithm* *any*)

*location*

*algorithm*

*any*)

Ensures that the given value is a key with the given algorithm name and returns the key. If the value does not pass the check, an error is raised that contains the given symbol as location information.

### procedure: `((generate-key `*location* *algorithm* *secret-keybytes* *secret->public*))

*location*

*algorithm*

*secret-keybytes*

*secret->public*))

### procedure: `((generate-key `*location* *algorithm* *secret-keybytes* *secret->public*) *port*)

*location*

*algorithm*

*secret-keybytes*

*secret->public*)

*port*)

Generates a new key or keypair using entropy from the given port or from *(current-entropy-port)*.

The secret part of the key is wiped automatically before its memory is reclaimed by the garbage collector.

If the entropy gathering fails, an error is raised that contains the given symbol as location information.

### procedure: `((derive-key `*location* *algorithm* *secret-keybytes* *secret->public*) *password* *salt* #!key *blocks* *iterations*)

*location*

*algorithm*

*secret-keybytes*

*secret->public*)

*password*

*salt*#!key

*blocks*

*iterations*)

Generates a new key or keypair from a password string using the Argon2i key derivation algorithm. The number of blocks defaults to 262144, i.e. 256 MiB. The number of iterations defaults to 8.

The secret part of the key is wiped automatically before its memory is reclaimed by the garbage collector.

If the input parameters are invalid, an error is raised that contains the given symbol as location information.

## Envelopes

### record: `envelope`

### procedure: `(envelope? `*any*)

*any*)

### procedure: `(make-envelope `*algorithm* *nonce* *message* *signature*)

*algorithm*

*nonce*

*message*

*signature*)

### procedure: `(envelope-algorithm `*envelope*)

*envelope*)

### procedure: `(envelope-nonce `*envelope*)

*envelope*)

### procedure: `(envelope-message `*envelope*)

*envelope*)

### procedure: `(envelope-signature `*envelope*)

*envelope*)

Encrypted and authenticated messages are represented by record instances that hold an algorithm name, a SRFI-4 nonce byte vector (if applicable), a message string, and a signature blob.

### procedure: `(valid-envelope? `*algorithm* *nonce-bytes* *signature-bytes* *any*)

*algorithm*

*nonce-bytes*

*signature-bytes*

*any*)

Checks whether the given value is an envelope with the given algorithm name, a SRFI-4 nonce byte vector of the given length, and a signature blob of the given length.

The `nonce-bytes`

parameter may be `#t`

, in which case a nonce of any length or no nonce is accepted, or it may be `#f`

, in which case an envelope is considered valid only if it contains no nonce.

## Message Digests

### constant: `hash-algorithm`

The name of the cryptographic message digest algorithm.

### procedure: `(hash `*message*)

*message*)

Computes a cryptographic message digest of the given string.

## Pseudo-Random Streams

### constant: `random-stream-algorithm`

The name of the pseudo-random number generator algorithm.

### constant: `random-stream-keybytes`

### constant: `random-stream-noncebytes`

Byte lengths of algorithm parameters.

### procedure: `(generate-random-stream-key)`

### procedure: `(generate-random-stream-key `*port*)

*port*)

### procedure: `(derive-random-stream-key `*password* *salt* #!key *blocks* *iterations*)

*password*

*salt*#!key

*blocks*

*iterations*)

Specialized versions of the `generate-key`

and `derive-key`

procedures for random stream keys.

### procedure: `(open-random-stream `*k* #!key *nonce* *limit*)

*k*#!key

*nonce*

*limit*)

Open a binary input port backed by a pseudo-random number generator.

If no nonce is given, a fresh one is created using `generate-nonce`

.

The default limit, after which the port will signal end of file, is 1 GiB of random data, but `#f` or `+inf.0` may be passed to deactivate the limit.

## Symmetric Signatures

### constant: `symmetric-sign-algorithm`

The name of the cryptographic message authentication code.

### constant: `symmetric-sign-keybytes`

The key length of the cryptographic message authentication code.

### procedure: `(generate-symmetric-sign-key)`

### procedure: `(generate-symmetric-sign-key `*port*)

*port*)

### procedure: `(derive-symmetric-sign-key `*password* *salt* #!key *blocks* *iterations*)

*password*

*salt*#!key

*blocks*

*iterations*)

Specialized versions of the `generate-key`

and `derive-key`

procedures for symmetric signature keys.

### procedure: `((symmetric-sign `*key*) *message* #!key aad nonce)

*key*)

*message*#!key aad nonce)

Compute a cryptographic message authentication code of the given message string using the given key and return an envelope containing the plain message and the signature. Optionally also authenticate the given additional data string `aad`

.

If no nonce is given, a fresh one is created using `generate-nonce`

, however using no nonce is possible by passing `#f`

.

### procedure: `((symmetric-verify `*key*) *envelope* #!key aad)

*key*)

*envelope*#!key aad)

Verify the cryptographic message authentication code of the given envelope using the given key and return the valid message string or `#f`

in case of failure. Optionally also authenticate the given additional data string `aad`

.

### procedure: `((symmetric-key-sign `*key*) *inner-key* #!key nonce)

*key*)

*inner-key*#!key nonce)

Add a cryptographic message authentication code to the public component of the inner key, if any. The algorithm and secret key components of the result are identical to the input.

If no nonce is given, a fresh one is created using `generate-nonce`

, however using no nonce is possible by passing `#f`

.

### procedure: `((symmetric-key-verify `*key*) *inner-key*)

*key*)

*inner-key*)

Verify the cryptographic message authentication code on the public component of the inner key. If the verification is successful, the procedure returns an equivalent of the inner key, otherwise it returns `#f`

.

## Symmetric Boxes

### constant: `symmetric-box-algorithm`

The name of the symmetric box algorithm combination.

### constant: `symmetric-box-keybytes`

### constant: `symmetric-box-noncebytes`

Byte lengths of algorithm parameters.

### procedure: `(generate-symmetric-box-key)`

### procedure: `(generate-symmetric-box-key `*port*)

*port*)

### procedure: `(derive-symmetric-box-key `*password* *salt* #!key *blocks* *iterations*)

*password*

*salt*#!key

*blocks*

*iterations*)

Specialized versions of the `generate-key`

and `derive-key`

procedures for symmetric box keys.

### procedure: `((symmetric-box `*key*) *message* #!key *aad* *nonce*)

*key*)

*message*#!key

*aad*

*nonce*)

Encrypt and authenticate the given message string using the given key and return an envelope containing the ciphertext and message authentication code. Optionally also authenticate the given additional data string `aad`

.

If no nonce is given, a fresh one is created using `generate-nonce`

.

### procedure: `((symmetric-unbox `*key*) *envelope* #!key *aad*)

*key*)

*envelope*#!key

*aad*)

Decrypt and authenticate the given envelope using the given key and return the valid plaintext string or `#f`

in case of failure. Optionally also authenticate the given additional data string `aad`

.

The resulting message is wiped automatically before its memory is reclaimed by the garbage collector.

### procedure: `((symmetric-key-box `*key*) *inner-key* #!key *nonce*)

*key*)

*inner-key*#!key

*nonce*)

Encrypt and authenticate the secret component of the inner key, if any, replacing it with an envelope. The algorithm and public key components of the result are identical to the input.

If no nonce is given, a fresh one is created using `generate-nonce`

.

### procedure: `((symmetric-key-unbox `*key*) *inner-key*)

*key*)

*inner-key*)

Decrypt and authenticate the secret component of the inner key, if any, replacing the envelope with a plain key. The algorithm and public key components of the result are identical to the input.

The secret component of the resulting key is wiped automatically before its memory is reclaimed by the garbage collector.

## Asymmetric Signatures

### constant: `asymmetric-sign-algorithm`

The name of the cryptographic signature algorithm combination.

### constant: `asymmetric-sign-publickeybytes`

### constant: `asymmetric-sign-secretkeybytes`

The key lengths of the cryptographic signature algorithm.

### procedure: `(generate-asymmetric-sign-key)`

### procedure: `(generate-asymmetric-sign-key `*port*)

*port*)

### procedure: `(derive-asymmetric-sign-key `*password* *salt* #!key *blocks* *iterations*)

*password*

*salt*#!key

*blocks*

*iterations*)

Specialized versions of the `generate-key`

and `derive-key`

procedures for asymmetric signature key pairs.

### procedure: `((asymmetric-sign `*key*) *message* #!key aad nonce)

*key*)

*message*#!key aad nonce)

Compute a cryptographic message digest and signature of the given message string using the given key and return an envelope containing the plain message and the signature. Optionally also authenticate the given additional data string `aad`

.

If no nonce is given, a fresh one is created using `generate-nonce`

, however using no nonce is possible by passing `#f`

.

### procedure: `((asymmetric-verify `*key*) *envelope* #!key aad)

*key*)

*envelope*#!key aad)

Verify the cryptographic message digest and signature of the given envelope using the given key and return the valid message string or `#f`

in case of failure. Optionally also authenticate the given additional data string `aad`

.

### procedure: `((asymmetric-key-sign `*key*) *inner-key* #!key nonce)

*key*)

*inner-key*#!key nonce)

Add a cryptographic message authentication code to the public component of the inner key, if any. The algorithm and secret key components of the result are identical to the input.

`generate-nonce`

, however using no nonce is possible by passing `#f`

.

### procedure: `((asymmetric-key-verify `*key*) *inner-key*)

*key*)

*inner-key*)

Verify the cryptographic message authentication code on the public component of the inner key. If the verification is successful, the procedure returns an equivalent of the inner key, otherwise it returns `#f`

.

## Asymmetric Boxes

### constant: `asymmetric-box-algorithm`

The name of the asymmetric box algorithm combination.

### constant: `asymmetric-box-publickeybytes`

### constant: `asymmetric-box-secretkeybytes`

### constant: `asymmetric-box-noncebytes`

Byte lengths of algorithm parameters.

### procedure: `(generate-asymmetric-box-key)`

### procedure: `(generate-asymmetric-box-key `*port*)

*port*)

### procedure: `(derive-asymmetric-box-key `*password* *salt* #!key *blocks* *iterations*)

*password*

*salt*#!key

*blocks*

*iterations*)

Specialized versions of the `generate-key`

and `derive-key`

procedures for key agreement key pairs.

### procedure: `(exchange-random-stream-key `*public* *secret*)

*public*

*secret*)

### procedure: `(exchange-symmetric-box-key `*public* *secret*)

*public*

*secret*)

Derive a random stream key or symmetric box key through an asymmetric key agreement given the other party's public and our own secret key.

The resulting key is wiped automatically before its memory is reclaimed by the garbage collector.

### procedure: `((asymmetric-box `*public* *secret*) *message* #!key *aad* *nonce*)

*public*

*secret*)

*message*#!key

*aad*

*nonce*)

Derive a symmetric box key through an asymmetric key agreement given the other party's public and our own secret key, then encrypt and authenticate the given message string using the derived key and return an envelope containing the ciphertext and message authentication code. Optionally also authenticate the given additional data string `aad`

.

If no nonce is given, a fresh one is created using `generate-nonce`

.

### procedure: `((asymmetric-unbox `*public* *secret*) *envelope* #!key *aad*)

*public*

*secret*)

*envelope*#!key

*aad*)

Derive a symmetric box key through an asymmetric key agreement given the other party's public and our own secret key, then decrypt and authenticate the given envelope using the derived key and return the valid plaintext string or `#f`

in case of failure. Optionally also authenticate the given additional data string.

The resulting message is wiped automatically before its memory is reclaimed by the garbage collector.

### procedure: `((asymmetric-key-box `*public* *secret*) *inner-key* #!key *nonce*)

*public*

*secret*)

*inner-key*#!key

*nonce*)

Derive a symmetric box key through an asymmetric key agreement given the other party's public and our own secret key, then encrypt and authenticate the secret component of the inner key, if any, replacing it with an envelope. The algorithm and public key components of the result are identical to the input.

If no nonce is given, a fresh one is created using `generate-nonce`

.

### procedure: `((asymmetric-key-unbox `*public* *secret*) *inner-key*)

*public*

*secret*)

*inner-key*)

Derive a symmetric box key through an asymmetric key agreement given the other party's public and our own secret key, then decrypt and authenticate the secret component of the inner key, if any, replacing the envelope with a plain key. The algorithm and public key components of the result are identical to the input.

The secret component of the resulting key is wiped automatically before its memory is reclaimed by the garbage collector.