@c -*-texinfo-*-

@node crypto
@section Cryptographic primitives

Beware that if you're using some of these libraries for sensitive
data, let's say passwords, then there is probably no way to make sure
a password is ever gone from memory. There is no guarantee that the
passwords will not be swapped out to disk or transmitted by radio.
There might be other problems as well. The algorithms themselves might
be weak. Don't pick weak keys. Know what you're doing.

Your Scheme's implementation of @code{(srfi :27 random-bits)} might be
too weak. It's common that it will be initialized from time alone, so
an attacker can easily guess your @code{random-source} internal state
by trying a few timestamps and checking which one generates the data
you sent. These libraries try to use @code{/dev/urandom} if it exists,
but if it doesn't they fall back on SRFI-27 and could reveal the
secret of your heart to the enemy. See RFC4086 for details on how
randomness works.
@cindex randomness
@cindex entropy

Please remember that these are low-level primitives. To be useful they
must be part of a protocol. And remember what the license says about
warranties.
@cindex security, warning

@menu
* crypto aes::            Advanced Encryption Standard (AES)
* crypto arcfour::        ARCFOUR stream cipher
* crypto blowfish::       The Blowfish cipher
* crypto chacha20::       ChaCha20 stream cipher
* crypto ecdh::           Elliptic Curve Diffie-Hellman key exchange
* crypto eddsa::          Edwards-curve Digital Signature Algorithm (EdDSA)
* crypto des::            Data Encryption Standard (DES, 3DES)
* crypto dh::             Diffie-Hellman key exchange
* crypto dsa::            Digital Signature Algorithm (DSA)
* crypto ec::             Elliptic Curve Cryptography
* crypto ecdsa::          Elliptic Curve Digital Signature Algorithm (ECDSA)
* crypto entropy::        Entropy and randomness
* crypto rsa::            RSA public key encryption and signatures
@end menu

@c ======================================================================
@node crypto aes
@subsection Advanced Encryption Standard
The @code{(industria crypto aes)} library provides an implementation of
the symmetrical Rijndael cipher as parameterized by the Advanced
Encryption Standard (AES). It was created by the Belgian
cryptographers Joan Daemen and Vincent Rijmen. Key lengths of 128, 192
and 256 bits are supported.

The code uses clever lookup tables and is probably as fast as any
R6RS implementation of AES can be without using an FFI. The number
of modes provided is pretty sparse though (only ECB and CTR). It also
leaks key material via memory.

AES modes have recommendations for how many times they should be used
with the same keying data.

@deffn Procedure expand-aes-key key
Expands the @var{key} into an @dfn{AES key schedule} suitable for
@code{aes-encrypt!}. The @var{key} must be a bytevector of length 16,
24 or 32 bytes. The type of the return value is unspecified.
@end deffn

@deffn Procedure aes-encrypt! source source-start target target-start key-schedule
Takes the 16 bytes at @var{source}+@var{source-start}, encrypts
them in Electronic Code Book (ECB) mode using the given
@var{key-schedule}, and then writes the result at
@var{target}+@var{target-start}. The @var{source} and the @var{target}
can be the same.

@example
(import (industria crypto aes))
(let ((buf (string->utf8 "A Scheme at work"))
      (sched (expand-aes-key (string->utf8 "super-secret-key"))))
  (aes-encrypt! buf 0 buf 0 sched)
  buf)
@result{} #vu8(116 7 242 187 114 235 130 138 166 39 24 204 117 224 5 8)
@end example

It is generally not a good idea to use ECB mode alone.
@end deffn

@deffn Procedure reverse-aes-schedule key-schedule
Reverses the @var{key-schedule} to make it suitable for @code{aes-decrypt!}.
@end deffn

@deffn Procedure aes-decrypt! source source-start target target-start key-schedule
Performs the inverse of @code{aes-encrypt!}. The @var{key-schedule}
should first be reversed with @code{reverse-aes-schedule}.

@example
(import (industria crypto aes))
(let ((buf (bytevector-copy #vu8(116 7 242 187 114 235 130 138
                                 166 39 24 204 117 224 5 8)))
      (sched (reverse-aes-schedule
              (expand-aes-key
               (string->utf8 "super-secret-key")))))
  (aes-decrypt! buf 0 buf 0 sched)
  (utf8->string buf))
@result{} "A Scheme at work"
@end example
@end deffn

@deffn Procedure clear-aes-schedule! key-schedule
Clears the AES key schedule so that it no longer contains
cryptographic material. Please note that there is no guarantee that
the key material will actually be gone from memory. It might remain in
temporary numbers or other values.
@end deffn

@deffn Procedure aes-ctr! source source-start target target-start len key-schedule ctr
Encrypts or decrypts the @var{len} bytes at
@var{source}+@var{source-start} using Counter (CTR) mode and writes
the result to @var{target}+@var{target-start}. The @var{len} does not
need to be a block multiple. The @var{ctr} argument is a non-negative
integer.

This procedure is its own inverse and the @var{key-schedule} should
not be reversed for decryption.

Never encrypt more than once using the same @var{key-schedule} and
@var{ctr} value. If you're not sure why that is a bad idea, you should
read up on CTR mode.
@end deffn

@deffn Procedure aes-cbc-encrypt! source source-start target target-start k key-schedule iv
Encrypts @var{k} bytes in the bytevector @var{source} starting at
@var{source-start} with AES in CBC mode and writes the result to
@var{target} at @var{target-start}.

The argument @var{k} must be an integer multiple of 16, which is the block length.

The @var{iv} bytevector is an Initial Vector. It should be 16 bytes
long, initialized to random bytes. This procedure updates the @var{iv}
after processing a block.
@end deffn

