module RSA: sig
.. end
The RSA
module implements RSA public-key cryptography.
Public-key cryptography is asymmetric: two distinct keys are used
for encrypting a message, then decrypting it. Moreover, while one of
the keys must remain secret, the other can be made public, since
it is computationally very hard to reconstruct the private key
from the public key. This feature supports both public-key
encryption (anyone can encode with the public key, but only the
owner of the private key can decrypt) and digital signature
(only the owner of the private key can sign, but anyone can check
the signature with the public key).
type
key = {
|
size : int ; |
|
n : string ; |
|
e : string ; |
|
d : string ; |
|
p : string ; |
|
q : string ; |
|
dp : string ; |
|
dq : string ; |
|
qinv : string ; |
}
The type of RSA keys. Components size
, n
and e
define
the public part of the key. Components size
, n
and d
define the private part of the key. To speed up private key operations
through the use of the Chinese remainder theorem (CRT), additional
components p
, q
, dp
, dq
and qinv
are provided. These
are part of the private key.
val wipe_key : key -> unit
Erase all components of a RSA key.
val new_key : ?rng:Cryptokit.Random.rng -> ?e:int -> int -> key
Generate a new, random RSA key. The non-optional
int
argument is the desired size for the modulus, in bits
(e.g. 1024). The optional
rng
argument specifies a random
number generator to use for generating the key; it defaults to
Cryptokit.Random.secure_rng
. The optional
e
argument
specifies the public exponent desired. If not specified,
e
is chosen randomly. Small values of
e
such as
e = 3
or
e = 65537
significantly speeds up encryption and
signature checking compared with a random
e
.
The result of
new_key
is a complete RSA key with all
components defined: public, private, and private for use with
the CRT.
val encrypt : key -> string -> string
encrypt k msg
encrypts the string msg
with the public part
of key k
(components n
and e
).
msg
must be smaller than key.n
when both strings
are viewed as natural numbers in big-endian notation.
In practice, msg
should be of length key.size / 8 - 1
,
using padding if necessary. If you need to encrypt longer plaintexts
using RSA, encrypt them with a symmetric cipher, using a
randomly-generated key, and encrypt only that key with RSA.
val decrypt : key -> string -> string
decrypt k msg
decrypts the ciphertext string
msg
with the
private part of key
k
(components
n
and
d
). The size of
msg
is limited as described for
Cryptokit.RSA.encrypt
.
val decrypt_CRT : key -> string -> string
decrypt_CRT k msg
decrypts the ciphertext string
msg
with
the CRT private part of key
k
(components
n
,
p
,
q
,
dp
,
dq
and
qinv
). The use of the Chinese remainder
theorem (CRT) allows significantly faster decryption than
Cryptokit.RSA.decrypt
, at no loss in security. The size of
msg
is limited as described for
Cryptokit.RSA.encrypt
.
val sign : key -> string -> string
sign k msg
encrypts the plaintext string
msg
with the
private part of key
k
(components
n
and
d
), thus
performing a digital signature on
msg
.
The size of
msg
is limited as described for
Cryptokit.RSA.encrypt
.
If you need to sign longer messages, compute a cryptographic
hash of the message and sign only the hash with RSA.
val sign_CRT : key -> string -> string
sign_CRT k msg
encrypts the plaintext string
msg
with the
CRT private part of key
k
(components
n
,
p
,
q
,
dp
,
dq
and
qinv
), thus performing a digital signature on
msg
. The use of the Chinese remainder theorem (CRT) allows
significantly faster signature than
Cryptokit.RSA.sign
, at
no loss in security. The size of
msg
is limited as
described for
Cryptokit.RSA.encrypt
.
val unwrap_signature : key -> string -> string
unwrap_signature k msg
decrypts the ciphertext string
msg
with the public part of key
k
(components
n
and
d
),
thus extracting the plaintext that was signed by the sender.
The size of
msg
is limited as described for
Cryptokit.RSA.encrypt
.