From f2ed0f50bb36ddf35174048d09bd0882bdcd78ff Mon Sep 17 00:00:00 2001 From: aunxx Date: Mon, 30 May 2016 12:15:13 +0100 Subject: [PATCH 01/20] change to python2 --- scripts/builder/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/builder/main.py b/scripts/builder/main.py index f1a4556..070e04a 100755 --- a/scripts/builder/main.py +++ b/scripts/builder/main.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # -*- coding: UTF-8 -*- import sys From 0c42ee2e76268490624f408095e4c5fff2b5f51f Mon Sep 17 00:00:00 2001 From: aunxx Date: Mon, 30 May 2016 12:15:43 +0100 Subject: [PATCH 02/20] Update changes --- backend/php/src/index.php | 34 ++++++++++--- frontend/beta/js/Clipperz/Crypto/SRP.js | 57 ++++++++++++++-------- frontend/delta/js/Clipperz/Crypto/SRP.js | 61 +++++++++++++++--------- frontend/gamma/js/Clipperz/Crypto/SRP.js | 57 ++++++++++++++-------- 4 files changed, 142 insertions(+), 67 deletions(-) diff --git a/backend/php/src/index.php b/backend/php/src/index.php index da7c60c..977591d 100644 --- a/backend/php/src/index.php +++ b/backend/php/src/index.php @@ -107,7 +107,8 @@ function digits($base) { //----------------------------------------------------------------------------- function clipperz_hash($value) { - return hash("sha256", hash("sha256", $value, true)); + //return hash("sha256", hash("sha256", $value, true)); + return hash("sha256", $value, false); } //----------------------------------------------------------------------------- @@ -251,6 +252,8 @@ error_log("registration"); error_log("handshake"); $srp_g = "2"; $srp_n = base2dec("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); + // Define k: k = H(N, g) in SRP-6a + $srp_k = base2dec(clipperz_hash($srp_n . $srp_g), 16); $message = $parameters["message"]; @@ -287,9 +290,12 @@ error_log("handshake"); $_SESSION["v"] = "112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00"; } - $_SESSION["b"] = clipperz_randomSeed(); +// This should now work with a random seed. Need to check. +// $_SESSION["b"] = clipperz_randomSeed(); // $_SESSION["b"] = "5761e6c84d22ea3c5649de01702d60f674ccfe79238540eb34c61cd020230c53"; - $_SESSION["B"] = dec2base(bcadd(base2dec($_SESSION["v"], 16), bcpowmod($srp_g, base2dec($_SESSION["b"], 16), $srp_n)), 16); + $_SESSION["b"] = "23309839184091712110293815740584558132927982490099443826709662564655631314481"; + + $_SESSION["B"] = dec2base(bcmod( bcadd( bcmod( bcmul( $srp_k, base2dec($_SESSION["v"], 16)), $srp_n), bcpowmod( $srp_g, $_SESSION["b"], $srp_n) ), $srp_n), 16); $result["s"] = $_SESSION["s"]; $result["B"] = $_SESSION["B"]; @@ -297,11 +303,13 @@ error_log("handshake"); //============================================================= } else if ($message == "credentialCheck") { error_log("credentialCheck"); - $u = clipperz_hash(base2dec($_SESSION["B"],16)); $A = base2dec($_SESSION["A"], 16); - $S = bcpowmod(bcmul($A, bcpowmod(base2dec($_SESSION["v"], 16), base2dec($u, 16), $srp_n)), base2dec($_SESSION["b"], 16), $srp_n); + // u = H(A, B) + $u = base2dec(clipperz_hash($A . base2dec($_SESSION["B"],16)), 16); + // S = (Av^u) ^ b + $S = bcpowmod( bcmul( $A, bcpowmod( base2dec($_SESSION["v"], 16), $u, $srp_n) ), $_SESSION["b"], $srp_n ); $K = clipperz_hash($S); - $M1 = clipperz_hash($A.base2dec($_SESSION["B"],16).$K); + $M1 = clipperz_hash("597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" . clipperz_hash($_SESSION['C']) . base2dec($_SESSION["s"],16) . base2dec($_SESSION['A'],16) . base2dec($_SESSION['B'],16) . base2dec($K,16)); //$result["B"] = $_SESSION["B"]; //$result["u"] = $u; @@ -310,6 +318,20 @@ error_log("credentialCheck"); //$result["K"] = $K; //$result["M1"] = $M1; //$result["_M1"] = $parameters["parameters"]["M1"]; + +// error_log("credentialCheck calculated: ". $M1); +// error_log("credentialCheck S: ". $S); +// error_log("credentialCheck A: ". $A); +// error_log("credentialCheck B: ". $_SESSION["B"]); +// error_log("credentialCheck base2dec: ". base2dec($_SESSION["B"],16)); +// error_log("credentialCheck K: ". base2dec($K,16)); +// error_log("credentialCheck n: ". $srp_n); +// error_log("credentialCheck u: ". $u); +// error_log("credentialCheck v: ". base2dec($_SESSION['v'],16)); +// error_log("credentialCheck expected: ". $parameters["parameters"]["M1"]); + + +//User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K) if ($M1 == $parameters["parameters"]["M1"]) { $_SESSION["K"] = $K; diff --git a/frontend/beta/js/Clipperz/Crypto/SRP.js b/frontend/beta/js/Clipperz/Crypto/SRP.js index 4015b2a..0c3fc8e 100644 --- a/frontend/beta/js/Clipperz/Crypto/SRP.js +++ b/frontend/beta/js/Clipperz/Crypto/SRP.js @@ -138,8 +138,10 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'a': function () { if (this._a == null) { - this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); -// this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); +// this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); + // Due to the problem with BigInt not handling signed numbers, this must be even. + // Possible generate any number, then bitwise shift right then left. + this._a = new Clipperz.Crypto.BigInt("33361134861037855263467252772741875431812790785257651194773534061185325245730", 10); } return this._a; @@ -191,7 +193,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'x': function () { if (this._x == null) { - this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); + // Private key x = H(s, p) + this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s() + this.P()), 16); } return this._x; @@ -210,6 +213,7 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { //------------------------------------------------------------------------- 'S': function () { + // S = (B - kg^x) ^ (a + ux) if (this._S == null) { var bigint; var srp; @@ -217,17 +221,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { bigint = Clipperz.Crypto.BigInt; srp = Clipperz.Crypto.SRP; - this._S = bigint.powerModule( - bigint.subtract( - this.B(), - bigint.multiply( - Clipperz.Crypto.SRP.k(), - bigint.powerModule(srp.g(), this.x(), srp.n()) - ) - ), - bigint.add(this.a(), bigint.multiply(this.u(), this.x())), - srp.n() - ) + this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); + } return this._S; @@ -258,9 +253,25 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { this.s().asString() + this.A().asString() + this.B().asString() + - this.K() + new Clipperz.Crypto.BigInt(this.K(),16).asString() ); //console.log("M1", this._M1); +//console.log("g", this.g().asString()); +//console.log("s", this.s().asString()); +//console.log("a", this.a().asString()); +//console.log("A", this.A().asString()); +//console.log("B", this.B().asString()); +//console.log("S", this.S().asString()); +//console.log("k", Clipperz.Crypto.SRP.k().asString()); +//console.log("K", this.K()); +//console.log("x", this.x().asString()); +//console.log("P", this.P()); +//console.log("u", this.u()); +//console.log("u", this.u().asString()); +//console.log("Test", this.stringHash(this.A().asString)); +//console.log("N", Clipperz.Crypto.SRP.n().asString()); +//console.log("g", Clipperz.Crypto.SRP.g().asString()); +//console.log("test", this.A().asString() + this.B().asString()); } return this._M1; @@ -283,15 +294,22 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { var result; var s, x, v; - s = aSalt; +//` s = aSalt; + s = new Clipperz.Crypto.BigInt(aSalt,16); + x = this.stringHash(s.asString() + this.P()); x = this.stringHash(s + this.P()); v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); result = {}; result['C'] = this.C(); - result['s'] = s; + result['s'] = s.asString(16); result['v'] = v.asString(16); +//console.log("ServerSide C", result['C']); +//console.log("ServerSide s", result['s']); +//console.log("ServerSide v", result['v']); +//console.log("ServerSide P", this.P()); +//console.log("ServerSide x", ge.asString()); return result; }, @@ -334,8 +352,9 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'stringHash': function(aValue) { var result; - result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); - + //result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); + result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + return result; }, diff --git a/frontend/delta/js/Clipperz/Crypto/SRP.js b/frontend/delta/js/Clipperz/Crypto/SRP.js index d3fd4dd..0d67efa 100644 --- a/frontend/delta/js/Clipperz/Crypto/SRP.js +++ b/frontend/delta/js/Clipperz/Crypto/SRP.js @@ -56,8 +56,6 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, { return Clipperz.Crypto.SRP._n; }, - //......................................................................... - 'g': function() { if (Clipperz.Crypto.SRP._g == null) { Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); // eventually 5 (as suggested on the Diffi-Helmann documentation) @@ -66,8 +64,6 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, { return Clipperz.Crypto.SRP._g; }, - //......................................................................... - 'k': function() { if (Clipperz.Crypto.SRP._k == null) { // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); @@ -140,8 +136,10 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'a': function () { if (this._a == null) { - this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); -// this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); +// this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); + // Due to the problem with BigInt not handling signed numbers, this must be even. + // Possible generate any number, then bitwise shift right then left. + this._a = new Clipperz.Crypto.BigInt("33361134861037855263467252772741875431812790785257651194773534061185325245730", 10); } return this._a; @@ -193,7 +191,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'x': function () { if (this._x == null) { - this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); + // Private key x = H(s, p) + this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s() + this.P()), 16); } return this._x; @@ -212,6 +211,7 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { //------------------------------------------------------------------------- 'S': function () { + // S = (B - kg^x) ^ (a + ux) if (this._S == null) { var bigint; var srp; @@ -219,17 +219,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { bigint = Clipperz.Crypto.BigInt; srp = Clipperz.Crypto.SRP; - this._S = bigint.powerModule( - bigint.subtract( - this.B(), - bigint.multiply( - Clipperz.Crypto.SRP.k(), - bigint.powerModule(srp.g(), this.x(), srp.n()) - ) - ), - bigint.add(this.a(), bigint.multiply(this.u(), this.x())), - srp.n() - ) + this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); + } return this._S; @@ -260,9 +251,25 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { this.s().asString() + this.A().asString() + this.B().asString() + - this.K() + new Clipperz.Crypto.BigInt(this.K(),16).asString() ); //console.log("M1", this._M1); +//console.log("g", this.g().asString()); +//console.log("s", this.s().asString()); +//console.log("a", this.a().asString()); +//console.log("A", this.A().asString()); +//console.log("B", this.B().asString()); +//console.log("S", this.S().asString()); +//console.log("k", Clipperz.Crypto.SRP.k().asString()); +//console.log("K", this.K()); +//console.log("x", this.x().asString()); +//console.log("P", this.P()); +//console.log("u", this.u()); +//console.log("u", this.u().asString()); +//console.log("Test", this.stringHash(this.A().asString)); +//console.log("N", Clipperz.Crypto.SRP.n().asString()); +//console.log("g", Clipperz.Crypto.SRP.g().asString()); +//console.log("test", this.A().asString() + this.B().asString()); } return this._M1; @@ -285,15 +292,22 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { var result; var s, x, v; - s = aSalt; +//` s = aSalt; + s = new Clipperz.Crypto.BigInt(aSalt,16); + x = this.stringHash(s.asString() + this.P()); x = this.stringHash(s + this.P()); v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); result = {}; result['C'] = this.C(); - result['s'] = s; + result['s'] = s.asString(16); result['v'] = v.asString(16); +//console.log("ServerSide C", result['C']); +//console.log("ServerSide s", result['s']); +//console.log("ServerSide v", result['v']); +//console.log("ServerSide P", this.P()); +//console.log("ServerSide x", ge.asString()); return result; }, @@ -336,8 +350,9 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'stringHash': function(aValue) { var result; - result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); - + //result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); + result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + return result; }, diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js index 3b079d8..e2b31ed 100644 --- a/frontend/gamma/js/Clipperz/Crypto/SRP.js +++ b/frontend/gamma/js/Clipperz/Crypto/SRP.js @@ -138,8 +138,10 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'a': function () { if (this._a == null) { - this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); -// this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); +// this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); + // Due to the problem with BigInt not handling signed numbers, this must be even. + // Possible generate any number, then bitwise shift right then left. + this._a = new Clipperz.Crypto.BigInt("33361134861037855263467252772741875431812790785257651194773534061185325245730", 10); } return this._a; @@ -191,7 +193,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'x': function () { if (this._x == null) { - this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); + // Private key x = H(s, p) + this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s() + this.P()), 16); } return this._x; @@ -210,6 +213,7 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { //------------------------------------------------------------------------- 'S': function () { + // S = (B - kg^x) ^ (a + ux) if (this._S == null) { var bigint; var srp; @@ -217,17 +221,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { bigint = Clipperz.Crypto.BigInt; srp = Clipperz.Crypto.SRP; - this._S = bigint.powerModule( - bigint.subtract( - this.B(), - bigint.multiply( - Clipperz.Crypto.SRP.k(), - bigint.powerModule(srp.g(), this.x(), srp.n()) - ) - ), - bigint.add(this.a(), bigint.multiply(this.u(), this.x())), - srp.n() - ) + this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); + } return this._S; @@ -258,9 +253,25 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { this.s().asString() + this.A().asString() + this.B().asString() + - this.K() + new Clipperz.Crypto.BigInt(this.K(),16).asString() ); //console.log("M1", this._M1); +//console.log("g", this.g().asString()); +//console.log("s", this.s().asString()); +//console.log("a", this.a().asString()); +//console.log("A", this.A().asString()); +//console.log("B", this.B().asString()); +//console.log("S", this.S().asString()); +//console.log("k", Clipperz.Crypto.SRP.k().asString()); +//console.log("K", this.K()); +//console.log("x", this.x().asString()); +//console.log("P", this.P()); +//console.log("u", this.u()); +//console.log("u", this.u().asString()); +//console.log("Test", this.stringHash(this.A().asString)); +//console.log("N", Clipperz.Crypto.SRP.n().asString()); +//console.log("g", Clipperz.Crypto.SRP.g().asString()); +//console.log("test", this.A().asString() + this.B().asString()); } return this._M1; @@ -283,15 +294,22 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { var result; var s, x, v; - s = aSalt; +//` s = aSalt; + s = new Clipperz.Crypto.BigInt(aSalt,16); + x = this.stringHash(s.asString() + this.P()); x = this.stringHash(s + this.P()); v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); result = {}; result['C'] = this.C(); - result['s'] = s; + result['s'] = s.asString(16); result['v'] = v.asString(16); +//console.log("ServerSide C", result['C']); +//console.log("ServerSide s", result['s']); +//console.log("ServerSide v", result['v']); +//console.log("ServerSide P", this.P()); +//console.log("ServerSide x", ge.asString()); return result; }, @@ -334,8 +352,9 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 'stringHash': function(aValue) { var result; - result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); - + //result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); + result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + return result; }, From df5fab7b0cea4fcad748c3fee715f0d8b20bc680 Mon Sep 17 00:00:00 2001 From: aunxx Date: Wed, 1 Jun 2016 15:52:09 +0100 Subject: [PATCH 03/20] Updated Record to remove exception raised by a problem in the access date of the record --- frontend/delta/js/Clipperz/PM/DataModel/Record.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/delta/js/Clipperz/PM/DataModel/Record.js b/frontend/delta/js/Clipperz/PM/DataModel/Record.js index e5b811d..49bde11 100644 --- a/frontend/delta/js/Clipperz/PM/DataModel/Record.js +++ b/frontend/delta/js/Clipperz/PM/DataModel/Record.js @@ -33,7 +33,8 @@ Clipperz.PM.DataModel.Record = function(args) { Clipperz.PM.DataModel.Record.superclass.constructor.apply(this, arguments); this._updateDate = (args.updateDate ? Clipperz.PM.Date.parse(args.updateDate) : Clipperz.Base.exception.raise('MandatoryParameter')); - this._accessDate = (args.accessDate ? Clipperz.PM.Date.parse(args.accessDate) : Clipperz.Base.exception.raise('MandatoryParameter')); +// Disabled due to invalid data and the raised exception +// this._accessDate = (args.accessDate ? Clipperz.PM.Date.parse(args.accessDate) : Clipperz.Base.exception.raise('MandatoryParameter')); this._retrieveIndexDataFunction = args.retrieveIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter'); this._updateIndexDataFunction = args.updateIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter'); @@ -1754,4 +1755,4 @@ Clipperz.PM.DataModel.Record.labelContainsTag = function (aLabel, aTag) { Clipperz.PM.DataModel.Record.labelContainsArchiveTag = function (aLabel) { return Clipperz.PM.DataModel.Record.labelContainsTag(aLabel, Clipperz.PM.DataModel.Record.archivedTag); -}; \ No newline at end of file +}; From 79c9efbc33df9d48789c211613723a5c4ca5b15e Mon Sep 17 00:00:00 2001 From: aunxx Date: Wed, 1 Jun 2016 16:00:49 +0100 Subject: [PATCH 04/20] Hard code some of the account details. No databaase backend at this point --- .../delta/js/Clipperz/PM/UI/MainController.js | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/frontend/delta/js/Clipperz/PM/UI/MainController.js b/frontend/delta/js/Clipperz/PM/UI/MainController.js index dce27cb..3c606d0 100644 --- a/frontend/delta/js/Clipperz/PM/UI/MainController.js +++ b/frontend/delta/js/Clipperz/PM/UI/MainController.js @@ -1265,10 +1265,33 @@ Clipperz.log("THE BROWSER IS OFFLINE"); 'certificateQuota' ]; - var attributes = this.user().accountInfo()._attributes; - MochiKit.Iter.forEach(usefulFields, function (aFieldName) { - result[aFieldName] = attributes[aFieldName]; - }) +// +// Disable loading of the details of the account. Hard code similar to the python frontend +// +// var attributes = this.user().accountInfo()._attributes; +// MochiKit.Iter.forEach(usefulFields, function (aFieldName) { +// result[aFieldName] = attributes[aFieldName]; +// }) + + result['currentSubscriptionType'] = 'EARLY_ADOPTER' ; + result['expirationDate'] = 'Mon, 01 January 4001 00:00:00 UTC' ; + result['referenceDate'] = 'Fri, 03 April 2015 08:17:46 UTC' ; + result['featureSet'] = 'FULL' ; + result['features'] = ['UPDATE_CREDENTIALS', + 'EDIT_CARD', + 'CARD_DETAILS', + 'REGISTER_CARD', + 'ADD_CARD', + 'DELETE_CARD', + 'OFFLINE_COPY', + 'LIST_CARDS']; + result['isExpired'] = false ; + result['isExpiring'] = false ; + result['paymentVerificationPending'] = false ; + result['attachmentQuota'] = 100 ; + result['certificateQuota'] = 100 ; + + }; return result; From 4ac73a1ab39238b624a2eed080f305a64ba1f7bf Mon Sep 17 00:00:00 2001 From: aunxx Date: Wed, 1 Jun 2016 16:39:13 +0100 Subject: [PATCH 05/20] Include variable --- frontend/delta/js/Clipperz/PM/UI/MainController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/delta/js/Clipperz/PM/UI/MainController.js b/frontend/delta/js/Clipperz/PM/UI/MainController.js index 3c606d0..9b707ce 100644 --- a/frontend/delta/js/Clipperz/PM/UI/MainController.js +++ b/frontend/delta/js/Clipperz/PM/UI/MainController.js @@ -1265,10 +1265,10 @@ Clipperz.log("THE BROWSER IS OFFLINE"); 'certificateQuota' ]; + var attributes = this.user().accountInfo()._attributes; // // Disable loading of the details of the account. Hard code similar to the python frontend // -// var attributes = this.user().accountInfo()._attributes; // MochiKit.Iter.forEach(usefulFields, function (aFieldName) { // result[aFieldName] = attributes[aFieldName]; // }) From 79d3b5790df076d90c43ee6c7b640d41aa1f1f60 Mon Sep 17 00:00:00 2001 From: aunxx Date: Sat, 4 Jun 2016 17:56:32 +0100 Subject: [PATCH 06/20] Added signed BigInt library --- .../beta/js/Clipperz/Crypto/biginteger.js | 1620 +++++++++++++++++ 1 file changed, 1620 insertions(+) create mode 100644 frontend/beta/js/Clipperz/Crypto/biginteger.js diff --git a/frontend/beta/js/Clipperz/Crypto/biginteger.js b/frontend/beta/js/Clipperz/Crypto/biginteger.js new file mode 100644 index 0000000..3f56d18 --- /dev/null +++ b/frontend/beta/js/Clipperz/Crypto/biginteger.js @@ -0,0 +1,1620 @@ +/* + JavaScript BigInteger library version 0.9.1 + http://silentmatt.com/biginteger/ + + Copyright (c) 2009 Matthew Crumley + Copyright (c) 2010,2011 by John Tobey + Licensed under the MIT license. + + Support for arbitrary internal representation base was added by + Vitaly Magerya. +*/ + +/* + File: biginteger.js + + Exports: + + +*/ +(function(exports) { +"use strict"; +/* + Class: BigInteger + An arbitrarily-large integer. + + objects should be considered immutable. None of the "built-in" + methods modify *this* or their arguments. All properties should be + considered private. + + All the methods of instances can be called "statically". The + static versions are convenient if you don't already have a + object. + + As an example, these calls are equivalent. + + > BigInteger(4).multiply(5); // returns BigInteger(20); + > BigInteger.multiply(4, 5); // returns BigInteger(20); + + > var a = 42; + > var a = BigInteger.toJSValue("0b101010"); // Not completely useless... +*/ + +var CONSTRUCT = {}; // Unique token to call "private" version of constructor + +/* + Constructor: BigInteger() + Convert a value to a . + + Although is the constructor for objects, it is + best not to call it as a constructor. If *n* is a object, it is + simply returned as-is. Otherwise, is equivalent to + without a radix argument. + + > var n0 = BigInteger(); // Same as + > var n1 = BigInteger("123"); // Create a new with value 123 + > var n2 = BigInteger(123); // Create a new with value 123 + > var n3 = BigInteger(n2); // Return n2, unchanged + + The constructor form only takes an array and a sign. *n* must be an + array of numbers in little-endian order, where each digit is between 0 + and BigInteger.base. The second parameter sets the sign: -1 for + negative, +1 for positive, or 0 for zero. The array is *not copied and + may be modified*. If the array contains only zeros, the sign parameter + is ignored and is forced to zero. + + > new BigInteger([5], -1): create a new BigInteger with value -5 + + Parameters: + + n - Value to convert to a . + + Returns: + + A value. + + See Also: + + , +*/ +function BigInteger(n, s, token) { + if (token !== CONSTRUCT) { + if (n instanceof BigInteger) { + return n; + } + else if (typeof n === "undefined") { + return ZERO; + } + return BigInteger.parse(n); + } + + n = n || []; // Provide the nullary constructor for subclasses. + while (n.length && !n[n.length - 1]) { + --n.length; + } + this._d = n; + this._s = n.length ? (s || 1) : 0; +} + +BigInteger._construct = function(n, s) { + return new BigInteger(n, s, CONSTRUCT); +}; + +// Base-10 speedup hacks in parse, toString, exp10 and log functions +// require base to be a power of 10. 10^7 is the largest such power +// that won't cause a precision loss when digits are multiplied. +var BigInteger_base = 10000000; +var BigInteger_base_log10 = 7; + +BigInteger.base = BigInteger_base; +BigInteger.base_log10 = BigInteger_base_log10; + +var ZERO = new BigInteger([], 0, CONSTRUCT); +// Constant: ZERO +// 0. +BigInteger.ZERO = ZERO; + +var ONE = new BigInteger([1], 1, CONSTRUCT); +// Constant: ONE +// 1. +BigInteger.ONE = ONE; + +var M_ONE = new BigInteger(ONE._d, -1, CONSTRUCT); +// Constant: M_ONE +// -1. +BigInteger.M_ONE = M_ONE; + +// Constant: _0 +// Shortcut for . +BigInteger._0 = ZERO; + +// Constant: _1 +// Shortcut for . +BigInteger._1 = ONE; + +/* + Constant: small + Array of from 0 to 36. + + These are used internally for parsing, but useful when you need a "small" + . + + See Also: + + , , <_0>, <_1> +*/ +BigInteger.small = [ + ZERO, + ONE, + /* Assuming BigInteger_base > 36 */ + new BigInteger( [2], 1, CONSTRUCT), + new BigInteger( [3], 1, CONSTRUCT), + new BigInteger( [4], 1, CONSTRUCT), + new BigInteger( [5], 1, CONSTRUCT), + new BigInteger( [6], 1, CONSTRUCT), + new BigInteger( [7], 1, CONSTRUCT), + new BigInteger( [8], 1, CONSTRUCT), + new BigInteger( [9], 1, CONSTRUCT), + new BigInteger([10], 1, CONSTRUCT), + new BigInteger([11], 1, CONSTRUCT), + new BigInteger([12], 1, CONSTRUCT), + new BigInteger([13], 1, CONSTRUCT), + new BigInteger([14], 1, CONSTRUCT), + new BigInteger([15], 1, CONSTRUCT), + new BigInteger([16], 1, CONSTRUCT), + new BigInteger([17], 1, CONSTRUCT), + new BigInteger([18], 1, CONSTRUCT), + new BigInteger([19], 1, CONSTRUCT), + new BigInteger([20], 1, CONSTRUCT), + new BigInteger([21], 1, CONSTRUCT), + new BigInteger([22], 1, CONSTRUCT), + new BigInteger([23], 1, CONSTRUCT), + new BigInteger([24], 1, CONSTRUCT), + new BigInteger([25], 1, CONSTRUCT), + new BigInteger([26], 1, CONSTRUCT), + new BigInteger([27], 1, CONSTRUCT), + new BigInteger([28], 1, CONSTRUCT), + new BigInteger([29], 1, CONSTRUCT), + new BigInteger([30], 1, CONSTRUCT), + new BigInteger([31], 1, CONSTRUCT), + new BigInteger([32], 1, CONSTRUCT), + new BigInteger([33], 1, CONSTRUCT), + new BigInteger([34], 1, CONSTRUCT), + new BigInteger([35], 1, CONSTRUCT), + new BigInteger([36], 1, CONSTRUCT) +]; + +// Used for parsing/radix conversion +BigInteger.digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); + +/* + Method: toString + Convert a to a string. + + When *base* is greater than 10, letters are upper case. + + Parameters: + + base - Optional base to represent the number in (default is base 10). + Must be between 2 and 36 inclusive, or an Error will be thrown. + + Returns: + + The string representation of the . +*/ +BigInteger.prototype.toString = function(base) { + base = +base || 10; + if (base < 2 || base > 36) { + throw new Error("illegal radix " + base + "."); + } + if (this._s === 0) { + return "0"; + } + if (base === 10) { + var str = this._s < 0 ? "-" : ""; + str += this._d[this._d.length - 1].toString(); + for (var i = this._d.length - 2; i >= 0; i--) { + var group = this._d[i].toString(); + while (group.length < BigInteger_base_log10) group = '0' + group; + str += group; + } + return str; + } + else { + var numerals = BigInteger.digits; + base = BigInteger.small[base]; + var sign = this._s; + + var n = this.abs(); + var digits = []; + var digit; + + while (n._s !== 0) { + var divmod = n.divRem(base); + n = divmod[0]; + digit = divmod[1]; + // TODO: This could be changed to unshift instead of reversing at the end. + // Benchmark both to compare speeds. + digits.push(numerals[digit.valueOf()]); + } + return (sign < 0 ? "-" : "") + digits.reverse().join(""); + } +}; + +// Verify strings for parsing +BigInteger.radixRegex = [ + /^$/, + /^$/, + /^[01]*$/, + /^[012]*$/, + /^[0-3]*$/, + /^[0-4]*$/, + /^[0-5]*$/, + /^[0-6]*$/, + /^[0-7]*$/, + /^[0-8]*$/, + /^[0-9]*$/, + /^[0-9aA]*$/, + /^[0-9abAB]*$/, + /^[0-9abcABC]*$/, + /^[0-9a-dA-D]*$/, + /^[0-9a-eA-E]*$/, + /^[0-9a-fA-F]*$/, + /^[0-9a-gA-G]*$/, + /^[0-9a-hA-H]*$/, + /^[0-9a-iA-I]*$/, + /^[0-9a-jA-J]*$/, + /^[0-9a-kA-K]*$/, + /^[0-9a-lA-L]*$/, + /^[0-9a-mA-M]*$/, + /^[0-9a-nA-N]*$/, + /^[0-9a-oA-O]*$/, + /^[0-9a-pA-P]*$/, + /^[0-9a-qA-Q]*$/, + /^[0-9a-rA-R]*$/, + /^[0-9a-sA-S]*$/, + /^[0-9a-tA-T]*$/, + /^[0-9a-uA-U]*$/, + /^[0-9a-vA-V]*$/, + /^[0-9a-wA-W]*$/, + /^[0-9a-xA-X]*$/, + /^[0-9a-yA-Y]*$/, + /^[0-9a-zA-Z]*$/ +]; + +/* + Function: parse + Parse a string into a . + + *base* is optional but, if provided, must be from 2 to 36 inclusive. If + *base* is not provided, it will be guessed based on the leading characters + of *s* as follows: + + - "0x" or "0X": *base* = 16 + - "0c" or "0C": *base* = 8 + - "0b" or "0B": *base* = 2 + - else: *base* = 10 + + If no base is provided, or *base* is 10, the number can be in exponential + form. For example, these are all valid: + + > BigInteger.parse("1e9"); // Same as "1000000000" + > BigInteger.parse("1.234*10^3"); // Same as 1234 + > BigInteger.parse("56789 * 10 ** -2"); // Same as 567 + + If any characters fall outside the range defined by the radix, an exception + will be thrown. + + Parameters: + + s - The string to parse. + base - Optional radix (default is to guess based on *s*). + + Returns: + + a instance. +*/ +BigInteger.parse = function(s, base) { + // Expands a number in exponential form to decimal form. + // expandExponential("-13.441*10^5") === "1344100"; + // expandExponential("1.12300e-1") === "0.112300"; + // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000"; + function expandExponential(str) { + str = str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e"); + + return str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function(x, s, n, f, c) { + c = +c; + var l = c < 0; + var i = n.length + c; + x = (l ? n : f).length; + c = ((c = Math.abs(c)) >= x ? c - x + l : 0); + var z = (new Array(c + 1)).join("0"); + var r = n + f; + return (s || "") + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : ""); + }); + } + + s = s.toString(); + if (typeof base === "undefined" || +base === 10) { + s = expandExponential(s); + } + + var prefixRE; + if (typeof base === "undefined") { + prefixRE = '0[xcb]'; + } + else if (base == 16) { + prefixRE = '0x'; + } + else if (base == 8) { + prefixRE = '0c'; + } + else if (base == 2) { + prefixRE = '0b'; + } + else { + prefixRE = ''; + } + var parts = new RegExp('^([+\\-]?)(' + prefixRE + ')?([0-9a-z]*)(?:\\.\\d*)?$', 'i').exec(s); + if (parts) { + var sign = parts[1] || "+"; + var baseSection = parts[2] || ""; + var digits = parts[3] || ""; + + if (typeof base === "undefined") { + // Guess base + if (baseSection === "0x" || baseSection === "0X") { // Hex + base = 16; + } + else if (baseSection === "0c" || baseSection === "0C") { // Octal + base = 8; + } + else if (baseSection === "0b" || baseSection === "0B") { // Binary + base = 2; + } + else { + base = 10; + } + } + else if (base < 2 || base > 36) { + throw new Error("Illegal radix " + base + "."); + } + + base = +base; + + // Check for digits outside the range + if (!(BigInteger.radixRegex[base].test(digits))) { + throw new Error("Bad digit for radix " + base); + } + + // Strip leading zeros, and convert to array + digits = digits.replace(/^0+/, "").split(""); + if (digits.length === 0) { + return ZERO; + } + + // Get the sign (we know it's not zero) + sign = (sign === "-") ? -1 : 1; + + // Optimize 10 + if (base == 10) { + var d = []; + while (digits.length >= BigInteger_base_log10) { + d.push(parseInt(digits.splice(digits.length-BigInteger.base_log10, BigInteger.base_log10).join(''), 10)); + } + d.push(parseInt(digits.join(''), 10)); + return new BigInteger(d, sign, CONSTRUCT); + } + + // Do the conversion + var d = ZERO; + base = BigInteger.small[base]; + var small = BigInteger.small; + for (var i = 0; i < digits.length; i++) { + d = d.multiply(base).add(small[parseInt(digits[i], 36)]); + } + return new BigInteger(d._d, sign, CONSTRUCT); + } + else { + throw new Error("Invalid BigInteger format: " + s); + } +}; + +/* + Function: add + Add two . + + Parameters: + + n - The number to add to *this*. Will be converted to a . + + Returns: + + The numbers added together. + + See Also: + + , , , +*/ +BigInteger.prototype.add = function(n) { + if (this._s === 0) { + return BigInteger(n); + } + + n = BigInteger(n); + if (n._s === 0) { + return this; + } + if (this._s !== n._s) { + n = n.negate(); + return this.subtract(n); + } + + var a = this._d; + var b = n._d; + var al = a.length; + var bl = b.length; + var sum = new Array(Math.max(al, bl) + 1); + var size = Math.min(al, bl); + var carry = 0; + var digit; + + for (var i = 0; i < size; i++) { + digit = a[i] + b[i] + carry; + sum[i] = digit % BigInteger_base; + carry = (digit / BigInteger_base) | 0; + } + if (bl > al) { + a = b; + al = bl; + } + for (i = size; carry && i < al; i++) { + digit = a[i] + carry; + sum[i] = digit % BigInteger_base; + carry = (digit / BigInteger_base) | 0; + } + if (carry) { + sum[i] = carry; + } + + for ( ; i < al; i++) { + sum[i] = a[i]; + } + + return new BigInteger(sum, this._s, CONSTRUCT); +}; + +/* + Function: negate + Get the additive inverse of a . + + Returns: + + A with the same magnatude, but with the opposite sign. + + See Also: + + +*/ +BigInteger.prototype.negate = function() { + return new BigInteger(this._d, (-this._s) | 0, CONSTRUCT); +}; + +/* + Function: abs + Get the absolute value of a . + + Returns: + + A with the same magnatude, but always positive (or zero). + + See Also: + + +*/ +BigInteger.prototype.abs = function() { + return (this._s < 0) ? this.negate() : this; +}; + +/* + Function: subtract + Subtract two . + + Parameters: + + n - The number to subtract from *this*. Will be converted to a . + + Returns: + + The *n* subtracted from *this*. + + See Also: + + , , , +*/ +BigInteger.prototype.subtract = function(n) { + if (this._s === 0) { + return BigInteger(n).negate(); + } + + n = BigInteger(n); + if (n._s === 0) { + return this; + } + if (this._s !== n._s) { + n = n.negate(); + return this.add(n); + } + + var m = this; + // negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a| + if (this._s < 0) { + m = new BigInteger(n._d, 1, CONSTRUCT); + n = new BigInteger(this._d, 1, CONSTRUCT); + } + + // Both are positive => a - b + var sign = m.compareAbs(n); + if (sign === 0) { + return ZERO; + } + else if (sign < 0) { + // swap m and n + var t = n; + n = m; + m = t; + } + + // a > b + var a = m._d; + var b = n._d; + var al = a.length; + var bl = b.length; + var diff = new Array(al); // al >= bl since a > b + var borrow = 0; + var i; + var digit; + + for (i = 0; i < bl; i++) { + digit = a[i] - borrow - b[i]; + if (digit < 0) { + digit += BigInteger_base; + borrow = 1; + } + else { + borrow = 0; + } + diff[i] = digit; + } + for (i = bl; i < al; i++) { + digit = a[i] - borrow; + if (digit < 0) { + digit += BigInteger_base; + } + else { + diff[i++] = digit; + break; + } + diff[i] = digit; + } + for ( ; i < al; i++) { + diff[i] = a[i]; + } + + return new BigInteger(diff, sign, CONSTRUCT); +}; + +(function() { + function addOne(n, sign) { + var a = n._d; + var sum = a.slice(); + var carry = true; + var i = 0; + + while (true) { + var digit = (a[i] || 0) + 1; + sum[i] = digit % BigInteger_base; + if (digit <= BigInteger_base - 1) { + break; + } + ++i; + } + + return new BigInteger(sum, sign, CONSTRUCT); + } + + function subtractOne(n, sign) { + var a = n._d; + var sum = a.slice(); + var borrow = true; + var i = 0; + + while (true) { + var digit = (a[i] || 0) - 1; + if (digit < 0) { + sum[i] = digit + BigInteger_base; + } + else { + sum[i] = digit; + break; + } + ++i; + } + + return new BigInteger(sum, sign, CONSTRUCT); + } + + /* + Function: next + Get the next (add one). + + Returns: + + *this* + 1. + + See Also: + + , + */ + BigInteger.prototype.next = function() { + switch (this._s) { + case 0: + return ONE; + case -1: + return subtractOne(this, -1); + // case 1: + default: + return addOne(this, 1); + } + }; + + /* + Function: prev + Get the previous (subtract one). + + Returns: + + *this* - 1. + + See Also: + + , + */ + BigInteger.prototype.prev = function() { + switch (this._s) { + case 0: + return M_ONE; + case -1: + return addOne(this, -1); + // case 1: + default: + return subtractOne(this, 1); + } + }; +})(); + +/* + Function: compareAbs + Compare the absolute value of two . + + Calling is faster than calling twice, then . + + Parameters: + + n - The number to compare to *this*. Will be converted to a . + + Returns: + + -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*. + + See Also: + + , +*/ +BigInteger.prototype.compareAbs = function(n) { + if (this === n) { + return 0; + } + + if (!(n instanceof BigInteger)) { + if (!isFinite(n)) { + return(isNaN(n) ? n : -1); + } + n = BigInteger(n); + } + + if (this._s === 0) { + return (n._s !== 0) ? -1 : 0; + } + if (n._s === 0) { + return 1; + } + + var l = this._d.length; + var nl = n._d.length; + if (l < nl) { + return -1; + } + else if (l > nl) { + return 1; + } + + var a = this._d; + var b = n._d; + for (var i = l-1; i >= 0; i--) { + if (a[i] !== b[i]) { + return a[i] < b[i] ? -1 : 1; + } + } + + return 0; +}; + +/* + Function: compare + Compare two . + + Parameters: + + n - The number to compare to *this*. Will be converted to a . + + Returns: + + -1, 0, or +1 if *this* is less than, equal to, or greater than *n*. + + See Also: + + , , , +*/ +BigInteger.prototype.compare = function(n) { + if (this === n) { + return 0; + } + + n = BigInteger(n); + + if (this._s === 0) { + return -n._s; + } + + if (this._s === n._s) { // both positive or both negative + var cmp = this.compareAbs(n); + return cmp * this._s; + } + else { + return this._s; + } +}; + +/* + Function: isUnit + Return true iff *this* is either 1 or -1. + + Returns: + + true if *this* compares equal to or . + + See Also: + + , , , , , + , +*/ +BigInteger.prototype.isUnit = function() { + return this === ONE || + this === M_ONE || + (this._d.length === 1 && this._d[0] === 1); +}; + +/* + Function: multiply + Multiply two . + + Parameters: + + n - The number to multiply *this* by. Will be converted to a + . + + Returns: + + The numbers multiplied together. + + See Also: + + , , , +*/ +BigInteger.prototype.multiply = function(n) { + // TODO: Consider adding Karatsuba multiplication for large numbers + if (this._s === 0) { + return ZERO; + } + + n = BigInteger(n); + if (n._s === 0) { + return ZERO; + } + if (this.isUnit()) { + if (this._s < 0) { + return n.negate(); + } + return n; + } + if (n.isUnit()) { + if (n._s < 0) { + return this.negate(); + } + return this; + } + if (this === n) { + return this.square(); + } + + var r = (this._d.length >= n._d.length); + var a = (r ? this : n)._d; // a will be longer than b + var b = (r ? n : this)._d; + var al = a.length; + var bl = b.length; + + var pl = al + bl; + var partial = new Array(pl); + var i; + for (i = 0; i < pl; i++) { + partial[i] = 0; + } + + for (i = 0; i < bl; i++) { + var carry = 0; + var bi = b[i]; + var jlimit = al + i; + var digit; + for (var j = i; j < jlimit; j++) { + digit = partial[j] + bi * a[j - i] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = (digit % BigInteger_base) | 0; + } + if (carry) { + digit = partial[j] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = digit % BigInteger_base; + } + } + return new BigInteger(partial, this._s * n._s, CONSTRUCT); +}; + +// Multiply a BigInteger by a single-digit native number +// Assumes that this and n are >= 0 +// This is not really intended to be used outside the library itself +BigInteger.prototype.multiplySingleDigit = function(n) { + if (n === 0 || this._s === 0) { + return ZERO; + } + if (n === 1) { + return this; + } + + var digit; + if (this._d.length === 1) { + digit = this._d[0] * n; + if (digit >= BigInteger_base) { + return new BigInteger([(digit % BigInteger_base)|0, + (digit / BigInteger_base)|0], 1, CONSTRUCT); + } + return new BigInteger([digit], 1, CONSTRUCT); + } + + if (n === 2) { + return this.add(this); + } + if (this.isUnit()) { + return new BigInteger([n], 1, CONSTRUCT); + } + + var a = this._d; + var al = a.length; + + var pl = al + 1; + var partial = new Array(pl); + for (var i = 0; i < pl; i++) { + partial[i] = 0; + } + + var carry = 0; + for (var j = 0; j < al; j++) { + digit = n * a[j] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = (digit % BigInteger_base) | 0; + } + if (carry) { + partial[j] = carry; + } + + return new BigInteger(partial, 1, CONSTRUCT); +}; + +/* + Function: square + Multiply a by itself. + + This is slightly faster than regular multiplication, since it removes the + duplicated multiplcations. + + Returns: + + > this.multiply(this) + + See Also: + +*/ +BigInteger.prototype.square = function() { + // Normally, squaring a 10-digit number would take 100 multiplications. + // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated. + // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies). + // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org + + if (this._s === 0) { + return ZERO; + } + if (this.isUnit()) { + return ONE; + } + + var digits = this._d; + var length = digits.length; + var imult1 = new Array(length + length + 1); + var product, carry, k; + var i; + + // Calculate diagonal + for (i = 0; i < length; i++) { + k = i * 2; + product = digits[i] * digits[i]; + carry = (product / BigInteger_base) | 0; + imult1[k] = product % BigInteger_base; + imult1[k + 1] = carry; + } + + // Calculate repeating part + for (i = 0; i < length; i++) { + carry = 0; + k = i * 2 + 1; + for (var j = i + 1; j < length; j++, k++) { + product = digits[j] * digits[i] * 2 + imult1[k] + carry; + carry = (product / BigInteger_base) | 0; + imult1[k] = product % BigInteger_base; + } + k = length + i; + var digit = carry + imult1[k]; + carry = (digit / BigInteger_base) | 0; + imult1[k] = digit % BigInteger_base; + imult1[k + 1] += carry; + } + + return new BigInteger(imult1, 1, CONSTRUCT); +}; + +/* + Function: quotient + Divide two and truncate towards zero. + + throws an exception if *n* is zero. + + Parameters: + + n - The number to divide *this* by. Will be converted to a . + + Returns: + + The *this* / *n*, truncated to an integer. + + See Also: + + , , , , +*/ +BigInteger.prototype.quotient = function(n) { + return this.divRem(n)[0]; +}; + +/* + Function: divide + Deprecated synonym for . +*/ +BigInteger.prototype.divide = BigInteger.prototype.quotient; + +/* + Function: remainder + Calculate the remainder of two . + + throws an exception if *n* is zero. + + Parameters: + + n - The remainder after *this* is divided *this* by *n*. Will be + converted to a . + + Returns: + + *this* % *n*. + + See Also: + + , +*/ +BigInteger.prototype.remainder = function(n) { + return this.divRem(n)[1]; +}; + +/* + Function: divRem + Calculate the integer quotient and remainder of two . + + throws an exception if *n* is zero. + + Parameters: + + n - The number to divide *this* by. Will be converted to a . + + Returns: + + A two-element array containing the quotient and the remainder. + + > a.divRem(b) + + is exactly equivalent to + + > [a.quotient(b), a.remainder(b)] + + except it is faster, because they are calculated at the same time. + + See Also: + + , +*/ +BigInteger.prototype.divRem = function(n) { + n = BigInteger(n); + if (n._s === 0) { + throw new Error("Divide by zero"); + } + if (this._s === 0) { + return [ZERO, ZERO]; + } + if (n._d.length === 1) { + return this.divRemSmall(n._s * n._d[0]); + } + + // Test for easy cases -- |n1| <= |n2| + switch (this.compareAbs(n)) { + case 0: // n1 == n2 + return [this._s === n._s ? ONE : M_ONE, ZERO]; + case -1: // |n1| < |n2| + return [ZERO, this]; + } + + var sign = this._s * n._s; + var a = n.abs(); + var b_digits = this._d; + var b_index = b_digits.length; + var digits = n._d.length; + var quot = []; + var guess; + + var part = new BigInteger([], 0, CONSTRUCT); + + while (b_index) { + part._d.unshift(b_digits[--b_index]); + part = new BigInteger(part._d, 1, CONSTRUCT); + + if (part.compareAbs(n) < 0) { + quot.push(0); + continue; + } + if (part._s === 0) { + guess = 0; + } + else { + var xlen = part._d.length, ylen = a._d.length; + var highx = part._d[xlen-1]*BigInteger_base + part._d[xlen-2]; + var highy = a._d[ylen-1]*BigInteger_base + a._d[ylen-2]; + if (part._d.length > a._d.length) { + // The length of part._d can either match a._d length, + // or exceed it by one. + highx = (highx+1)*BigInteger_base; + } + guess = Math.ceil(highx/highy); + } + do { + var check = a.multiplySingleDigit(guess); + if (check.compareAbs(part) <= 0) { + break; + } + guess--; + } while (guess); + + quot.push(guess); + if (!guess) { + continue; + } + var diff = part.subtract(check); + part._d = diff._d.slice(); + } + + return [new BigInteger(quot.reverse(), sign, CONSTRUCT), + new BigInteger(part._d, this._s, CONSTRUCT)]; +}; + +// Throws an exception if n is outside of (-BigInteger.base, -1] or +// [1, BigInteger.base). It's not necessary to call this, since the +// other division functions will call it if they are able to. +BigInteger.prototype.divRemSmall = function(n) { + var r; + n = +n; + if (n === 0) { + throw new Error("Divide by zero"); + } + + var n_s = n < 0 ? -1 : 1; + var sign = this._s * n_s; + n = Math.abs(n); + + if (n < 1 || n >= BigInteger_base) { + throw new Error("Argument out of range"); + } + + if (this._s === 0) { + return [ZERO, ZERO]; + } + + if (n === 1 || n === -1) { + return [(sign === 1) ? this.abs() : new BigInteger(this._d, sign, CONSTRUCT), ZERO]; + } + + // 2 <= n < BigInteger_base + + // divide a single digit by a single digit + if (this._d.length === 1) { + var q = new BigInteger([(this._d[0] / n) | 0], 1, CONSTRUCT); + r = new BigInteger([(this._d[0] % n) | 0], 1, CONSTRUCT); + if (sign < 0) { + q = q.negate(); + } + if (this._s < 0) { + r = r.negate(); + } + return [q, r]; + } + + var digits = this._d.slice(); + var quot = new Array(digits.length); + var part = 0; + var diff = 0; + var i = 0; + var guess; + + while (digits.length) { + part = part * BigInteger_base + digits[digits.length - 1]; + if (part < n) { + quot[i++] = 0; + digits.pop(); + diff = BigInteger_base * diff + part; + continue; + } + if (part === 0) { + guess = 0; + } + else { + guess = (part / n) | 0; + } + + var check = n * guess; + diff = part - check; + quot[i++] = guess; + if (!guess) { + digits.pop(); + continue; + } + + digits.pop(); + part = diff; + } + + r = new BigInteger([diff], 1, CONSTRUCT); + if (this._s < 0) { + r = r.negate(); + } + return [new BigInteger(quot.reverse(), sign, CONSTRUCT), r]; +}; + +/* + Function: isEven + Return true iff *this* is divisible by two. + + Note that is even. + + Returns: + + true if *this* is even, false otherwise. + + See Also: + + +*/ +BigInteger.prototype.isEven = function() { + var digits = this._d; + return this._s === 0 || digits.length === 0 || (digits[0] % 2) === 0; +}; + +/* + Function: isOdd + Return true iff *this* is not divisible by two. + + Returns: + + true if *this* is odd, false otherwise. + + See Also: + + +*/ +BigInteger.prototype.isOdd = function() { + return !this.isEven(); +}; + +/* + Function: sign + Get the sign of a . + + Returns: + + * -1 if *this* < 0 + * 0 if *this* == 0 + * +1 if *this* > 0 + + See Also: + + , , , , +*/ +BigInteger.prototype.sign = function() { + return this._s; +}; + +/* + Function: isPositive + Return true iff *this* > 0. + + Returns: + + true if *this*.compare() == 1. + + See Also: + + , , , , , +*/ +BigInteger.prototype.isPositive = function() { + return this._s > 0; +}; + +/* + Function: isNegative + Return true iff *this* < 0. + + Returns: + + true if *this*.compare() == -1. + + See Also: + + , , , , , +*/ +BigInteger.prototype.isNegative = function() { + return this._s < 0; +}; + +/* + Function: isZero + Return true iff *this* == 0. + + Returns: + + true if *this*.compare() == 0. + + See Also: + + , , , , +*/ +BigInteger.prototype.isZero = function() { + return this._s === 0; +}; + +/* + Function: exp10 + Multiply a by a power of 10. + + This is equivalent to, but faster than + + > if (n >= 0) { + > return this.multiply(BigInteger("1e" + n)); + > } + > else { // n <= 0 + > return this.quotient(BigInteger("1e" + -n)); + > } + + Parameters: + + n - The power of 10 to multiply *this* by. *n* is converted to a + javascipt number and must be no greater than + (0x7FFFFFFF), or an exception will be thrown. + + Returns: + + *this* * (10 ** *n*), truncated to an integer if necessary. + + See Also: + + , +*/ +BigInteger.prototype.exp10 = function(n) { + n = +n; + if (n === 0) { + return this; + } + if (Math.abs(n) > Number(MAX_EXP)) { + throw new Error("exponent too large in BigInteger.exp10"); + } + // Optimization for this == 0. This also keeps us from having to trim zeros in the positive n case + if (this._s === 0) { + return ZERO; + } + if (n > 0) { + var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT); + + for (; n >= BigInteger_base_log10; n -= BigInteger_base_log10) { + k._d.unshift(0); + } + if (n == 0) + return k; + k._s = 1; + k = k.multiplySingleDigit(Math.pow(10, n)); + return (this._s < 0 ? k.negate() : k); + } else if (-n >= this._d.length*BigInteger_base_log10) { + return ZERO; + } else { + var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT); + + for (n = -n; n >= BigInteger_base_log10; n -= BigInteger_base_log10) { + k._d.shift(); + } + return (n == 0) ? k : k.divRemSmall(Math.pow(10, n))[0]; + } +}; + +/* + Function: pow + Raise a to a power. + + In this implementation, 0**0 is 1. + + Parameters: + + n - The exponent to raise *this* by. *n* must be no greater than + (0x7FFFFFFF), or an exception will be thrown. + + Returns: + + *this* raised to the *nth* power. + + See Also: + + +*/ +BigInteger.prototype.pow = function(n) { + if (this.isUnit()) { + if (this._s > 0) { + return this; + } + else { + return BigInteger(n).isOdd() ? this : this.negate(); + } + } + + n = BigInteger(n); + if (n._s === 0) { + return ONE; + } + else if (n._s < 0) { + if (this._s === 0) { + throw new Error("Divide by zero"); + } + else { + return ZERO; + } + } + if (this._s === 0) { + return ZERO; + } + if (n.isUnit()) { + return this; + } + + if (n.compareAbs(MAX_EXP) > 0) { + throw new Error("exponent too large in BigInteger.pow"); + } + var x = this; + var aux = ONE; + var two = BigInteger.small[2]; + + while (n.isPositive()) { + if (n.isOdd()) { + aux = aux.multiply(x); + if (n.isUnit()) { + return aux; + } + } + x = x.square(); + n = n.quotient(two); + } + + return aux; +}; + +/* + Function: modPow + Raise a to a power (mod m). + + Because it is reduced by a modulus, is not limited by + like . + + Parameters: + + exponent - The exponent to raise *this* by. Must be positive. + modulus - The modulus. + + Returns: + + *this* ^ *exponent* (mod *modulus*). + + See Also: + + , +*/ +BigInteger.prototype.modPow = function(exponent, modulus) { + var result = ONE; + var base = this; + + while (exponent.isPositive()) { + if (exponent.isOdd()) { + result = result.multiply(base).remainder(modulus); + } + + exponent = exponent.quotient(BigInteger.small[2]); + if (exponent.isPositive()) { + base = base.square().remainder(modulus); + } + } + + return result; +}; + +/* + Function: log + Get the natural logarithm of a as a native JavaScript number. + + This is equivalent to + + > Math.log(this.toJSValue()) + + but handles values outside of the native number range. + + Returns: + + log( *this* ) + + See Also: + + +*/ +BigInteger.prototype.log = function() { + switch (this._s) { + case 0: return -Infinity; + case -1: return NaN; + default: // Fall through. + } + + var l = this._d.length; + + if (l*BigInteger_base_log10 < 30) { + return Math.log(this.valueOf()); + } + + var N = Math.ceil(30/BigInteger_base_log10); + var firstNdigits = this._d.slice(l - N); + return Math.log((new BigInteger(firstNdigits, 1, CONSTRUCT)).valueOf()) + (l - N) * Math.log(BigInteger_base); +}; + +/* + Function: valueOf + Convert a to a native JavaScript integer. + + This is called automatically by JavaScipt to convert a to a + native value. + + Returns: + + > parseInt(this.toString(), 10) + + See Also: + + , +*/ +BigInteger.prototype.valueOf = function() { + return parseInt(this.toString(), 10); +}; + +/* + Function: toJSValue + Convert a to a native JavaScript integer. + + This is the same as valueOf, but more explicitly named. + + Returns: + + > parseInt(this.toString(), 10) + + See Also: + + , +*/ +BigInteger.prototype.toJSValue = function() { + return parseInt(this.toString(), 10); +}; + +var MAX_EXP = BigInteger(0x7FFFFFFF); +// Constant: MAX_EXP +// The largest exponent allowed in and (0x7FFFFFFF or 2147483647). +BigInteger.MAX_EXP = MAX_EXP; + +(function() { + function makeUnary(fn) { + return function(a) { + return fn.call(BigInteger(a)); + }; + } + + function makeBinary(fn) { + return function(a, b) { + return fn.call(BigInteger(a), BigInteger(b)); + }; + } + + function makeTrinary(fn) { + return function(a, b, c) { + return fn.call(BigInteger(a), BigInteger(b), BigInteger(c)); + }; + } + + (function() { + var i, fn; + var unary = "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(","); + var binary = "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(","); + var trinary = ["modPow"]; + + for (i = 0; i < unary.length; i++) { + fn = unary[i]; + BigInteger[fn] = makeUnary(BigInteger.prototype[fn]); + } + + for (i = 0; i < binary.length; i++) { + fn = binary[i]; + BigInteger[fn] = makeBinary(BigInteger.prototype[fn]); + } + + for (i = 0; i < trinary.length; i++) { + fn = trinary[i]; + BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]); + } + + BigInteger.exp10 = function(x, n) { + return BigInteger(x).exp10(n); + }; + })(); +})(); + +exports.BigInteger = BigInteger; +})(typeof exports !== 'undefined' ? exports : this); From 6936e9a78c01618071867c6b8a12bf33abf27714 Mon Sep 17 00:00:00 2001 From: aunxx Date: Sat, 4 Jun 2016 17:57:34 +0100 Subject: [PATCH 07/20] Added signed BigInt library --- .../delta/js/Clipperz/Crypto/biginteger.js | 1620 +++++++++++++++++ .../gamma/js/Clipperz/Crypto/biginteger.js | 1620 +++++++++++++++++ 2 files changed, 3240 insertions(+) create mode 100644 frontend/delta/js/Clipperz/Crypto/biginteger.js create mode 100644 frontend/gamma/js/Clipperz/Crypto/biginteger.js diff --git a/frontend/delta/js/Clipperz/Crypto/biginteger.js b/frontend/delta/js/Clipperz/Crypto/biginteger.js new file mode 100644 index 0000000..3f56d18 --- /dev/null +++ b/frontend/delta/js/Clipperz/Crypto/biginteger.js @@ -0,0 +1,1620 @@ +/* + JavaScript BigInteger library version 0.9.1 + http://silentmatt.com/biginteger/ + + Copyright (c) 2009 Matthew Crumley + Copyright (c) 2010,2011 by John Tobey + Licensed under the MIT license. + + Support for arbitrary internal representation base was added by + Vitaly Magerya. +*/ + +/* + File: biginteger.js + + Exports: + + +*/ +(function(exports) { +"use strict"; +/* + Class: BigInteger + An arbitrarily-large integer. + + objects should be considered immutable. None of the "built-in" + methods modify *this* or their arguments. All properties should be + considered private. + + All the methods of instances can be called "statically". The + static versions are convenient if you don't already have a + object. + + As an example, these calls are equivalent. + + > BigInteger(4).multiply(5); // returns BigInteger(20); + > BigInteger.multiply(4, 5); // returns BigInteger(20); + + > var a = 42; + > var a = BigInteger.toJSValue("0b101010"); // Not completely useless... +*/ + +var CONSTRUCT = {}; // Unique token to call "private" version of constructor + +/* + Constructor: BigInteger() + Convert a value to a . + + Although is the constructor for objects, it is + best not to call it as a constructor. If *n* is a object, it is + simply returned as-is. Otherwise, is equivalent to + without a radix argument. + + > var n0 = BigInteger(); // Same as + > var n1 = BigInteger("123"); // Create a new with value 123 + > var n2 = BigInteger(123); // Create a new with value 123 + > var n3 = BigInteger(n2); // Return n2, unchanged + + The constructor form only takes an array and a sign. *n* must be an + array of numbers in little-endian order, where each digit is between 0 + and BigInteger.base. The second parameter sets the sign: -1 for + negative, +1 for positive, or 0 for zero. The array is *not copied and + may be modified*. If the array contains only zeros, the sign parameter + is ignored and is forced to zero. + + > new BigInteger([5], -1): create a new BigInteger with value -5 + + Parameters: + + n - Value to convert to a . + + Returns: + + A value. + + See Also: + + , +*/ +function BigInteger(n, s, token) { + if (token !== CONSTRUCT) { + if (n instanceof BigInteger) { + return n; + } + else if (typeof n === "undefined") { + return ZERO; + } + return BigInteger.parse(n); + } + + n = n || []; // Provide the nullary constructor for subclasses. + while (n.length && !n[n.length - 1]) { + --n.length; + } + this._d = n; + this._s = n.length ? (s || 1) : 0; +} + +BigInteger._construct = function(n, s) { + return new BigInteger(n, s, CONSTRUCT); +}; + +// Base-10 speedup hacks in parse, toString, exp10 and log functions +// require base to be a power of 10. 10^7 is the largest such power +// that won't cause a precision loss when digits are multiplied. +var BigInteger_base = 10000000; +var BigInteger_base_log10 = 7; + +BigInteger.base = BigInteger_base; +BigInteger.base_log10 = BigInteger_base_log10; + +var ZERO = new BigInteger([], 0, CONSTRUCT); +// Constant: ZERO +// 0. +BigInteger.ZERO = ZERO; + +var ONE = new BigInteger([1], 1, CONSTRUCT); +// Constant: ONE +// 1. +BigInteger.ONE = ONE; + +var M_ONE = new BigInteger(ONE._d, -1, CONSTRUCT); +// Constant: M_ONE +// -1. +BigInteger.M_ONE = M_ONE; + +// Constant: _0 +// Shortcut for . +BigInteger._0 = ZERO; + +// Constant: _1 +// Shortcut for . +BigInteger._1 = ONE; + +/* + Constant: small + Array of from 0 to 36. + + These are used internally for parsing, but useful when you need a "small" + . + + See Also: + + , , <_0>, <_1> +*/ +BigInteger.small = [ + ZERO, + ONE, + /* Assuming BigInteger_base > 36 */ + new BigInteger( [2], 1, CONSTRUCT), + new BigInteger( [3], 1, CONSTRUCT), + new BigInteger( [4], 1, CONSTRUCT), + new BigInteger( [5], 1, CONSTRUCT), + new BigInteger( [6], 1, CONSTRUCT), + new BigInteger( [7], 1, CONSTRUCT), + new BigInteger( [8], 1, CONSTRUCT), + new BigInteger( [9], 1, CONSTRUCT), + new BigInteger([10], 1, CONSTRUCT), + new BigInteger([11], 1, CONSTRUCT), + new BigInteger([12], 1, CONSTRUCT), + new BigInteger([13], 1, CONSTRUCT), + new BigInteger([14], 1, CONSTRUCT), + new BigInteger([15], 1, CONSTRUCT), + new BigInteger([16], 1, CONSTRUCT), + new BigInteger([17], 1, CONSTRUCT), + new BigInteger([18], 1, CONSTRUCT), + new BigInteger([19], 1, CONSTRUCT), + new BigInteger([20], 1, CONSTRUCT), + new BigInteger([21], 1, CONSTRUCT), + new BigInteger([22], 1, CONSTRUCT), + new BigInteger([23], 1, CONSTRUCT), + new BigInteger([24], 1, CONSTRUCT), + new BigInteger([25], 1, CONSTRUCT), + new BigInteger([26], 1, CONSTRUCT), + new BigInteger([27], 1, CONSTRUCT), + new BigInteger([28], 1, CONSTRUCT), + new BigInteger([29], 1, CONSTRUCT), + new BigInteger([30], 1, CONSTRUCT), + new BigInteger([31], 1, CONSTRUCT), + new BigInteger([32], 1, CONSTRUCT), + new BigInteger([33], 1, CONSTRUCT), + new BigInteger([34], 1, CONSTRUCT), + new BigInteger([35], 1, CONSTRUCT), + new BigInteger([36], 1, CONSTRUCT) +]; + +// Used for parsing/radix conversion +BigInteger.digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); + +/* + Method: toString + Convert a to a string. + + When *base* is greater than 10, letters are upper case. + + Parameters: + + base - Optional base to represent the number in (default is base 10). + Must be between 2 and 36 inclusive, or an Error will be thrown. + + Returns: + + The string representation of the . +*/ +BigInteger.prototype.toString = function(base) { + base = +base || 10; + if (base < 2 || base > 36) { + throw new Error("illegal radix " + base + "."); + } + if (this._s === 0) { + return "0"; + } + if (base === 10) { + var str = this._s < 0 ? "-" : ""; + str += this._d[this._d.length - 1].toString(); + for (var i = this._d.length - 2; i >= 0; i--) { + var group = this._d[i].toString(); + while (group.length < BigInteger_base_log10) group = '0' + group; + str += group; + } + return str; + } + else { + var numerals = BigInteger.digits; + base = BigInteger.small[base]; + var sign = this._s; + + var n = this.abs(); + var digits = []; + var digit; + + while (n._s !== 0) { + var divmod = n.divRem(base); + n = divmod[0]; + digit = divmod[1]; + // TODO: This could be changed to unshift instead of reversing at the end. + // Benchmark both to compare speeds. + digits.push(numerals[digit.valueOf()]); + } + return (sign < 0 ? "-" : "") + digits.reverse().join(""); + } +}; + +// Verify strings for parsing +BigInteger.radixRegex = [ + /^$/, + /^$/, + /^[01]*$/, + /^[012]*$/, + /^[0-3]*$/, + /^[0-4]*$/, + /^[0-5]*$/, + /^[0-6]*$/, + /^[0-7]*$/, + /^[0-8]*$/, + /^[0-9]*$/, + /^[0-9aA]*$/, + /^[0-9abAB]*$/, + /^[0-9abcABC]*$/, + /^[0-9a-dA-D]*$/, + /^[0-9a-eA-E]*$/, + /^[0-9a-fA-F]*$/, + /^[0-9a-gA-G]*$/, + /^[0-9a-hA-H]*$/, + /^[0-9a-iA-I]*$/, + /^[0-9a-jA-J]*$/, + /^[0-9a-kA-K]*$/, + /^[0-9a-lA-L]*$/, + /^[0-9a-mA-M]*$/, + /^[0-9a-nA-N]*$/, + /^[0-9a-oA-O]*$/, + /^[0-9a-pA-P]*$/, + /^[0-9a-qA-Q]*$/, + /^[0-9a-rA-R]*$/, + /^[0-9a-sA-S]*$/, + /^[0-9a-tA-T]*$/, + /^[0-9a-uA-U]*$/, + /^[0-9a-vA-V]*$/, + /^[0-9a-wA-W]*$/, + /^[0-9a-xA-X]*$/, + /^[0-9a-yA-Y]*$/, + /^[0-9a-zA-Z]*$/ +]; + +/* + Function: parse + Parse a string into a . + + *base* is optional but, if provided, must be from 2 to 36 inclusive. If + *base* is not provided, it will be guessed based on the leading characters + of *s* as follows: + + - "0x" or "0X": *base* = 16 + - "0c" or "0C": *base* = 8 + - "0b" or "0B": *base* = 2 + - else: *base* = 10 + + If no base is provided, or *base* is 10, the number can be in exponential + form. For example, these are all valid: + + > BigInteger.parse("1e9"); // Same as "1000000000" + > BigInteger.parse("1.234*10^3"); // Same as 1234 + > BigInteger.parse("56789 * 10 ** -2"); // Same as 567 + + If any characters fall outside the range defined by the radix, an exception + will be thrown. + + Parameters: + + s - The string to parse. + base - Optional radix (default is to guess based on *s*). + + Returns: + + a instance. +*/ +BigInteger.parse = function(s, base) { + // Expands a number in exponential form to decimal form. + // expandExponential("-13.441*10^5") === "1344100"; + // expandExponential("1.12300e-1") === "0.112300"; + // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000"; + function expandExponential(str) { + str = str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e"); + + return str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function(x, s, n, f, c) { + c = +c; + var l = c < 0; + var i = n.length + c; + x = (l ? n : f).length; + c = ((c = Math.abs(c)) >= x ? c - x + l : 0); + var z = (new Array(c + 1)).join("0"); + var r = n + f; + return (s || "") + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : ""); + }); + } + + s = s.toString(); + if (typeof base === "undefined" || +base === 10) { + s = expandExponential(s); + } + + var prefixRE; + if (typeof base === "undefined") { + prefixRE = '0[xcb]'; + } + else if (base == 16) { + prefixRE = '0x'; + } + else if (base == 8) { + prefixRE = '0c'; + } + else if (base == 2) { + prefixRE = '0b'; + } + else { + prefixRE = ''; + } + var parts = new RegExp('^([+\\-]?)(' + prefixRE + ')?([0-9a-z]*)(?:\\.\\d*)?$', 'i').exec(s); + if (parts) { + var sign = parts[1] || "+"; + var baseSection = parts[2] || ""; + var digits = parts[3] || ""; + + if (typeof base === "undefined") { + // Guess base + if (baseSection === "0x" || baseSection === "0X") { // Hex + base = 16; + } + else if (baseSection === "0c" || baseSection === "0C") { // Octal + base = 8; + } + else if (baseSection === "0b" || baseSection === "0B") { // Binary + base = 2; + } + else { + base = 10; + } + } + else if (base < 2 || base > 36) { + throw new Error("Illegal radix " + base + "."); + } + + base = +base; + + // Check for digits outside the range + if (!(BigInteger.radixRegex[base].test(digits))) { + throw new Error("Bad digit for radix " + base); + } + + // Strip leading zeros, and convert to array + digits = digits.replace(/^0+/, "").split(""); + if (digits.length === 0) { + return ZERO; + } + + // Get the sign (we know it's not zero) + sign = (sign === "-") ? -1 : 1; + + // Optimize 10 + if (base == 10) { + var d = []; + while (digits.length >= BigInteger_base_log10) { + d.push(parseInt(digits.splice(digits.length-BigInteger.base_log10, BigInteger.base_log10).join(''), 10)); + } + d.push(parseInt(digits.join(''), 10)); + return new BigInteger(d, sign, CONSTRUCT); + } + + // Do the conversion + var d = ZERO; + base = BigInteger.small[base]; + var small = BigInteger.small; + for (var i = 0; i < digits.length; i++) { + d = d.multiply(base).add(small[parseInt(digits[i], 36)]); + } + return new BigInteger(d._d, sign, CONSTRUCT); + } + else { + throw new Error("Invalid BigInteger format: " + s); + } +}; + +/* + Function: add + Add two . + + Parameters: + + n - The number to add to *this*. Will be converted to a . + + Returns: + + The numbers added together. + + See Also: + + , , , +*/ +BigInteger.prototype.add = function(n) { + if (this._s === 0) { + return BigInteger(n); + } + + n = BigInteger(n); + if (n._s === 0) { + return this; + } + if (this._s !== n._s) { + n = n.negate(); + return this.subtract(n); + } + + var a = this._d; + var b = n._d; + var al = a.length; + var bl = b.length; + var sum = new Array(Math.max(al, bl) + 1); + var size = Math.min(al, bl); + var carry = 0; + var digit; + + for (var i = 0; i < size; i++) { + digit = a[i] + b[i] + carry; + sum[i] = digit % BigInteger_base; + carry = (digit / BigInteger_base) | 0; + } + if (bl > al) { + a = b; + al = bl; + } + for (i = size; carry && i < al; i++) { + digit = a[i] + carry; + sum[i] = digit % BigInteger_base; + carry = (digit / BigInteger_base) | 0; + } + if (carry) { + sum[i] = carry; + } + + for ( ; i < al; i++) { + sum[i] = a[i]; + } + + return new BigInteger(sum, this._s, CONSTRUCT); +}; + +/* + Function: negate + Get the additive inverse of a . + + Returns: + + A with the same magnatude, but with the opposite sign. + + See Also: + + +*/ +BigInteger.prototype.negate = function() { + return new BigInteger(this._d, (-this._s) | 0, CONSTRUCT); +}; + +/* + Function: abs + Get the absolute value of a . + + Returns: + + A with the same magnatude, but always positive (or zero). + + See Also: + + +*/ +BigInteger.prototype.abs = function() { + return (this._s < 0) ? this.negate() : this; +}; + +/* + Function: subtract + Subtract two . + + Parameters: + + n - The number to subtract from *this*. Will be converted to a . + + Returns: + + The *n* subtracted from *this*. + + See Also: + + , , , +*/ +BigInteger.prototype.subtract = function(n) { + if (this._s === 0) { + return BigInteger(n).negate(); + } + + n = BigInteger(n); + if (n._s === 0) { + return this; + } + if (this._s !== n._s) { + n = n.negate(); + return this.add(n); + } + + var m = this; + // negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a| + if (this._s < 0) { + m = new BigInteger(n._d, 1, CONSTRUCT); + n = new BigInteger(this._d, 1, CONSTRUCT); + } + + // Both are positive => a - b + var sign = m.compareAbs(n); + if (sign === 0) { + return ZERO; + } + else if (sign < 0) { + // swap m and n + var t = n; + n = m; + m = t; + } + + // a > b + var a = m._d; + var b = n._d; + var al = a.length; + var bl = b.length; + var diff = new Array(al); // al >= bl since a > b + var borrow = 0; + var i; + var digit; + + for (i = 0; i < bl; i++) { + digit = a[i] - borrow - b[i]; + if (digit < 0) { + digit += BigInteger_base; + borrow = 1; + } + else { + borrow = 0; + } + diff[i] = digit; + } + for (i = bl; i < al; i++) { + digit = a[i] - borrow; + if (digit < 0) { + digit += BigInteger_base; + } + else { + diff[i++] = digit; + break; + } + diff[i] = digit; + } + for ( ; i < al; i++) { + diff[i] = a[i]; + } + + return new BigInteger(diff, sign, CONSTRUCT); +}; + +(function() { + function addOne(n, sign) { + var a = n._d; + var sum = a.slice(); + var carry = true; + var i = 0; + + while (true) { + var digit = (a[i] || 0) + 1; + sum[i] = digit % BigInteger_base; + if (digit <= BigInteger_base - 1) { + break; + } + ++i; + } + + return new BigInteger(sum, sign, CONSTRUCT); + } + + function subtractOne(n, sign) { + var a = n._d; + var sum = a.slice(); + var borrow = true; + var i = 0; + + while (true) { + var digit = (a[i] || 0) - 1; + if (digit < 0) { + sum[i] = digit + BigInteger_base; + } + else { + sum[i] = digit; + break; + } + ++i; + } + + return new BigInteger(sum, sign, CONSTRUCT); + } + + /* + Function: next + Get the next (add one). + + Returns: + + *this* + 1. + + See Also: + + , + */ + BigInteger.prototype.next = function() { + switch (this._s) { + case 0: + return ONE; + case -1: + return subtractOne(this, -1); + // case 1: + default: + return addOne(this, 1); + } + }; + + /* + Function: prev + Get the previous (subtract one). + + Returns: + + *this* - 1. + + See Also: + + , + */ + BigInteger.prototype.prev = function() { + switch (this._s) { + case 0: + return M_ONE; + case -1: + return addOne(this, -1); + // case 1: + default: + return subtractOne(this, 1); + } + }; +})(); + +/* + Function: compareAbs + Compare the absolute value of two . + + Calling is faster than calling twice, then . + + Parameters: + + n - The number to compare to *this*. Will be converted to a . + + Returns: + + -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*. + + See Also: + + , +*/ +BigInteger.prototype.compareAbs = function(n) { + if (this === n) { + return 0; + } + + if (!(n instanceof BigInteger)) { + if (!isFinite(n)) { + return(isNaN(n) ? n : -1); + } + n = BigInteger(n); + } + + if (this._s === 0) { + return (n._s !== 0) ? -1 : 0; + } + if (n._s === 0) { + return 1; + } + + var l = this._d.length; + var nl = n._d.length; + if (l < nl) { + return -1; + } + else if (l > nl) { + return 1; + } + + var a = this._d; + var b = n._d; + for (var i = l-1; i >= 0; i--) { + if (a[i] !== b[i]) { + return a[i] < b[i] ? -1 : 1; + } + } + + return 0; +}; + +/* + Function: compare + Compare two . + + Parameters: + + n - The number to compare to *this*. Will be converted to a . + + Returns: + + -1, 0, or +1 if *this* is less than, equal to, or greater than *n*. + + See Also: + + , , , +*/ +BigInteger.prototype.compare = function(n) { + if (this === n) { + return 0; + } + + n = BigInteger(n); + + if (this._s === 0) { + return -n._s; + } + + if (this._s === n._s) { // both positive or both negative + var cmp = this.compareAbs(n); + return cmp * this._s; + } + else { + return this._s; + } +}; + +/* + Function: isUnit + Return true iff *this* is either 1 or -1. + + Returns: + + true if *this* compares equal to or . + + See Also: + + , , , , , + , +*/ +BigInteger.prototype.isUnit = function() { + return this === ONE || + this === M_ONE || + (this._d.length === 1 && this._d[0] === 1); +}; + +/* + Function: multiply + Multiply two . + + Parameters: + + n - The number to multiply *this* by. Will be converted to a + . + + Returns: + + The numbers multiplied together. + + See Also: + + , , , +*/ +BigInteger.prototype.multiply = function(n) { + // TODO: Consider adding Karatsuba multiplication for large numbers + if (this._s === 0) { + return ZERO; + } + + n = BigInteger(n); + if (n._s === 0) { + return ZERO; + } + if (this.isUnit()) { + if (this._s < 0) { + return n.negate(); + } + return n; + } + if (n.isUnit()) { + if (n._s < 0) { + return this.negate(); + } + return this; + } + if (this === n) { + return this.square(); + } + + var r = (this._d.length >= n._d.length); + var a = (r ? this : n)._d; // a will be longer than b + var b = (r ? n : this)._d; + var al = a.length; + var bl = b.length; + + var pl = al + bl; + var partial = new Array(pl); + var i; + for (i = 0; i < pl; i++) { + partial[i] = 0; + } + + for (i = 0; i < bl; i++) { + var carry = 0; + var bi = b[i]; + var jlimit = al + i; + var digit; + for (var j = i; j < jlimit; j++) { + digit = partial[j] + bi * a[j - i] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = (digit % BigInteger_base) | 0; + } + if (carry) { + digit = partial[j] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = digit % BigInteger_base; + } + } + return new BigInteger(partial, this._s * n._s, CONSTRUCT); +}; + +// Multiply a BigInteger by a single-digit native number +// Assumes that this and n are >= 0 +// This is not really intended to be used outside the library itself +BigInteger.prototype.multiplySingleDigit = function(n) { + if (n === 0 || this._s === 0) { + return ZERO; + } + if (n === 1) { + return this; + } + + var digit; + if (this._d.length === 1) { + digit = this._d[0] * n; + if (digit >= BigInteger_base) { + return new BigInteger([(digit % BigInteger_base)|0, + (digit / BigInteger_base)|0], 1, CONSTRUCT); + } + return new BigInteger([digit], 1, CONSTRUCT); + } + + if (n === 2) { + return this.add(this); + } + if (this.isUnit()) { + return new BigInteger([n], 1, CONSTRUCT); + } + + var a = this._d; + var al = a.length; + + var pl = al + 1; + var partial = new Array(pl); + for (var i = 0; i < pl; i++) { + partial[i] = 0; + } + + var carry = 0; + for (var j = 0; j < al; j++) { + digit = n * a[j] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = (digit % BigInteger_base) | 0; + } + if (carry) { + partial[j] = carry; + } + + return new BigInteger(partial, 1, CONSTRUCT); +}; + +/* + Function: square + Multiply a by itself. + + This is slightly faster than regular multiplication, since it removes the + duplicated multiplcations. + + Returns: + + > this.multiply(this) + + See Also: + +*/ +BigInteger.prototype.square = function() { + // Normally, squaring a 10-digit number would take 100 multiplications. + // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated. + // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies). + // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org + + if (this._s === 0) { + return ZERO; + } + if (this.isUnit()) { + return ONE; + } + + var digits = this._d; + var length = digits.length; + var imult1 = new Array(length + length + 1); + var product, carry, k; + var i; + + // Calculate diagonal + for (i = 0; i < length; i++) { + k = i * 2; + product = digits[i] * digits[i]; + carry = (product / BigInteger_base) | 0; + imult1[k] = product % BigInteger_base; + imult1[k + 1] = carry; + } + + // Calculate repeating part + for (i = 0; i < length; i++) { + carry = 0; + k = i * 2 + 1; + for (var j = i + 1; j < length; j++, k++) { + product = digits[j] * digits[i] * 2 + imult1[k] + carry; + carry = (product / BigInteger_base) | 0; + imult1[k] = product % BigInteger_base; + } + k = length + i; + var digit = carry + imult1[k]; + carry = (digit / BigInteger_base) | 0; + imult1[k] = digit % BigInteger_base; + imult1[k + 1] += carry; + } + + return new BigInteger(imult1, 1, CONSTRUCT); +}; + +/* + Function: quotient + Divide two and truncate towards zero. + + throws an exception if *n* is zero. + + Parameters: + + n - The number to divide *this* by. Will be converted to a . + + Returns: + + The *this* / *n*, truncated to an integer. + + See Also: + + , , , , +*/ +BigInteger.prototype.quotient = function(n) { + return this.divRem(n)[0]; +}; + +/* + Function: divide + Deprecated synonym for . +*/ +BigInteger.prototype.divide = BigInteger.prototype.quotient; + +/* + Function: remainder + Calculate the remainder of two . + + throws an exception if *n* is zero. + + Parameters: + + n - The remainder after *this* is divided *this* by *n*. Will be + converted to a . + + Returns: + + *this* % *n*. + + See Also: + + , +*/ +BigInteger.prototype.remainder = function(n) { + return this.divRem(n)[1]; +}; + +/* + Function: divRem + Calculate the integer quotient and remainder of two . + + throws an exception if *n* is zero. + + Parameters: + + n - The number to divide *this* by. Will be converted to a . + + Returns: + + A two-element array containing the quotient and the remainder. + + > a.divRem(b) + + is exactly equivalent to + + > [a.quotient(b), a.remainder(b)] + + except it is faster, because they are calculated at the same time. + + See Also: + + , +*/ +BigInteger.prototype.divRem = function(n) { + n = BigInteger(n); + if (n._s === 0) { + throw new Error("Divide by zero"); + } + if (this._s === 0) { + return [ZERO, ZERO]; + } + if (n._d.length === 1) { + return this.divRemSmall(n._s * n._d[0]); + } + + // Test for easy cases -- |n1| <= |n2| + switch (this.compareAbs(n)) { + case 0: // n1 == n2 + return [this._s === n._s ? ONE : M_ONE, ZERO]; + case -1: // |n1| < |n2| + return [ZERO, this]; + } + + var sign = this._s * n._s; + var a = n.abs(); + var b_digits = this._d; + var b_index = b_digits.length; + var digits = n._d.length; + var quot = []; + var guess; + + var part = new BigInteger([], 0, CONSTRUCT); + + while (b_index) { + part._d.unshift(b_digits[--b_index]); + part = new BigInteger(part._d, 1, CONSTRUCT); + + if (part.compareAbs(n) < 0) { + quot.push(0); + continue; + } + if (part._s === 0) { + guess = 0; + } + else { + var xlen = part._d.length, ylen = a._d.length; + var highx = part._d[xlen-1]*BigInteger_base + part._d[xlen-2]; + var highy = a._d[ylen-1]*BigInteger_base + a._d[ylen-2]; + if (part._d.length > a._d.length) { + // The length of part._d can either match a._d length, + // or exceed it by one. + highx = (highx+1)*BigInteger_base; + } + guess = Math.ceil(highx/highy); + } + do { + var check = a.multiplySingleDigit(guess); + if (check.compareAbs(part) <= 0) { + break; + } + guess--; + } while (guess); + + quot.push(guess); + if (!guess) { + continue; + } + var diff = part.subtract(check); + part._d = diff._d.slice(); + } + + return [new BigInteger(quot.reverse(), sign, CONSTRUCT), + new BigInteger(part._d, this._s, CONSTRUCT)]; +}; + +// Throws an exception if n is outside of (-BigInteger.base, -1] or +// [1, BigInteger.base). It's not necessary to call this, since the +// other division functions will call it if they are able to. +BigInteger.prototype.divRemSmall = function(n) { + var r; + n = +n; + if (n === 0) { + throw new Error("Divide by zero"); + } + + var n_s = n < 0 ? -1 : 1; + var sign = this._s * n_s; + n = Math.abs(n); + + if (n < 1 || n >= BigInteger_base) { + throw new Error("Argument out of range"); + } + + if (this._s === 0) { + return [ZERO, ZERO]; + } + + if (n === 1 || n === -1) { + return [(sign === 1) ? this.abs() : new BigInteger(this._d, sign, CONSTRUCT), ZERO]; + } + + // 2 <= n < BigInteger_base + + // divide a single digit by a single digit + if (this._d.length === 1) { + var q = new BigInteger([(this._d[0] / n) | 0], 1, CONSTRUCT); + r = new BigInteger([(this._d[0] % n) | 0], 1, CONSTRUCT); + if (sign < 0) { + q = q.negate(); + } + if (this._s < 0) { + r = r.negate(); + } + return [q, r]; + } + + var digits = this._d.slice(); + var quot = new Array(digits.length); + var part = 0; + var diff = 0; + var i = 0; + var guess; + + while (digits.length) { + part = part * BigInteger_base + digits[digits.length - 1]; + if (part < n) { + quot[i++] = 0; + digits.pop(); + diff = BigInteger_base * diff + part; + continue; + } + if (part === 0) { + guess = 0; + } + else { + guess = (part / n) | 0; + } + + var check = n * guess; + diff = part - check; + quot[i++] = guess; + if (!guess) { + digits.pop(); + continue; + } + + digits.pop(); + part = diff; + } + + r = new BigInteger([diff], 1, CONSTRUCT); + if (this._s < 0) { + r = r.negate(); + } + return [new BigInteger(quot.reverse(), sign, CONSTRUCT), r]; +}; + +/* + Function: isEven + Return true iff *this* is divisible by two. + + Note that is even. + + Returns: + + true if *this* is even, false otherwise. + + See Also: + + +*/ +BigInteger.prototype.isEven = function() { + var digits = this._d; + return this._s === 0 || digits.length === 0 || (digits[0] % 2) === 0; +}; + +/* + Function: isOdd + Return true iff *this* is not divisible by two. + + Returns: + + true if *this* is odd, false otherwise. + + See Also: + + +*/ +BigInteger.prototype.isOdd = function() { + return !this.isEven(); +}; + +/* + Function: sign + Get the sign of a . + + Returns: + + * -1 if *this* < 0 + * 0 if *this* == 0 + * +1 if *this* > 0 + + See Also: + + , , , , +*/ +BigInteger.prototype.sign = function() { + return this._s; +}; + +/* + Function: isPositive + Return true iff *this* > 0. + + Returns: + + true if *this*.compare() == 1. + + See Also: + + , , , , , +*/ +BigInteger.prototype.isPositive = function() { + return this._s > 0; +}; + +/* + Function: isNegative + Return true iff *this* < 0. + + Returns: + + true if *this*.compare() == -1. + + See Also: + + , , , , , +*/ +BigInteger.prototype.isNegative = function() { + return this._s < 0; +}; + +/* + Function: isZero + Return true iff *this* == 0. + + Returns: + + true if *this*.compare() == 0. + + See Also: + + , , , , +*/ +BigInteger.prototype.isZero = function() { + return this._s === 0; +}; + +/* + Function: exp10 + Multiply a by a power of 10. + + This is equivalent to, but faster than + + > if (n >= 0) { + > return this.multiply(BigInteger("1e" + n)); + > } + > else { // n <= 0 + > return this.quotient(BigInteger("1e" + -n)); + > } + + Parameters: + + n - The power of 10 to multiply *this* by. *n* is converted to a + javascipt number and must be no greater than + (0x7FFFFFFF), or an exception will be thrown. + + Returns: + + *this* * (10 ** *n*), truncated to an integer if necessary. + + See Also: + + , +*/ +BigInteger.prototype.exp10 = function(n) { + n = +n; + if (n === 0) { + return this; + } + if (Math.abs(n) > Number(MAX_EXP)) { + throw new Error("exponent too large in BigInteger.exp10"); + } + // Optimization for this == 0. This also keeps us from having to trim zeros in the positive n case + if (this._s === 0) { + return ZERO; + } + if (n > 0) { + var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT); + + for (; n >= BigInteger_base_log10; n -= BigInteger_base_log10) { + k._d.unshift(0); + } + if (n == 0) + return k; + k._s = 1; + k = k.multiplySingleDigit(Math.pow(10, n)); + return (this._s < 0 ? k.negate() : k); + } else if (-n >= this._d.length*BigInteger_base_log10) { + return ZERO; + } else { + var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT); + + for (n = -n; n >= BigInteger_base_log10; n -= BigInteger_base_log10) { + k._d.shift(); + } + return (n == 0) ? k : k.divRemSmall(Math.pow(10, n))[0]; + } +}; + +/* + Function: pow + Raise a to a power. + + In this implementation, 0**0 is 1. + + Parameters: + + n - The exponent to raise *this* by. *n* must be no greater than + (0x7FFFFFFF), or an exception will be thrown. + + Returns: + + *this* raised to the *nth* power. + + See Also: + + +*/ +BigInteger.prototype.pow = function(n) { + if (this.isUnit()) { + if (this._s > 0) { + return this; + } + else { + return BigInteger(n).isOdd() ? this : this.negate(); + } + } + + n = BigInteger(n); + if (n._s === 0) { + return ONE; + } + else if (n._s < 0) { + if (this._s === 0) { + throw new Error("Divide by zero"); + } + else { + return ZERO; + } + } + if (this._s === 0) { + return ZERO; + } + if (n.isUnit()) { + return this; + } + + if (n.compareAbs(MAX_EXP) > 0) { + throw new Error("exponent too large in BigInteger.pow"); + } + var x = this; + var aux = ONE; + var two = BigInteger.small[2]; + + while (n.isPositive()) { + if (n.isOdd()) { + aux = aux.multiply(x); + if (n.isUnit()) { + return aux; + } + } + x = x.square(); + n = n.quotient(two); + } + + return aux; +}; + +/* + Function: modPow + Raise a to a power (mod m). + + Because it is reduced by a modulus, is not limited by + like . + + Parameters: + + exponent - The exponent to raise *this* by. Must be positive. + modulus - The modulus. + + Returns: + + *this* ^ *exponent* (mod *modulus*). + + See Also: + + , +*/ +BigInteger.prototype.modPow = function(exponent, modulus) { + var result = ONE; + var base = this; + + while (exponent.isPositive()) { + if (exponent.isOdd()) { + result = result.multiply(base).remainder(modulus); + } + + exponent = exponent.quotient(BigInteger.small[2]); + if (exponent.isPositive()) { + base = base.square().remainder(modulus); + } + } + + return result; +}; + +/* + Function: log + Get the natural logarithm of a as a native JavaScript number. + + This is equivalent to + + > Math.log(this.toJSValue()) + + but handles values outside of the native number range. + + Returns: + + log( *this* ) + + See Also: + + +*/ +BigInteger.prototype.log = function() { + switch (this._s) { + case 0: return -Infinity; + case -1: return NaN; + default: // Fall through. + } + + var l = this._d.length; + + if (l*BigInteger_base_log10 < 30) { + return Math.log(this.valueOf()); + } + + var N = Math.ceil(30/BigInteger_base_log10); + var firstNdigits = this._d.slice(l - N); + return Math.log((new BigInteger(firstNdigits, 1, CONSTRUCT)).valueOf()) + (l - N) * Math.log(BigInteger_base); +}; + +/* + Function: valueOf + Convert a to a native JavaScript integer. + + This is called automatically by JavaScipt to convert a to a + native value. + + Returns: + + > parseInt(this.toString(), 10) + + See Also: + + , +*/ +BigInteger.prototype.valueOf = function() { + return parseInt(this.toString(), 10); +}; + +/* + Function: toJSValue + Convert a to a native JavaScript integer. + + This is the same as valueOf, but more explicitly named. + + Returns: + + > parseInt(this.toString(), 10) + + See Also: + + , +*/ +BigInteger.prototype.toJSValue = function() { + return parseInt(this.toString(), 10); +}; + +var MAX_EXP = BigInteger(0x7FFFFFFF); +// Constant: MAX_EXP +// The largest exponent allowed in and (0x7FFFFFFF or 2147483647). +BigInteger.MAX_EXP = MAX_EXP; + +(function() { + function makeUnary(fn) { + return function(a) { + return fn.call(BigInteger(a)); + }; + } + + function makeBinary(fn) { + return function(a, b) { + return fn.call(BigInteger(a), BigInteger(b)); + }; + } + + function makeTrinary(fn) { + return function(a, b, c) { + return fn.call(BigInteger(a), BigInteger(b), BigInteger(c)); + }; + } + + (function() { + var i, fn; + var unary = "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(","); + var binary = "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(","); + var trinary = ["modPow"]; + + for (i = 0; i < unary.length; i++) { + fn = unary[i]; + BigInteger[fn] = makeUnary(BigInteger.prototype[fn]); + } + + for (i = 0; i < binary.length; i++) { + fn = binary[i]; + BigInteger[fn] = makeBinary(BigInteger.prototype[fn]); + } + + for (i = 0; i < trinary.length; i++) { + fn = trinary[i]; + BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]); + } + + BigInteger.exp10 = function(x, n) { + return BigInteger(x).exp10(n); + }; + })(); +})(); + +exports.BigInteger = BigInteger; +})(typeof exports !== 'undefined' ? exports : this); diff --git a/frontend/gamma/js/Clipperz/Crypto/biginteger.js b/frontend/gamma/js/Clipperz/Crypto/biginteger.js new file mode 100644 index 0000000..3f56d18 --- /dev/null +++ b/frontend/gamma/js/Clipperz/Crypto/biginteger.js @@ -0,0 +1,1620 @@ +/* + JavaScript BigInteger library version 0.9.1 + http://silentmatt.com/biginteger/ + + Copyright (c) 2009 Matthew Crumley + Copyright (c) 2010,2011 by John Tobey + Licensed under the MIT license. + + Support for arbitrary internal representation base was added by + Vitaly Magerya. +*/ + +/* + File: biginteger.js + + Exports: + + +*/ +(function(exports) { +"use strict"; +/* + Class: BigInteger + An arbitrarily-large integer. + + objects should be considered immutable. None of the "built-in" + methods modify *this* or their arguments. All properties should be + considered private. + + All the methods of instances can be called "statically". The + static versions are convenient if you don't already have a + object. + + As an example, these calls are equivalent. + + > BigInteger(4).multiply(5); // returns BigInteger(20); + > BigInteger.multiply(4, 5); // returns BigInteger(20); + + > var a = 42; + > var a = BigInteger.toJSValue("0b101010"); // Not completely useless... +*/ + +var CONSTRUCT = {}; // Unique token to call "private" version of constructor + +/* + Constructor: BigInteger() + Convert a value to a . + + Although is the constructor for objects, it is + best not to call it as a constructor. If *n* is a object, it is + simply returned as-is. Otherwise, is equivalent to + without a radix argument. + + > var n0 = BigInteger(); // Same as + > var n1 = BigInteger("123"); // Create a new with value 123 + > var n2 = BigInteger(123); // Create a new with value 123 + > var n3 = BigInteger(n2); // Return n2, unchanged + + The constructor form only takes an array and a sign. *n* must be an + array of numbers in little-endian order, where each digit is between 0 + and BigInteger.base. The second parameter sets the sign: -1 for + negative, +1 for positive, or 0 for zero. The array is *not copied and + may be modified*. If the array contains only zeros, the sign parameter + is ignored and is forced to zero. + + > new BigInteger([5], -1): create a new BigInteger with value -5 + + Parameters: + + n - Value to convert to a . + + Returns: + + A value. + + See Also: + + , +*/ +function BigInteger(n, s, token) { + if (token !== CONSTRUCT) { + if (n instanceof BigInteger) { + return n; + } + else if (typeof n === "undefined") { + return ZERO; + } + return BigInteger.parse(n); + } + + n = n || []; // Provide the nullary constructor for subclasses. + while (n.length && !n[n.length - 1]) { + --n.length; + } + this._d = n; + this._s = n.length ? (s || 1) : 0; +} + +BigInteger._construct = function(n, s) { + return new BigInteger(n, s, CONSTRUCT); +}; + +// Base-10 speedup hacks in parse, toString, exp10 and log functions +// require base to be a power of 10. 10^7 is the largest such power +// that won't cause a precision loss when digits are multiplied. +var BigInteger_base = 10000000; +var BigInteger_base_log10 = 7; + +BigInteger.base = BigInteger_base; +BigInteger.base_log10 = BigInteger_base_log10; + +var ZERO = new BigInteger([], 0, CONSTRUCT); +// Constant: ZERO +// 0. +BigInteger.ZERO = ZERO; + +var ONE = new BigInteger([1], 1, CONSTRUCT); +// Constant: ONE +// 1. +BigInteger.ONE = ONE; + +var M_ONE = new BigInteger(ONE._d, -1, CONSTRUCT); +// Constant: M_ONE +// -1. +BigInteger.M_ONE = M_ONE; + +// Constant: _0 +// Shortcut for . +BigInteger._0 = ZERO; + +// Constant: _1 +// Shortcut for . +BigInteger._1 = ONE; + +/* + Constant: small + Array of from 0 to 36. + + These are used internally for parsing, but useful when you need a "small" + . + + See Also: + + , , <_0>, <_1> +*/ +BigInteger.small = [ + ZERO, + ONE, + /* Assuming BigInteger_base > 36 */ + new BigInteger( [2], 1, CONSTRUCT), + new BigInteger( [3], 1, CONSTRUCT), + new BigInteger( [4], 1, CONSTRUCT), + new BigInteger( [5], 1, CONSTRUCT), + new BigInteger( [6], 1, CONSTRUCT), + new BigInteger( [7], 1, CONSTRUCT), + new BigInteger( [8], 1, CONSTRUCT), + new BigInteger( [9], 1, CONSTRUCT), + new BigInteger([10], 1, CONSTRUCT), + new BigInteger([11], 1, CONSTRUCT), + new BigInteger([12], 1, CONSTRUCT), + new BigInteger([13], 1, CONSTRUCT), + new BigInteger([14], 1, CONSTRUCT), + new BigInteger([15], 1, CONSTRUCT), + new BigInteger([16], 1, CONSTRUCT), + new BigInteger([17], 1, CONSTRUCT), + new BigInteger([18], 1, CONSTRUCT), + new BigInteger([19], 1, CONSTRUCT), + new BigInteger([20], 1, CONSTRUCT), + new BigInteger([21], 1, CONSTRUCT), + new BigInteger([22], 1, CONSTRUCT), + new BigInteger([23], 1, CONSTRUCT), + new BigInteger([24], 1, CONSTRUCT), + new BigInteger([25], 1, CONSTRUCT), + new BigInteger([26], 1, CONSTRUCT), + new BigInteger([27], 1, CONSTRUCT), + new BigInteger([28], 1, CONSTRUCT), + new BigInteger([29], 1, CONSTRUCT), + new BigInteger([30], 1, CONSTRUCT), + new BigInteger([31], 1, CONSTRUCT), + new BigInteger([32], 1, CONSTRUCT), + new BigInteger([33], 1, CONSTRUCT), + new BigInteger([34], 1, CONSTRUCT), + new BigInteger([35], 1, CONSTRUCT), + new BigInteger([36], 1, CONSTRUCT) +]; + +// Used for parsing/radix conversion +BigInteger.digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); + +/* + Method: toString + Convert a to a string. + + When *base* is greater than 10, letters are upper case. + + Parameters: + + base - Optional base to represent the number in (default is base 10). + Must be between 2 and 36 inclusive, or an Error will be thrown. + + Returns: + + The string representation of the . +*/ +BigInteger.prototype.toString = function(base) { + base = +base || 10; + if (base < 2 || base > 36) { + throw new Error("illegal radix " + base + "."); + } + if (this._s === 0) { + return "0"; + } + if (base === 10) { + var str = this._s < 0 ? "-" : ""; + str += this._d[this._d.length - 1].toString(); + for (var i = this._d.length - 2; i >= 0; i--) { + var group = this._d[i].toString(); + while (group.length < BigInteger_base_log10) group = '0' + group; + str += group; + } + return str; + } + else { + var numerals = BigInteger.digits; + base = BigInteger.small[base]; + var sign = this._s; + + var n = this.abs(); + var digits = []; + var digit; + + while (n._s !== 0) { + var divmod = n.divRem(base); + n = divmod[0]; + digit = divmod[1]; + // TODO: This could be changed to unshift instead of reversing at the end. + // Benchmark both to compare speeds. + digits.push(numerals[digit.valueOf()]); + } + return (sign < 0 ? "-" : "") + digits.reverse().join(""); + } +}; + +// Verify strings for parsing +BigInteger.radixRegex = [ + /^$/, + /^$/, + /^[01]*$/, + /^[012]*$/, + /^[0-3]*$/, + /^[0-4]*$/, + /^[0-5]*$/, + /^[0-6]*$/, + /^[0-7]*$/, + /^[0-8]*$/, + /^[0-9]*$/, + /^[0-9aA]*$/, + /^[0-9abAB]*$/, + /^[0-9abcABC]*$/, + /^[0-9a-dA-D]*$/, + /^[0-9a-eA-E]*$/, + /^[0-9a-fA-F]*$/, + /^[0-9a-gA-G]*$/, + /^[0-9a-hA-H]*$/, + /^[0-9a-iA-I]*$/, + /^[0-9a-jA-J]*$/, + /^[0-9a-kA-K]*$/, + /^[0-9a-lA-L]*$/, + /^[0-9a-mA-M]*$/, + /^[0-9a-nA-N]*$/, + /^[0-9a-oA-O]*$/, + /^[0-9a-pA-P]*$/, + /^[0-9a-qA-Q]*$/, + /^[0-9a-rA-R]*$/, + /^[0-9a-sA-S]*$/, + /^[0-9a-tA-T]*$/, + /^[0-9a-uA-U]*$/, + /^[0-9a-vA-V]*$/, + /^[0-9a-wA-W]*$/, + /^[0-9a-xA-X]*$/, + /^[0-9a-yA-Y]*$/, + /^[0-9a-zA-Z]*$/ +]; + +/* + Function: parse + Parse a string into a . + + *base* is optional but, if provided, must be from 2 to 36 inclusive. If + *base* is not provided, it will be guessed based on the leading characters + of *s* as follows: + + - "0x" or "0X": *base* = 16 + - "0c" or "0C": *base* = 8 + - "0b" or "0B": *base* = 2 + - else: *base* = 10 + + If no base is provided, or *base* is 10, the number can be in exponential + form. For example, these are all valid: + + > BigInteger.parse("1e9"); // Same as "1000000000" + > BigInteger.parse("1.234*10^3"); // Same as 1234 + > BigInteger.parse("56789 * 10 ** -2"); // Same as 567 + + If any characters fall outside the range defined by the radix, an exception + will be thrown. + + Parameters: + + s - The string to parse. + base - Optional radix (default is to guess based on *s*). + + Returns: + + a instance. +*/ +BigInteger.parse = function(s, base) { + // Expands a number in exponential form to decimal form. + // expandExponential("-13.441*10^5") === "1344100"; + // expandExponential("1.12300e-1") === "0.112300"; + // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000"; + function expandExponential(str) { + str = str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e"); + + return str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function(x, s, n, f, c) { + c = +c; + var l = c < 0; + var i = n.length + c; + x = (l ? n : f).length; + c = ((c = Math.abs(c)) >= x ? c - x + l : 0); + var z = (new Array(c + 1)).join("0"); + var r = n + f; + return (s || "") + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : ""); + }); + } + + s = s.toString(); + if (typeof base === "undefined" || +base === 10) { + s = expandExponential(s); + } + + var prefixRE; + if (typeof base === "undefined") { + prefixRE = '0[xcb]'; + } + else if (base == 16) { + prefixRE = '0x'; + } + else if (base == 8) { + prefixRE = '0c'; + } + else if (base == 2) { + prefixRE = '0b'; + } + else { + prefixRE = ''; + } + var parts = new RegExp('^([+\\-]?)(' + prefixRE + ')?([0-9a-z]*)(?:\\.\\d*)?$', 'i').exec(s); + if (parts) { + var sign = parts[1] || "+"; + var baseSection = parts[2] || ""; + var digits = parts[3] || ""; + + if (typeof base === "undefined") { + // Guess base + if (baseSection === "0x" || baseSection === "0X") { // Hex + base = 16; + } + else if (baseSection === "0c" || baseSection === "0C") { // Octal + base = 8; + } + else if (baseSection === "0b" || baseSection === "0B") { // Binary + base = 2; + } + else { + base = 10; + } + } + else if (base < 2 || base > 36) { + throw new Error("Illegal radix " + base + "."); + } + + base = +base; + + // Check for digits outside the range + if (!(BigInteger.radixRegex[base].test(digits))) { + throw new Error("Bad digit for radix " + base); + } + + // Strip leading zeros, and convert to array + digits = digits.replace(/^0+/, "").split(""); + if (digits.length === 0) { + return ZERO; + } + + // Get the sign (we know it's not zero) + sign = (sign === "-") ? -1 : 1; + + // Optimize 10 + if (base == 10) { + var d = []; + while (digits.length >= BigInteger_base_log10) { + d.push(parseInt(digits.splice(digits.length-BigInteger.base_log10, BigInteger.base_log10).join(''), 10)); + } + d.push(parseInt(digits.join(''), 10)); + return new BigInteger(d, sign, CONSTRUCT); + } + + // Do the conversion + var d = ZERO; + base = BigInteger.small[base]; + var small = BigInteger.small; + for (var i = 0; i < digits.length; i++) { + d = d.multiply(base).add(small[parseInt(digits[i], 36)]); + } + return new BigInteger(d._d, sign, CONSTRUCT); + } + else { + throw new Error("Invalid BigInteger format: " + s); + } +}; + +/* + Function: add + Add two . + + Parameters: + + n - The number to add to *this*. Will be converted to a . + + Returns: + + The numbers added together. + + See Also: + + , , , +*/ +BigInteger.prototype.add = function(n) { + if (this._s === 0) { + return BigInteger(n); + } + + n = BigInteger(n); + if (n._s === 0) { + return this; + } + if (this._s !== n._s) { + n = n.negate(); + return this.subtract(n); + } + + var a = this._d; + var b = n._d; + var al = a.length; + var bl = b.length; + var sum = new Array(Math.max(al, bl) + 1); + var size = Math.min(al, bl); + var carry = 0; + var digit; + + for (var i = 0; i < size; i++) { + digit = a[i] + b[i] + carry; + sum[i] = digit % BigInteger_base; + carry = (digit / BigInteger_base) | 0; + } + if (bl > al) { + a = b; + al = bl; + } + for (i = size; carry && i < al; i++) { + digit = a[i] + carry; + sum[i] = digit % BigInteger_base; + carry = (digit / BigInteger_base) | 0; + } + if (carry) { + sum[i] = carry; + } + + for ( ; i < al; i++) { + sum[i] = a[i]; + } + + return new BigInteger(sum, this._s, CONSTRUCT); +}; + +/* + Function: negate + Get the additive inverse of a . + + Returns: + + A with the same magnatude, but with the opposite sign. + + See Also: + + +*/ +BigInteger.prototype.negate = function() { + return new BigInteger(this._d, (-this._s) | 0, CONSTRUCT); +}; + +/* + Function: abs + Get the absolute value of a . + + Returns: + + A with the same magnatude, but always positive (or zero). + + See Also: + + +*/ +BigInteger.prototype.abs = function() { + return (this._s < 0) ? this.negate() : this; +}; + +/* + Function: subtract + Subtract two . + + Parameters: + + n - The number to subtract from *this*. Will be converted to a . + + Returns: + + The *n* subtracted from *this*. + + See Also: + + , , , +*/ +BigInteger.prototype.subtract = function(n) { + if (this._s === 0) { + return BigInteger(n).negate(); + } + + n = BigInteger(n); + if (n._s === 0) { + return this; + } + if (this._s !== n._s) { + n = n.negate(); + return this.add(n); + } + + var m = this; + // negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a| + if (this._s < 0) { + m = new BigInteger(n._d, 1, CONSTRUCT); + n = new BigInteger(this._d, 1, CONSTRUCT); + } + + // Both are positive => a - b + var sign = m.compareAbs(n); + if (sign === 0) { + return ZERO; + } + else if (sign < 0) { + // swap m and n + var t = n; + n = m; + m = t; + } + + // a > b + var a = m._d; + var b = n._d; + var al = a.length; + var bl = b.length; + var diff = new Array(al); // al >= bl since a > b + var borrow = 0; + var i; + var digit; + + for (i = 0; i < bl; i++) { + digit = a[i] - borrow - b[i]; + if (digit < 0) { + digit += BigInteger_base; + borrow = 1; + } + else { + borrow = 0; + } + diff[i] = digit; + } + for (i = bl; i < al; i++) { + digit = a[i] - borrow; + if (digit < 0) { + digit += BigInteger_base; + } + else { + diff[i++] = digit; + break; + } + diff[i] = digit; + } + for ( ; i < al; i++) { + diff[i] = a[i]; + } + + return new BigInteger(diff, sign, CONSTRUCT); +}; + +(function() { + function addOne(n, sign) { + var a = n._d; + var sum = a.slice(); + var carry = true; + var i = 0; + + while (true) { + var digit = (a[i] || 0) + 1; + sum[i] = digit % BigInteger_base; + if (digit <= BigInteger_base - 1) { + break; + } + ++i; + } + + return new BigInteger(sum, sign, CONSTRUCT); + } + + function subtractOne(n, sign) { + var a = n._d; + var sum = a.slice(); + var borrow = true; + var i = 0; + + while (true) { + var digit = (a[i] || 0) - 1; + if (digit < 0) { + sum[i] = digit + BigInteger_base; + } + else { + sum[i] = digit; + break; + } + ++i; + } + + return new BigInteger(sum, sign, CONSTRUCT); + } + + /* + Function: next + Get the next (add one). + + Returns: + + *this* + 1. + + See Also: + + , + */ + BigInteger.prototype.next = function() { + switch (this._s) { + case 0: + return ONE; + case -1: + return subtractOne(this, -1); + // case 1: + default: + return addOne(this, 1); + } + }; + + /* + Function: prev + Get the previous (subtract one). + + Returns: + + *this* - 1. + + See Also: + + , + */ + BigInteger.prototype.prev = function() { + switch (this._s) { + case 0: + return M_ONE; + case -1: + return addOne(this, -1); + // case 1: + default: + return subtractOne(this, 1); + } + }; +})(); + +/* + Function: compareAbs + Compare the absolute value of two . + + Calling is faster than calling twice, then . + + Parameters: + + n - The number to compare to *this*. Will be converted to a . + + Returns: + + -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*. + + See Also: + + , +*/ +BigInteger.prototype.compareAbs = function(n) { + if (this === n) { + return 0; + } + + if (!(n instanceof BigInteger)) { + if (!isFinite(n)) { + return(isNaN(n) ? n : -1); + } + n = BigInteger(n); + } + + if (this._s === 0) { + return (n._s !== 0) ? -1 : 0; + } + if (n._s === 0) { + return 1; + } + + var l = this._d.length; + var nl = n._d.length; + if (l < nl) { + return -1; + } + else if (l > nl) { + return 1; + } + + var a = this._d; + var b = n._d; + for (var i = l-1; i >= 0; i--) { + if (a[i] !== b[i]) { + return a[i] < b[i] ? -1 : 1; + } + } + + return 0; +}; + +/* + Function: compare + Compare two . + + Parameters: + + n - The number to compare to *this*. Will be converted to a . + + Returns: + + -1, 0, or +1 if *this* is less than, equal to, or greater than *n*. + + See Also: + + , , , +*/ +BigInteger.prototype.compare = function(n) { + if (this === n) { + return 0; + } + + n = BigInteger(n); + + if (this._s === 0) { + return -n._s; + } + + if (this._s === n._s) { // both positive or both negative + var cmp = this.compareAbs(n); + return cmp * this._s; + } + else { + return this._s; + } +}; + +/* + Function: isUnit + Return true iff *this* is either 1 or -1. + + Returns: + + true if *this* compares equal to or . + + See Also: + + , , , , , + , +*/ +BigInteger.prototype.isUnit = function() { + return this === ONE || + this === M_ONE || + (this._d.length === 1 && this._d[0] === 1); +}; + +/* + Function: multiply + Multiply two . + + Parameters: + + n - The number to multiply *this* by. Will be converted to a + . + + Returns: + + The numbers multiplied together. + + See Also: + + , , , +*/ +BigInteger.prototype.multiply = function(n) { + // TODO: Consider adding Karatsuba multiplication for large numbers + if (this._s === 0) { + return ZERO; + } + + n = BigInteger(n); + if (n._s === 0) { + return ZERO; + } + if (this.isUnit()) { + if (this._s < 0) { + return n.negate(); + } + return n; + } + if (n.isUnit()) { + if (n._s < 0) { + return this.negate(); + } + return this; + } + if (this === n) { + return this.square(); + } + + var r = (this._d.length >= n._d.length); + var a = (r ? this : n)._d; // a will be longer than b + var b = (r ? n : this)._d; + var al = a.length; + var bl = b.length; + + var pl = al + bl; + var partial = new Array(pl); + var i; + for (i = 0; i < pl; i++) { + partial[i] = 0; + } + + for (i = 0; i < bl; i++) { + var carry = 0; + var bi = b[i]; + var jlimit = al + i; + var digit; + for (var j = i; j < jlimit; j++) { + digit = partial[j] + bi * a[j - i] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = (digit % BigInteger_base) | 0; + } + if (carry) { + digit = partial[j] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = digit % BigInteger_base; + } + } + return new BigInteger(partial, this._s * n._s, CONSTRUCT); +}; + +// Multiply a BigInteger by a single-digit native number +// Assumes that this and n are >= 0 +// This is not really intended to be used outside the library itself +BigInteger.prototype.multiplySingleDigit = function(n) { + if (n === 0 || this._s === 0) { + return ZERO; + } + if (n === 1) { + return this; + } + + var digit; + if (this._d.length === 1) { + digit = this._d[0] * n; + if (digit >= BigInteger_base) { + return new BigInteger([(digit % BigInteger_base)|0, + (digit / BigInteger_base)|0], 1, CONSTRUCT); + } + return new BigInteger([digit], 1, CONSTRUCT); + } + + if (n === 2) { + return this.add(this); + } + if (this.isUnit()) { + return new BigInteger([n], 1, CONSTRUCT); + } + + var a = this._d; + var al = a.length; + + var pl = al + 1; + var partial = new Array(pl); + for (var i = 0; i < pl; i++) { + partial[i] = 0; + } + + var carry = 0; + for (var j = 0; j < al; j++) { + digit = n * a[j] + carry; + carry = (digit / BigInteger_base) | 0; + partial[j] = (digit % BigInteger_base) | 0; + } + if (carry) { + partial[j] = carry; + } + + return new BigInteger(partial, 1, CONSTRUCT); +}; + +/* + Function: square + Multiply a by itself. + + This is slightly faster than regular multiplication, since it removes the + duplicated multiplcations. + + Returns: + + > this.multiply(this) + + See Also: + +*/ +BigInteger.prototype.square = function() { + // Normally, squaring a 10-digit number would take 100 multiplications. + // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated. + // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies). + // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org + + if (this._s === 0) { + return ZERO; + } + if (this.isUnit()) { + return ONE; + } + + var digits = this._d; + var length = digits.length; + var imult1 = new Array(length + length + 1); + var product, carry, k; + var i; + + // Calculate diagonal + for (i = 0; i < length; i++) { + k = i * 2; + product = digits[i] * digits[i]; + carry = (product / BigInteger_base) | 0; + imult1[k] = product % BigInteger_base; + imult1[k + 1] = carry; + } + + // Calculate repeating part + for (i = 0; i < length; i++) { + carry = 0; + k = i * 2 + 1; + for (var j = i + 1; j < length; j++, k++) { + product = digits[j] * digits[i] * 2 + imult1[k] + carry; + carry = (product / BigInteger_base) | 0; + imult1[k] = product % BigInteger_base; + } + k = length + i; + var digit = carry + imult1[k]; + carry = (digit / BigInteger_base) | 0; + imult1[k] = digit % BigInteger_base; + imult1[k + 1] += carry; + } + + return new BigInteger(imult1, 1, CONSTRUCT); +}; + +/* + Function: quotient + Divide two and truncate towards zero. + + throws an exception if *n* is zero. + + Parameters: + + n - The number to divide *this* by. Will be converted to a . + + Returns: + + The *this* / *n*, truncated to an integer. + + See Also: + + , , , , +*/ +BigInteger.prototype.quotient = function(n) { + return this.divRem(n)[0]; +}; + +/* + Function: divide + Deprecated synonym for . +*/ +BigInteger.prototype.divide = BigInteger.prototype.quotient; + +/* + Function: remainder + Calculate the remainder of two . + + throws an exception if *n* is zero. + + Parameters: + + n - The remainder after *this* is divided *this* by *n*. Will be + converted to a . + + Returns: + + *this* % *n*. + + See Also: + + , +*/ +BigInteger.prototype.remainder = function(n) { + return this.divRem(n)[1]; +}; + +/* + Function: divRem + Calculate the integer quotient and remainder of two . + + throws an exception if *n* is zero. + + Parameters: + + n - The number to divide *this* by. Will be converted to a . + + Returns: + + A two-element array containing the quotient and the remainder. + + > a.divRem(b) + + is exactly equivalent to + + > [a.quotient(b), a.remainder(b)] + + except it is faster, because they are calculated at the same time. + + See Also: + + , +*/ +BigInteger.prototype.divRem = function(n) { + n = BigInteger(n); + if (n._s === 0) { + throw new Error("Divide by zero"); + } + if (this._s === 0) { + return [ZERO, ZERO]; + } + if (n._d.length === 1) { + return this.divRemSmall(n._s * n._d[0]); + } + + // Test for easy cases -- |n1| <= |n2| + switch (this.compareAbs(n)) { + case 0: // n1 == n2 + return [this._s === n._s ? ONE : M_ONE, ZERO]; + case -1: // |n1| < |n2| + return [ZERO, this]; + } + + var sign = this._s * n._s; + var a = n.abs(); + var b_digits = this._d; + var b_index = b_digits.length; + var digits = n._d.length; + var quot = []; + var guess; + + var part = new BigInteger([], 0, CONSTRUCT); + + while (b_index) { + part._d.unshift(b_digits[--b_index]); + part = new BigInteger(part._d, 1, CONSTRUCT); + + if (part.compareAbs(n) < 0) { + quot.push(0); + continue; + } + if (part._s === 0) { + guess = 0; + } + else { + var xlen = part._d.length, ylen = a._d.length; + var highx = part._d[xlen-1]*BigInteger_base + part._d[xlen-2]; + var highy = a._d[ylen-1]*BigInteger_base + a._d[ylen-2]; + if (part._d.length > a._d.length) { + // The length of part._d can either match a._d length, + // or exceed it by one. + highx = (highx+1)*BigInteger_base; + } + guess = Math.ceil(highx/highy); + } + do { + var check = a.multiplySingleDigit(guess); + if (check.compareAbs(part) <= 0) { + break; + } + guess--; + } while (guess); + + quot.push(guess); + if (!guess) { + continue; + } + var diff = part.subtract(check); + part._d = diff._d.slice(); + } + + return [new BigInteger(quot.reverse(), sign, CONSTRUCT), + new BigInteger(part._d, this._s, CONSTRUCT)]; +}; + +// Throws an exception if n is outside of (-BigInteger.base, -1] or +// [1, BigInteger.base). It's not necessary to call this, since the +// other division functions will call it if they are able to. +BigInteger.prototype.divRemSmall = function(n) { + var r; + n = +n; + if (n === 0) { + throw new Error("Divide by zero"); + } + + var n_s = n < 0 ? -1 : 1; + var sign = this._s * n_s; + n = Math.abs(n); + + if (n < 1 || n >= BigInteger_base) { + throw new Error("Argument out of range"); + } + + if (this._s === 0) { + return [ZERO, ZERO]; + } + + if (n === 1 || n === -1) { + return [(sign === 1) ? this.abs() : new BigInteger(this._d, sign, CONSTRUCT), ZERO]; + } + + // 2 <= n < BigInteger_base + + // divide a single digit by a single digit + if (this._d.length === 1) { + var q = new BigInteger([(this._d[0] / n) | 0], 1, CONSTRUCT); + r = new BigInteger([(this._d[0] % n) | 0], 1, CONSTRUCT); + if (sign < 0) { + q = q.negate(); + } + if (this._s < 0) { + r = r.negate(); + } + return [q, r]; + } + + var digits = this._d.slice(); + var quot = new Array(digits.length); + var part = 0; + var diff = 0; + var i = 0; + var guess; + + while (digits.length) { + part = part * BigInteger_base + digits[digits.length - 1]; + if (part < n) { + quot[i++] = 0; + digits.pop(); + diff = BigInteger_base * diff + part; + continue; + } + if (part === 0) { + guess = 0; + } + else { + guess = (part / n) | 0; + } + + var check = n * guess; + diff = part - check; + quot[i++] = guess; + if (!guess) { + digits.pop(); + continue; + } + + digits.pop(); + part = diff; + } + + r = new BigInteger([diff], 1, CONSTRUCT); + if (this._s < 0) { + r = r.negate(); + } + return [new BigInteger(quot.reverse(), sign, CONSTRUCT), r]; +}; + +/* + Function: isEven + Return true iff *this* is divisible by two. + + Note that is even. + + Returns: + + true if *this* is even, false otherwise. + + See Also: + + +*/ +BigInteger.prototype.isEven = function() { + var digits = this._d; + return this._s === 0 || digits.length === 0 || (digits[0] % 2) === 0; +}; + +/* + Function: isOdd + Return true iff *this* is not divisible by two. + + Returns: + + true if *this* is odd, false otherwise. + + See Also: + + +*/ +BigInteger.prototype.isOdd = function() { + return !this.isEven(); +}; + +/* + Function: sign + Get the sign of a . + + Returns: + + * -1 if *this* < 0 + * 0 if *this* == 0 + * +1 if *this* > 0 + + See Also: + + , , , , +*/ +BigInteger.prototype.sign = function() { + return this._s; +}; + +/* + Function: isPositive + Return true iff *this* > 0. + + Returns: + + true if *this*.compare() == 1. + + See Also: + + , , , , , +*/ +BigInteger.prototype.isPositive = function() { + return this._s > 0; +}; + +/* + Function: isNegative + Return true iff *this* < 0. + + Returns: + + true if *this*.compare() == -1. + + See Also: + + , , , , , +*/ +BigInteger.prototype.isNegative = function() { + return this._s < 0; +}; + +/* + Function: isZero + Return true iff *this* == 0. + + Returns: + + true if *this*.compare() == 0. + + See Also: + + , , , , +*/ +BigInteger.prototype.isZero = function() { + return this._s === 0; +}; + +/* + Function: exp10 + Multiply a by a power of 10. + + This is equivalent to, but faster than + + > if (n >= 0) { + > return this.multiply(BigInteger("1e" + n)); + > } + > else { // n <= 0 + > return this.quotient(BigInteger("1e" + -n)); + > } + + Parameters: + + n - The power of 10 to multiply *this* by. *n* is converted to a + javascipt number and must be no greater than + (0x7FFFFFFF), or an exception will be thrown. + + Returns: + + *this* * (10 ** *n*), truncated to an integer if necessary. + + See Also: + + , +*/ +BigInteger.prototype.exp10 = function(n) { + n = +n; + if (n === 0) { + return this; + } + if (Math.abs(n) > Number(MAX_EXP)) { + throw new Error("exponent too large in BigInteger.exp10"); + } + // Optimization for this == 0. This also keeps us from having to trim zeros in the positive n case + if (this._s === 0) { + return ZERO; + } + if (n > 0) { + var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT); + + for (; n >= BigInteger_base_log10; n -= BigInteger_base_log10) { + k._d.unshift(0); + } + if (n == 0) + return k; + k._s = 1; + k = k.multiplySingleDigit(Math.pow(10, n)); + return (this._s < 0 ? k.negate() : k); + } else if (-n >= this._d.length*BigInteger_base_log10) { + return ZERO; + } else { + var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT); + + for (n = -n; n >= BigInteger_base_log10; n -= BigInteger_base_log10) { + k._d.shift(); + } + return (n == 0) ? k : k.divRemSmall(Math.pow(10, n))[0]; + } +}; + +/* + Function: pow + Raise a to a power. + + In this implementation, 0**0 is 1. + + Parameters: + + n - The exponent to raise *this* by. *n* must be no greater than + (0x7FFFFFFF), or an exception will be thrown. + + Returns: + + *this* raised to the *nth* power. + + See Also: + + +*/ +BigInteger.prototype.pow = function(n) { + if (this.isUnit()) { + if (this._s > 0) { + return this; + } + else { + return BigInteger(n).isOdd() ? this : this.negate(); + } + } + + n = BigInteger(n); + if (n._s === 0) { + return ONE; + } + else if (n._s < 0) { + if (this._s === 0) { + throw new Error("Divide by zero"); + } + else { + return ZERO; + } + } + if (this._s === 0) { + return ZERO; + } + if (n.isUnit()) { + return this; + } + + if (n.compareAbs(MAX_EXP) > 0) { + throw new Error("exponent too large in BigInteger.pow"); + } + var x = this; + var aux = ONE; + var two = BigInteger.small[2]; + + while (n.isPositive()) { + if (n.isOdd()) { + aux = aux.multiply(x); + if (n.isUnit()) { + return aux; + } + } + x = x.square(); + n = n.quotient(two); + } + + return aux; +}; + +/* + Function: modPow + Raise a to a power (mod m). + + Because it is reduced by a modulus, is not limited by + like . + + Parameters: + + exponent - The exponent to raise *this* by. Must be positive. + modulus - The modulus. + + Returns: + + *this* ^ *exponent* (mod *modulus*). + + See Also: + + , +*/ +BigInteger.prototype.modPow = function(exponent, modulus) { + var result = ONE; + var base = this; + + while (exponent.isPositive()) { + if (exponent.isOdd()) { + result = result.multiply(base).remainder(modulus); + } + + exponent = exponent.quotient(BigInteger.small[2]); + if (exponent.isPositive()) { + base = base.square().remainder(modulus); + } + } + + return result; +}; + +/* + Function: log + Get the natural logarithm of a as a native JavaScript number. + + This is equivalent to + + > Math.log(this.toJSValue()) + + but handles values outside of the native number range. + + Returns: + + log( *this* ) + + See Also: + + +*/ +BigInteger.prototype.log = function() { + switch (this._s) { + case 0: return -Infinity; + case -1: return NaN; + default: // Fall through. + } + + var l = this._d.length; + + if (l*BigInteger_base_log10 < 30) { + return Math.log(this.valueOf()); + } + + var N = Math.ceil(30/BigInteger_base_log10); + var firstNdigits = this._d.slice(l - N); + return Math.log((new BigInteger(firstNdigits, 1, CONSTRUCT)).valueOf()) + (l - N) * Math.log(BigInteger_base); +}; + +/* + Function: valueOf + Convert a to a native JavaScript integer. + + This is called automatically by JavaScipt to convert a to a + native value. + + Returns: + + > parseInt(this.toString(), 10) + + See Also: + + , +*/ +BigInteger.prototype.valueOf = function() { + return parseInt(this.toString(), 10); +}; + +/* + Function: toJSValue + Convert a to a native JavaScript integer. + + This is the same as valueOf, but more explicitly named. + + Returns: + + > parseInt(this.toString(), 10) + + See Also: + + , +*/ +BigInteger.prototype.toJSValue = function() { + return parseInt(this.toString(), 10); +}; + +var MAX_EXP = BigInteger(0x7FFFFFFF); +// Constant: MAX_EXP +// The largest exponent allowed in and (0x7FFFFFFF or 2147483647). +BigInteger.MAX_EXP = MAX_EXP; + +(function() { + function makeUnary(fn) { + return function(a) { + return fn.call(BigInteger(a)); + }; + } + + function makeBinary(fn) { + return function(a, b) { + return fn.call(BigInteger(a), BigInteger(b)); + }; + } + + function makeTrinary(fn) { + return function(a, b, c) { + return fn.call(BigInteger(a), BigInteger(b), BigInteger(c)); + }; + } + + (function() { + var i, fn; + var unary = "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(","); + var binary = "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(","); + var trinary = ["modPow"]; + + for (i = 0; i < unary.length; i++) { + fn = unary[i]; + BigInteger[fn] = makeUnary(BigInteger.prototype[fn]); + } + + for (i = 0; i < binary.length; i++) { + fn = binary[i]; + BigInteger[fn] = makeBinary(BigInteger.prototype[fn]); + } + + for (i = 0; i < trinary.length; i++) { + fn = trinary[i]; + BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]); + } + + BigInteger.exp10 = function(x, n) { + return BigInteger(x).exp10(n); + }; + })(); +})(); + +exports.BigInteger = BigInteger; +})(typeof exports !== 'undefined' ? exports : this); From d06ea8eecf85dd401f0e4c02d10bb271969fd84e Mon Sep 17 00:00:00 2001 From: aunxx Date: Sun, 5 Jun 2016 12:47:49 +0100 Subject: [PATCH 08/20] Updated hash algorythm --- backend/php/src/index.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/php/src/index.php b/backend/php/src/index.php index 977591d..cad2dec 100644 --- a/backend/php/src/index.php +++ b/backend/php/src/index.php @@ -107,8 +107,8 @@ function digits($base) { //----------------------------------------------------------------------------- function clipperz_hash($value) { - //return hash("sha256", hash("sha256", $value, true)); - return hash("sha256", $value, false); + return hash("sha256", hash("sha256", $value, true)); + //return hash("sha256", $value, false); } //----------------------------------------------------------------------------- @@ -295,6 +295,7 @@ error_log("handshake"); // $_SESSION["b"] = "5761e6c84d22ea3c5649de01702d60f674ccfe79238540eb34c61cd020230c53"; $_SESSION["b"] = "23309839184091712110293815740584558132927982490099443826709662564655631314481"; + // B = kv + g^b $_SESSION["B"] = dec2base(bcmod( bcadd( bcmod( bcmul( $srp_k, base2dec($_SESSION["v"], 16)), $srp_n), bcpowmod( $srp_g, $_SESSION["b"], $srp_n) ), $srp_n), 16); $result["s"] = $_SESSION["s"]; From 756d5006987e18e95cff8168a0062b265ff9f41b Mon Sep 17 00:00:00 2001 From: aunxx Date: Sun, 5 Jun 2016 13:47:35 +0100 Subject: [PATCH 09/20] SRP.js --- frontend/beta/js/Clipperz/Crypto/SRP.js | 43 +++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/frontend/beta/js/Clipperz/Crypto/SRP.js b/frontend/beta/js/Clipperz/Crypto/SRP.js index 0c3fc8e..2a90633 100644 --- a/frontend/beta/js/Clipperz/Crypto/SRP.js +++ b/frontend/beta/js/Clipperz/Crypto/SRP.js @@ -67,9 +67,14 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, { }, 'k': function() { + //k = H(N, g) if (Clipperz.Crypto.SRP._k == null) { // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); - Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); + // This is a fixed hash derived from a hash of N and G + // Following hash for just AES256 + // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); + // Following hash for dual AES256 + Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("23059873679103356965010473015094804246238452944122574891019568752064785140295", 10); } return Clipperz.Crypto.SRP._k; @@ -221,10 +226,43 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { bigint = Clipperz.Crypto.BigInt; srp = Clipperz.Crypto.SRP; + // S can be negative. This breaks as the BigInt Library is unsigned this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); + + var tmp_B = new BigInteger(this.B()); + var tmp_k = new BigInteger(Clipperz.Crypto.SRP.k()); + var tmp_g = new BigInteger(srp.g()); + var tmp_x = new BigInteger(this.x()); + var tmp_a = new BigInteger(this.a()); + var tmp_n = new BigInteger(srp.n()); + var tmp_u = new BigInteger(this.u()); + + var tmp_S1 = new BigInteger(tmp_B.subtract(tmp_k.multiply(tmp_g.modPow(tmp_x,tmp_n)))); + var tmp_S2 = new BigInteger(tmp_a.add(tmp_u.multiply(tmp_x))); + var tmp_S = new BigInteger(tmp_S1.modPow(tmp_S2,tmp_n)); + + if (tmp_S.isNegative() == true ) { + tmp_S = tmp_S.add(srp.n()); + } + +//console.log("_B", tmp_B.toString()); +//console.log("_k", tmp_k.toString()); +//console.log("_g", tmp_g.toString()); +//console.log("_x", tmp_x.toString()); +//console.log("_a", tmp_a.toString()); +//console.log("_n", tmp_n.toString()); +//console.log("_u", tmp_u.toString()); + +//console.log("S1", tmp_S1.toString()); +//console.log("S2", tmp_S2.toString()); +//console.log("S-", tmp_S.toString()); + + + } + //this._S= Clipperz.Crypto.BigInt(tmp_S.toString(),10); return this._S; }, @@ -353,7 +391,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { var result; //result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); - result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + //result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + result = Clipperz.Crypto.SHA.sha_d256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); return result; }, From 8c732e0060fcb08948dad1f79465269a7f637f55 Mon Sep 17 00:00:00 2001 From: aunxx Date: Sun, 5 Jun 2016 14:06:38 +0100 Subject: [PATCH 10/20] Updated propertied --- frontend/beta/properties/beta.properties.json | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/beta/properties/beta.properties.json b/frontend/beta/properties/beta.properties.json index 7d34677..c3ece3b 100644 --- a/frontend/beta/properties/beta.properties.json +++ b/frontend/beta/properties/beta.properties.json @@ -80,6 +80,7 @@ "Clipperz/Crypto/AES_2.js", "Clipperz/Crypto/PRNG.js", "Clipperz/Crypto/BigInt.js", + "Clipperz/Crypto/biginteger.js", "Clipperz/Crypto/Base.js", "Clipperz/Crypto/SRP.js", "Clipperz/Crypto/RSA.js", From eb0fb97e0ba98b6bd5c40781b8dc41042d0c619a Mon Sep 17 00:00:00 2001 From: aunxx Date: Sun, 5 Jun 2016 14:41:31 +0100 Subject: [PATCH 11/20] Remove biginteger.js --- frontend/beta/js/Clipperz/Crypto/SRP.js | 28 +++++++++---------- frontend/beta/properties/beta.properties.json | 1 - 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/frontend/beta/js/Clipperz/Crypto/SRP.js b/frontend/beta/js/Clipperz/Crypto/SRP.js index 2a90633..078ad7f 100644 --- a/frontend/beta/js/Clipperz/Crypto/SRP.js +++ b/frontend/beta/js/Clipperz/Crypto/SRP.js @@ -230,21 +230,21 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); - var tmp_B = new BigInteger(this.B()); - var tmp_k = new BigInteger(Clipperz.Crypto.SRP.k()); - var tmp_g = new BigInteger(srp.g()); - var tmp_x = new BigInteger(this.x()); - var tmp_a = new BigInteger(this.a()); - var tmp_n = new BigInteger(srp.n()); - var tmp_u = new BigInteger(this.u()); +// var tmp_B = new BigInteger(this.B()); +// var tmp_k = new BigInteger(Clipperz.Crypto.SRP.k()); +// var tmp_g = new BigInteger(srp.g()); +// var tmp_x = new BigInteger(this.x()); +// var tmp_a = new BigInteger(this.a()); +// var tmp_n = new BigInteger(srp.n()); +// var tmp_u = new BigInteger(this.u()); +// +// var tmp_S1 = new BigInteger(tmp_B.subtract(tmp_k.multiply(tmp_g.modPow(tmp_x,tmp_n)))); +// var tmp_S2 = new BigInteger(tmp_a.add(tmp_u.multiply(tmp_x))); +// var tmp_S = new BigInteger(tmp_S1.modPow(tmp_S2,tmp_n)); - var tmp_S1 = new BigInteger(tmp_B.subtract(tmp_k.multiply(tmp_g.modPow(tmp_x,tmp_n)))); - var tmp_S2 = new BigInteger(tmp_a.add(tmp_u.multiply(tmp_x))); - var tmp_S = new BigInteger(tmp_S1.modPow(tmp_S2,tmp_n)); - - if (tmp_S.isNegative() == true ) { - tmp_S = tmp_S.add(srp.n()); - } +// if (tmp_S.isNegative() == true ) { +// tmp_S = tmp_S.add(srp.n()); +// } //console.log("_B", tmp_B.toString()); //console.log("_k", tmp_k.toString()); diff --git a/frontend/beta/properties/beta.properties.json b/frontend/beta/properties/beta.properties.json index c3ece3b..7d34677 100644 --- a/frontend/beta/properties/beta.properties.json +++ b/frontend/beta/properties/beta.properties.json @@ -80,7 +80,6 @@ "Clipperz/Crypto/AES_2.js", "Clipperz/Crypto/PRNG.js", "Clipperz/Crypto/BigInt.js", - "Clipperz/Crypto/biginteger.js", "Clipperz/Crypto/Base.js", "Clipperz/Crypto/SRP.js", "Clipperz/Crypto/RSA.js", From f683a7e43e9cd0e1bae7c74e3a7518ebca49e8d6 Mon Sep 17 00:00:00 2001 From: aunxx Date: Sun, 5 Jun 2016 14:49:30 +0100 Subject: [PATCH 12/20] Updated hash --- frontend/delta/js/Clipperz/Crypto/SRP.js | 45 ++++++++++++++++++++++-- frontend/gamma/js/Clipperz/Crypto/SRP.js | 43 ++++++++++++++++++++-- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/frontend/delta/js/Clipperz/Crypto/SRP.js b/frontend/delta/js/Clipperz/Crypto/SRP.js index 0d67efa..7031380 100644 --- a/frontend/delta/js/Clipperz/Crypto/SRP.js +++ b/frontend/delta/js/Clipperz/Crypto/SRP.js @@ -56,6 +56,8 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, { return Clipperz.Crypto.SRP._n; }, + //------------------------------------------------------------------------- + 'g': function() { if (Clipperz.Crypto.SRP._g == null) { Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); // eventually 5 (as suggested on the Diffi-Helmann documentation) @@ -65,9 +67,14 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, { }, 'k': function() { + //k = H(N, g) if (Clipperz.Crypto.SRP._k == null) { // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); - Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); + // This is a fixed hash derived from a hash of N and G + // Following hash for just AES256 + // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); + // Following hash for dual AES256 + Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("23059873679103356965010473015094804246238452944122574891019568752064785140295", 10); } return Clipperz.Crypto.SRP._k; @@ -219,10 +226,43 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { bigint = Clipperz.Crypto.BigInt; srp = Clipperz.Crypto.SRP; + // S can be negative. This breaks as the BigInt Library is unsigned this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); + +// var tmp_B = new BigInteger(this.B()); +// var tmp_k = new BigInteger(Clipperz.Crypto.SRP.k()); +// var tmp_g = new BigInteger(srp.g()); +// var tmp_x = new BigInteger(this.x()); +// var tmp_a = new BigInteger(this.a()); +// var tmp_n = new BigInteger(srp.n()); +// var tmp_u = new BigInteger(this.u()); +// +// var tmp_S1 = new BigInteger(tmp_B.subtract(tmp_k.multiply(tmp_g.modPow(tmp_x,tmp_n)))); +// var tmp_S2 = new BigInteger(tmp_a.add(tmp_u.multiply(tmp_x))); +// var tmp_S = new BigInteger(tmp_S1.modPow(tmp_S2,tmp_n)); + +// if (tmp_S.isNegative() == true ) { +// tmp_S = tmp_S.add(srp.n()); +// } + +//console.log("_B", tmp_B.toString()); +//console.log("_k", tmp_k.toString()); +//console.log("_g", tmp_g.toString()); +//console.log("_x", tmp_x.toString()); +//console.log("_a", tmp_a.toString()); +//console.log("_n", tmp_n.toString()); +//console.log("_u", tmp_u.toString()); + +//console.log("S1", tmp_S1.toString()); +//console.log("S2", tmp_S2.toString()); +//console.log("S-", tmp_S.toString()); + + + } + //this._S= Clipperz.Crypto.BigInt(tmp_S.toString(),10); return this._S; }, @@ -351,7 +391,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { var result; //result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); - result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + //result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + result = Clipperz.Crypto.SHA.sha_d256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); return result; }, diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js index e2b31ed..7031380 100644 --- a/frontend/gamma/js/Clipperz/Crypto/SRP.js +++ b/frontend/gamma/js/Clipperz/Crypto/SRP.js @@ -67,9 +67,14 @@ MochiKit.Base.update(Clipperz.Crypto.SRP, { }, 'k': function() { + //k = H(N, g) if (Clipperz.Crypto.SRP._k == null) { // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16); - Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); + // This is a fixed hash derived from a hash of N and G + // Following hash for just AES256 + // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16); + // Following hash for dual AES256 + Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("23059873679103356965010473015094804246238452944122574891019568752064785140295", 10); } return Clipperz.Crypto.SRP._k; @@ -221,10 +226,43 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { bigint = Clipperz.Crypto.BigInt; srp = Clipperz.Crypto.SRP; + // S can be negative. This breaks as the BigInt Library is unsigned this._S = bigint.powerModule( bigint.subtract( bigint.multiply(Clipperz.Crypto.SRP.k(),bigint.powerModule(srp.g(), this.x(), srp.n())), this.B()), bigint.add(this.a(), bigint.multiply(this.u(), this.x())),srp.n() ); + +// var tmp_B = new BigInteger(this.B()); +// var tmp_k = new BigInteger(Clipperz.Crypto.SRP.k()); +// var tmp_g = new BigInteger(srp.g()); +// var tmp_x = new BigInteger(this.x()); +// var tmp_a = new BigInteger(this.a()); +// var tmp_n = new BigInteger(srp.n()); +// var tmp_u = new BigInteger(this.u()); +// +// var tmp_S1 = new BigInteger(tmp_B.subtract(tmp_k.multiply(tmp_g.modPow(tmp_x,tmp_n)))); +// var tmp_S2 = new BigInteger(tmp_a.add(tmp_u.multiply(tmp_x))); +// var tmp_S = new BigInteger(tmp_S1.modPow(tmp_S2,tmp_n)); + +// if (tmp_S.isNegative() == true ) { +// tmp_S = tmp_S.add(srp.n()); +// } + +//console.log("_B", tmp_B.toString()); +//console.log("_k", tmp_k.toString()); +//console.log("_g", tmp_g.toString()); +//console.log("_x", tmp_x.toString()); +//console.log("_a", tmp_a.toString()); +//console.log("_n", tmp_n.toString()); +//console.log("_u", tmp_u.toString()); + +//console.log("S1", tmp_S1.toString()); +//console.log("S2", tmp_S2.toString()); +//console.log("S-", tmp_S.toString()); + + + } + //this._S= Clipperz.Crypto.BigInt(tmp_S.toString(),10); return this._S; }, @@ -353,7 +391,8 @@ Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { var result; //result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); - result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + //result = Clipperz.Crypto.SHA.sha256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); + result = Clipperz.Crypto.SHA.sha_d256( new Clipperz.ByteArray(aValue)).toHexString().substring(2); return result; }, From 63f5452107b255919061f16e522dafd4d280711e Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Sat, 20 May 2017 10:47:53 +0100 Subject: [PATCH 13/20] Updated to use mysqli --- backend/php/src/objects/class.database.php | 29 ++++++++-------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/backend/php/src/objects/class.database.php b/backend/php/src/objects/class.database.php index e8a13f7..ce34e4c 100644 --- a/backend/php/src/objects/class.database.php +++ b/backend/php/src/objects/class.database.php @@ -17,17 +17,10 @@ $databaseUser = $GLOBALS['configuration']['user']; $databasePassword = $GLOBALS['configuration']['pass']; $databasePort = $GLOBALS['configuration']['port']; - $this->connection = mysql_connect ($serverName.":".$databasePort, $databaseUser, $databasePassword); - if ($this->connection) + $this->connection = mysqli_connect ($serverName, $databaseUser, $databasePassword , $databaseName, $databasePort); + if (!$this->connection) { - if (!mysql_select_db ($databaseName)) - { - throw new Exception('I cannot find the specified database "'.$databaseName.'". Please edit configuration.php.'); - } - } - else - { - throw new Exception('I cannot connect to the database. Please edit configuration.php with your database configuration.'); + throw new Exception('I cannot find the specified database "'.$databaseName.'". Please edit configuration.php.'); } } @@ -43,19 +36,19 @@ public static function Reader($query, $connection) { - $cursor = mysql_query($query, $connection); + $cursor = mysqli_query($connection, $query); return $cursor; } public static function Read($cursor) { - return mysql_fetch_assoc($cursor); + return mysqli_fetch_assoc($cursor); } public static function NonQuery($query, $connection) { - mysql_query($query, $connection); - $result = mysql_affected_rows($connection); + mysqli_query($connection, $query); + $result = mysqli_affected_rows($connection); if ($result == -1) { return false; @@ -66,14 +59,14 @@ public static function Query($query, $connection) { - $result = mysql_query($query, $connection); - return mysql_num_rows($result); + $result = mysqli_query($connection, $query); + return mysqli_num_rows($result); } public static function InsertOrUpdate($query, $connection) { - $result = mysql_query($query, $connection); - return intval(mysql_insert_id($connection)); + $result = mysqli_query($connection, $query); + return intval(mysqli_insert_id($connection)); } } ?> From 3df61ed87ac88789387e4632e5b85446095132a8 Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Sat, 27 May 2017 11:24:07 +0100 Subject: [PATCH 14/20] Fixed POG --- backend/php/src/objects/class.pog_base.php | 6 ++--- backend/php/src/setup/index.php | 20 +++++++++-------- .../src/setup/setup_library/setup_misc.php | 22 +++++++++---------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/backend/php/src/objects/class.pog_base.php b/backend/php/src/objects/class.pog_base.php index 6a8f570..2eb6a9b 100644 --- a/backend/php/src/objects/class.pog_base.php +++ b/backend/php/src/objects/class.pog_base.php @@ -92,10 +92,10 @@ class POG_Base return $objectList; } - private function CreateObjects($mysql_result, $objectClass, $lazyLoad = true) + private function CreateObjects($mysqli_result, $objectClass, $lazyLoad = true) { $objectList = array(); - while ($row = mysql_fetch_assoc($mysql_result)) + while ($row = mysqli_fetch_assoc($mysqli_result)) { $pog_object = new $objectClass(); $this->PopulateObjectAttributes($row, $pog_object); @@ -140,4 +140,4 @@ class POG_Base return false; } } -?> \ No newline at end of file +?> diff --git a/backend/php/src/setup/index.php b/backend/php/src/setup/index.php index 93dea6f..712c1ac 100644 --- a/backend/php/src/setup/index.php +++ b/backend/php/src/setup/index.php @@ -164,24 +164,26 @@ if(count($_POST) > 0 && $_SESSION['diagnosticsSuccessful']==false) if ($errors == 0) { AddTrace('File Structure....OK!'); - if (!mysql_connect ($GLOBALS['configuration']['host'].":".$GLOBALS['configuration']['port'], $GLOBALS['configuration']['user'], $GLOBALS['configuration']['pass'])) + #if (!mysql_connect ($GLOBALS['configuration']['host'].":".$GLOBALS['configuration']['port'], $GLOBALS['configuration']['user'], $GLOBALS['configuration']['pass'])) + if (!mysqli_connect ($GLOBALS['configuration']['host'], $GLOBALS['configuration']['user'], $GLOBALS['configuration']['pass'],$GLOBALS['configuration']['db'], $GLOBALS['configuration']['port'])) { $errors++; AddError('Cannot connect to the specified database server. Edit configuration.php'); + AddError('Cannot find the specified database "'.$GLOBALS['configuration']['db'].'". Edit configuration.php'); } if (isset($GLOBALS['configuration']['db_encoding']) && $GLOBALS['configuration']['db_encoding'] == 1 && !Base64::IsBase64FunctionInstalled()) { $errors++; AddError('$configuration[db_encoding] needs to be set to 0 until you install the base64 plugin. Set db_encoding to 0 by editing configuration.php, run setup again and go to the "Manage Plugins" tab. Install the base64 plugin. Then you can set db_encoding = 1'); } - if ($errors == 0) - { - if (!@mysql_select_db ($GLOBALS['configuration']['db'])) - { - $errors++; - AddError('Cannot find the specified database "'.$GLOBALS['configuration']['db'].'". Edit configuration.php'); - } - } +# if ($errors == 0) +# { +# if (!@mysql_select_db ($GLOBALS['configuration']['db'])) +# { +# $errors++; +# AddError('Cannot find the specified database "'.$GLOBALS['configuration']['db'].'". Edit configuration.php'); +# } +# } } /** diff --git a/backend/php/src/setup/setup_library/setup_misc.php b/backend/php/src/setup/setup_library/setup_misc.php index f0e4f0e..2fcbe07 100644 --- a/backend/php/src/setup/setup_library/setup_misc.php +++ b/backend/php/src/setup/setup_library/setup_misc.php @@ -276,10 +276,10 @@ { $link = ''; $content = file_get_contents($objectFilePath); - $contentParts = split("",$content); + $contentParts = explode("",$content); if (isset($contentParts[1])) { - $contentParts2 = split("",$contentParts[1]); + $contentParts2 = explode("",$contentParts[1]); } if (isset($contentParts2[0])) { @@ -287,8 +287,8 @@ } if (isset($className)) { - $linkParts1 = split("\*\/", $contentParts[1]); - $linkParts2 = split("\@link", $linkParts1[0]); + $linkParts1 = explode("\*\/", $contentParts[1]); + $linkParts2 = explode("\@link", $linkParts1[0]); if (isset($linkParts2[1])) { $link = $linkParts2[1]; @@ -313,10 +313,10 @@ function GetObjectName($objectFilePath) { $content = file_get_contents($objectFilePath); - $contentParts = split("",$content); + $contentParts = explode("",$content); if (isset($contentParts[1])) { - $contentParts2 = split("",$contentParts[1]); + $contentParts2 = explode("",$contentParts[1]); } if (isset($contentParts2[0])) { @@ -593,10 +593,10 @@ //extract sql $content = file_get_contents($objectFilePath); - $contentParts = split("",$content); + $contentParts = explode("",$content); if (isset($contentParts[1])) { - $contentParts2 = split("",$contentParts[1]); + $contentParts2 = explode("",$contentParts[1]); } if (isset($contentParts2[0])) { @@ -604,8 +604,8 @@ } if (isset($className)) { - $sqlParts = split(";",$contentParts[0]); - $sqlPart = split("CREATE",$sqlParts[0]); + $sqlParts = explode(";",$contentParts[0]); + $sqlPart = explode("CREATE",$sqlParts[0]); $sql = "CREATE ".$sqlPart[1].";"; //execute sql @@ -2354,4 +2354,4 @@ } return 0; } -?> \ No newline at end of file +?> From a2a216f9c914cc209824e4cf14ca821b1a783c39 Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Sat, 27 May 2017 14:36:17 +0100 Subject: [PATCH 15/20] Check for NULL in value --- backend/php/src/index.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/php/src/index.php b/backend/php/src/index.php index cad2dec..9b6ebf7 100644 --- a/backend/php/src/index.php +++ b/backend/php/src/index.php @@ -543,7 +543,11 @@ error_log("message"); $user->Save(); - $recordToDeleteReferenceList = $parameters["parameters"]["records"]["deleted"]; + if (isset( $parameters["parameters"]["records"]["deleted"] ) ) { + $recordToDeleteReferenceList = $parameters["parameters"]["records"]["deleted"]; + } else { + $recordToDeleteReferenceList = NULL; + } $recordList = array(); $c = count($recordToDeleteReferenceList); for ($i=0; $i<$c; $i++) { From 083a6a5ceae25afae729debbcd7e45892dd6d74b Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Sat, 27 May 2017 14:50:05 +0100 Subject: [PATCH 16/20] Fixed new login with empty records --- backend/php/src/index.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/php/src/index.php b/backend/php/src/index.php index 9b6ebf7..2fdb5be 100644 --- a/backend/php/src/index.php +++ b/backend/php/src/index.php @@ -409,7 +409,11 @@ error_log("message"); $recordStats["updateDate"] = $record->update_date; $recordsStats[$record->reference] = $recordStats; } - $result["recordsStats"] = $recordsStats; + if ( isset( $recordsStats ) ) { + $result["recordsStats"] = $recordsStats; + } else { + $result["recordsStats"] = NULL; + } $result["statistics"] = $user->statistics; $result["version"] = $user->version; From 29ebc6162738dd4edb6032b1d00aecc3f7672f00 Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Wed, 28 Nov 2018 14:48:07 +0000 Subject: [PATCH 17/20] Fix offline password authentication --- .../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | 13 ++++++++----- .../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | 13 ++++++++----- .../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js | 13 ++++++++----- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js index 93f14cf..9a45e39 100644 --- a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js +++ b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js @@ -354,7 +354,8 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { this.set_C(someParameters.parameters.C); this.set_b(new Clipperz.Crypto.BigInt(randomBytes, 16)); v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); - this.set_B((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n()))); + //this.set_B((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n()))); + this.set_B((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n())).module(Clipperz.Crypto.SRP.n())); this.set_A(someParameters.parameters.A); @@ -363,7 +364,7 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { nextTollRequestType = 'CONNECT'; } else if (someParameters.message == "credentialCheck") { - var v, u, s, S, A, K, M1; + var v, u, s, S, A, K, M1, KK; var stringHash = function (aValue) { return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); }; @@ -373,9 +374,11 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { A = new Clipperz.Crypto.BigInt(this.A(), 16); u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + this.B().asString(10))).toHexString(), 16); s = new Clipperz.Crypto.BigInt(this.userData()['s'], 16); - S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n()); + //S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n()); + S = v.powerModule(u, Clipperz.Crypto.SRP.n()).multiply(A).module(Clipperz.Crypto.SRP.n()).powerModule(this.b(), Clipperz.Crypto.SRP.n()) K = stringHash(S.asString(10)); + KK = new Clipperz.Crypto.BigInt(K,16); M1 = stringHash( "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + @@ -383,7 +386,7 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { s.asString(10) + A.asString(10) + this.B().asString(10) + - K + KK.asString(10) ); if (someParameters.parameters.M1 == M1) { var M2; @@ -823,4 +826,4 @@ Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { Clipperz.PM.Proxy.Offline.DataStore['exception'] = { 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") -}; \ No newline at end of file +}; diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js index cbb02ce..3015218 100644 --- a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js @@ -434,7 +434,8 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); - aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); + //aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); + aConnection['B'] = ((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())).module(Clipperz.Crypto.SRP.n())); aConnection['A'] = someParameters.parameters.A; @@ -443,7 +444,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { nextTollRequestType = 'CONNECT'; } else if (someParameters.message == "credentialCheck") { - var v, u, s, S, A, K, M1; + var v, u, s, S, A, K, M1, KK; var stringHash = function (aValue) { return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); }; @@ -452,9 +453,11 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10))).toHexString(), 16); s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16); - S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); + //S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); + S = v.powerModule(u, Clipperz.Crypto.SRP.n()).multiply(A).module(Clipperz.Crypto.SRP.n()).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); K = stringHash(S.asString(10)); + KK = new Clipperz.Crypto.BigInt(K,16); M1 = stringHash( "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + @@ -462,7 +465,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { s.asString(10) + A.asString(10) + aConnection['B'].asString(10) + - K + KK.asString(10) ); if (someParameters.parameters.M1 == M1) { var M2; @@ -1047,4 +1050,4 @@ Clipperz.PM.Proxy.Offline.DataStore.defaultAccountInfo = { 'referenceDate': 'Fri, 03 April 2015 08:17:46 UTC', 'isExpired': false, 'expirationDate': 'Mon, 01 January 4001 00:00:00 UTC' -}; \ No newline at end of file +}; diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js index cd0f1b7..0e9c648 100644 --- a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js +++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js @@ -329,7 +329,8 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); - aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); + //aConnection['B'] = (Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); + aConnection['B'] = ((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())).module(Clipperz.Crypto.SRP.n())); aConnection['A'] = someParameters.parameters.A; @@ -338,7 +339,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { nextTollRequestType = 'CONNECT'; } else if (someParameters.message == "credentialCheck") { - var v, u, s, S, A, K, M1; + var v, u, s, S, A, K, M1, KK; var stringHash = function (aValue) { return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); }; @@ -347,9 +348,11 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10))).toHexString(), 16); s = new Clipperz.Crypto.BigInt(aConnection['userData']['s'], 16); - S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); + //S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); + S = v.powerModule(u, Clipperz.Crypto.SRP.n()).multiply(A).module(Clipperz.Crypto.SRP.n()).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); K = stringHash(S.asString(10)); + KK = new Clipperz.Crypto.BigInt(K,16); M1 = stringHash( "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" + @@ -357,7 +360,7 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { s.asString(10) + A.asString(10) + aConnection['B'].asString(10) + - K + KK.asString(10) ); if (someParameters.parameters.M1 == M1) { var M2; @@ -800,4 +803,4 @@ Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { Clipperz.PM.Proxy.Offline.DataStore['exception'] = { 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly") -}; \ No newline at end of file +}; From 22fb8b0cf950dbc2bde74b83ff6450aa5704e841 Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Wed, 28 Nov 2018 15:54:01 +0000 Subject: [PATCH 18/20] Update dump php page --- backend/php/src/dump.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/backend/php/src/dump.php b/backend/php/src/dump.php index d4e8544..28ad223 100644 --- a/backend/php/src/dump.php +++ b/backend/php/src/dump.php @@ -11,7 +11,22 @@ header('Content-Disposition: attachment; filename=Clipperz_'.date("Ymd").'.html' include "./objects/class.onetimepassword.php"; include "./objects/class.onetimepasswordstatus.php"; - $htmlContent = file_get_contents("../index.html"); + //$htmlContent = file_get_contents("../index.html"); + switch ($_GET["frontend"]) { + case 'beta': + $htmlContent = file_get_contents("beta/index.html"); + break; + case 'gamma': + $htmlContent = file_get_contents("gamma/index.html"); + break; + case 'delta': + $htmlContent = file_get_contents("delta/index.html"); + break; + default: + exit ("Invalid Frontend"); + + } + session_start(); @@ -100,4 +115,4 @@ header('Content-Disposition: attachment; filename=Clipperz_'.date("Ymd").'.html' session_write_close(); echo str_replace("/*offline_data_placeholder*/", $data, $htmlContent); -?> \ No newline at end of file +?> From d66e7b9aa502223b231eceff14d3b9abf49245a9 Mon Sep 17 00:00:00 2001 From: Graham Eades Date: Wed, 28 Nov 2018 16:08:35 +0000 Subject: [PATCH 19/20] Updated Frontend templates --- frontend/beta/html/index_template.html | 2 +- frontend/delta/html/index_template.html | 2 +- frontend/gamma/html/index_template.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/beta/html/index_template.html b/frontend/beta/html/index_template.html index 7f58898..376cf77 100644 --- a/frontend/beta/html/index_template.html +++ b/frontend/beta/html/index_template.html @@ -13,7 +13,7 @@