@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

And remember what the license says about warranties. Don't come crying
to me if the enemy deciphers your secret messages and your whole
convoy blows up. These libraries have not been validated by the NIST
or the FDA and quite likely aren't allowed for government work.
@cindex security, warning

@menu
* crypto aes::            Advanced Encryption Standard (AES)
* crypto arcfour::        ARCFOUR stream cipher
* crypto blowfish::       The Blowfish cipher
* crypto crc::            Cyclic Redundancy Codes (CRC)
* 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 ec dsa::         Elliptic Curve Digital Signature Algorithm (ECDSA)
* crypto entropy::        Entropy and randomness
* crypto md5::            Message-Digest algorithm 5 (MD5)
* crypto openpgp::        OpenPGP signature verification
* crypto password::       Password hashing
* crypto rsa::            RSA public key encryption and signatures
* crypto sha-1::          Secure Hash Algorithm 1 (SHA-1)
* crypto sha-2::          Secure Hash Algorithm 2 (SHA-256, SHA-512, etc)
* crypto ssh-public-key:: SSH public key format conversion
* crypto x509::           X.509 Public-Key Infrastructure
@end menu

@c ======================================================================
@node crypto aes
@subsection Advanced Encryption Standard
The @code{(weinholt 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
@rnrs{} 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.

@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 (weinholt 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 (weinholt 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

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize

@c ======================================================================
@node crypto arcfour
@subsection ARCFOUR stream cipher
The @code{(weinholt 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 (weinholt 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{(weinholt 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

@noindent
Version history:
@itemize
@item
@code{(0 0)} -- Initial version.
@item
@code{(0 1)} -- Added procedures for CBC mode.
@end itemize

@c ======================================================================
@node crypto crc
@subsection Cyclic Redundancy Codes
The @code{(weinholt crypto crc)} library exports syntax for defining
procedures that calculate CRCs. There is a simple syntax that simply
requires the name of the CRC, and an advanced syntax that can define
new CRCs.

CRCs do not really qualify as cryptography, because it is trivial to
modify data so that the modified data's CRC matches the old one.

@deffn Syntax define-crc name
This is the simple interface that requires merely the name of the CRC
algorithm. The pre-defined CRCs that can be used this way are
currently: @code{crc-32}, @code{crc-16}, @code{crc-16/ccitt},
@code{crc-32c}, @code{crc-24}, @code{crc-64} (CRC-64-ISO), and
@code{crc-64/ecma-182}.

@example
(import (weinholt crypto crc))
(define-crc crc-32)
@end example
@end deffn

@deffn Syntax define-crc name width polynomial init ref-in ref-out xor-out check
For details on how the arguments work, and the theory behind them, see
Ross N.@tie{}Williams's paper @cite{A painless guide to CRC error
detection algorithms}, which is available at
@url{http://www.ross.net/crc/crcpaper.html}. A brief description of the
arguments follows.

The @var{width} is the bitwise length of the polynomial. You might be
led to believe that it should sometimes be 33, but if so you've
been counting the highest bit, which doesn't count.

The polynomial for CRC-16 is sometimes given as @math{x^{16} + x^{15}
+ x^2 + 1}. This translates to @code{#b1000000000000101}
(@code{#x8005}). Notice that @math{x^{16}} is absent. Don't use the
reversed polynomial if you have one of those, instead set @var{ref-in}
and @var{ref-out} properly.

After a CRC has been calculated it is sometimes @sc{xor}'d with a
final value, this is @var{xor-out}.

@var{check} is either @code{#f} or the CRC of the string @code{"123456789"}.
@end deffn

@deffn Syntax define-crc name (coefficients ...) init ref-in ref-out xor-out check
This is a slightly easier version of the advanced interface where you
can simply specify the powers of the coefficients. CRC-16 in this
syntax becomes:

@example
(import (weinholt crypto crc))
(define-crc crc-16 (16 15 2 0) #x0000 #t #t #x0000 #xBB3D)
@expansion{}
(begin
  (define (crc-16 bv)
    (crc-16-finish (crc-16-update (crc-16-init) bv)))
  (define (crc-16-init) #x0000)
  (define (crc-16-finish r) (bitwise-xor r #x0000))
  (define (crc-16-self-test)
    (if #xBB3D
        (if (= (crc-16 (string->utf8 "123456789")) #xBB3D)
            'success 'failure)
        'no-self-test))
  @dots{})
@end example

Another example: the polynomial @math{x^8 + x^2 + x + 1} in this syntax
is @code{(8 2 1 0)}.
@end deffn

After e.g.@: @code{(define-crc crc-32)} has been used, these bindings
will be available (with names that match the name of the CRC):

@deffn Procedure crc-32 bytevector
Calculates the final CRC of the entire bytevector and returns it as an
integer.

@example
(import (weinholt crypto crc))
(define-crc crc-32)
(crc-32 (string->utf8 "A fiendish scheme"))
@result{} 1384349758
@end example
@end deffn

@deffn Procedure crc-32-init
Returns an initial CRC state.
@end deffn

@deffn Procedure crc-32-update state bv [start end]
Uses the @var{state} and returns a new state that includes the CRC of
the given bytes.

@example
(import (weinholt crypto crc))
(define-crc crc-32)
(crc-32-finish
 (crc-32-update (crc-32-init)
                (string->utf8 "A fiendish scheme")))
@result{} 1384349758
@end example
@end deffn

@deffn Procedure crc-32-finish state
Finalizes the CRC @var{state}.
@end deffn

@deffn Procedure crc-32-width
Returns the bit-width of the CRC, e.g.@: 32 for CRC-32.
@end deffn

@deffn Procedure crc-32-self-test
Performs a sanity check and returns either
@code{success}, @code{failure} or @code{no-self-test}.
@end deffn

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version. Includes crc-32, crc-16,
 crc-16/ccitt, crc-32c, and crc-24.
@item
@code{(1 1)} -- Added crc-64 and the @code{-width} procedures. The
@code{-update} procedures use fixnums if @code{(fixnum-width)} is
larger than the CRC's width.
@code{(1 2)} -- Added crc-64/ecma-182.
@end itemize

@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{(weinholt 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 (weinholt 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 (weinholt 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 (weinholt crypto des))
(des-crypt "password" "4t")
@result{} "4tQSEW3lEnOio"
@end example

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


@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize


@c ======================================================================
@node crypto dh
@subsection Diffie-Hellman key exchange
The @code{(weinholt 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 (weinholt 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

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize


@c ======================================================================
@node crypto dsa
@subsection Digital Signature Algorithm
The @code{(weinholt 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

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize

@c ======================================================================
@node crypto ec
@subsection Elliptic Curve Cryptography
The @code{(weinholt 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

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize

@c ======================================================================
@node crypto ec dsa
@subsection Elliptic Curve Digital Signature Algorithm (ECDSA)
The @code{(weinholt crypto ec dsa)} library builds on the
@code{(weinholt crypto ec)} library and provides an interface similar
to @code{(weinholt 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 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

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize

@c ======================================================================
@node crypto entropy
@subsection Entropy and randomness
The @code{(weinholt 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 (weinholt crypto entropy))
(make-random-bytevector 8)
@result{} #vu8(68 229 38 253 58 70 198 161)
@end example
@end deffn

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize

@c ======================================================================
@node crypto md5
@subsection Message-Digest algorithm 5
The @code{(weinholt crypto md5)} library is an implementation of the
cryptographic hash function MD5. It takes bytes as input and returns a
@dfn{message digest}, which is like a one-way summary of the data. The
idea is that even the smallest change in the data should produce a
completely different digest, and it should be difficult to find
different data that has the same digest. An MD5 digest is 16 bytes.

MD5 has a maximum message size of @math{2^{64}-1} bits.

The MD5 algorithm is considered broken and you will likely want to use
SHA-2 instead, if possible.

@deffn Procedure md5 bv ...
The complete all-in-one procedure to calculate the MD5 message digest
of all the given bytevectors in order. Returns an md5 state, which
should be used with @code{md5->bytevector} or @code{md5->string}.

@example
(md5->string (md5 (string->utf8 "A Scheme in my pocket")))
@result{} "65A2B2D8EE076250EA0A105A8D5EF1BB"
@end example
@end deffn

@deffn Procedure md5-length
The length of md5 message digests in bytes.
@end deffn

@deffn Procedure make-md5
Returns a new MD5 state for use with the procedures below. The type of
the return value is unspecified.
@end deffn

@deffn Procedure md5-update! md5state bv [start end]
Updates the @var{md5state} to include the specified range of data from
@var{bv}.
@end deffn

@deffn Procedure md5-finish! md5state
Finalizes the @var{md5state}. This must be used after the last call to
@code{md5-update!}.
@end deffn

@deffn Procedure md5-clear! md5state
Clear the @var{md5state} so that it does not contain any part of the
input data or the message digest.
@end deffn

@deffn Procedure md5-copy md5state
Make a copy of the @var{md5state}.
@end deffn

@deffn Procedure md5-finish md5state
Performs @code{md5-finish!} on a copy of @var{md5state} and then
returns the new state.
@end deffn

@deffn Procedure md5-copy-hash! md5state bv offset
Copies the message digest (a.k.a.@: hash) in the finalized
@var{md5state} into @var{bv} at the given offset.
@end deffn

@deffn Procedure md5-96-copy-hash! md5state bv offset
Like @code{md5-copy-hash!}, but only copies the leftmost 96 bits.
@end deffn

@deffn Procedure md5->bytevector md5state
Returns a new bytevector which contains a binary representation of the
finalized @var{md5state}.
@end deffn

@deffn Procedure md5->string md5state
Returns a new string which contains a textual representation of the
finalized @var{md5state}. The conventional hexadecimal representation
is used.
@end deffn

@deffn Procedure md5-hash=? md5state bv
Compares the finalized @var{md5state} with the leading bytes of
@var{bv}. The comparison is designed to take the same amount of time
regardless of where any differences may be. This may be important for
networked programs that would otherwise be vulnerable to timing
attacks.
@end deffn

@deffn Procedure md5-96-hash=? md5state bv
Like @code{md5-hash=?} except it only compares the leftmost 96 bits.
@end deffn

@deffn Procedure hmac-md5 secret bytevector ...
An HMAC is a Hash-based Message Authentication Code. This procedure uses
MD5 to generate such a code. The return value is an MD5 state.
@end deffn

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@item
@code{(1 1)} -- Added @code{md5-length}, @code{md5-96-copy-hash!},
@code{md5-hash=?} and @code{md5-96-hash=?}.
@end itemize

@c ======================================================================
@node crypto openpgp
@subsection OpenPGP signature verification
The @code{(weinholt crypto openpgp)} library provides procedures for
reading OpenPGP keyrings and verifying signatures. OpenPGP signatures
can be created with e.g.@: GNU Private Guard (GnuPG) and are often
used to verify the integrity of software releases.

Version 4 keys and version 3/4 signatures are supported. The
implemented public key algorithms are RSA and DSA, and it verifies
signatures made using the message digest algorithms MD5, SHA-1,
SHA-224, SHA-256, SHA-384 and SHA-512 (all the standard algorithms
except RIPE-MD160).

An OpenPGP key is actually a list of OpenPGP packets with a certain
structure: first is the primary key (e.g. an RSA or DSA key), next
possibly a revocation, then a number of user IDs, attributes,
signatures and also subkeys (which are just like primary keys, except
marked as subkeys). See RFC 4880 section 11 for the exact composition.
This library represents keyrings as hashtables indexed by key ID and
where the entries are lists of packets in the order they appeared in
the keyring file.

Please note that this library assumes the program that wrote the
keyring did due diligence when importing keys, and made sure that
e.g.@: subkey binding signatures are verified, and that the order of
packets is correct.

@deffn Procedure port-ascii-armored? port
Returns false if the data at the beginning of @var{port} doesn't look
like a valid binary OpenPGP packet. The port must be a binary input
port. The port position is not changed.
@end deffn

@deffn Procedure get-openpgp-packet port
Reads an OpenPGP packet from @var{port}, which must be a binary input
port. An error is raised if the packet type is unimplemented.
@end deffn

@deffn Procedure get-openpgp-keyring p
Reads a keyring from the binary input port @var{p}. Returns a
hashtable where all primary keys and subkeys are indexed by their key
ID (an integer). The values in the hashtable are lists that contain
all OpenPGP packets associated with each key. No effort at all is made
to verify that keys have valid signatures.

Warning: this can take a while if the keyring is very big.
@end deffn

@deffn Procedure get-openpgp-keyring/keyid p keyid
Searches the binary input port @var{p} for the public key with the
given @var{keyid}. Returns a hashtable similar to
@code{get-openpgp-keyring}, except it will only contain the primary
and subkeys associated with the @var{keyid}.

The @var{keyid} can be either a 64 or 32 bit exact integer.

Warning: this is faster than get-openpgp-keyring, but is still rather
slow with big keyrings. The speed depends on the SHA-1 implementation.
@end deffn

@deffn Procedure get-openpgp-detached-signature/ascii p
Reads a detached OpenPGP signature from the textual input port
@var{p}. Returns either an OpenPGP signature object or the end of file
object.

These signatures can be created with e.g.@: @code{gpg -a --detach-sign filename}.
@end deffn

@deffn Procedure verify-openpgp-signature sig keyring p
Verifies the signature data in @var{sig}. The @var{keyring} hashtable
is used to find the public key of the signature issuer. The signed
data is read from the binary input port @var{p}.

This procedure returns two values. These are the possible
combinations:
@itemize
@item
@t{good-signature }@emph{key-data} -- The signature matches
the data. The @emph{key-data} contains the public key list that was
used to verify the signature.
@item
@t{bad-signature }@emph{key-data} -- The signature does not
match the data. The @emph{key-data} is the same as above.
@item
@t{missing-key }@emph{key-id} -- The issuer public key for the
signature was not found in the keyring. The @emph{key-id} is the
64-bit key ID of the issuer.
@end itemize
@end deffn

@deffn Procedure openpgp-signature? obj
True if @var{obj} is an OpenPGP signature object. Such objects are
read with @code{get-openpgp-detached-signature/ascii} and are also
contained in keyring entries.
@end deffn

@deffn Procedure openpgp-signature-issuer sig
The 64-bit key ID of the OpenPGP public key that issued the
signature @var{sig}.
@end deffn

@deffn Procedure openpgp-signature-public-key-algorithm sig
Returns the name of the public key algorithm used to create the
signature @var{sig}. This is currently the symbol @code{dsa} or
@emph{rsa}.
@end deffn

@deffn Procedure openpgp-signature-hash-algorithm sig
The name of the message digest algorithm used to create the
signature @var{sig}. This is currently one of @code{md5},
@code{sha-1}, @code{ripe-md160} (unsupported), @code{sha-224},
@code{sha-256}, @code{sha-384} or @code{sha-512}.
@end deffn

@deffn Procedure openpgp-signature-creation-time sig
An SRFI-19 date object representing the time at which the signature
@var{sig} was created.
@end deffn

@deffn Procedure openpgp-signature-expiration-time sig
An SRFI-19 date object representing the time at which the signature
@var{sig} expires. Returns @code{#f} if there's no expiration time.
@end deffn

@deffn Procedure openpgp-user-id? obj
True if @var{obj} is an OpenPGP user id.
@end deffn

@deffn Procedure openpgp-user-id-value user-id
The string value of the @var{user-id}. This is often the name of the
person who owns the key.
@end deffn

@deffn Procedure openpgp-user-attribute? obj
True if @var{obj} is an OpenPGP user attribute. Attributes are used to
encode JPEG images. There's currently no way to access the image.
@end deffn

@deffn Procedure openpgp-public-key? obj
True if @var{obj} is an OpenPGP primary key or subkey.
@end deffn

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

@deffn Procedure openpgp-public-key-value key
The DSA or RSA public key contained in the OpenPGP public @var{key}.
The value returned has the same type as the @code{(crypto weinholt
dsa)} or @code{(crypto weinholt rsa)}.
@end deffn

@deffn Procedure openpgp-public-key-fingerprint key
The fingerprint of the OpenPGP public @var{key} as a bytevector. This
is an SHA-1 digest based on the public key values.
@end deffn

@deffn Procedure openpgp-format-fingerprint bv
Formats the bytevector @var{bv}, which was presumably created by
@code{openpgp-public-key-fingerprint}, as a string in the format
preferred for PGP public key fingerprints.
@end deffn

@deffn Procedure openpgp-public-key-id key
The 64-bit key ID of the OpenPGP public @var{key}.
@end deffn

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@item
@code{(1 1)} -- Added @code{get-openpgp-packet} and
@code{port-ascii-armored?}.
@end itemize

@c ======================================================================
@node crypto password
@subsection Password hashing
The procedure provided by @code{(weinholt crypto password)} is the
same type of procedure that is called @code{crypt} in the standard C
library. It is used for password hashing, i.e.@: it scrambles
passwords. This is a method often used when passwords need to be
stored in databases.

The scrambling algorithms are based on cryptographic primitives but
have been modified so that they take more time to compute. They also
happen to be quite annoying to implement.

Only DES and MD5 based hashes are currently supported.

@deffn Procedure crypt password salt
Scrambles a @var{password} using the given @var{salt}. The @var{salt}
can also be a hash. The returned hash will be prefixed by the salt.

A fresh random salt should be used when hashing a new password. The
purpose of the salt is to make it infeasible to reverse the hash
using lookup tables.

To verify that a password matches a hash, you can do something like
@code{(string=? hash (crypt password hash))}.

@example
(import (weinholt crypto password))
(crypt "test" "..")
@result{} "..9sjyf8zL76k"
@end example

@example
(crypt "test" "$1$RQ3YWMJd$")
@result{} "$1$RQ3YWMJd$oIomUD5DCxenAs2icezcn."
@end example

@example
(string=? "$1$ggKHY.Dz$fNBcmNFTa1BFGXoLsRDkS."
          (crypt "test" "$1$ggKHY.Dz$fNBcmNFTa1BFGXoLsRDkS."))
@result{} #t
@end example
@end deffn

@c TODO: there ought be a simple way to generate a fresh salt

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@end itemize

@c ======================================================================
@node crypto rsa
@subsection RSA public key encryption and signatures
The @code{(weinholt 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 (weinholt 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 (weinholt 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-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

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@item
@code{(1 1)} -- Implemented private key operations.
@end itemize

@c ======================================================================
@node crypto sha-1
@subsection Secure Hash Algorithm 1
The interface provided by @code{(weinholt crypto sha-1)} is identical
to the one provided by the MD5 library, except every procedure is
prefixed by @code{sha-1} instead of @code{md5}. @xref{crypto md5}.

SHA-1 also has a maximum message size of @math{2^{64}-1} bits, but
the message digests are 160 bits instead of MD5's 128.
@cindex SHA-1

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@item
@code{(1 1)} -- Added @code{sha-1-length}, @code{sha-1-96-copy-hash!},
@code{sha-1-hash=?} and @code{sha-1-96-hash=?}.
@end itemize

@c ======================================================================
@node crypto sha-2
@subsection Secure Hash Algorithm 2
The interface provided by @code{(weinholt crypto sha-2)} is identical
to the one provided by the MD5 library, but instead of @code{md5},
every procedure is prefixed by @code{sha-224}, @code{sha-256},
@code{sha-384} or @code{sha-512}. In addition the procedures that
operate on the leftmost 96 bits are instead defined for the leftmost
128 bits (e.g.@: @code{sha-512-128-hash=?}). @xref{crypto md5}.

SHA-224 and SHA-256 have a maximum message size of @math{2^{64}-1}
bits. For SHA-384 and SHA-512 the maximum is @math{2^{128}-1} bits.
The message digests produced by SHA-224 are 224 bits, and so on.
@cindex SHA-224
@cindex SHA-256
@cindex SHA-384
@cindex SHA-512

@noindent
Version history:
@itemize
@item
@code{(0 0)} -- Initial version.
@item
@code{(1 1)} -- Added @code{sha-224-length}, @code{sha-256-length},
@code{sha-384-length}, @code{sha-512-length} that return the length of
a digest in bytes. Added the comparison predicates
@code{sha-224-hash=?}, @code{sha-256-hash=?}, @code{sha-384-hash=?}
@code{sha-512-hash=?} that run in constant time. Added procedures for
truncated digests: @code{sha-224-128-hash=?},
@code{sha-256-128-hash=?}, @code{sha-384-128-hash=?}
@code{sha-512-128-hash=?}, @code{sha-224-128-copy-hash!},
@code{sha-256-128-copy-hash!}, @code{sha-384-128-copy-hash!} and
@code{sha-512-128-copy-hash!}. Now uses the correct definition of
HMAC-SHA-384 and HMAC-SHA-512. The HMACs now also handle key lengths
larger than the block size.
@end itemize

@c ======================================================================
@node crypto ssh-public-key
@subsection SSH public key format conversion
Use @code{(weinholt crypto ssh-public-key)} to convert public RSA,
DSA, and ECDSA keys from records to the binary SSH public key format,
and the other way around. SSH is the name of a network protocol for
secure terminal connections defined by RFCs 4250-4254. The key format
is specified by RFC 4716. ECDSA keys are specified by RFC 5656.

The types used for RSA, DSA and ECDSA keys in this library are the
same types used elsewhere. The ECDSA keys must have the record type
@code{ecdsa-sha-2-public-key}.

Future work would be to implement parsing of the various textual
formats that contain Base64 public SSH keys.

@deffn Procedure get-ssh-public-key p
Reads a public RSA/DSA/ECDSA key encoded in the SSH public key format
from the binary input port @var{p}.
@end deffn

@deffn Procedure ssh-public-key->bytevector key
Converts the public RSA/DSA/ECDSA @var{key} to the SSH public key
format.
@end deffn

@deffn Procedure ssh-public-key-algorithm key
Returns the SSH algorithm identifier of @var{key}. For RSA keys this
is @code{"ssh-rsa"}, for DSA keys it is @code{"ssh-dss"}, and for
ECDSA keys it is @code{"ecdsa-sha2-[identifier]"} where
@code{[identifier]} identifies the curve.
@end deffn

@deffn Procedure ssh-public-key-fingerprint key
The MD5 based fingerprint of the RSA/DSA/ECDSA @var{key} in the same
format used by common SSH software and specified by RFC 4716.
@end deffn

@deffn Procedure ssh-public-key-random-art key
The random art of the RSA/DSA/ECDSA key. This is a visual
representation of the key can is easier for humans to distinguish than
fingerprints. This is the same art that OpenSSH's VisualHostKey
feature displays.
@cindex VisualHostKey
@end deffn

@noindent
Version history:
@itemize
@item
@code{(1 0)} -- Initial version.
@item
@code{(1 1)} -- Added @code{ssh-public-key-algorithm}. Added support
for ecdsa-sha2-* keys using the elliptic curves nistp256, nistp384,
and nistp521.
@end itemize

@c ======================================================================
@node crypto x509
@subsection X.509 Public-Key Infrastructure
The @code{(weinholt crypto x509)} library implements parts of ITU-T's
X.509 standard for public-key infrastructure.

An X.509 certificate is a data structure that contains a public RSA or
DSA key and some identifying information. There is a @emph{subject}
and an @emph{issuer} (and lots of details). The subject specifies who
the certificate belongs to, and the issuer specifies who signed it.
Certificate path validation is used to get from a trusted issuer to
the subject, often via several intermediates.
@cindex X.509 certificate

X.509 certificates are used in many places, e.g.@: TLS, S/MIME email
and IPsec.

@deffn Procedure certificate? obj
True if @var{obj} is an X.509 certificate.
@end deffn

@deffn Procedure certificate-from-bytevector bv [start end]
Reads an X.509 certificate from the bytevector @var{bv}. The
certificate is in the ASN.1 DER format customarily used for X.509
certificates. For certificates in PEM format, first read them with
@code{get-delimited-base64}. @xref{text base64}.
@end deffn

@deffn Procedure certificate-public-key certificate
Returns the public key contained in the @var{certificate}. The return
value's type is either an RSA or a DSA public key. @xref{crypto dsa}.
@xref{crypto rsa}.
@end deffn

@deffn Procedure validate-certificate-path path [common-name time CA-cert]
Returns @code{ok} if the certificates in the @var{path} list form a
valid certificate path. A valid certificate path begins with a trusted
CA certificate and ends with an end entity's certificate. Each
certificate in the chain signs the next certificate. This is intended
to form a chain of trust from a certificate you already trust (the CA
certificate) to a new certificate, the end entity's certificate.

Optionally a @var{common-name} string can be given. This is normally a
good idea. If you've tried to connect to a service at the domain name
example.com, you might like to know that the certificate it presents
actually belongs to example.com. Both the common name and
subjectAltName fields of the certificate are checked. Currently only
tested with domain names.

An SRFI-19 @var{time} can also optionally be given, in which case it
is used instead of the system's current time.

If the optional @var{CA-cert} argument is given it is a trusted
certificate that will be used to validate the start of the path. If
this argument is given then no other trusted certificates will be
tried.
@end deffn

@deffn Parameter CA-path
@end deffn
@deffn Parameter CA-file
@end deffn
@deffn Parameter CA-procedure
These SRFI-39 parameters can be used to provide the
@code{validate-certificate-path} procedure with trusted Certificate
Authority (CA) certificates, also known as root certificates. It is
beyond the scope of this library collection to provide you with
trusted certificates. Many operating systems have such collections,
e.g.@: Debian's ca-certificates package. Technically, a CA certificate
is a self-issued certificate with correctly set ``basic constraints''
and ``key usage'' attributes.
@cindex CA certificate
@cindex trusted certificate

The @code{CA-path} parameter should be the name (ending in the path
separator character, if any) of a directory containing files named by
OpenSSL's c_rehash program. The files contain PEM encoded CA
certificates. The filenames are partially a hash which also can be
retrieved from the @code{name-hash} value in the issuer/subject
alists. Default: @code{"/etc/ssl/certs/"}.

The @code{CA-file} parameter is not yet implemented. In the future
this will be the name of a file which contains trusted certificates.
Default: @code{"/etc/ssl/certs/ca-certificates.crt"}.

The @code{CA-procedure} parameter is a procedure which takes a single
argument: an issuer alist. If you have the requested certificate,
return it. Otherwise return @code{#f}. For forward compatibility the
procedure should accept any number of arguments.
Default: @code{(lambda (issuer . _) #f)}
@end deffn

The following part of the library is for more advanced uses.

@deffn Procedure certificate-key-usage certificate
Returns the keyUsage extension data from @var{certificate}. If the
extension is absent then the return value is @code{#f}. Otherwise it
is a list in which the possible entries are: @code{digitalSignature},
@code{nonRepudiation}, @code{keyEncipherment},
@code{dataEncipherment}, @code{keyAgreement}, @code{keyCertSign},
@code{cRLSign}, @code{encipherOnly}, and @code{decipherOnly}. See
RFC@: 5280 for an explanation of their meaning. If you are
implementing a protocol where keyUsage is important, the specification
will probably mention it.
@end deffn

@deffn Procedure certificate-tbs-data certificate
Returns the To Be Signed (TBS) part of @var{certificate} as a DER
encoded bytevector. Except for the certificate's signature, the whole
certificate is contained in the TBS data.
@end deffn

@deffn Procedure decipher-certificate-signature subject-cert issuer-cert
Uses the public key of @var{issuer-cert} to decipher the signature on
@var{subject-cert}.
@end deffn

@noindent
Version history:
@itemize
@item
@code{(0 0)} -- Initial version.
@end itemize
