Skip to content
Bren2010 edited this page Nov 16, 2014 · 11 revisions

(This page is written at a slightly higher level than the rest of the wiki.)

Underlying SJCL's ECC module are fully functional big number and elliptic curve arithmetic libraries which can implement tons of other cryptosystems from textbook RSA to elliptic curve ElGamal encryption. This page is intended to be an introduction to using the libraries and an overview of what they're capable of.

Big Numbers

The big number library in SJCL is fairly intuitive if you've ever worked with big numbers in other languages: they have to be initialized with either a javascript Number, a hexadecimal string, or another sjcl.bn object. Alternatively, you can call .toString() on a sjcl.bn object and get the number in hexadecimal.

var a = new sjcl.bn(100)
var b = new sjcl.bn("0x64")

a.toString() // 0x64

They can also work a bit like codecs in that you can call .toBits() on a sjcl.bn object and get a bit array which is compatible with the sjcl.bn.fromBits function. (The .toString() method isn't compatible with sjcl.bn.fromBits, even through the hex codec.)

Along with a few notes, the rest of the library is fairly easy to figure out from the technical documentation.

  1. All methods return their output. Methods that end with an M don't copy this to a separate variable, so it will change to the value that's returned. The same function without the M ensures that this remains the same after it's called.
  2. 'Normalizing' means propagating carries. You only need to call the .normalize() or .cnormalize() after doing a batch of addition or subtraction.

And as another little sanity test, here's part of a toy CRT implementation:

// Define parameters.
var p = new sjcl.bn(6307),
    q = new sjcl.bn(7919),
    N = p.mul(q)

var e = new sjcl.bn(3)

// Chinese Remainder Theorem
// Calculate d, the inverse of e mod N=pq
// by combining inverses mod p and mod q
var a = e.inverseMod(p),
    b = e.inverseMod(q)

var r = a.sub(b).normalize().mul(q.inverseMod(p)),
    d = b.add(q.mul(r)).normalize().mod(N)

console.log("Calculated d:", d.toString())

// Verify
var one  = new sjcl.bn(1),
    test = e.mulmod(d, N)

console.log("Inverses? ", test.equals(one))
// Output:
//   Calculated d: 0xfe08ba
//   Inverses?  true

Fields

The normal big number library operates in the ring of integers, so to abstract away from calling the mod method every other line, SJCL implements specific fields which look similar to normal big numbers, but instead perform field operations.

In a field, there's no need to call mod (mulmod, powermod, or inverseMod) because, as mentioned, operations are already in the field. Fields implement a new method called .inverse() which returns the multiplicative inverse of the element. They also implement .reduce() and .fullReduce()--both simply marshal the stored value back into the field in case addition or subtraction has pushed it out. The former is approximate but fast, the latter is exact but expensive.

Currently, only fields for supported elliptic curves are implemented, in addition to p521 (for curve NIST P-521), p127 (unknown origin), and p25519 (for Curve25519). All of them have large prime characteristic.

var a = new sjcl.bn.prime.p256(2)
a.power(5000).toString()
// Value:  0x92b7b8427b64df31da69a98bbc8660dcf282d78b409492bac1c27ba5780830ca
// Running time:  Very fast

// As opposed to:
var b = new sjcl.bn(2)
b.power(5000).toString()
// Which will freeze Node.