Short Introduction to SJCL

The Stanford Javascript Crypto Library, or simply SJCL, is probably the best option available right now for using cryptography on the client-side: the project started in 2009 as a paper describing how to implement a secure and fast crypto library for web browsers, including, for instance, a CSPRNG algorithm and symmetric encryption. Today, it also has public-key crypto, hashing, and ECC primitives. It’s very small (just 37kb uncompressed w/ ECC), the code is pretty clean, and it’s being maintained by various contributors on GitHub. One of the biggest problems right now is the auto-generated documentation, which isn’t super helpful, but that’s not a big deal since you can always read the sources.

Let’s start with a very simple example using the convenience functions to easily encrypt and decrypt data (using AES):

1
2
var msg = sjcl.encrypt("secret", "Hi Alice!");
console.log(sjcl.decrypt("secret", msg));

That was pretty simple. Let’s try something different, like hashing a string using SHA-256:

1
2
3
var hash = sjcl.hash.sha256.hash("hello world");
console.log("hash: "+sjcl.codec.hex.fromBits(hash));
// It should print: "hash: b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"

SJCL has many ADTs. In this case myhash is an array of 8 numbers (in js this is 64 bits floats) but it’s actually holding binary data (using just 32 bits for each number), so SJCL provides functions to convert, for example, from a binary array to a string in hexadecimal format.

For the next example, I would like to use some elliptic curve cryptography, but to do that we need to build SJCL first to enable this option:

1
2
3
4
$ git clone https://github.com/bitwiseshiftleft/sjcl.git sjcl
$ cd sjcl
$ ./configure --with-ecc
$ make

Now with our custom sjcl.js we can use the ECC primitives like DSA. So let’s sign the previous hash:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Generate a key pair and use it to sign the SHA-256 hash
var curve = sjcl.ecc.curves.k256;
var keys = sjcl.ecc.ecdsa.generateKeys(curve,6); // 6 is actually the default paranoia, so you can omit that
var signature = keys.sec.sign(hash);

// Extract the coordinates of the public point and create a public key object for testing
var pubkey_x = new curve.field(sjcl.bn.fromBits(keys.pub.get().x));
var pubkey_y = new curve.field(sjcl.bn.fromBits(keys.pub.get().y));
var point = new sjcl.ecc.point(curve, pubkey_x, pubkey_y);
var newpubkey = new sjcl.ecc.ecdsa.publicKey(curve, point);

// Print the signature and verify it
console.log("sign: "+sjcl.codec.base64.fromBits(signature));
console.log("verified: "+newpubkey.verify(hash, signature));

Obviously we didn’t need to create a new public key object to verify the signature, but I wanted to show how to obtain the public point. Finally, here is how we can serialize the public key (a point in the curve) and the private key (the exponent):

1
2
3
4
5
6
7
8
9
var pubkey_hex = sjcl.codec.hex.fromBits(keys.pub.get().x) + sjcl.codec.hex.fromBits(keys.pub.get().y);
var seckey_hex = sjcl.codec.hex.fromBits(keys.sec.get());

// Unserialize and create a public key object (SJCL will divide the binary array in two parts and get each coordinate)
var public_key = new sjcl.ecc.ecdsa.publicKey(curve, sjcl.codec.hex.toBits(pubkey_hex));

// Unserialize and create a private key object (we have to create a bignum object)
var secret_key_bn = new sjcl.bn(seckey_hex);
var secret_key = new sjcl.ecc.ecdsa.secretKey(curve, secret_key_bn);

There is a branch that already includes functions for serialization, so this method will be deprecated in the future.

Congratulations Adventurer

Your quest is at an end for you have reached the home of Peramides1.

This is a personal blog about things I’ve learnt, discovered, thought, or that I just need to write down somewhere because I always forget them. It’s a spiritual successor of my old WordPress blog. I needed something fresh so I built this using Jekyll/Octopress (I almost chose Hakyll but its documentation was scarce and outdated, and I’m not really proficient in Haskell yet) and I’m hosting it with GitHub Pages. By the way, the current theme is a fork of CleanPress I made called CleanerPress; actually I wanted a Professor Doctor Style, but probably most visitors would have considered that something awful.

Having said that… My posts are not peer-reviewed and could be pretty opinionated at times. Also, English is not my first language, so expect syntactic, grammatical, and spelling errors. Finally, there is no comments section (and there will never be). Complaints? Please use the contact form or write me an e-mail to bri at this domain.

So, I think that’s all. Welcome and enjoy your stay!


  1. Peramides is a partial anagram of Parmenides, which includes the lexeme pera (i.e. pear in Spanish).