mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 22:45:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
1
grunt.js
1
grunt.js
@@ -36,6 +36,7 @@ module.exports = function(grunt) {
|
||||
"src/js/sjcl-custom/sjcl-secp256k1.js",
|
||||
"src/js/sjcl-custom/sjcl-ripemd160.js",
|
||||
"src/js/sjcl-custom/sjcl-extramath.js",
|
||||
"src/js/sjcl-custom/sjcl-validecc.js",
|
||||
"src/js/sjcl-custom/sjcl-ecdsa-der.js"
|
||||
],
|
||||
dest: 'build/sjcl.js'
|
||||
|
||||
@@ -138,6 +138,12 @@ Request.prototype.tx_json = function (j) {
|
||||
return this;
|
||||
};
|
||||
|
||||
Request.prototype.tx_blob = function (j) {
|
||||
this.message.tx_blob = j;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Request.prototype.ripple_state = function (account, issuer, currency) {
|
||||
this.message.ripple_state = {
|
||||
'accounts' : [
|
||||
|
||||
@@ -27,19 +27,35 @@ Seed.prototype.constructor = Seed;
|
||||
// value = NaN on error.
|
||||
// One day this will support rfc1751 too.
|
||||
Seed.prototype.parse_json = function (j) {
|
||||
if ('string' !== typeof j) {
|
||||
this._value = NaN;
|
||||
if ('string' === typeof j) {
|
||||
if (!j.length) {
|
||||
this._value = NaN;
|
||||
// XXX Should actually always try and continue if it failed.
|
||||
} else if (j[0] === "s") {
|
||||
this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);
|
||||
} else if (j.length === 32) {
|
||||
this._value = this.parse_hex(j);
|
||||
// XXX Should also try 1751
|
||||
} else {
|
||||
this.parse_passphrase(j);
|
||||
}
|
||||
} else {
|
||||
this._value = NaN;
|
||||
}
|
||||
else if (j[0] === "s") {
|
||||
this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);
|
||||
}
|
||||
else if (16 === j.length) {
|
||||
this._value = new BigInteger(utils.stringToArray(j), 128);
|
||||
}
|
||||
else {
|
||||
this._value = NaN;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Seed.prototype.parse_passphrase = function (j) {
|
||||
if ("string" !== typeof j) {
|
||||
throw new Error("Passphrase must be a string");
|
||||
}
|
||||
|
||||
var hash = sjcl.hash.sha512.hash(sjcl.codec.utf8String.toBits(j));
|
||||
var bits = sjcl.bitArray.bitSlice(hash, 0, 128);
|
||||
|
||||
this.parse_bits(bits);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -68,6 +84,9 @@ function SHA256_RIPEMD160(bits) {
|
||||
}
|
||||
|
||||
Seed.prototype.get_key = function (account_id) {
|
||||
if (!this.is_valid()) {
|
||||
throw new Error("Cannot generate keys from invalid seed!");
|
||||
}
|
||||
// XXX Should loop over keys until we find the right one
|
||||
|
||||
var curve = this._curve;
|
||||
|
||||
@@ -92,7 +92,7 @@ SerializedObject.prototype.serialize_field = function (spec, obj)
|
||||
Type = spec.shift();
|
||||
|
||||
if ("undefined" !== typeof obj[name]) {
|
||||
console.log(name, Type.id, field_id);
|
||||
//console.log(name, Type.id, field_id);
|
||||
this.append(SerializedObject.get_field_header(Type.id, field_id));
|
||||
|
||||
try {
|
||||
|
||||
@@ -12,7 +12,8 @@ var extend = require('extend'),
|
||||
|
||||
var amount = require('./amount'),
|
||||
UInt160 = amount.UInt160,
|
||||
Amount = amount.Amount;
|
||||
Amount = amount.Amount,
|
||||
Currency= amount.Currency;
|
||||
|
||||
// Shortcuts
|
||||
var hex = sjcl.codec.hex,
|
||||
@@ -47,7 +48,7 @@ SerializedType.prototype.serialize_varint = function (so, val) {
|
||||
} else throw new Error("Variable integer overflow.");
|
||||
};
|
||||
|
||||
exports.Int8 = new SerializedType({
|
||||
var STInt8 = exports.Int8 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append([val & 0xff]);
|
||||
},
|
||||
@@ -56,7 +57,7 @@ exports.Int8 = new SerializedType({
|
||||
}
|
||||
});
|
||||
|
||||
exports.Int16 = new SerializedType({
|
||||
var STInt16 = exports.Int16 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append([
|
||||
val >>> 8 & 0xff,
|
||||
@@ -65,10 +66,11 @@ exports.Int16 = new SerializedType({
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Int16 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Int32 = new SerializedType({
|
||||
var STInt32 = exports.Int32 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
so.append([
|
||||
val >>> 24 & 0xff,
|
||||
@@ -79,46 +81,82 @@ exports.Int32 = new SerializedType({
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Int32 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Int64 = new SerializedType({
|
||||
var STInt64 = exports.Int64 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Int64 not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Int64 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Hash128 = new SerializedType({
|
||||
var STHash128 = exports.Hash128 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Hash128 not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Hash128 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Hash256 = new SerializedType({
|
||||
var STHash256 = exports.Hash256 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Hash256 not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Hash256 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Hash160 = new SerializedType({
|
||||
var STHash160 = exports.Hash160 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Hash160 not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Hash160 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Amount = new SerializedType({
|
||||
// Internal
|
||||
var STCurrency = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
var currency = val.to_json();
|
||||
if ("string" === typeof currency && currency.length === 3) {
|
||||
var currencyCode = currency.toUpperCase(),
|
||||
currencyData = utils.arraySet(20, 0);
|
||||
|
||||
if (!/^[A-Z]{3}$/.test(currencyCode)) {
|
||||
throw new Error('Invalid currency code');
|
||||
}
|
||||
|
||||
currencyData[12] = currencyCode.charCodeAt(0) & 0xff;
|
||||
currencyData[13] = currencyCode.charCodeAt(1) & 0xff;
|
||||
currencyData[14] = currencyCode.charCodeAt(2) & 0xff;
|
||||
|
||||
so.append(currencyData);
|
||||
} else {
|
||||
throw new Error('Tried to serialize invalid/unimplemented currency type.');
|
||||
}
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Currency not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
var STAmount = exports.Amount = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
var amount = Amount.from_json(val);
|
||||
if (!amount.is_valid()) {
|
||||
@@ -126,6 +164,7 @@ exports.Amount = new SerializedType({
|
||||
}
|
||||
|
||||
// Amount (64-bit integer)
|
||||
var valueBytes = utils.arraySet(8, 0);
|
||||
if (amount.is_native()) {
|
||||
var valueHex = amount._value.toString(16);
|
||||
|
||||
@@ -137,103 +176,138 @@ exports.Amount = new SerializedType({
|
||||
valueHex = "0" + valueHex;
|
||||
}
|
||||
|
||||
var valueBytes = bytes.fromBits(hex.toBits(valueHex));
|
||||
valueBytes = bytes.fromBits(hex.toBits(valueHex));
|
||||
// Clear most significant two bits - these bits should already be 0 if
|
||||
// Amount enforces the range correctly, but we'll clear them anyway just
|
||||
// so this code can make certain guarantees about the encoded value.
|
||||
valueBytes[0] &= 0x3f;
|
||||
if (!amount.is_negative()) valueBytes[0] |= 0x40;
|
||||
|
||||
so.append(valueBytes);
|
||||
} else {
|
||||
// XXX
|
||||
throw new Error("Non-native amounts not implemented!");
|
||||
var hi = 0, lo = 0;
|
||||
|
||||
// First bit: non-native
|
||||
hi |= 1 << 31;
|
||||
|
||||
if (!amount.is_zero()) {
|
||||
// Second bit: non-negative?
|
||||
if (!amount.is_negative()) hi |= 1 << 30;
|
||||
|
||||
// Next eight bits: offset/exponent
|
||||
hi |= ((97 + amount._offset) & 0xff) << 22;
|
||||
|
||||
// Remaining 52 bits: mantissa
|
||||
hi |= amount._value.shiftRight(32).intValue() & 0x3fffff;
|
||||
lo = amount._value.intValue() & 0xffffffff;
|
||||
}
|
||||
|
||||
valueBytes = sjcl.codec.bytes.fromBits([hi, lo]);
|
||||
}
|
||||
|
||||
so.append(valueBytes);
|
||||
|
||||
if (!amount.is_native()) {
|
||||
// Currency (160-bit hash)
|
||||
var currency = amount.currency().to_json();
|
||||
if ("string" === typeof currency && currency.length === 3) {
|
||||
var currencyCode = currency.toUpperCase(),
|
||||
currencyData = utils.arraySet(20, 0);
|
||||
|
||||
if (!/^[A-Z]{3}$/.test(currencyCode)) {
|
||||
throw new Error('Invalid currency code');
|
||||
}
|
||||
|
||||
currencyData[12] = currencyCode.charCodeAt(0) & 0xff;
|
||||
currencyData[13] = currencyCode.charCodeAt(1) & 0xff;
|
||||
currencyData[14] = currencyCode.charCodeAt(2) & 0xff;
|
||||
|
||||
var currencyBits = bytes.toBits(currencyData),
|
||||
currencyHash = sjcl.hash.ripemd160.hash(currencyBits);
|
||||
|
||||
so.append(bytes.fromBits(currencyHash));
|
||||
} else {
|
||||
throw new Error('Tried to serialize invalid/unimplemented currency type.');
|
||||
}
|
||||
var currency = amount.currency();
|
||||
STCurrency.serialize(so, currency);
|
||||
|
||||
// Issuer (160-bit hash)
|
||||
// XXX
|
||||
so.append(amount.issuer().to_bytes());
|
||||
}
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Amount not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.VariableLength = new SerializedType({
|
||||
var STVL = exports.VariableLength = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
if ("string" === typeof val) this.serialize_hex(so, val);
|
||||
else throw new Error("Unknown datatype.");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing VL not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Account = new SerializedType({
|
||||
var STAccount = exports.Account = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
var account = UInt160.from_json(val);
|
||||
this.serialize_hex(so, account.to_hex());
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Account not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.PathSet = new SerializedType({
|
||||
var STPathSet = exports.PathSet = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
for (var i = 0, l = val.length; i < l; i++) {
|
||||
for (var j = 0, l2 = val[i].length; j < l2; j++) {
|
||||
var entry = val[i][j];
|
||||
|
||||
var type = 0;
|
||||
|
||||
if (entry.account) type |= 0x01;
|
||||
if (entry.currency) type |= 0x10;
|
||||
if (entry.issuer) type |= 0x20;
|
||||
|
||||
STInt8.serialize(so, type);
|
||||
|
||||
if (entry.account) {
|
||||
so.append(UInt160.from_json(entry.account).to_bytes());
|
||||
}
|
||||
if (entry.currency) {
|
||||
var currency = Currency.from_json(entry.currency);
|
||||
STCurrency.serialize(so, currency);
|
||||
}
|
||||
if (entry.issuer) {
|
||||
so.append(UInt160.from_json(entry.issuer).to_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
if (j < l2) STInt8.serialize(so, 0xff);
|
||||
}
|
||||
STInt8.serialize(so, 0x00);
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing PathSet not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Vector256 = new SerializedType({
|
||||
var STVector256 = exports.Vector256 = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Vector256 not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Vector256 not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Object = new SerializedType({
|
||||
var STObject = exports.Object = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Object not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Object not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
exports.Array = new SerializedType({
|
||||
var STArray = exports.Array = new SerializedType({
|
||||
serialize: function (so, val) {
|
||||
// XXX
|
||||
throw new Error("Serializing Array not implemented");
|
||||
},
|
||||
parse: function (so) {
|
||||
// XXX
|
||||
throw new Error("Parsing Array not implemented");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,12 +5,18 @@ sjcl.ecc.ecdsa.secretKey.prototype.signDER = function(hash, paranoia) {
|
||||
sjcl.ecc.ecdsa.secretKey.prototype.encodeDER = function(rs) {
|
||||
var w = sjcl.bitArray,
|
||||
R = this._curve.r,
|
||||
l = R.bitLength(),
|
||||
r = sjcl.bn.fromBits(w.bitSlice(rs,0,l)).toBits(),
|
||||
s = sjcl.bn.fromBits(w.bitSlice(rs,l,2*l)).toBits();
|
||||
l = R.bitLength();
|
||||
|
||||
var rb = sjcl.codec.bytes.fromBits(r),
|
||||
sb = sjcl.codec.bytes.fromBits(s);
|
||||
var rb = sjcl.codec.bytes.fromBits(w.bitSlice(rs,0,l)),
|
||||
sb = sjcl.codec.bytes.fromBits(w.bitSlice(rs,l,2*l));
|
||||
|
||||
// Drop empty leading bytes
|
||||
while (!rb[0] && rb.length) rb.shift();
|
||||
while (!sb[0] && sb.length) sb.shift();
|
||||
|
||||
// If high bit is set, prepend an extra zero byte (DER signed integer)
|
||||
if (rb[0] & 0x80) rb.unshift(0);
|
||||
if (sb[0] & 0x80) sb.unshift(0);
|
||||
|
||||
var buffer = [].concat(
|
||||
0x30,
|
||||
|
||||
30
src/js/sjcl-custom/sjcl-validecc.js
Normal file
30
src/js/sjcl-custom/sjcl-validecc.js
Normal file
@@ -0,0 +1,30 @@
|
||||
sjcl.ecc.ecdsa.secretKey.prototype = {
|
||||
sign: function(hash, paranoia) {
|
||||
var R = this._curve.r,
|
||||
l = R.bitLength(),
|
||||
k = sjcl.bn.random(R.sub(1), paranoia).add(1),
|
||||
r = this._curve.G.mult(k).x.mod(R),
|
||||
s = sjcl.bn.fromBits(hash).add(r.mul(this._exponent)).mul(k.inverseMod(R)).mod(R);
|
||||
|
||||
return sjcl.bitArray.concat(r.toBits(l), s.toBits(l));
|
||||
}
|
||||
};
|
||||
|
||||
sjcl.ecc.ecdsa.publicKey.prototype = {
|
||||
verify: function(hash, rs) {
|
||||
var w = sjcl.bitArray,
|
||||
R = this._curve.r,
|
||||
l = R.bitLength(),
|
||||
r = sjcl.bn.fromBits(w.bitSlice(rs,0,l)),
|
||||
s = sjcl.bn.fromBits(w.bitSlice(rs,l,2*l)),
|
||||
sInv = s.modInverse(R),
|
||||
hG = sjcl.bn.fromBits(hash).mul(sInv).mod(R),
|
||||
hA = r.mul(sInv).mod(R),
|
||||
r2 = this._curve.G.mult2(hG, hA, this._point).x;
|
||||
|
||||
if (r.equals(0) || s.equals(0) || r.greaterEquals(R) || s.greaterEquals(R) || !r2.equals(r)) {
|
||||
throw (new sjcl.exception.corrupt("signature didn't check out"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -356,6 +356,7 @@ Transaction.prototype.submit = function (callback) {
|
||||
return this;
|
||||
} else if (this.remote.local_signing) {
|
||||
this.sign();
|
||||
request.tx_blob(this.serialize().to_hex());
|
||||
} else {
|
||||
if (!this.remote.trusted) {
|
||||
this.emit('error', {
|
||||
@@ -363,13 +364,13 @@ Transaction.prototype.submit = function (callback) {
|
||||
'result_message' : "Attempt to give a secret to an untrusted server."
|
||||
});
|
||||
return this;
|
||||
} else {
|
||||
request.secret(this._secret);
|
||||
}
|
||||
|
||||
request.secret(this._secret);
|
||||
request.build_path(this._build_path);
|
||||
request.tx_json(this.tx_json);
|
||||
}
|
||||
|
||||
request.build_path(this._build_path);
|
||||
request.tx_json(this.tx_json);
|
||||
request.request();
|
||||
|
||||
return this;
|
||||
|
||||
@@ -32,6 +32,28 @@ var Server = function (name, config, verbose) {
|
||||
this.started = false;
|
||||
this.quiet = !verbose;
|
||||
this.stopping = false;
|
||||
|
||||
var nodejs_version = process.version.match(/^v(\d+)+\.(\d+)\.(\d+)$/).slice(1,4);
|
||||
var wanted_version = [ 0, 8, 18 ];
|
||||
|
||||
while (wanted_version.length && nodejs_version.length && nodejs_version[0] == wanted_version[0])
|
||||
{
|
||||
nodejs_version.shift();
|
||||
wanted_version.shift();
|
||||
}
|
||||
|
||||
var sgn = !nodejs_version.length && !wanted_version.length
|
||||
? 0
|
||||
: nodejs_version.length
|
||||
? nodejs_version[0] - wanted_version[0]
|
||||
: -1;
|
||||
|
||||
if (sgn < 0)
|
||||
{
|
||||
console.log("\n*** Node.js version is too low.");
|
||||
|
||||
throw "Nodejs version is too low.";
|
||||
}
|
||||
};
|
||||
|
||||
Server.prototype = new EventEmitter;
|
||||
|
||||
Reference in New Issue
Block a user