This library is deprecated, please consider to use Cryptographic libraries instead.
This documentation does not describe cryptography itself. For example, it does not describe what initial vector is and how long it must be. So users must know about cryptography's this library supports.
This library uses libtomcrypt
's functionalities. The library is public
domain. Thank you for the great library.
Note: the libtomcrypt
is a huge cryptographic library and I am not so
good with cryptographics, so the (crypto)
library is not totally tested.
Just the functionalities which I usually use are tested. If you find a bug or
wrong documentation, pleas report it.
This library is the top most library, it exports all the other libraries procedures. Users must import only this and not to use the others.
(crypto)
library supports both symmetric cryptography and public/private
key mechanism. For public/private key, it only supports RSA for now.
Returns #t if obj is crypto-object
.
crypto-object
can be either cipher
or key
.
Creates a cipher object.
type must be known cryptographic algorithm. Currently, (crypto)
library exports the algorithm below.
The symmetric key algorithms.
AES-128
, AES-192
and AES-256
are fixed key size AES algorithms.
AES
allows key size of 16, 24 or 32 bytes, however, fixed sized
version only accepts 16 for AES-128
, 24 for AES-192
and 32 for
AES-256
.
The public key algorithm
key must be a key object which will be created by key generate procedures described below.
mode specifies the symmetric cipher's encryption and description mode. If the cipher type is public key cipher, it will be ignored. Some modes require initial vector iv. The possible mods are below.
The keyword argument mode-parameter is specified, it must be a mode parameter object, then the object will be parsed properly by the cipher.
Returns given cipher type's recommended keysize.
cipher must cipher object created by cipher
procedure.
test must be fixnum.
If test is too small for the cipher, it will raise an error.
Note: this procedure is for helper. It is designed to use check keysize you want to use.
Returns #t if the obj is cipher object.
cipher must be a cipher object.
pt must be a bytevector.
encrypt
encrypts given plain text pt according to the given
cipher.
Similar with cipher-encrypt
. The difference is that this
procedure returns 2 values, encrypted pt and calculated tag if the
given cipher supports authentication.
If the keyword argument tag-size is specified and must be an integer,
then the returning tag has the specified size. If the cipher supports
less size than the specified size, then the remaining tag contains unspecified
value. To retrieve the maximum length of tag, use cipher-max-tag-size
.
cipher must be a cipher object.
ct must be a bytevector.
decrypt
decrypts given encrypted text ct according to the given
cipher.
Similar with cipher-decrypt
. The difference is that this
procedure returns 2 values, decrypted ct and calculated tag if the
given cipher supports authentication.
If the keyword argument tag-size is specified and must be an integer,
then the returning tag has the specified size. If the cipher supports
less size than the specified size, then the remaining tag contains unspecified
value. To retrieve the maximum length of tag, use cipher-max-tag-size
.
Similar with cipher-decrypt
. The difference is that this
procedure validates the calculated tag. If the given tag and
calculated tag are not the same, then &decrypt
is raised.
NOTE: if the tag is *not* calculated by the cipher, then this procedure always raises an error.
Returns the maximum length of tag size.
If the given cipher does not support authentication tag, then
returning value is 0
.
Updates the additional authentication data.
dst must be a bytevector.
Retrieves the authentication tag from given cipher.
NOTE: this procedure must be called after either cipher-encrypt
or
cipher-decrypt
. Otherwise the filled value is unspecified.
Retrieves the authentication tag from given cipher.
If the keyword argument size is specified, then the returning bytevector has the size length, otherwise maximum tag length.
NOTE: this procedure must be called after either cipher-encrypt
or
cipher-decrypt
. Otherwise the filled value is unspecified.
public-cipher must be a cipher object created with public/private key algorithm.
data must be a bytevector.
Signs given data. This procedure is just a wrapper for the real implementations. Currently Sagittarius supports only RSA sign.
opt can specify the signer behaviour. Default supported RSA cipher can accept keyword argument encode.
encode specifies the encoder. The default encoder is
pkcs1-emsa-pss-encode
. And the rest keyword arguments will be passed to
the encoder. Supported encoders are described below.
The following shows how to implement SHA256WithRSA
signature
;; Importing a RSA private key.
(define private-key (import-private-key RSA #vu8(...)))
(define signer (make-cipher RSA private-key))
(cipher-signature signer #vu8() :encode pkcs1-emsa-v1.5-encode :hash SHA-256)
public-cipher must be a cipher object created with public/private key algorithm.
M and S must be bytevectors.
M is master message which will be compared with encoded message.
S is signed message.
The verity
procedure verifies two messages.
opt can specify the verifier behaviour. Default supported RSA cipher can accept keyword argument verify.
verify specifies the verifier. The defaule verifier is
pkcs1-emsa-pss-verify
. And the rest keyword arguments will be passed to
verifier. Supported verifiers are described below.
Mode parameters are pareters which can be used by specified mode. For example,
iv-parameter
is a parameter contains an IV.
Returns #t if the given obj is a mode parameter, otherwise #f.
Creates a composite mode parameter.
A composite parameter can hold multiple parameters.
Record type for initial vector (IV) parameter.
iv must be a bytevector or #f.
Creates an IV mode parameter.
IV is required by some modes. e.g. MODE_CBC
.
Record type for counter mode parameter.
This parameter is a subclass of <iv-parameter>
.
Creates a counter mode parameter. This is used by MODE_CTR
.
iv is passed to parent constructor.
The followings are description of keyword parameters.
rounds specify how many times the cipher rounds the key.
ctr-mode specifies counter mode. The possible mode is blow.
Record type for AES-CTR mode parameter defined in RFC 3686.
This parameter is a subclass of <ctr-parameter>
.
Creates RFC3686 mode parameter.
Record type for padding parameter.
Creates a padding mode parameter.
padder must be an procedure such as pkcs5-padder
.
type must be one of the supported symmetric algorithm.
key must be a bytevector and its length must satisfy the keysize which the given algorithm requires.
Returns a sercret key object.
type is for despatch. For default implementation, it must be
RSA
.
Generates a key pair object.
Default implementation supports RSA key geneartion and options can be keyword arguments described below.
size keyword argument is decides key length. Default value is 1024.
prng keyword argument is given, it will be passed to random-prime
.
For more detail, see (math random) library. Default
value is (secure-random RC4)
.
e keyword argument is an exponent. Usually it does not have to be specified with other number. Default value is 65537.
type is for despatch. For default implementation, it must be
RSA
.
Returns private key object.
Default RSA implementation options can be these arguments.
The private key's modulus
The private key's exponent
keyword argument. Used for CRT private key object.
keyword argument. Used for CRT private key object.
keyword argument. Used for CRT private key object.
type is for despatch. For default implementation, it must be
RSA
.
Returns public key object.
Default RSA implementation opt can be these arguments.
The public key's modulus
The public key's exponent
Returns #t if given obj is keypair object, otherwise #f
Returns private key from keypair
Returns public key from keypair
Returns #t if given obj is key object, otherwise #f
CLOS class of private key object.
CLOS class of public key object.
Returns #t if given obj is private key object, otherwise #f
Returns #t if given obj is public key object, otherwise #f
key must be a bytevector and plain key.
Splits the given key to count components and returns _count_values as key components.
The return values might be different each time.
Renaming export of bytevector-xor
and bytevector-xor!
respectively.
For more detail, see (util bytevector).
The procedures described in this section is implemented according to PKCS#1. I don't have any intend to describe functionality. If you need to know what exactly these procedures do, please see the PKCS#1 document.
bv must be a bytevector.
block-size must be a non negative exact integer.
padding? must be a boolean.
Pads or Unpads paddings from bv according to PKCS#5.
If padding? is #t, the procedure will pad. otherwise it will unpad.
prng must be prng object. See (math random).
key must be either private or public key object.
block-type must be one of these.
Returns a padding procedure. The procedure signature is the same as pkcs5-padder.
_ :key (hash (hash-algorithm SHA-1)
) (mgf mgf-1) (salt-length #f) _
_ (prng (secure-random RC4)
)
m must be a bytevector.
em-bits must be non negative exact integer.
Encodes given message m according to the PKCS#1 section 9.1.1.
The keyword arguments specified some behaviour.
hash specifies the hash algorithm. For more detail, see (math hash) library.
mgf specifies mask generation procedure.
Note: PKCS#1 only specifies MGF-1.
salt-length specifies salt's length. If it's #f encoder does not use salt.
prng is a pseudo random see (math random).
_ :key (hash (hash-algorithm SHA-1)
) (mgf mgf-1) _
_ (prng (secure-random RC4)
)
m must be a bytevector.
em-bits must be non negative exact integer.
Verify given message m according to the PKCS#1 section 9.1.1.
Other keyword arguments are the same as pkcs1-emsa-pss-encode
.
mgf-seed must be a bytevector.
mask-length must be a non negative exact integer.
hasher must be a hash algorithm. See (math random).
Creates a mask bytevector, according to PKCS#1 MGF-1.
m must be a bytevector.
em-bits must be non negative exact integer.
Encodes given message m according to the PKCS#1 section 9.2.
Other keyword arguments are the same as pkcs1-emsa-pss-encode
.
m must be a bytevector.
em-bits must be non negative exact integer.
Verify given message m according to the PKCS#1 section 9.2.
Other keyword arguments are the same as pkcs1-emsa-pss-encode
.
Returns AES key wrapping procedure which accepts one argument of bytevector to be wrapped.
The returning procedure wraps the given bytevector with AES Key Wrap algorithm specified by NIST or RFC 3394.
The keyword argument iv specifies initial value (IV) for data integrity.
The default value is #vu8(#xa6 #xa6 #xa6 #xa6 #xa6 #xa6 #xa6 #xa6)
specified by the specification.
Returns AES key unwrapping procedure which accepts one argument of bytevector to be unwrapped.
The returning procedure wraps the given bytevector with AES Key Wrap algorithm specified by NIST or RFC 3394.
The keyword argument iv specifies initial value (IV) for data integrity.
The default value is #vu8(#xa6 #xa6 #xa6 #xa6 #xa6 #xa6 #xa6 #xa6)
specified by the specification.
Subcondition of &error
.
Base condition type of all cryptographic conditions.
This condition will be raised when encrypt operation is failed.
This condition will be raised when decrypt operation is failed.
This condition will be raised when encoding operation is failed.
This condition will be raised when decoding operation is failed.
who, message and irritants are the same as
assertion-violation
.
mechanism should be a name of cryptographic algorithm.
Raises &encrypt-error
.
who, message and irritants are the same as
assertion-violation
.
mechanism should be a name of cryptographic algorithm.
Raises &decrypt-error
.
who, message and irritants are the same as
assertion-violation
.
Raises &encode-error
.
who, message and irritants are the same as
assertion-violation
.
Raises &decode-error
.
Subcondition of &crypto-error
This condition will be raised when key unwrap failed due to the
integrity check error.
If Sagittarius does not support sufficient cipher algorithm for you, then you can write own cipher such as DSA. For this purpose, you might need to know how this library works. It will be described the bottom of this section. If you just want to create a new cipher, you just need to follow the example.
(import (rnrs) (crypto) (clos user) (sagittarius))
(define (sample-encrypt pt key) pt)
(define (sample-decrypt ct key) ct)
(define-class <sample-cipher-spi> (<cipher-spi>) ())
(define-method initialize ((o <sample-cipher-spi>) initargs)
(slot-set! o 'name 'sample)
(slot-set! o 'key #f)
(slot-set! o 'encrypt sample-encrypt)
(slot-set! o 'decrypt sample-decrypt)
(slot-set! o 'padder #f)
(slot-set! o 'signer (lambda _ #vu8()))
(slot-set! o 'verifier (lambda _ #t))
(slot-set! o 'keysize (lambda _ 0)))
(define sample :sample)
(register-spi sample <sample-cipher-spi>)
;; test sample-cipher
(define sample-cipher (cipher sample #f))
(define message (string->utf8 "sample message"))
(let ((encrypted-message (encrypt sample-cipher message)))
(decrypt sample-cipher encrypted-message))
;; -> #vu8(115 97 109 112 108 101 32 109 101 115 115 97 103 101)
The sample code actually does nothing. If you want to see real working code,
ext/crypto/crypto/key/rsa.scm
might be a good example for you.
The basic idea of creating a new cipher is that you need to define own subclass
of <cipher-spi>
and register it.
The base class for all SPI (Service Provider Interface).
Subclass must set these slots.
The value must be a procedure which takes 2 arguments.
The value must be a procedure which takes 2 arguments.
NOTE: Default symmetric key ciphers use pkcs5-padder
which takes 3
arguments, bytevector, block-size and padding flag. This is because the
procedure can be used by multi ciphers. And custom cipher must know its own
block size.
These slots are optional.
Describe the cipher.
The value will be passed to encrypt
, decrypt
,
sign
and verify
to be used.
A procedure for signing. The given procedure must accept at least 2 arguments.
A procedure for verifying. The given procedure must accept at least 3 arguments.
A procedure to get recommended keysize of this cipher. The given procedure must accept 1 argument.
The value must be #f or a procedure which takes 2 arguments.
The value must be #f or a procedure which takes 1
arguments. This is called when cipher-update-aad!
is called.
The value must be #f or a procedure which takes 1
arguments. This is called when cipher-tag!
is called.
The value must be an integer. This represents the maximum length of authentication tag.
NOTE: Even required slots, Sagittarius does not check if it's set or not.
During its initialisation, the initargs (the second argument of
the initialize
method) takes at least 3 arguments, key,
:mode-parameter
keyword and parameter passed to
make-cipher
. The rest of other arguments are also passed if exist.
Returns #t if the given object o is a cipher SPI. Otherwise #f.
Register custom cipher SPI.
mark can be any thing which returns #t then compared by equal?
spi must be subclass of <cipher-spi>
NOTE: We recommend to make mark the same as example code does and export
the registered mark. And the mark must be unique enough not to
overwrite existing SPI names.
e.g. :rsa
, :dsa
and :ecdsa
are already used for
RSA, DSA and ECDSA
The concept of this SPI is influenced by Java's JCE. The toplevel of cipher is
just a wrapper for real implementaion (SPI). When a cipher is created, the
cipher
procedure actually creates an instance of SPI class and set it to
the cipher object. So users need not to know about the implementation and if the
implementation supply default parameter then users even can use it by default.
This is the class hierarchy of these crypto objects.
+ <top>
+ <crypto>
+ <cipher>
+ <cipher-spi>
+ <builtin-cipher-spi> <- default implementations of symmetric keys.
+ <rsa-cipher-spi> <- default RSA implementation
+ <key>
+ <symmetric-key>
+ <builtin-symmetric-key> <- default symmetric key. ex. DES
+ <asymmetric-key>
+ <private-key>
+ <rsa-private-key>
+ <rsa-private-crt-key>
+ <public-key>
+ <rsa-public-key>
The <cipher>
and builtin-
prefixed classes can not have any
subclass.
The following procedures are kept for backward compatibility.
cipher
- Use make-cipher
instead.
encrypt
- Use cipher-encrypt
instead.
decrypt
- Use cipher-decrypt
instead.
sign
- Use cipher-signature
instead.
verity
- Use cipher-verify
instead.
register-spi
- Use register-cipher-spi
instead.