@deffn Procedure aes-cbc-decrypt! source source-start target target-start k key-schedule iv
The inverse of @code{aes-cbc-encrypt!}.
@end deffn

@deffn Procedure make-aes-gcm-state key-schedule iv-length tag-length
Creates an AES GCM state object that is used by the procedures below.
The @var{key-schedule} argument is the key schedule created by
@code{expand-aes-key}.
@end deffn

@deffn Procedure aes-gcm-encrypt! source source-start target target-start k gcm-state iv aad tag tag-start
Encrypts @var{k} bytes in the bytevector @var{source} starting at
@var{source-start} with AES in Galois/Counter Mode (GCM) mode and
writes the result to @var{target} at @var{target-start}. Source
and target may overlap.

The argument @var{k} must be an exact integer. There is no block
length for this mode.

The @var{gcm-state} argument must be an object created by
@code{make-aes-gcm-state}.

The @var{iv} bytevector is an initial vector. It must never be reused
with the same key.

GCM is different from CBC and CTR in that it offers Authenticated
Encryption with Associated Data (@dfn{AEAD}). This means that it does
not need to be combined with a separate HMAC procedure. The @var{aad}
argument is a bytevector that contains additional data to be
authenticated (or signed). The authentication tag (or signature) is
written to the bytevector @var{tag} starting at length
@var{tag-start}.

@example
(import (rnrs)
        (industria crypto aes))

(let* ((key #vu8(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16))
       (iv-length 12)
       (tag-length 16)
       (gcm-state (make-aes-gcm-state (expand-aes-key key)
                                      iv-length tag-length)))
  (let* ((plaintext
          (string->utf8 "This is our message to you"))
         (ciphertext
          (make-bytevector (bytevector-length plaintext)))
         (iv (make-bytevector iv-length 0))
         (aad (string->utf8 "aad"))
         (tag (make-bytevector tag-length)))
    (bytevector-u32-set! iv 0 42 (endianness big))
    (aes-gcm-encrypt! plaintext 0 ciphertext 0
                      (bytevector-length plaintext)
                      gcm-state iv aad tag 0)
    (display ciphertext)
    (newline)
    (let ((decrypted
           (make-bytevector (bytevector-length plaintext))))
      ;; The assertion will fail if ciphertext, aad and tag
      ;; do not match up.
      (assert (eq? 'ok (aes-gcm-decrypt!?
                         ciphertext 0 decrypted 0
                         (bytevector-length ciphertext)
                         gcm-state iv aad tag 0)))
      (utf8->string decrypted))))
@print{} #vu8(202 108 237 127 3 64 111 82 76 90 193 152 36
        47 45 169 38 116 185 13 217 240 2 127 246 15)
@result{} "This is our message to you"
@end example
@end deffn

@deffn Procedure aes-gcm-decrypt!? source source-start target target-start k gcm-state iv aad tag tag-start
Encrypts @var{k} bytes in the bytevector @var{source} starting at
@var{source-start} with AES in Galois/Counter Mode (GCM) mode and
writes the result to @var{target} at @var{target-start}.

The other arguments are as for @code{aes-gcm-encrypt!}.

Note: the return value must be checked by the caller. If the symbol
@code{ok} is returned then the data was authenticated correctly.
@end deffn

@c ======================================================================
@node crypto arcfour
@subsection ARCFOUR stream cipher
The @code{(industria crypto arcfour)} library provides the well-known
ARCFOUR stream cipher. It is the fastest of the ciphers provided by
this library collection.

Since this is a stream cipher there is no block length.

@deffn Procedure expand-arcfour-key key
Expands the bytevector @var{key} into an ARCFOUR keystream value. The
return value has an unspecified type and is suitable for use with the
other procedures exported by this library.

Never use the same key to encrypt two different plaintexts.
@end deffn

@deffn Procedure arcfour! source source-start target target-start k keystream
Reads @var{k} bytes from @var{source} starting at @var{source-start},
XORs them with bytes from the @var{keystream}, and writes them to
@var{target} starting at @var{target-start}. If @var{source} and
@var{target} are the same object then it is required that
@var{target-start} be less then or equal to @var{source-start}.

@example
(import (industria crypto arcfour))
(let ((buf #vu8(90 60 247 233 181 200 38 52 121 82 133
                98 244 159 12 97 90 157 43 183 249 170
                73 244 126))
      (keystream (expand-arcfour-key
                  (string->utf8 "hardly a secret"))))
  (arcfour-discard! keystream 3000)
  (arcfour! buf 0 buf 0 (bytevector-length buf) keystream)
  (clear-arcfour-keystream! keystream)
  (utf8->string buf))
@result{} "I AM POKEY THE PENGUIN!!!"
@end example
@end deffn

@deffn Procedure arcfour-discard! keystream n
Discards @var{n} bytes from the keystream @var{keystream}. It is
recommended that the beginning of the keystream is discarded. Some
protocols, e.g.@: RFC 4345, require it.
@end deffn

@deffn Procedure clear-arcfour-keystream! keystream
Removes all key material from the @var{keystream}.
@end deffn

@c ======================================================================
@node crypto blowfish
@subsection The Blowfish Cipher
The @code{(industria crypto blowfish)} library is a complete
implementation of Bruce Schneier's Blowfish cipher. It is a symmetric
block cipher with key length between 8 and 448 bits. The key
length does not affect the performance.

@deffn Procedure expand-blowfish-key key
Expands a Blowfish @var{key}, which is a bytevector of length between
1 and 56 bytes (the longer the better). The returned key schedule can
be used with @code{blowfish-encrypt!} or
@code{reverse-blowfish-schedule}.
@end deffn

