Skip to content

Commit

Permalink
[FEATURE] Inject sjcl as dependency to modules.
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Zeiler committed Jul 9, 2014
1 parent 5966b9b commit cb5acfb
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 216 deletions.
175 changes: 88 additions & 87 deletions lib/base58.js
Original file line number Diff line number Diff line change
@@ -1,106 +1,107 @@
var sjcl = require('ripple-lib').sjcl

var Base58Utils = (function () {
var alphabets = {
'ripple': "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
'bitcoin': "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
};

var SHA256 = function (bytes) {
return sjcl.codec.bytes.fromBits(sjcl.hash.sha256.hash(sjcl.codec.bytes.toBits(bytes)));
};

return {
// --> input: big-endian array of bytes.
// <-- string at least as long as input.
encode_base: function (input, alphabetName) {
var alphabet = alphabets[alphabetName || 'ripple'],
base = new sjcl.bn(alphabet.length),
bi = sjcl.bn.fromBits(sjcl.codec.bytes.toBits(input)),
buffer = [];

while (bi.greaterEquals(base)) {
var mod = bi.mod(base);
buffer.push(alphabet[mod.limbs[0]]);
bi = bi.div(base);
}
buffer.push(alphabet[bi.limbs[0]]);

// Convert leading zeros too.
for (var i = 0; i != input.length && !input[i]; i += 1) {
buffer.push(alphabet[0]);
}

return buffer.reverse().join("");
},
module.exports = function(options) { // inject sjcl dependency
var sjcl = options.sjcl;

var Base58Utils = (function () {
var alphabets = {
'ripple': "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
'bitcoin': "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
};

var SHA256 = function (bytes) {
return sjcl.codec.bytes.fromBits(sjcl.hash.sha256.hash(sjcl.codec.bytes.toBits(bytes)));
};

return {
// --> input: big-endian array of bytes.
// <-- string at least as long as input.
encode_base: function (input, alphabetName) {
var alphabet = alphabets[alphabetName || 'ripple'],
base = new sjcl.bn(alphabet.length),
bi = sjcl.bn.fromBits(sjcl.codec.bytes.toBits(input)),
buffer = [];

while (bi.greaterEquals(base)) {
var mod = bi.mod(base);
buffer.push(alphabet[mod.limbs[0]]);
bi = bi.div(base);
}
buffer.push(alphabet[bi.limbs[0]]);

// --> input: String
// <-- array of bytes or undefined.
decode_base: function (input, alphabetName) {
var alphabet = alphabets[alphabetName || 'ripple'],
base = new sjcl.bn(alphabet.length),
bi = new sjcl.bn(0);
// Convert leading zeros too.
for (var i = 0; i != input.length && !input[i]; i += 1) {
buffer.push(alphabet[0]);
}

var i;
while (i != input.length && input[i] === alphabet[0]) {
i += 1;
}
return buffer.reverse().join("");
},

for (i = 0; i != input.length; i += 1) {
var v = alphabet.indexOf(input[i]);
// --> input: String
// <-- array of bytes or undefined.
decode_base: function (input, alphabetName) {
var alphabet = alphabets[alphabetName || 'ripple'],
base = new sjcl.bn(alphabet.length),
bi = new sjcl.bn(0);

if (v < 0) {
return null;
var i;
while (i != input.length && input[i] === alphabet[0]) {
i += 1;
}

bi = bi.mul(base).addM(v);
}
for (i = 0; i != input.length; i += 1) {
var v = alphabet.indexOf(input[i]);

var bytes = sjcl.codec.bytes.fromBits(bi.toBits()).reverse();
if (v < 0) {
return null;
}

// Remove leading zeros
while(bytes[bytes.length-1] === 0) {
bytes.pop();
}
bi = bi.mul(base).addM(v);
}

// Add the right number of leading zeros
for (i = 0; input[i] === alphabet[0]; i++) {
bytes.push(0);
}
var bytes = sjcl.codec.bytes.fromBits(bi.toBits()).reverse();

bytes.reverse();
// Remove leading zeros
while(bytes[bytes.length-1] === 0) {
bytes.pop();
}

return bytes;
},
// Add the right number of leading zeros
for (i = 0; input[i] === alphabet[0]; i++) {
bytes.push(0);
}

// --> input: Array
// <-- String
encode_base_check: function (version, input, alphabet) {
var buffer = [].concat(version, input);
var check = SHA256(SHA256(buffer)).slice(0, 4);
return Base58Utils.encode_base([].concat(buffer, check), alphabet);
},
bytes.reverse();

// --> input : String
// <-- NaN || BigInteger
decode_base_check: function (version, input, alphabet) {
var buffer = Base58Utils.decode_base(input, alphabet);
return bytes;
},

if (!buffer || buffer[0] !== version || buffer.length < 5) {
return NaN;
}
// --> input: Array
// <-- String
encode_base_check: function (version, input, alphabet) {
var buffer = [].concat(version, input);
var check = SHA256(SHA256(buffer)).slice(0, 4);
return Base58Utils.encode_base([].concat(buffer, check), alphabet);
},

var computed = SHA256(SHA256(buffer.slice(0, -4))).slice(0, 4),
checksum = buffer.slice(-4);
// --> input : String
// <-- NaN || BigInteger
decode_base_check: function (version, input, alphabet) {
var buffer = Base58Utils.decode_base(input, alphabet);

var i;
for (i = 0; i != 4; i += 1)
if (computed[i] !== checksum[i])
if (!buffer || buffer[0] !== version || buffer.length < 5) {
return NaN;
}

return buffer.slice(1, -4);
}
};
})();
var computed = SHA256(SHA256(buffer.slice(0, -4))).slice(0, 4),
checksum = buffer.slice(-4);

module.exports = Base58Utils;
var i;
for (i = 0; i != 4; i += 1)
if (computed[i] !== checksum[i])
return NaN;

return buffer.slice(1, -4);
}
};
})();
return Base58Utils;
};
36 changes: 18 additions & 18 deletions lib/master_key.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
var sjcl = require('ripple-lib').sjcl;
var base58 = require(__dirname+'/base58.js');
module.exports = function(options) {
var sjcl = options.sjcl;
var base58 = require(__dirname+'/base58.js');

function MasterKey(key){
this.value = key;
};
function MasterKey(key){
this.value = key;
};

MasterKey.fromBytes = function(bytes){
return new MasterKey(base58.encode_base_check(33, bytes));
};

MasterKey.getRandom = function(){
for (var i = 0; i < 8; i++) {
sjcl.random.addEntropy(Math.random(), 32, "Math.random()");
}
var randomBytes = sjcl.codec.bytes.fromBits(sjcl.random.randomWords(4));
return MasterKey.fromBytes(randomBytes);
};

module.exports = MasterKey;
MasterKey.fromBytes = function(bytes){
return new MasterKey(base58.encode_base_check(33, bytes));
};

MasterKey.getRandom = function(){
for (var i = 0; i < 8; i++) {
sjcl.random.addEntropy(Math.random(), 32, "Math.random()");
}
var randomBytes = sjcl.codec.bytes.fromBits(sjcl.random.randomWords(4));
return MasterKey.fromBytes(randomBytes);
};
return MasterKey;
}
38 changes: 20 additions & 18 deletions lib/public_generator.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
var sjcl = require('ripple-lib').sjcl;
module.exports = function(options) { // inject sjcl dependency
var sjcl = options.sjcl;

function PublicGenerator(eccPoint) {
if (eccPoint instanceof sjcl.ecc.point) {
this.value = eccPoint;
} else {
throw new Error('eccPoint must be a sjcl.ecc.point');
function PublicGenerator(eccPoint) {
if (eccPoint instanceof sjcl.ecc.point) {
this.value = eccPoint;
} else {
throw new Error('eccPoint must be a sjcl.ecc.point');
}
}
}

PublicGenerator.fromPrivateGenerator = function(privateGenerator) {
/* Compute the public generator using from the
private generator on the elliptic curve
*/
return new this(sjcl.ecc.curves.c256.G.mult(privateGenerator));
};
PublicGenerator.fromPrivateGenerator = function(privateGenerator) {
/* Compute the public generator using from the
private generator on the elliptic curve
*/
return new this(sjcl.ecc.curves.c256.G.mult(privateGenerator));
};

PublicGenerator.prototype = {
toString: function() {
return this.value.toString();
PublicGenerator.prototype = {
toString: function() {
return this.value.toString();
}
}
}

module.exports = PublicGenerator;
return PublicGenerator;
}

35 changes: 19 additions & 16 deletions lib/ripple_address.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
var sjcl = require('ripple-lib').sjcl;
var base58 = require(__dirname+'/base58.js');

function SHA256_RIPEMD160(bits) {
return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));
}
module.exports = function(options) { // inject sjcl dependency
var sjcl = options.sjcl
var base58 = require(__dirname+'/base58.js')({ sjcl: sjcl });

function RippleAddress(address){
this.value = address;
}

RippleAddress.fromPublicKey = function(publicKey){
/* Encode the EC public key as a ripple address
using SHA256 and then RIPEMD160
*/
var publicKeyBytes = sjcl.codec.bytes.fromBits(SHA256_RIPEMD160(sjcl.codec.bytes.toBits(publicKey.toBytesCompressed())));
return new this(base58.encode_base_check(0, publicKeyBytes));
}
function SHA256_RIPEMD160(bits) {
return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));
}

module.exports = RippleAddress;
function RippleAddress(address){
this.value = address;
}

RippleAddress.fromPublicKey = function(publicKey){
/* Encode the EC public key as a ripple address
using SHA256 and then RIPEMD160
*/
var publicKeyBytes = sjcl.codec.bytes.fromBits(SHA256_RIPEMD160(sjcl.codec.bytes.toBits(publicKey.toBytesCompressed())));
return new this(base58.encode_base_check(0, publicKeyBytes));
}

return RippleAddress;
}
Loading

0 comments on commit cb5acfb

Please sign in to comment.