# LispKit Crypto

Library `(lispkit crypto)` provides an API for cryptographic operations, including message digests, the creation and management of secure keys, and cryptographic algorithms for encrypting, decrypting, signing, and verifying messages.

The following sample code illustrates how `(lispkit crypto)` can be used to implement public key cryptography:

    (define msg (string->utf8 "This is a secret message!"))
    (define privkey (make-private-key 'rsa))
    (define pubkey (public-key privkey))
    (define encr (encrypt pubkey 'rsa-encryption-pkcs1 msg))
    (define decr (decrypt privkey 'rsa-encryption-pkcs1 encr))
    (utf8->string decr)
    ⇒ "This is a secret message!"

## Hash functions

Library `(lispkit crypto)` provides a number of cryptographic hash functions, sometimes also called message digest functions. A cryptographic hash function maps variable-length, potentially long sequences of bytes to fixed length, relatively short hashes, also called digests.

(md5 bytevector) [procedure]
(md5 bytevector start)
(md5 bytevector start end)

Implementation of the MD5 message-digest algorithm. Computes a 128-bit hash for the bytes of bytevector between index start (including) and end (excluding) and returns the result as a bytevector. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(sha1 bytevector) [procedure]
(sha1 bytevector start)
(sha1 bytevector start end)

Implementation of the “Secure Hash Algorithm 1”. Computes a 160-bit hash for the bytes of bytevector between index start (including) and end (excluding) and returns the result as a bytevector. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(sha256 bytevector) [procedure]
(sha256 bytevector start)
(sha256 bytevector start end)

Implementation of the “Secure Hash Algorithm 2” with a 256-bit digest. Computes a 256-bit hash for the bytes of bytevector between index start (including) and end (excluding) and returns the result as a bytevector. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(sha384 bytevector) [procedure]
(sha384 bytevector start)
(sha384 bytevector start end)

Implementation of the “Secure Hash Algorithm 2” with a 384-bit digest. Computes a 384-bit hash for the bytes of bytevector between index start (including) and end (excluding) and returns the result as a bytevector. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(sha512 bytevector) [procedure]
(sha512 bytevector start)
(sha512 bytevector start end)

Implementation of the “Secure Hash Algorithm 2” with a 512-bit digest. Computes a 512-bit hash for the bytes of bytevector between index start (including) and end (excluding) and returns the result as a bytevector. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

## Secure keys

secure-key-type-tag [constant]

Symbol representing the `secure-key` type. The `type-for` procedure of library `(lispkit type)` returns this symbol for all secure key objects.

(make-private-key cs) [procedure]
(make-private-key cs size)
(make-private-key cs size tag)

Creates a new private key for the cryptographic system cs and returns it as a `secure-key` object. Cryptographic systems are identified via symbols. Currently only `rsa` is supported as value for cs. size defines the size of the key in bits; default is 1024. tag is an optional string identifying the application generating the key. If tag is not provided, a random UUID string is being used as application tag.

    (make-private-key 'rsa 2048 "myapp")
    ⇒ #<secure-key 600000b26ce0: rsa private 2048>

(public-key key) [procedure]

Returns a public key for the given private key as a `secure-key` object.

    (define privkey (make-private-key 'rsa 1024 "demo app"))
    (define pubkey (public-key privkey))
    (display (secure-key->string pubkey)) ⇒
    -----BEGIN RSA PUBLIC KEY-----
    MIGJAoGBAPh4qcCprhnrCelHVzhvlzVBxe62qDwes3IrMNcvKAYnqgVpSvUN+RNI
    AWcQPVEiIPWxMz0/75mT3jFukysGMg6LdFzjslmtgvVutUM7vqkaliGIiBp92QBa
    iXjZpD33YxQvKTp7F8hv4sJwgVz4junkM11X7Wnw8R6+1l4fYCbvAgMBAAE=
    -----END RSA PUBLIC KEY-----

(secure-key? obj) [procedure]

Returns `#t` if obj is a secure key; otherwise `#f` is returned.

(secure-key-type? key cs) [procedure]

Returns `#t` if the secure key is suitable to be used with the cryptographic system cs; otherwise `#f` is returned. Cryptographic systems are identified via symbols. Currently only `rsa` is supported as value for cs.

(secure-key-private? key) [procedure]

Returns `#t` if the secure key is a private key; otherwise `#f` is returned.

(secure-key-public? key) [procedure]

Returns `#t` if the secure key is a public key; otherwise `#f` is returned.

(secure-key-can-encrypt? key) [procedure]
(secure-key-can-encrypt? key algo)

Returns `#t` if secure key can be used to encrypt messages via algorithm algo, otherwise `#f` is returned. algo is a symbol identifying the encryption algorithm (see section on Crypto Algorithms). If algo is not provided, `secure-key-can-encrypt?` returns `#t` if key can be used to encrypt messages in general, independent of a concrete algorithm.

(secure-key-can-decrypt? key) [procedure]
(secure-key-can-decrypt? key algo)

Returns `#t` if secure key can be used to decrypt messages via algorithm algo, otherwise `#f` is returned. algo is a symbol identifying the encryption algorithm (see section on Crypto Algorithms). If algo is not provided, `secure-key-can-decrypt?` returns `#t` if key can be used to decrypt messages in general, independent of a concrete algorithm.

(secure-key-can-sign? key) [procedure]
(secure-key-can-sign? key algo)

Returns `#t` if secure key can be used to sign messages via algorithm algo, otherwise `#f` is returned. algo is a symbol identifying the encryption algorithm (see section on Crypto Algorithms). If algo is not provided, `secure-key-can-sign?` returns `#t` if key can be used to sign messages in general, independent of a concrete algorithm.

(secure-key-can-verify? key) [procedure]
(secure-key-can-verify? key algo)

Returns `#t` if secure key can be used to verify messages via algorithm algo, otherwise `#f` is returned. algo is a symbol identifying the encryption algorithm (see section on Crypto Algorithms). If algo is not provided, `secure-key-can-verify?` returns `#t` if key can be used to verify messages in general, independent of a concrete algorithm.

(secure-key-size key) [procedure]
(secure-key-size key effective)

Returns the size of the given secure key in bits. If effective is `#f` or omitted, the total number of bits in the secure key are returned, otherwise, the effective number of bits used by this secure key are returned.

(secure-key-block-size key) [procedure]

Returns the block length associated with the given secure key in bytes. If the secure key is an RSA key, for instance, this is the size of the modulus.

(secure-key-attributes key) [procedure]

Returns the attributes associated with the given secure key as an association list. Each attribute is represented by a cons whose car is the key of an attribute and whose cdr is the corresponding value.

    (secure-key-attributes (make-private-key 'rsa))
    ⇒ ((unwp . 1) (priv . 0) (sens . 0) (extr . 1) (vrfy . 0)
       (encr . 0) (drve . 1) (modi . 0) (sign . 1) (vyrc . 0)
       (next . 0) (type . "42") (bsiz . 1024) (kcls . "1")
       (asen . 0) (esiz . 1024) (decr . 1) (wrap . 0)
       (class . "keys") (snrc . 0) (perm . 1))

(secure-key=? key0 key …) [procedure]

Defines an identity relationship for secure keys. `secure-key=?` returns `#t` if each key … is the same key object as key0, otherwise `#f` gets returned.

(secure-key-data=? key …) [procedure]

Defines an equivalence relationship for secure keys based on the equivalence of a serialized representation of a secure key. `secure-key-data=?` returns `#t` if each key … is representing an equivalent key with the same serialized external representation as key0. Otherwise, `#f` gets returned.

(secure-key->bytevector key) [procedure]

Serializes the given secure key into a new bytevector and returns the bytevector.

(bytevector->private-key cs bytevector) [procedure]
(bytevector->private-key cs bytevector start)
(bytevector->private-key cs bytevector start end)

Turns a serialized representation of a secure key in bytevector between indices start (inclusive) and end (exclusive) into a new private key of the given cryptographic system cs. Cryptographic systems are identified via symbols. Currently only `rsa` is supported as value for cs. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(bytevector->public-key obj) [procedure]

Turns a serialized representation of a secure key in bytevector between indices start (inclusive) and end (exclusive) into a new public key of the given cryptographic system cs. Cryptographic systems are identified via symbols. Currently only `rsa` is supported as value for cs. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(secure-key->string key) [procedure]

Returns a PEM (Privacy Encoded Mail)-encoded string representation of the given secure key.

    (define pkey (make-private-key 'rsa 1024 "test"))
    (display (secure-key->string (public-key pkey))) ⇒
    -----BEGIN RSA PUBLIC KEY-----
    MIGJAoGBALz04JfvuKHfOtKE6rYGasoebv4T54m88OR0tJ0Bb+7gUWkX8DPWEy/y
    Y0m6QOUK0nvpCvNdvZq7dW2Pjnwd4Cwy9lCUGj+MTSrwqL8fM3FvbLGI6lAAPqYb
    S/T9zcG/YnNSmB/A6o3EcfYi/nT0u83t6bmSwa0SHNoOQ110fm6jAgMBAAE=
    -----END RSA PUBLIC KEY-----

(string->secure-key str) [procedure]

Turns a PEM (Privacy Encoded Mail)-encoded representation of a secure key str (a string) into a new secure key object and returns this object. An error is raised if it is not possible to extract a secure key supported by this library.

## Crypto algorithms

In library `(lispkit crypto)`, cryptographic algorithms are identified via interned symbols. The following cryptographic algorithms are supported:

RSA Encryption

- `rsa-encryption-raw`
- `rsa-encryption-pkcs1`

RSA Encryption OAEP

- `rsa-encryption-oaep-sha1`
- `rsa-encryption-oaep-sha256`
- `rsa-encryption-oaep-sha384`
- `rsa-encryption-oaep-sha512`

RSA Encryption OAEP AESGCM

- `rsa-encryption-oaep-sha1-aesgcm`
- `rsa-encryption-oaep-sha256-aesgcm`
- `rsa-encryption-oaep-sha384-aesgcm`
- `rsa-encryption-oaep-sha512-aesgcm`

RSA Signature Raw

- `rsa-signature-raw`

RSA Signature Digest PKCS1v15

- `rsa-signature-digest-pkcs1v15-raw`
- `rsa-signature-digest-pkcs1v15-sha1`
- `rsa-signature-digest-pkcs1v15-sha256`
- `rsa-signature-digest-pkcs1v15-sha384`
- `rsa-signature-digest-pkcs1v15-sha512`

RSA Signature Message PKCS1v15

- `rsa-signature-message-pkcs1v15-sha1`
- `rsa-signature-message-pkcs1v15-sha256`
- `rsa-signature-message-pkcs1v15-sha384`
- `rsa-signature-message-pkcs1v15-sha512`

RSA Signature Digest PSS

- `rsa-signature-digest-pss-sha1`
- `rsa-signature-digest-pss-sha256`
- `rsa-signature-digest-pss-sha384`
- `rsa-signature-digest-pss-sha512`

RSA Signature Message PSS

- `rsa-signature-message-pss-sha1`
- `rsa-signature-message-pss-sha256`
- `rsa-signature-message-pss-sha384`
- `rsa-signature-message-pss-sha512`

(encrypt key algo bytevector) [procedure]
(encrypt key algo bytevector start)
(encrypt key algo bytevector start end)

Encrypts a message represented by bytevector between indices start (inclusive) and end (exclusive) using the given secure key and encryption algorithm algo. The encrypted message is returned as a new bytevector.

algo is a symbol identifying the encryption algorithm. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(decrypt key algo bytevector) [procedure]
(decrypt key algo bytevector start)
(decrypt key algo bytevector start end)

Decrypts an encrypted message represented by bytevector between indices start (inclusive) and end (exclusive) using the given secure key and encryption algorithm algo. The decrypted message is returned as a new bytevector.

algo is a symbol identifying the encryption algorithm. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(sign key algo bytevector) [procedure]
(sign key algo bytevector start)
(sign key algo bytevector start end)

Signs a message represented by bytevector between indices start (inclusive) and end (exclusive) using the given secure key and signature algorithm algo. The signature of the message is returned as a new bytevector.

algo is a symbol identifying the signature algorithm. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

(verify key algo bytevector) [procedure]
(verify key algo bytevector start)
(verify key algo bytevector start end)

Verifies a signature represented by bytevector between indices start (inclusive) and end (exclusive) using the given secure key and signature algorithm algo. `verify` returns `#t` if the signature could be verified, otherwise `#f` is returned.

algo is a symbol identifying the signature algorithm. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.