@deffn Procedure blowfish-encrypt! source source-index target target-index schedule
Encrypts the eight bytes at @var{source}+@var{source-start} using
Electronic Code Book (ECB) mode. The result is written to
@var{target}+@var{target-start}.
@end deffn

@deffn Procedure reverse-blowfish-schedule
Reverses a Blowfish key schedule so that it can be used with
@code{blowfish-decrypt!}.
@end deffn

@deffn Procedure blowfish-decrypt! source source-index target target-index schedule
The inverse of @code{blowfish-encrypt!}.
@end deffn

@deffn Procedure clear-blowfish-schedule!
Clears the Blowfish key schedule so that it no longer contains
cryptographic material. Please note that there is no guarantee that
the key material will actually be gone from memory. It might remain in
temporary numbers or other values.
@end deffn

@deffn Procedure blowfish-cbc-encrypt! source source-start target target-start k schedule iv
Encrypts @var{k} bytes in the bytevector @var{source} starting at
@var{source-start} with Blowfish in CBC mode and writes the result to
@var{target} at @var{target-start}.

The argument @var{k} must be an integer multiple of 8, which is the block length.

The @var{iv} bytevector is an Initial Vector. It should be 8 bytes
long, initialized to random bytes. This procedure updates the @var{iv}
after processing a block.
@end deffn

@deffn Procedure blowfish-cbc-decrypt! source source-start target target-start k schedule iv
The inverse of @code{blowfish-cbc-encrypt!}.
@end deffn

@c ======================================================================
@node crypto chacha20
@subsection ChaCha20 stream cipher
The @code{(industria crypto chacha20)} library provides the ChaCha20
stream cipher, a 20-round variant of djb's ChaCha20 specified by RFC
7539.

Since this is a stream cipher there is no block length.

@deffn Procedure chacha20-block! out key block-count nonce
Update the first 64 bytes of the bytevector @var{out} with the output
from the ChaCha20 block function. The @var{key} is a 256-bit key given
as a 16-byte bytevector. The @var{block-count} is a 32-bit exact
integer. The @var{nonce} is a 96-bit @emph{number used only once}
(sometimes called an IV), given as a 48-byte bytevector.
@end deffn

@deffn Procedure chacha20-keystream key block-count nonce
Opens a binary input port that yields the ChaCha20 keystream. The
arguments are the same as for @code{chacha20-block!}.
@end deffn

@deffn Procedure chacha20-encrypt! source source-start target target-start len keystream
Copies @var{len} bytes from @var{source} to @var{target}, having the
same interface as @code{bytevector-copy!}, except that it encrypts the
bytes using the output from @var{keystream}.

The encryption is symmetric, so this is also the decryption primitive.
@end deffn

@deffn Procedure chacha20-encrypt source source-start len keystream
This is a convenience procedure that allocates a bytevector, but
otherwise performs the same operation as @code{chacha20-encrypt}.
@end deffn

@c ======================================================================
@node crypto ecdh
@subsection Elliptic Curve Diffie-Hellman key exchange
The @code{(industria crypto ecdh)} library exports procedures for
Elliptic Curve Diffie-Hellman key exchange. The library is based on
the X25519 and X448 functions from RFC 7748. ECDH is similar to DH,
@pxref{crypto dh}, but uses Curve25519 or Curve448. It is used when
two parties want to generate a key without sending the actual key over
the network.

The same caveats that apply to regular DH also apply to ECDH.
@cindex Elliptic Curve Diffie-Hellman

@deffn Procedure make-ecdh-curve25519-secret
Generates a Curve25519 private key @var{a} and a public key @var{K_A}.
@end deffn

@deffn Procedure make-ecdh-curve448-secret
Generates a Curve448 private key @var{a} and a public key @var{K_A}.
@end deffn

@deffn Procedure ecdh-curve25519 a K_B
Compute the shared key given Alice's private key @var{a} and Bob's
public key @var{K_B}.

@example
(import (industria crypto ecdh))

(let-values ([(a K_A) (make-ecdh-curve25519-secret)]
             [(b K_B) (make-ecdh-curve25519-secret)])
  ;; The bytevectors being compared are the shared secret
  (equal? (ecdh-curve25519 a K_B)
          (ecdh-curve25519 b K_A)))
@result{} #t
@end example
@end deffn

@deffn Procedure ecdh-curve448 a K_B
Compute the shared key given Alice's private key @var{a} and Bob's
public key @var{K_B}.
@end deffn

@deffn Procedure X25519 k u
The X25519 function, which is normally not needed, but is exposed for
those who want to use it. It is a scalar multiplication on the
Montgomery form of Curve25519.
@end deffn

@deffn Procedure X448 k u
Same as @code{X25519}, but with Curve448.
@end deffn

@c ======================================================================
@node crypto eddsa
@subsection Edwards-curve Digital Signature Algorithm (EdDSA)
EdDSA is a public key signature algorithm based on the edwards25519
and edwards448 curves. It is used in place for e.g. RSA signatures or
DSA. Currently only the Ed25519 variant is supported.

@deffn Procedure make-ed25519-public-key bv
Make an Ed25519 public key using @var{bv}, which is 32 bytes long.
@end deffn

@deffn Procedure ed25519-public-key? obj
True if @var{obj} is an Ed25519 public key.
@end deffn

@deffn Procedure ed25519-public-key=? key1 key2
True if @var{key1} is the same Ed25519 public key as @var{key2}.
@end deffn

@deffn Procedure ed25519-public-key-value key
The public key bytevector for @var{key}.
@end deffn

@deffn Procedure make-ed25519-private-key bv
Make an Ed25519 private key using the secret @var{bv}, which is 32
bytes long.
@end deffn

