diff --git a/demo/demo.css b/demo/demo.css
deleted file mode 100644
index 6912bee..0000000
--- a/demo/demo.css
+++ /dev/null
@@ -1,50 +0,0 @@
-p {
-    margin: 0.4em 0 0.2em;
-}
-
-input[type=text] {
-    width: 500px;
-}
-
-.alice, .bob {
-    margin: 1em;
-    width: 550px;
-    padding: 10px;
-}
-
-.alice {
-    border: 2px solid grey;
-    border-left-width: 20px;
-}
-
-.bob {
-    border: 2px solid grey;
-    border-right-width: 20px;
-}
-
-.messageleft, .messageright {
-    margin: 1em;
-    background-color: grey;
-    height: 30px;
-    text-align: center;
-    color: #fff;
-    line-height: 30px;
-    width: 590px;
-}
-
-.messageleft .arrow, .messageright .arrow {
-    border-top: 15px solid #fff;
-    border-bottom: 15px solid #fff;
-    width: 0;
-    height: 0;
-}
-
-.messageright .arrow {
-    float: right;
-    border-left: 15px solid grey;
-}
-
-.messageleft .arrow {
-    float: left;
-    border-right: 15px solid grey;
-}
diff --git a/demo/split-key.html b/demo/split-key.html
deleted file mode 100644
index 82175bd..0000000
--- a/demo/split-key.html
+++ /dev/null
@@ -1,194 +0,0 @@
-<!doctype html>
-<html>
-<head>
-<title>Two-party ECDSA signature generation</title>
-<link rel="stylesheet" type="text/css" href="demo.css"/>
-<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
-<script type="text/javascript">
-jQuery(function ($) {
-    var worker = new Worker("split-key.js");
-
-    worker.onmessage = function (event) {
-        var data = event.data;
-
-        switch (data.cmd) {
-        case "ff":
-            $("#"+data.field).val(data.value);
-            break;
-        case "log":
-            if (console && "function" === typeof console.log) {
-                console.log.apply(console, data.args);
-            }
-            break;
-        }
-    };
-    worker.onerror = function (error) {
-		    console.error(error);
-    };
-
-    worker.postMessage("start");
-});
-</script>
-</head>
-<body>
-<h1>Two-party ECDSA signature generation</h1>
-<p><strong>Initialization</strong></p>
-<div class="alice">
-  <p>Alice starts out with her share of the private key d<sub>1</sub></p>
-  <div>
-    <label for="d1">d<sub>1</sub>=</label>
-    <input id="d1" type="text" readonly="readonly"/>
-  </div>
-  <p>And a Paillier keypair pk/sk</p>
-  <div>
-    <label for="p1_n">n=</label>
-    <input id="p1_n" type="text" readonly="readonly"/>
-  </div>
-  <div>
-    <label for="p1_g">g=</label>
-    <input id="p1_g" type="text" readonly="readonly"/>
-  </div>
-  <div>
-    <label for="p1_l">&lambda;=</label>
-    <input id="p1_l" type="text" readonly="readonly"/>
-  </div>
-  <div>
-    <label for="p1_m">&mu;=</label>
-    <input id="p1_m" type="text" readonly="readonly"/>
-  </div>
-</div>
-<div class="bob">
-  <p>Bob starts out with his share d<sub>2</sub> of the private key d</p>
-  <div>
-    <label for="d2">d<sub>2</sub>=</label>
-    <input id="d2" type="text" readonly="readonly"/>
-  </div>
-</div>
-<p><strong>Protocol</strong></p>
-<div class="alice">
-  <p>First Alice generates her share of the one-time secret k<sub>1</sub></p>
-  <div>
-    <label for="k1">k<sub>1</sub>=</label>
-    <input id="k1" type="text" readonly="readonly"/>
-  </div>
-  <p>And its inverse z<sub>1</sub> = (k<sub>1</sub>)<sup>-1</sup> mod n</p>
-  <div>
-    <label for="z1">z<sub>1</sub>=</label>
-    <input id="z1" type="text" readonly="readonly"/>
-  </div>
-  <p>She also calculates Q<sub>1</sub> = k<sub>1</sub>G</p>
-  <div>
-    <label for="q1">Q<sub>1</sub>=</label>
-    <input id="q1" type="text" readonly="readonly"/>
-  </div>
-  <p>She then encrypts z<sub>1</sub> using Paillier to create &alpha; = E<sub>pk</sub>(z<sub>1</sub>)</p>
-  <div>
-    <label for="alpha">&alpha;=</label>
-    <input id="alpha" type="text" readonly="readonly"/>
-  </div>
-  <p>And &beta; = E<sub>pk</sub>(d<sub>1</sub>z<sub>1</sub> mod n)</p>
-  <div>
-    <label for="beta">&beta;=</label>
-    <input id="beta" type="text" readonly="readonly"/>
-  </div>
-  <p>And also generates an encrypted blinding factor A = E<sub>pk</sub>(c) for some c &in; [1, n<sub>P</sub>/n<sub>EC</sub>]</p>
-  <div>
-    <label for="A">A=</label>
-    <input id="A" type="text" readonly="readonly"/>
-  </div>
-  <p>Alice composes the encrypted signature &sigma;<sub>1</sub> = (&alpha; &times;<sub>pk</sub> e) +<sub>pk</sub> (&beta; &times;<sub>pk</sub> r) +<sub>pk</sub> (A &times;<sub>pk</sub> n)</p>
-  <div>
-    <label for="sigma_1">&sigma;<sub>1</sub>=</label>
-    <input id="sigma_1" type="text" readonly="readonly"/>
-  </div>
-  <p>She deterministically rerandomizes it to receive &sigma;<sub>1</sub>' = &sigma;<sub>1</sub>HASH(&sigma;<sub>1</sub>)<sup>n</sub> mod n<sup>2</sup></p>
-  <div>
-    <label for="sigma_1n">&sigma;<sub>1</sub>'=</label>
-    <input id="sigma_1n" type="text" readonly="readonly"/>
-  </div>
-  <p>And decrypts &sigma;<sub>1</sub>' to receive s<sub>1</sub></p>
-  <div>
-    <label for="s_1">s<sub>1</sub>=</label>
-    <input id="s_1" type="text" readonly="readonly"/>
-  </div>
-  <p>And v', the randomizing factor in &sigma;<sub>1</sub>'</p>
-  <div>
-    <label for="v_n">v<sub>'</sub>=</label>
-    <input id="v_n" type="text" readonly="readonly"/>
-  </div>
-</div>
-<div class="messageright"><div class="arrow"></div>
-Q<sub>1</sub>, &alpha;, &beta;, message, e, pk, A, s<sub>1</sub>, v'
-</div>
-<div class="bob">
-  <p>Bob validates Q<sub>1</sub> by ensuring that
-  <ol>
-    <li>Q<sub>1</sub> &ne; O</li>
-    <li>x<sub>Q<sub>1</sub></sub> and y<sub>Q<sub>1</sub></sub> are in the interval [1,n - 1]</li>
-    <li>y<sub>Q<sub>1</sub></sub><sup>2</sup> &equiv; x<sub>Q<sub>1</sub></sub><sup>3</sup> + ax<sub>Q<sub>1</sub></sub> + b (mod p)</li>
-    <li>nQ<sub>1</sub> = O</li>
-  </ol></p>
-  <p>And verifies the message to be signed</p>
-  <p>He then verifies s<sub>1</sub> as a valid signature</p>
-  <p>Bob also calculates &sigma;<sub>1</sub>' from &alpha;, &beta; and A</p>
-  <div>
-    <label for="sigma_1n_b">&sigma;<sub>1</sub>'=</label>
-    <input id="sigma_1n_b" type="text" readonly="readonly"/>
-  </div>
-  <p>And verifies it matches E<sub>pk</sub>(s<sub>1</sub>, v')</p>
-  <p>He then generates his share k<sub>2</sub> of the private one-time value k</p>
-  <div>
-    <label for="k2">k<sub>2</sub>=</label>
-    <input id="k2" type="text" readonly="readonly"/>
-  </div>
-  <p>And its inverse z<sub>2</sub> = (k<sub>2</sub>)<sup>-1</sup> mod n</p>
-  <div>
-    <label for="z2">z<sub>2</sub>=</label>
-    <input id="z2" type="text" readonly="readonly"/>
-  </div>
-  <p>He can calculate r = x<sub>Q</sub> where Q(x<sub>Q</sub>, y<sub>Q</sub>) = k<sub>2</sub>Q<sub>1</sub></p>
-  <div>
-    <label for="r">r=</label>
-    <input id="r" type="text" readonly="readonly"/>
-  </div>
-  <p>And Q<sub>2</sub> = k<sub>2</sub>G</p>
-  <div>
-    <label for="q2">Q<sub>2</sub>=</label>
-    <input id="q2" type="text" readonly="readonly"/>
-  </div>
-  <p>Bob prepares a random value B &in; [1, n<sub>P</sub>/n<sub>EC</sub>] to use for blinding<p>
-  <div>
-    <label for="B">B=</label>
-    <input id="B" type="text" readonly="readonly"/>
-  </div>
-  <p>Finally he calculates &sigma; = (&alpha; &times;<sub>pk</sub> z<sub>2</sub>e) +<sub>pk</sub> (&beta; &times;<sub>pk</sub> z<sub>2</sub>d<sub>2</sub>r) +<sub>pk</sub> E<sub>pk</sub>(Bn<sub>EC</sub>)</p>
-  <div>
-    <label for="sigma">&sigma;=</label>
-    <input id="sigma" type="text" readonly="readonly"/>
-  </div>
-</div>
-<div class="messageleft"><div class="arrow"></div>
-Q<sub>2</sub>, r, &sigma;
-</div>
-<div class="alice">
-  <p>Alice confirms Q<sub>2</sub> is a valid public point
-  <ol>
-    <li>Q<sub>2</sub> &ne; O</li>
-    <li>x<sub>Q<sub>2</sub></sub> and y<sub>Q<sub>2</sub></sub> are in the interval [1,n - 1]</li>
-    <li>y<sub>Q<sub>2</sub></sub><sup>2</sup> &equiv; x<sub>Q<sub>2</sub></sub><sup>3</sup> + ax<sub>Q<sub>2</sub></sub> + b (mod p)</li>
-    <li>nQ<sub>2</sub> = O</li>
-  </ol></p>
-  <p>She now calculates r = x<sub>Q</sub> where Q = k<sub>1</sub>Q<sub>2</sub> and matches it against what Bob claimed</p>
-  <p>She decrypts &sigma; to receive s = D<sub>sk</sub>(&sigma;)</p>
-  <div>
-    <label for="s">s=</label>
-    <input id="s" type="text" readonly="readonly"/>
-  </div>
-  <p>She verifies the signature using r and the combined public key before publishing.</p>
-  <div>
-    <label for="result"></label>
-    <input id="result" type="text" readonly="readonly"/>
-  </div>
-</div>
-</body>
-</html>
diff --git a/demo/split-key.js b/demo/split-key.js
deleted file mode 100644
index 0ded297..0000000
--- a/demo/split-key.js
+++ /dev/null
@@ -1,283 +0,0 @@
-var window = this;
-
-importScripts(
-  "../src/crypto-js/crypto.js",
-  "../src/crypto-js/sha256.js",
-  "../src/jsbn/prng4.js",
-  "../src/jsbn/rng.js",
-  "../src/jsbn/jsbn.js",
-  "../src/jsbn/jsbn2.js",
-
-  "../src/jsbn/ec.js",
-  "../src/jsbn/sec.js",
-  "../src/events/eventemitter.js",
-  "../src/bitcoin.js",
-  "../src/util.js",
-  "../src/base58.js",
-
-  "../src/address.js",
-  "../src/ecdsa.js",
-  "../src/paillier.js"
-);
-
-function hex(value) {
-  if ("function" === typeof value.getEncoded) {
-    return Crypto.util.bytesToHex(value.getEncoded());
-  } else if ("function" === typeof value.toByteArrayUnsigned) {
-    return Crypto.util.bytesToHex(value.toByteArrayUnsigned());
-  } else if (Array.isArray(value)) {
-    return Crypto.util.bytesToHex(value);
-  }
-  return value;
-};
-function ff(field, value) {
-  value = hex(value);
-  postMessage({ "cmd": "ff", "field": field, "value": value });
-};
-
-function log() {
-  postMessage({ "cmd": "log", "args": Array.prototype.slice.apply(arguments) });
-};
-
-function start() {
-  var ecparams = getSECCurveByName("secp256k1");
-  var rng = new SecureRandom();
-
-  var G = ecparams.getG();
-  var n = ecparams.getN();
-
-  G.validate();
-
-  var Alice = function (pubShare) {
-    this.d1 = Bitcoin.ECDSA.getBigRandom(n);
-    ff('d1', this.d1);
-
-    this.paillier = Bitcoin.Paillier.generate(n.bitLength()*2+
-                                              Math.floor(Math.random()*10));
-
-    ff('p1_n', this.paillier.pub.n);
-    ff('p1_g', this.paillier.pub.g);
-    ff('p1_l', this.paillier.l);
-    ff('p1_m', this.paillier.m);
-  };
-  var Bob = function () {
-    this.d2 = Bitcoin.ECDSA.getBigRandom(n);
-    ff('d2', this.d2);
-  };
-
-  Alice.prototype.getPub = function (P) {
-    if (this.pub) return this.pub;
-
-    P.validate();
-
-    return this.pub = P.multiply(this.d1).getEncoded();
-  };
-
-  Alice.prototype.getPubShare = function () {
-    return G.multiply(this.d1);
-  };
-
-  Bob.prototype.getPubShare = function () {
-    return G.multiply(this.d2);
-  };
-
-  Alice.prototype.step1 = function (message) {
-    var hash = Crypto.SHA256(Crypto.SHA256(message, {asBytes: true}), {asBytes: true});
-    this.e = BigInteger.fromByteArrayUnsigned(hash).mod(n);
-
-    this.k1 = Bitcoin.ECDSA.getBigRandom(n);
-    ff('k1', this.k1);
-
-    this.z1 = this.k1.modInverse(n);
-    ff('z1', this.z1);
-
-    var Q_1 = G.multiply(this.k1);
-    ff('q1', Q_1);
-
-    var alpha = this.paillier.encrypt(this.z1);
-    ff('alpha', alpha);
-
-    var beta = this.paillier.encrypt(this.d1.multiply(this.z1).mod(n));
-    ff('beta', beta);
-
-    var r_1 = Q_1.getX().toBigInteger().mod(n);
-    var A = this.paillier.encrypt(Bitcoin.ECDSA.getBigRandom(this.paillier.n.divide(n)));
-    ff('A', A);
-    var s_a = this.paillier.multiply(alpha, this.e);
-    var s_b = this.paillier.multiply(beta, r_1);
-    var sigma_1 = this.paillier.addCrypt(this.paillier.addCrypt(s_a, s_b), this.paillier.multiply(A, n));
-    ff('sigma_1', sigma_1);
-
-    var e = Crypto.SHA256(sigma_1.toByteArrayUnsigned(), {asBytes: true});
-    e = BigInteger.fromByteArrayUnsigned(e);
-    var sigma_1n = this.paillier.rerandomize(sigma_1, e);
-    ff('sigma_1n', sigma_1n);
-
-    var s_1 = this.paillier.decrypt(sigma_1n);
-    ff('s_1', s_1);
-    var v_n = this.paillier.decryptR(sigma_1n, s_1);
-    ff('v_n', v_n);
-
-    return {
-      Q_1: Q_1,
-      P_1: this.getPubShare(),
-      alpha: alpha,
-      beta: beta,
-      message: message,
-      paillier: this.paillier.pub,
-      A: A,
-      s_1: s_1,
-      v_n: v_n
-    };
-  };
-
-  Bob.prototype.step2 = function (pkg) {
-    // ... In real life we would check that message is a valid transaction and
-    //     does what we want.
-
-    // Throws exception on error
-    pkg.Q_1.validate();
-
-    var hash = Crypto.SHA256(Crypto.SHA256(message, {asBytes: true}), {asBytes: true});
-    this.e = BigInteger.fromByteArrayUnsigned(hash).mod(n);
-
-    this.paillier = pkg.paillier;
-    this.alpha = pkg.alpha;
-    this.beta = pkg.beta;
-
-    var r_1 = pkg.Q_1.getX().toBigInteger().mod(n);
-    var testSig = Bitcoin.ECDSA.serializeSig(r_1, pkg.s_1.mod(n));
-    if (!Bitcoin.ECDSA.verify(hash, testSig, pkg.P_1.getEncoded())) {
-      throw new Error('Verification of s1 failed.');
-    }
-
-    // Verify that alpha and beta are valid by generating and verifying sigma_1n
-    var s_a_1 = this.paillier.multiply(this.alpha, this.e);
-    var s_b_1 = this.paillier.multiply(this.beta, r_1);
-    var sigma_1 = this.paillier.addCrypt(this.paillier.addCrypt(s_a_1, s_b_1), this.paillier.multiply(pkg.A, n));
-
-    var e = Crypto.SHA256(sigma_1.toByteArrayUnsigned(), {asBytes: true});
-    e = BigInteger.fromByteArrayUnsigned(e);
-    var sigma_1n = this.paillier.rerandomize(sigma_1, e);
-    ff('sigma_1n_b', sigma_1n);
-
-    var sigma_1_verify = this.paillier.encrypt(pkg.s_1, pkg.v_n);
-    if (!sigma_1n.equals(sigma_1_verify)) {
-      throw new Error('Sigma ciphertext did not match expected value.');
-    }
-
-    this.k2 = Bitcoin.ECDSA.getBigRandom(n);
-    ff('k2', this.k2);
-
-    this.z2 = this.k2.modInverse(n);
-    ff('z2', this.z2);
-
-    var Q_2 = G.multiply(this.k2);
-    ff('q2', Q_2);
-
-    var Q = pkg.Q_1.multiply(this.k2);
-    this.r = Q.getX().toBigInteger().mod(n);
-    ff('r', this.r);
-
-    if (this.r.equals(BigInteger.ZERO)) {
-      throw new Error('r must not be zero.');
-    }
-
-    var B = Bitcoin.ECDSA.getBigRandom(this.paillier.n.divide(n));
-    ff('B', B);
-
-    var p = this.paillier;
-    var s_a = p.multiply(this.alpha, this.e.multiply(this.z2));
-    var s_b = p.multiply(this.beta, this.r.multiply(this.d2).multiply(this.z2));
-    var sigma = p.add(p.addCrypt(s_a, s_b), B.multiply(n));
-    ff('sigma', sigma);
-
-    return {
-      Q_2: Q_2,
-      r: this.r,
-      sigma: sigma
-    };
-  };
-
-  Alice.prototype.step3 = function (pkg) {
-    pkg.Q_2.validate();
-
-    var Q = pkg.Q_2.multiply(this.k1);
-    this.r = Q.getX().toBigInteger().mod(n);
-
-    if (!this.r.equals(pkg.r)) {
-      throw new Error('Could not confirm value for r.');
-    }
-
-    if (this.r.equals(BigInteger.ZERO)) {
-      throw new Error('r must not be zero.');
-    }
-
-    var s = this.paillier.decrypt(pkg.sigma).mod(n);
-    ff('s', s);
-
-    var sig = Bitcoin.ECDSA.serializeSig(this.r, s);
-
-    var hash = this.e.toByteArrayUnsigned();
-    if (!Bitcoin.ECDSA.verify(hash, sig, this.getPub())) {
-      throw new Error('Signature failed to verify.');
-    }
-
-    return {
-      r: this.r,
-      s: s
-    };
-  };
-
-  var message = "testmessage";
-
-  var bob = new Bob();
-  var pubShare = bob.getPubShare();
-
-  var alice = new Alice(pubShare);
-  var pub = alice.getPub(pubShare);
-
-  var pkg1 = alice.step1(message);
-  var pkg2 = bob.step2(pkg1);
-  var pkg3 = alice.step3(pkg2);
-
-  var sig = Bitcoin.ECDSA.serializeSig(pkg3.r, pkg3.s);
-
-  var kChk = alice.k1.multiply(bob.k2);
-  var rChk = G.multiply(kChk).getX().toBigInteger();
-  log("r    :", hex(pkg3.r));
-  log("r/CHK:", hex(rChk));
-
-  var hash = Crypto.SHA256(Crypto.SHA256(message, {asBytes: true}), {asBytes: true});
-  var eChk = BigInteger.fromByteArrayUnsigned(hash).mod(n);
-  var dChk = alice.d1.multiply(bob.d2);
-  var sChk = kChk.modInverse(n).multiply(eChk.add(dChk.multiply(rChk))).mod(n);
-  log("s    :", hex(pkg3.s));
-  log("s/CHK:", hex(sChk));
-
-  var sigChk = Bitcoin.ECDSA.serializeSig(rChk, sChk);
-  log("sig    :", hex(sig));
-  log("sig/CHK:", hex(sigChk));
-
-  var ver = Bitcoin.ECDSA.verify(hash, sig, pub);
-  log("ver    :", ver);
-  log("ver/CHK:", Bitcoin.ECDSA.verify(hash, sigChk, pub));
-  log("ver/CTL:", Bitcoin.ECDSA.verify(hash, Bitcoin.ECDSA.sign(hash, dChk), pub));
-  ff("result", ver ? "SIGNATURE VALID" : "SIGNATURE INVALID");
-
-  var priv = Bitcoin.ECDSA.getBigRandom(n);
-  pub = G.multiply(priv).getEncoded();
-  log("ver/GEN:", Bitcoin.ECDSA.verify(hash, Bitcoin.ECDSA.sign(hash, priv), pub));
-};
-
-self.onmessage = function (event) {
-  try {
-    start();
-  } catch(e) {
-    var stack = e.stack.replace(/^[^\(]+?[\n$]/gm, '')
-      .replace(/^\s+at\s+/gm, '')
-      .replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@')
-      .split('\n');
-    log(e+'\n'+stack);
-  }
-};