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 @@
-
-
-
-Two-party ECDSA signature generation
-
-
-
-
-
-Two-party ECDSA signature generation
-Initialization
-
-
Alice starts out with her share of the private key d1
-
-
-
-
-
And a Paillier keypair pk/sk
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Bob starts out with his share d2 of the private key d
-
-
-
-
-
-Protocol
-
-
First Alice generates her share of the one-time secret k1
-
-
-
-
-
And its inverse z1 = (k1)-1 mod n
-
-
-
-
-
She also calculates Q1 = k1G
-
-
-
-
-
She then encrypts z1 using Paillier to create α = Epk(z1)
-
-
-
-
-
And β = Epk(d1z1 mod n)
-
-
-
-
-
And also generates an encrypted blinding factor A = Epk(c) for some c ∈ [1, nP/nEC]
-
-
-
-
-
Alice composes the encrypted signature σ1 = (α ×pk e) +pk (β ×pk r) +pk (A ×pk n)
-
-
-
-
-
She deterministically rerandomizes it to receive σ1' = σ1HASH(σ1)n mod n2
-
-
-
-
-
And decrypts σ1' to receive s1
-
-
-
-
-
And v', the randomizing factor in σ1'
-
-
-
-
-
-
-Q
1, α, β, message, e, pk, A, s
1, v'
-
-
-
Bob validates Q1 by ensuring that
-
- - Q1 ≠ O
- - xQ1 and yQ1 are in the interval [1,n - 1]
- - yQ12 ≡ xQ13 + axQ1 + b (mod p)
- - nQ1 = O
-
-
And verifies the message to be signed
-
He then verifies s1 as a valid signature
-
Bob also calculates σ1' from α, β and A
-
-
-
-
-
And verifies it matches Epk(s1, v')
-
He then generates his share k2 of the private one-time value k
-
-
-
-
-
And its inverse z2 = (k2)-1 mod n
-
-
-
-
-
He can calculate r = xQ where Q(xQ, yQ) = k2Q1
-
-
-
-
-
And Q2 = k2G
-
-
-
-
-
Bob prepares a random value B ∈ [1, nP/nEC] to use for blinding
-
-
-
-
-
Finally he calculates σ = (α ×pk z2e) +pk (β ×pk z2d2r) +pk Epk(BnEC)
-
-
-
-
-
-
-
-
Alice confirms Q2 is a valid public point
-
- - Q2 ≠ O
- - xQ2 and yQ2 are in the interval [1,n - 1]
- - yQ22 ≡ xQ23 + axQ2 + b (mod p)
- - nQ2 = O
-
-
She now calculates r = xQ where Q = k1Q2 and matches it against what Bob claimed
-
She decrypts σ to receive s = Dsk(σ)
-
-
-
-
-
She verifies the signature using r and the combined public key before publishing.
-
-
-
-
-
-
-
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.\s*\(/gm, '{anonymous}()@')
- .split('\n');
- log(e+'\n'+stack);
- }
-};