@deffn Procedure ed25519-private-key? obj
True if @var{obj} is an Ed25519 private key.
@end deffn

@deffn Procedure ed25519-private-key-secret
The private key bytevector for @var{key}.
@end deffn

@deffn Procedure ed25519-private->public key
Returns the public key that corresponds to the Ed25519 private @var{key}.
@end deffn

@deffn Procedure eddsa-private-key-from-bytevector bv
Decodes @var{bv} as a private EdDSA key. This is intended to also
support Ed448 in the future.
@end deffn

@deffn Procedure ed25519-sign private-key msg
Generate a SHA-512 based Ed25519 signature of @var{msg} using
@var{private-key}.
@end deffn

@deffn Procedure ed25519-verify public-key msg signature
Verify a SHA-512 based Ed25519 @var{signature} of @var{msg} that was
purportedly made with @var{public-key}. Returns @code{#t} iff the
signature is valid.
@end deffn


@c ======================================================================
@node crypto des
@subsection Data Encryption Standard
The Data Encryption Standard (DES) is older than AES and uses shorter
keys. To get longer keys the Triple Data Encryption Algorithm (TDEA,
3DES) is commonly used instead of DES alone.
@cindex Triple Data Encryption Algorithm
@cindex 3DES


The @code{(industria crypto des)} library is incredibly inefficient and
the API is, for no good reason, different from the AES library. You
should probably use AES instead, if possible.

@deffn Procedure des-key-bad-parity? key
Returns @code{#f} if the DES @var{key} has good parity, or the index
of the first bad byte. Each byte of the @var{key} has one parity bit,
so even though it is a bytevector of length eight (64 bits), only 56
bits are used for encryption and decryption. Parity is usually
ignored.
@end deffn

@deffn Procedure des! bv key-schedule [offset E]
The fundamental DES procedure, which performs both encryption and
decryption in Electronic Code Book (ECB) mode. The eight bytes
starting at @var{offset} in the bytevector @var{bv} are modified
in-place.

The @var{offset} can be omitted, in which case 0 is used.

The @var{E} argument will normally be omitted. It is only used by the
@code{des-crypt} procedure.

@example
(import (industria crypto des))
(let ((buf (string->utf8 "security"))
      (sched (permute-key (string->utf8 "terrible"))))
  (des! buf sched)
  buf)
@result{} #vu8(106 72 113 111 248 178 225 208)
@end example

@example
(import (industria crypto des))
(let ((buf (bytevector-copy #vu8(106 72 113 111 248 178 225 208)))
      (sched (reverse (permute-key (string->utf8 "terrible")))))
  (des! buf sched)
  (utf8->string buf))
@result{} "security"
@end example
@end deffn

@deffn Procedure permute-key key
Permutes the DES @var{key} into a key schedule. The key schedule is
then used as an argument to @code{des!}. To decrypt, simply reverse
the key schedule. The return value is a list.
@end deffn

@deffn Procedure tdea-permute-key key1 [key2 key3]
Permutes a 3DES key into a key schedule. If only one argument is given
then it must be a bytevector of length 24. If three arguments are given
they must all be bytevectors of length eight.

The return value's type is unspecified.
@end deffn

@deffn Procedure tdea-encipher! bv offset key
Encrypts the eight bytes at @var{offset} of @var{bv} using the given
3DES key schedule.
@end deffn

@deffn Procedure tdea-decipher! bv offset key
The inverse of @code{tdea-encipher!}.
@end deffn

@deffn Procedure tdea-cbc-encipher! bv key iv offset count
Encrypts the @var{count} bytes at @var{offset} of @var{bv} using
Cipher Block Chaining (CBC) mode.

The @var{iv} argument is the @dfn{Initial Vector}, which is XOR'd with
the data before encryption. It is a bytevector of length eight and it
is modified for each block.

Both @var{offset} and @var{count} must be a multiples of eight.
@end deffn

@deffn Procedure tdea-cbc-decipher! bv key iv offset count
The inverse of @code{tdea-cbc-encipher!}.
@end deffn

@deffn Procedure des-crypt password salt
This is a password hashing algorithm that used to be very popular on
Unix systems, but is today too fast (which means brute forcing
passwords from hashes is fast). The @var{password} string is at most
eight characters.

The algorithm is based on 25 rounds of a slightly modified DES.

The @var{salt} must be a string of two characters from the alphabet
@code{#\A}--@code{#\Z}, @code{#\a}--@code{#\z},
@code{#\0}--@code{#\9}, @code{#\.} and @code{#\/}.

@example
(import (industria crypto des))
(des-crypt "password" "4t")
@result{} "4tQSEW3lEnOio"
@end example

A more general interface is also available, @pxref{password}.
@end deffn

@c ======================================================================
@node crypto dh
@subsection Diffie-Hellman key exchange
The @code{(industria crypto dh)} library exports procedures and
constants for Diffie-Hellman (Merkle) key exchange. D-H works by
generating a pair of numbers, sending one of them to the other party,
and using the other one and the one you receive to compute a shared
secret. The idea is that it's difficult for an eavesdropper to deduce
the shared secret.

The D-H exchange must be protected by e.g.@: public key encryption
because otherwise a MITM attack is trivial. It is best to use a
security protocol designed by an expert.
@cindex Diffie-Hellman

@deffn Procedure make-dh-secret generator prime bit-length
Generates a Diffie-Hellman secret key pair. Returns two values: the
secret key (of bitwise length @var{bit-length}) part and the public
key part.
@end deffn

@deffn Procedure expt-mod base exponent modulus
Computes @code{(mod (expt @var{base} @var{exponent}) @var{modulus})}.
This is modular exponentiation, so all the parameters must be
integers.

The @var{exponent} can also be negative (set it to -1 to calculate the
multiplicative inverse of @var{base}).

@example
(import (industria crypto dh))
(let ((g modp-group15-g) (p modp-group15-p))
  (let-values (((y Y) (make-dh-secret g p 320))
               ((x X) (make-dh-secret g p 320)))
    ;; The numbers being compared are the shared secret
    (= (expt-mod X y modp-group15-p)
       (expt-mod Y x modp-group15-p))))
@result{} #t
@end example
@end deffn

This library also exports a few well known modular exponential (MODP)
Diffie-Hellman groups (generators and primes) that have been defined
by Internet RFCs. They are named modp-groupN-g (generator) and
modp-groupN-p (prime) where N is the number of the group. Groups 1, 2,
5, 14, 15, 16, 17 and 18 are currently exported. They all have
different lengths and longer primes are more secure but also slower.
See RFC 3526 for more on this.
@cindex MODP groups

@c ======================================================================
@node crypto dsa
@subsection Digital Signature Algorithm
The @code{(industria crypto dsa)} library provides procedures for
creating and verifying DSA signatures. DSA is a public key signature
algorithm, which means that it uses private and public key pairs. With
a private key you can create a signature that can then be verified by
someone using the corresponding public key. The idea is that it's very
difficult to create a correct signature without having access to the
private key, so if the signature can be verified it must have been
made by someone who has access to the private key.

DSA is standardized by FIPS Publication 186. It is available at this
web site: @url{http://csrc.nist.gov/publications/PubsFIPS.html}.

There is currently no procedure to generate a new DSA key. Here is
how to generate keys with OpenSSL or GnuTLS:
@verbatim
openssl dsaparam 1024 | openssl gendsa /dev/stdin > dsa.pem
certtool --dsa --bits 1024 -p > dsa.pem
@end verbatim

The key can then be loaded with @code{dsa-private-key-from-pem-file}.

@deffn Procedure make-dsa-public-key p q g y
Returns a DSA public key value. See the FIPS standard for a
description of the parameters.

To access the fields use @code{dsa-public-key-p},
@code{dsa-public-key-q}, @code{dsa-public-key-g} and
@code{dsa-public-key-y}.
@end deffn

@deffn Procedure dsa-public-key? obj
True if @var{obj} is a DSA public key value.
@end deffn

@deffn Procedure dsa-public-key-length key
Returns the number of bits in the @emph{p} value of @var{key}. This is
often considered to be the length of the key. The bitwise-length of
@emph{q} is also important, it corresponds with the length of the
hashes used for signatures.
@end deffn

@deffn Procedure make-dsa-private-key p q g y x
Returns a DSA private key value. See the FIPS standard for a
description of the parameters.

To access the fields use @code{dsa-private-key-p},
@code{dsa-private-key-q}, @code{dsa-private-key-g},
@code{dsa-private-key-y} and @code{dsa-private-key-x}.
@end deffn

@deffn Procedure dsa-private-key? obj
Returns @code{#t} if @var{obj} is a DSA private key.
@end deffn

@deffn Procedure dsa-private->public private-key
Converts a private DSA key into a public DSA key by removing the
private fields.
@end deffn

@deffn Procedure dsa-private-key-from-bytevector bv
Parses @var{bv} as an ASN.1 DER encoded private DSA key.
@end deffn

@deffn Procedure dsa-private-key-from-pem-file filename
Opens the file and reads a private DSA key. The file should be in
Privacy Enhanced Mail (PEM) format and contain an ASN.1 DER encoded
private DSA key.

Encrypted keys are currently not supported.
@end deffn

@deffn Procedure dsa-signature-from-bytevector bv
Parses the bytevector @var{bv} as an ASN.1 DER encoded DSA signature.
The return value is a list with the @var{r} and @var{s} values that
make up a DSA signature.
@end deffn

@deffn Procedure dsa-create-signature hash private-key
The @var{hash} is the message digest (as a bytevector) of the data you
want to sign. The @var{hash} and the @var{private-key} are used to
create a signature which is returned as two values: @code{r} and
@code{s}.

The @var{hash} can e.g.@: be an SHA-1 message digest. Such a digest is
160 bits and the @var{q} parameter should then be 160 bits.
@end deffn

@deffn Procedure dsa-verify-signature hash public-key r s
The @var{hash} is the message digest (as a bytevector) of the data
which the signature is signing.

Returns @code{#t} if the signature matches, otherwise @code{#f}.
@end deffn

@c ======================================================================
@node crypto ec
@subsection Elliptic Curve Cryptography
The @code{(industria crypto ec)} provides algorithms and definitions
for working with elliptic curves.

Only curves over prime finite fields are currently supported. Points
are either @code{+inf.0} (the point at infinity) or a pair of x and y
coordinates.

Some standardized curves are exported:

@vtable @code
@item secp256r1
This curve is equivalent to a 3072-bit RSA modulus.
@item nistp256
Curve P-256. This is the same curve as above.
@item secp384r1
This curve is equivalent to a 7680-bit RSA modulus.
@item nistp384
Curve P-384. This is the same curve as above.
@item secp521r1
This curve is equivalent to a 15360-bit RSA modulus. The ``521'' is
not a typo.
@item nistp521
Curve P-521. This is the same curve as above.
@end vtable

@deffn Procedure make-elliptic-prime-curve p a b G n h
Constructs a new elliptic-curve object given the domain parameters of
a curve:

@math{y^2 \equiv x^3 + ax + b} (mod @math{p}).

Normally one will be working with pre-defined curves, so this
constructor can be safely ignored. The curve definition will include
all these parameters.
@end deffn

@deffn Procedure elliptic-prime-curve? obj
Returns @code{#t} if @var{obj} is an elliptic prime curve.
@end deffn

The accessors can be safely ignored unless you're interested in the
curves themselves.

@deffn Procedure elliptic-curve-a elliptic-curve
This is one of the parameters that defines the curve: an element in
the field.
@end deffn

@deffn Procedure elliptic-curve-b elliptic-curve
This is one of the parameters that defines the curve: another element
in the field.
@end deffn

@deffn Procedure elliptic-curve-G elliptic-curve
This is one of the parameters that defines the curve: the base point,
i.e.@: an actual point on the curve.
@end deffn

@deffn Procedure elliptic-curve-n elliptic-curve
This is one of the parameters that defines the curve: a prime that is
the order of G (the base point).
@end deffn

@deffn Procedure elliptic-curve-h elliptic-curve
This is one of the parameters that defines the curve: the cofactor.
@end deffn

@deffn Procedure elliptic-prime-curve-p elliptic-prime-curve
This is one of the parameters that defines the curve: the integer that
defines the prime finite field.
@end deffn

@deffn Procedure elliptic-curve=? elliptic-curve@math{_1} elliptic-curve@math{_2}
Returns @code{#t} if the elliptic curve objects are equal (in the
sense that all domain parameters are equal).
@end deffn

@deffn Procedure ec+ P Q elliptic-curve
This adds the points @var{P} and @var{Q}, which must be points on
@var{elliptic-curve}.
@end deffn

@deffn Procedure ec- P [Q] elliptic-curve
This subtracts @var{Q} from @var{P}, both of which must be points on
@var{elliptic-curve}. If @var{Q} is omitted it returns the complement
of @var{P}.
@end deffn

@deffn Procedure ec* multiplier P elliptic-curve
This multiplies @var{P} by @var{multiplier}. @var{P} must be a point
on @var{elliptic-curve} and @var{multiplier} must be a non-negative
integer.

This operation is the elliptic curve equivalence of @code{expt-mod}.
@end deffn

@deffn Procedure bytevector->elliptic-point bytevector elliptic-curve
Converts @var{bytevector} to a point on @var{elliptic-curve}. When
points are sent over the network or stored in files they are first
converted to bytevectors.
@end deffn

@deffn Procedure integer->elliptic-point integer elliptic-curve
Performs the same conversion as @code{bytevector->elliptic-point}, but
first converts @var{integer} to a bytevector.
@end deffn

@deffn Procedure ->elliptic-point x elliptic-curve
A generic procedure that accepts as input an @var{x} that is either
already a point, a bytevector representing a point, or an integer
representing a point.
@end deffn

@deffn Procedure elliptic-point->bytevector point elliptic-curve
Converts @var{point} to its bytevector representation. This
representation is sometimes hashed, e.g.@: in SSH public keys, so the
canonical representation is used for compatibility with other
software.
@end deffn

@c ======================================================================
@node crypto ecdsa
@subsection Elliptic Curve Digital Signature Algorithm (ECDSA)
The @code{(industria crypto ecdsa)} library builds on the
@code{(industria crypto ec)} library and provides an interface similar
to @code{(industria crypto dsa)}. The keys and the operations are
defined to work with elliptic curves instead of modular
exponentiation.

@deffn Procedure make-ecdsa-public-key elliptic-curve Q
Constructs an ECDSA public key object. @var{Q} is a point on
@var{elliptic-curve}. @var{Q} is only checked to be on the curve if it
is in bytevector format.
@end deffn

@deffn Procedure ecdsa-public-key? obj
Returns @code{#t} if @var{obj} is an ECDSA public key object.
@end deffn

@deffn Procedure ecdsa-public-key-curve ecdsa-public-key
Returns the curve that @var{ecdsa-public-key} uses.
@end deffn

@deffn Procedure ecdsa-public-key-Q ecdsa-public-key
The point on the curve that defines @var{ecdsa-public-key}.
@end deffn

@deffn Procedure ecdsa-public-key-length ecdsa-public-key
The bitwise length of the ECDSA public key @var{ecdsa-public-key}.
@end deffn


@deffn Procedure make-ecdsa-private-key elliptic-curve [d Q]
Constructs an ECDSA private key object. @var{d} is a secret
multiplier, which gives a public point @var{Q} on
@var{elliptic-curve}.

If @var{Q} is omitted it is recomputed based on @var{d} and the curve.
If @var{d} is omitted a random multiplier is chosen. Please note the
warning about entropy at the start of this section. @xref{crypto}.
@end deffn

@deffn Procedure ecdsa-private-key? obj
Returns @code{#t} if @var{obj} is an ECDSA private key object.
@end deffn

@deffn Procedure ecdsa-private-key-d ecdsa-private-key
The secret multiplier of @var{ecdsa-private-key}.
@end deffn

@deffn Procedure ecdsa-private-key-Q ecdsa-private-key
The public point of @var{ecdsa-private-key}.
@end deffn


@deffn Procedure ecdsa-private->public ecdsa-private-key
Strips @var{ecdsa-private-key} of the secret multiplier and returns an
ECDSA public key object.
@end deffn


@deffn Procedure ecdsa-private-key-from-bytevector bytevector
Parses @var{bytevector} as an ECDSA private key encoded in RFC 5915
format. A curve identifier is encoded along with the key. Currently
only the curves secp256r1, secp384r1 and secp521r1 are supported.
@end deffn


@deffn Procedure ecdsa-verify-signature hash ecdsa-public-key r s
Returns @code{#t} if the signature (@var{r},@var{s}) was made by the
private key corresponding to @var{ecdsa-public-key}. The bytevector
@var{hash} is the message digest that was signed.
@end deffn

@deffn Procedure ecdsa-create-signature hash ecdsa-private-key
Creates a signature of the bytevector @var{hash} using
@var{ecdsa-private-key}. Returns the values r and s.
@end deffn

ECDSA keys are normally defined to work together with some particular
message digest algorithm. RFC 5656 defines ECDSA with SHA-2 and this
library provides the record types @code{ecdsa-sha-2-public-key} and
@code{ecdsa-sha-2-private-key} so that keys defined to work with SHA-2
can be distinguished from other keys. Keys of this type are still
usable for operations that expect the normal ECDSA key types.

@deffn Procedure ecdsa-signature-from-bytevector bv
Parses the bytevector @var{bv} as an ASN.1 DER encoded ECDSA signature
as per RFC 4492. The return value is a list with the @var{r} and
@var{s} values that make up a ECDSA signature. These values should be
passed to @code{ecdsa-verify-signature}.
@end deffn

@deffn Procedure ecdsa-signature-to-bytevector r s
Encodes the ECDSA signature @var{r} and @var{s} as a bytevector in the
ASN.1 DER format given in RFC 4492.
@end deffn

@deffn Procedure make-ecdsa-sha-2-public-key elliptic-curve Q
Performs the same function as @code{make-ecdsa-public-key}, but the
returned key is marked to be used with SHA-2.
@end deffn

@deffn Procedure ecdsa-sha-2-public-key? obj
Returns @code{#t} if @var{obj} is an ECDSA public key marked to be
used with SHA-2.
@end deffn


@deffn Procedure make-ecdsa-sha-2-private-key
Performs the same function as @code{make-ecdsa-private-key}, but the
returned key is marked to be used with SHA-2.
@end deffn

@deffn Procedure ecdsa-sha-2-private-key?
Returns @code{#t} if @var{obj} is an ECDSA private key marked to be
used with SHA-2.
@end deffn

@deffn Procedure ecdsa-sha-2-verify-signature message ecdsa-sha2-public-key r s
The bytevector @var{message} is hashed with the appropriate message
digest algorithm (see RFC 5656) and the signature (@var{r},@var{s}) is
then verified. Returns @code{#t} if the signature was made with the
private key corresponding to @var{ecdsa-sha2-public-key}.
@end deffn

@deffn Procedure ecdsa-sha-2-create-signature message ecdsa-sha2-private-key
The bytevector @var{message} is hashed with the appropriate message
digest algorithm (see RFC 5656) and a signature is created using
@var{ecdsa-sha2-private-key}. Returns the values r and s.
@end deffn

@deffn Procedure ecdsa-sha-2-private-key-from-bytevector bytevector
Performs the same function as
@code{ecdsa-private-key-from-bytevector}, except the returned value is
marked to be used with SHA-2.
@end deffn

@c ======================================================================
@node crypto entropy
@subsection Entropy and randomness
The @code{(industria crypto entropy)} library is meant to help with
generating random data. It tries to use the system's
@code{/dev/urandom} device if possible, otherwise it uses SRFI-27.

Please see the note at the beginning of the chapter.

@deffn Procedure bytevector-randomize! target [target-start k]
Writes @var{k} random bytes to the bytevector @var{target} starting at
index @var{target-start}.
@end deffn

@deffn Procedure make-random-bytevector k
Returns a bytevector of length @var{k} with random content.

@example
(import (industria crypto entropy))
(make-random-bytevector 8)
@result{} #vu8(68 229 38 253 58 70 198 161)
@end example
@end deffn


@c ======================================================================
@node crypto rsa
@subsection RSA public key encryption and signatures
The @code{(industria crypto rsa)} library implements the RSA (Rivest,
Shamir and Adleman) algorithm and a few helpers.

@deffn Procedure make-rsa-public-key n e
Returns an RSA public key object containing the modulus @var{n} and
the public exponent @var{e}.
@end deffn

@deffn Procedure rsa-public-key? obj
True if @var{obj} is a public RSA key.
@end deffn

@deffn Procedure rsa-public-key-n key
@end deffn
@deffn Procedure rsa-public-key-modulus key
Returns the @emph{modulus} of @var{key}.
@end deffn

@deffn Procedure rsa-public-key-e key
@end deffn
@deffn Procedure rsa-public-key-public-exponent key
Returns the @emph{public exponent} of @var{key}.
@end deffn

@deffn Procedure rsa-public-key-from-bytevector bytevector
Parses @var{bytevector} as an ASN.1 DER encoded public RSA key. The
return value can be used with the other procedures in this library.
@end deffn

@deffn Procedure rsa-public-key-length key
Returns the number of bits in the modulus of @var{key}. This is also
the maximum length of data that can be encrypted or decrypted with the
key.
@end deffn

@deffn Procedure rsa-public-key-byte-length key
Returns the number of 8-bit bytes required to store the modulus of
@var{key}.
@end deffn

@deffn Procedure make-rsa-private-key n e d [p q exponent1 exponent2 coefficient]
Returns an RSA private key object with the given modulus @var{n},
public exponent @var{e}, and private exponent @var{d}.

The other parameters are used to improve the efficiency of
@code{rsa-encrypt}. They are optional and will be computed if they are
omitted.
@end deffn

@deffn Procedure rsa-private-key? obj
True if @var{obj} is a private RSA key.
@end deffn

@deffn Procedure rsa-private-key-n key
@end deffn
@deffn Procedure rsa-private-key-modulus key
Returns the @emph{modulus} of @var{key}.
@end deffn

@deffn Procedure rsa-private-key-public-exponent key
Returns the @emph{public exponent} of @var{key}. This exponent is used
for encryption and signature verification.
@end deffn

@deffn Procedure rsa-private-key-d key
@end deffn
@deffn Procedure rsa-private-key-private-exponent key
Returns the @emph{private exponent} of @var{key}. This exponent is
used for decryption and signature creation.
@end deffn

@deffn Procedure rsa-private-key-prime1 key
@end deffn
@deffn Procedure rsa-private-key-prime2 key
These two procedures return the first and second prime factors
(@math{p},@math{q}) of the modulus (@math{n=pq}).
@end deffn

@deffn Procedure rsa-private-key-exponent1 key
This should be equivalent to @code{(mod d (- p 1))}. It is used to
speed up @code{rsa-decrypt}.
@end deffn

@deffn Procedure rsa-private-key-exponent2 key
This should be equivalent to @code{(mod d (- q 1))}. It is used to
speed up @code{rsa-decrypt}.
@end deffn

@deffn Procedure rsa-private-key-coefficient key
This should be equivalent to @code{(expt-mod q -1 p)}. It is used to
speed up @code{rsa-decrypt}.
@end deffn

@deffn Procedure rsa-private->public key
Uses the @emph{modulus} and @emph{public exponent} of @var{key} to
construct a public RSA key object.
@end deffn

@deffn Procedure rsa-private-key-from-bytevector bytevector
Parses @var{bytevector} as an ASN.1 DER encoded private RSA key. The
return value can be used with the other procedures in this library.
@end deffn

@deffn Procedure rsa-private-key-from-pem-file filename
Opens the file and reads a private RSA key. The file should be in
Privacy Enhanced Mail (PEM) format and contain an ASN.1 DER encoded
private RSA key.

Encrypted keys are currently not supported.
@end deffn

@deffn Procedure rsa-encrypt plaintext key
Encrypts the @var{plaintext} integer using the @var{key}, which is
either a public or private RSA key.

@var{plaintext} must be an exact integer that is less than the modulus
of @var{key}.
@end deffn

@deffn Procedure rsa-decrypt ciphertext key
Decrypts the @var{ciphertext} integer using the @var{key}, which
must be a private RSA key.

@var{ciphertext} must be an exact integer that is less than the
modulus of @var{key}.

@example
(import (industria crypto rsa))
(let ((key (make-rsa-private-key 3233 17 2753)))
  (rsa-decrypt (rsa-encrypt 42 key) key))
@result{} 42
@end example
@end deffn

@deffn Procedure rsa-decrypt/blinding ciphertext key
This performs the same function as @code{rsa-decrypt}, but it uses RSA
blinding. It has been shown that the private key can be recovered by
measuring the time it takes to run the RSA decryption function. Use
RSA blinding to protect against these timing attacks.

For more technical information on the subject, see Paul C.@: Kocher's
article
@url{http://www.cryptography.com/resources/whitepapers/TimingAttacks.pdf,
Timing Attacks on Implementations of Diffie-Hellman@comma{}
RSA@comma{} DSS@comma{} and Other Systems}.
@end deffn

It is often not enough to just use the plain encryption and decryption
procedures; a protocol for what to put in the plaintext should also be
used. PKCS #1 (RFC@: 3447) is a standard for how to perform RSA
encryption and signing with padding. New protocols should use one of
the other protocols from the RFC.

@deffn Procedure rsa-pkcs1-encrypt plaintext public-key
Pads and encrypts the @var{plaintext} bytevector using
@var{public-key}, a public RSA key. The return value is an integer.

The plaintext can't be longer than the length of the key modulus, in
bytes, minus 11.
@end deffn

@deffn Procedure rsa-pkcs1-decrypt ciphertext private-key
The inverse of @var{rsa-pkcs1-encrypt}. Decrypts the @var{ciphertext}
integer using @var{private-key}, a private RSA key. The padding is
then checked for correctness and removed.

@example
(import (industria crypto rsa))
(let ((key (make-rsa-private-key
            288412728347463293650191476303670753583
            65537
            190905048380501971055612558936725496993)))
  (utf8->string
   (rsa-pkcs1-decrypt
    (rsa-pkcs1-encrypt (string->utf8 "Hello")
                       (rsa-private->public key))
    key)))
@result{} "Hello"
@end example
@end deffn

@deffn Procedure rsa-pkcs1-decrypt-signature signature public-key
Decrypts the signature (a bytevector) contained in the @var{signature}
integer by using the @var{public-key}. The signature initially
contains PKCS #1 padding, but this is removed.
@end deffn

@deffn Procedure rsa-pkcs1-encrypt-signature digest private-key
Sign the bytevector @var{digest} using @var{private-key}. The inverse
of @code{rsa-pkcs1-decrypt-signature}.
@end deffn

@deffn Procedure rsa-pkcs1-decrypt-digest signature public-key
This performs the same operation as
@code{rsa-pkcs1-decrypt-signature}, except it then treats the
decrypted signature as a DER encoded DigestInfo. The return value is a
list containing a digest algorithm specifier and a digest.
@end deffn

@deffn Procedure rsa-pkcs1-encrypt-digest algorithm digest private-key
Create a DER encoded DigestInfo signature (inverse of
@code{rsa-pkcs1-decrypt-digest}). The @var{digest} must be a
bytevector and should have a length appropriate for the
@var{algorithm}, which may be either an object ID or one of these
symbols: md5, sha-1, sha-224, sha-256, sha-384, sha-512, sha-512-224,
sha-512-256, sha3-224, sha3-256, sha3-384, sha3-512, shake-128,
shake-256.
@end deffn
