Last year, I've written a portable cryptographic library
Springkussen. And then
I've also noticed that (crypto)
and (math)
libraries are not really
well designed. For example, a cipher object must support both encryption
and signing operations which can only be applied to RSA operations. So, I decided to
rewrite Sagittarius' cryptograpihc library and now I can show what it looks
like.
Library structure
The old (crypto)
and (math)
libraries are basically aggregated libraries.
This means it exports a lot of bindings even if you don't need them.
The new cryptographic libraries are per components, for example, if you only
need cipher operations, then you only need to import
(sagittarius crypto ciphers)
library. So, users need to combine the libraries
to achieve the target operation.
(math)
library is also integrated to (sagittarius crypto *)
. For
example, message digest operations are located in
(sagittarius crypto digests)
.
Most of the cryptographic operations are now provided by one of the
(sagittarius crypto *)
libraries. The existing libraries are replaced by
them and some of them are deprecated. For example, (rfc x.509)
library now
re-exports the (sagittarius crypto *)
procedures.
Example of block cipher operations
This is an example of how to use block cipher operations provided by
(sagittarius crypto ciphers)
library. Suppose, you want to encrypt
a message with a randomly generated key and export the key as plain text.
(Don't do this kind of operation in production, exporting a plain key is
not a good practice...)
The library doesn't provide key operations, such as generating a symmetric
key. So, you need to import (sagittarius crypto keys)
library as well.
To combine them, you can do it like this:
(import (rnrs)
(sagittarius crypto ciphers)
(sagittarius crypto keys))
;; Generate a random key suitable for AES-256
(define key (generate-symmetric-key *scheme:aes-256*))
;; Using ECB mode, with PKCS7 padding
;; Don't do it in production code :)
(define aes-cipher (make-block-cipher *scheme:aes-256* *mode:ecb* pkcs7-padding))
(define msg (string->utf8 "Hello new crypto library"))
;; No parameter needed
(block-cipher-init! aes-cipher (cipher-direction encrypt) key)
(block-cipher-encrypt-last-block aes-cipher msg)
;; -> bytevector length of 32 (2 blocks), the result is always different
;; Clean up
(block-cipher-done! aes-cipher)
;; A symmetric key is exportable, so you can export
(exportable->bytevector key)
;; -> bytevector length of 32
To see how the current development branch looks, you can also use the Docker image of edge
tag. If you put the above script into crypto.scm
file, then you can execute it with the below command:
docker run -it --mount src=$(pwd),target=/scripts,type=bind ktakashi/sagittarius:edge scripts/crypto.scm
Though the cache is not available, so loading a script may take a lot of time...