init
This commit is contained in:
+15
@@ -0,0 +1,15 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2012-2015 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# ripple-keypairs [](https://npmjs.org/package/ripple-keypairs) [](https://travis-ci.org/ripple/ripple-keypairs) 
|
||||
|
||||
An implementation of XRP Ledger keypairs & wallet generation using
|
||||
[elliptic](https://github.com/indutny/elliptic) which supports rfc6979 and
|
||||
eddsa deterministic signatures.
|
||||
|
||||
[](https://www.npmjs.org/package/ripple-keypairs)
|
||||
|
||||
## API Methods
|
||||
|
||||
```
|
||||
generateSeed({entropy?: Array<integer>, algorithm?: string}) -> string
|
||||
```
|
||||
Generate a seed that can be used to generate keypairs. Entropy can be provided as an array of bytes expressed as integers in the range 0-255. If provided, it must be 16 bytes long (additional bytes are ignored). If not provided, entropy will be automatically generated. The "algorithm" defaults to "ecdsa-secp256k1", but can also be set to "ed25519". The result is a seed encoded in base58, starting with "s".
|
||||
|
||||
```
|
||||
deriveKeypair(seed: string) -> {privateKey: string, publicKey: string}
|
||||
```
|
||||
Derive a public and private key from a seed. The keys are represented as 33-byte hexadecimal strings.
|
||||
|
||||
```
|
||||
sign(messageHex: string, privateKey: string) -> string
|
||||
```
|
||||
Sign an arbitrary hex-encoded message with a private key. Returns the signature as a hexadecimal string.
|
||||
|
||||
```
|
||||
verify(messageHex: string, signature: string, publicKey: string) -> boolean
|
||||
```
|
||||
Verify a signature for a given hex-encoded message and public key. Returns true if the signature is valid, false otherwise.
|
||||
|
||||
```
|
||||
deriveAddress(publicKey: string) -> string
|
||||
```
|
||||
Derive an XRP Ledger classic address from a public key.
|
||||
|
||||
```
|
||||
deriveNodeAddress(publicKey: string) -> string
|
||||
```
|
||||
Derive a node address from a public key.
|
||||
|
||||
|
||||
## Generate a random XRP Ledger address
|
||||
|
||||
```
|
||||
const seed = generateSeed();
|
||||
const keypair = deriveKeypair(seed);
|
||||
const address = deriveAddress(keypair.publicKey);
|
||||
```
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export default class Sha512 {
|
||||
hash: any;
|
||||
constructor();
|
||||
add(bytes: any): this;
|
||||
addU32(i: any): this;
|
||||
finish(): any;
|
||||
first256(): any;
|
||||
first256BN(): any;
|
||||
}
|
||||
//# sourceMappingURL=Sha512.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Sha512.d.ts","sourceRoot":"","sources":["../src/Sha512.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,OAAO,MAAM;IAEzB,IAAI,EAAE,GAAG,CAAA;;IAMT,GAAG,CAAC,KAAK,KAAA;IAKT,MAAM,CAAC,CAAC,KAAA;IASR,MAAM;IAIN,QAAQ;IAIR,UAAU;CAGX"}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/* eslint-disable no-bitwise --
|
||||
* lots of bitwise operators necessary for this */
|
||||
const hashjs = __importStar(require("hash.js"));
|
||||
const BigNum = require("bn.js");
|
||||
class Sha512 {
|
||||
constructor() {
|
||||
this.hash = hashjs.sha512();
|
||||
}
|
||||
add(bytes) {
|
||||
this.hash.update(bytes);
|
||||
return this;
|
||||
}
|
||||
addU32(i) {
|
||||
return this.add([
|
||||
(i >>> 24) & 0xff,
|
||||
(i >>> 16) & 0xff,
|
||||
(i >>> 8) & 0xff,
|
||||
i & 0xff,
|
||||
]);
|
||||
}
|
||||
finish() {
|
||||
return this.hash.digest();
|
||||
}
|
||||
first256() {
|
||||
return this.finish().slice(0, 32);
|
||||
}
|
||||
first256BN() {
|
||||
return new BigNum(this.first256());
|
||||
}
|
||||
}
|
||||
exports.default = Sha512;
|
||||
//# sourceMappingURL=Sha512.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"Sha512.js","sourceRoot":"","sources":["../src/Sha512.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;kDACkD;AAClD,gDAAiC;AACjC,gCAAgC;AAEhC,MAAqB,MAAM;IAIzB;QACE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;IAC7B,CAAC;IAED,GAAG,CAAC,KAAK;QACP,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACvB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,CAAC;QACN,OAAO,IAAI,CAAC,GAAG,CAAC;YACd,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;YACjB,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;YACjB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI;YAChB,CAAC,GAAG,IAAI;SACT,CAAC,CAAA;IACJ,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAA;IAC3B,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACnC,CAAC;IAED,UAAU;QACR,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IACpC,CAAC;CACF;AAjCD,yBAiCC"}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import * as addressCodec from 'ripple-address-codec';
|
||||
declare function generateSeed(options?: {
|
||||
entropy?: Uint8Array;
|
||||
algorithm?: 'ed25519' | 'ecdsa-secp256k1';
|
||||
}): string;
|
||||
declare function deriveKeypair(seed: string, options?: object): {
|
||||
publicKey: string;
|
||||
privateKey: string;
|
||||
};
|
||||
declare function sign(messageHex: any, privateKey: any): string;
|
||||
declare function verify(messageHex: any, signature: any, publicKey: any): boolean;
|
||||
declare function deriveAddress(publicKey: any): string;
|
||||
declare function deriveNodeAddress(publicKey: any): string;
|
||||
declare const decodeSeed: typeof addressCodec.decodeSeed;
|
||||
export { generateSeed, deriveKeypair, sign, verify, deriveAddress, deriveNodeAddress, decodeSeed, };
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAA;AAUpD,iBAAS,YAAY,CACnB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,UAAU,CAAA;IACpB,SAAS,CAAC,EAAE,SAAS,GAAG,iBAAiB,CAAA;CACrC,GACL,MAAM,CAQR;AA4ED,iBAAS,aAAa,CACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,GACf;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB,CAYA;AASD,iBAAS,IAAI,CAAC,UAAU,KAAA,EAAE,UAAU,KAAA,GAAG,MAAM,CAG5C;AAED,iBAAS,MAAM,CAAC,UAAU,KAAA,EAAE,SAAS,KAAA,EAAE,SAAS,KAAA,GAAG,OAAO,CAGzD;AAQD,iBAAS,aAAa,CAAC,SAAS,KAAA,GAAG,MAAM,CAExC;AAED,iBAAS,iBAAiB,CAAC,SAAS,KAAA,GAAG,MAAM,CAI5C;AAED,QAAA,MAAQ,UAAU,gCAAiB,CAAA;AAEnC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,UAAU,GACX,CAAA"}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.decodeSeed = exports.deriveNodeAddress = exports.deriveAddress = exports.verify = exports.sign = exports.deriveKeypair = exports.generateSeed = void 0;
|
||||
const assert = __importStar(require("assert"));
|
||||
const brorand = require("brorand");
|
||||
const hashjs = __importStar(require("hash.js"));
|
||||
const elliptic = __importStar(require("elliptic"));
|
||||
const addressCodec = __importStar(require("ripple-address-codec"));
|
||||
const secp256k1_1 = require("./secp256k1");
|
||||
const utils = __importStar(require("./utils"));
|
||||
const Ed25519 = elliptic.eddsa('ed25519');
|
||||
const Secp256k1 = elliptic.ec('secp256k1');
|
||||
const { hexToBytes } = utils;
|
||||
const { bytesToHex } = utils;
|
||||
function generateSeed(options = {}) {
|
||||
assert.ok(!options.entropy || options.entropy.length >= 16, 'entropy too short');
|
||||
const entropy = options.entropy ? options.entropy.slice(0, 16) : brorand(16);
|
||||
const type = options.algorithm === 'ed25519' ? 'ed25519' : 'secp256k1';
|
||||
return addressCodec.encodeSeed(Buffer.from(entropy), type);
|
||||
}
|
||||
exports.generateSeed = generateSeed;
|
||||
function hash(message) {
|
||||
return hashjs.sha512().update(message).digest().slice(0, 32);
|
||||
}
|
||||
const secp256k1 = {
|
||||
deriveKeypair(entropy, options) {
|
||||
const prefix = '00';
|
||||
const privateKey = prefix + (0, secp256k1_1.derivePrivateKey)(entropy, options).toString(16, 64).toUpperCase();
|
||||
const publicKey = bytesToHex(Secp256k1.keyFromPrivate(privateKey.slice(2))
|
||||
.getPublic()
|
||||
.encodeCompressed());
|
||||
return { privateKey, publicKey };
|
||||
},
|
||||
sign(message, privateKey) {
|
||||
return bytesToHex(Secp256k1.sign(hash(message), hexToBytes(privateKey), {
|
||||
canonical: true,
|
||||
}).toDER());
|
||||
},
|
||||
verify(message, signature, publicKey) {
|
||||
return Secp256k1.verify(hash(message), signature, hexToBytes(publicKey));
|
||||
},
|
||||
};
|
||||
const ed25519 = {
|
||||
deriveKeypair(entropy) {
|
||||
const prefix = 'ED';
|
||||
const rawPrivateKey = hash(entropy);
|
||||
const privateKey = prefix + bytesToHex(rawPrivateKey);
|
||||
const publicKey = prefix + bytesToHex(Ed25519.keyFromSecret(rawPrivateKey).pubBytes());
|
||||
return { privateKey, publicKey };
|
||||
},
|
||||
sign(message, privateKey) {
|
||||
// caution: Ed25519.sign interprets all strings as hex, stripping
|
||||
// any non-hex characters without warning
|
||||
assert.ok(Array.isArray(message), 'message must be array of octets');
|
||||
return bytesToHex(Ed25519.sign(message, hexToBytes(privateKey).slice(1)).toBytes());
|
||||
},
|
||||
verify(message, signature, publicKey) {
|
||||
return Ed25519.verify(message, hexToBytes(signature), hexToBytes(publicKey).slice(1));
|
||||
},
|
||||
};
|
||||
function select(algorithm) {
|
||||
const methods = { 'ecdsa-secp256k1': secp256k1, ed25519 };
|
||||
return methods[algorithm];
|
||||
}
|
||||
function deriveKeypair(seed, options) {
|
||||
const decoded = addressCodec.decodeSeed(seed);
|
||||
const algorithm = decoded.type === 'ed25519' ? 'ed25519' : 'ecdsa-secp256k1';
|
||||
const method = select(algorithm);
|
||||
const keypair = method.deriveKeypair(decoded.bytes, options);
|
||||
const messageToVerify = hash('This test message should verify.');
|
||||
const signature = method.sign(messageToVerify, keypair.privateKey);
|
||||
/* istanbul ignore if */
|
||||
if (method.verify(messageToVerify, signature, keypair.publicKey) !== true) {
|
||||
throw new Error('derived keypair did not generate verifiable signature');
|
||||
}
|
||||
return keypair;
|
||||
}
|
||||
exports.deriveKeypair = deriveKeypair;
|
||||
function getAlgorithmFromKey(key) {
|
||||
const bytes = hexToBytes(key);
|
||||
return bytes.length === 33 && bytes[0] === 0xed
|
||||
? 'ed25519'
|
||||
: 'ecdsa-secp256k1';
|
||||
}
|
||||
function sign(messageHex, privateKey) {
|
||||
const algorithm = getAlgorithmFromKey(privateKey);
|
||||
return select(algorithm).sign(hexToBytes(messageHex), privateKey);
|
||||
}
|
||||
exports.sign = sign;
|
||||
function verify(messageHex, signature, publicKey) {
|
||||
const algorithm = getAlgorithmFromKey(publicKey);
|
||||
return select(algorithm).verify(hexToBytes(messageHex), signature, publicKey);
|
||||
}
|
||||
exports.verify = verify;
|
||||
function deriveAddressFromBytes(publicKeyBytes) {
|
||||
return addressCodec.encodeAccountID(utils.computePublicKeyHash(publicKeyBytes));
|
||||
}
|
||||
function deriveAddress(publicKey) {
|
||||
return deriveAddressFromBytes(Buffer.from(hexToBytes(publicKey)));
|
||||
}
|
||||
exports.deriveAddress = deriveAddress;
|
||||
function deriveNodeAddress(publicKey) {
|
||||
const generatorBytes = addressCodec.decodeNodePublic(publicKey);
|
||||
const accountPublicBytes = (0, secp256k1_1.accountPublicFromPublicGenerator)(generatorBytes);
|
||||
return deriveAddressFromBytes(accountPublicBytes);
|
||||
}
|
||||
exports.deriveNodeAddress = deriveNodeAddress;
|
||||
const { decodeSeed } = addressCodec;
|
||||
exports.decodeSeed = decodeSeed;
|
||||
//# sourceMappingURL=index.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @param seed - Bytes.
|
||||
* @param [opts] - Object.
|
||||
* @param [opts.accountIndex=0] - The account number to generate.
|
||||
* @param [opts.validator=false] - Generate root key-pair,
|
||||
* as used by validators.
|
||||
* @returns {bn.js} 256 bit scalar value.
|
||||
*
|
||||
*/
|
||||
export declare function derivePrivateKey(seed: any, opts?: {
|
||||
validator?: boolean;
|
||||
accountIndex?: number;
|
||||
}): any;
|
||||
export declare function accountPublicFromPublicGenerator(publicGenBytes: any): any;
|
||||
//# sourceMappingURL=secp256k1.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"secp256k1.d.ts","sourceRoot":"","sources":["../src/secp256k1.ts"],"names":[],"mappings":"AAmCA;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,KAAA,EACJ,IAAI,GAAE;IACJ,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;CACjB,OAmBP;AAED,wBAAgB,gCAAgC,CAAC,cAAc,KAAA,OAM9D"}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.accountPublicFromPublicGenerator = exports.derivePrivateKey = void 0;
|
||||
const elliptic = __importStar(require("elliptic"));
|
||||
const Sha512_1 = __importDefault(require("./Sha512"));
|
||||
const secp256k1 = elliptic.ec('secp256k1');
|
||||
function deriveScalar(bytes, discrim) {
|
||||
const order = secp256k1.curve.n;
|
||||
for (let i = 0; i <= 0xffffffff; i++) {
|
||||
// We hash the bytes to find a 256 bit number, looping until we are sure it
|
||||
// is less than the order of the curve.
|
||||
const hasher = new Sha512_1.default().add(bytes);
|
||||
// If the optional discriminator index was passed in, update the hash.
|
||||
if (discrim !== undefined) {
|
||||
hasher.addU32(discrim);
|
||||
}
|
||||
hasher.addU32(i);
|
||||
const key = hasher.first256BN();
|
||||
/* istanbul ignore else */
|
||||
if (key.cmpn(0) > 0 && key.cmp(order) < 0) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
// This error is practically impossible to reach.
|
||||
// The order of the curve describes the (finite) amount of points on the curve
|
||||
// https://github.com/indutny/elliptic/blob/master/lib/elliptic/curves.js#L182
|
||||
// How often will an (essentially) random number generated by Sha512 be larger than that?
|
||||
// There's 2^32 chances (the for loop) to get a number smaller than the order,
|
||||
// and it's rare that you'll even get past the first loop iteration.
|
||||
// Note that in TypeScript we actually need the throw, otherwise the function signature would be BN | undefined
|
||||
//
|
||||
/* istanbul ignore next */
|
||||
throw new Error('impossible unicorn ;)');
|
||||
}
|
||||
/**
|
||||
* @param seed - Bytes.
|
||||
* @param [opts] - Object.
|
||||
* @param [opts.accountIndex=0] - The account number to generate.
|
||||
* @param [opts.validator=false] - Generate root key-pair,
|
||||
* as used by validators.
|
||||
* @returns {bn.js} 256 bit scalar value.
|
||||
*
|
||||
*/
|
||||
function derivePrivateKey(seed, opts = {}) {
|
||||
const root = opts.validator;
|
||||
const order = secp256k1.curve.n;
|
||||
// This private generator represents the `root` private key, and is what's
|
||||
// used by validators for signing when a keypair is generated from a seed.
|
||||
const privateGen = deriveScalar(seed);
|
||||
if (root) {
|
||||
// As returned by validation_create for a given seed
|
||||
return privateGen;
|
||||
}
|
||||
const publicGen = secp256k1.g.mul(privateGen);
|
||||
// A seed can generate many keypairs as a function of the seed and a uint32.
|
||||
// Almost everyone just uses the first account, `0`.
|
||||
const accountIndex = opts.accountIndex || 0;
|
||||
return deriveScalar(publicGen.encodeCompressed(), accountIndex)
|
||||
.add(privateGen)
|
||||
.mod(order);
|
||||
}
|
||||
exports.derivePrivateKey = derivePrivateKey;
|
||||
function accountPublicFromPublicGenerator(publicGenBytes) {
|
||||
const rootPubPoint = secp256k1.curve.decodePoint(publicGenBytes);
|
||||
const scalar = deriveScalar(publicGenBytes, 0);
|
||||
const point = secp256k1.g.mul(scalar);
|
||||
const offset = rootPubPoint.add(point);
|
||||
return offset.encodeCompressed();
|
||||
}
|
||||
exports.accountPublicFromPublicGenerator = accountPublicFromPublicGenerator;
|
||||
//# sourceMappingURL=secp256k1.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"secp256k1.js","sourceRoot":"","sources":["../src/secp256k1.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mDAAoC;AAEpC,sDAA6B;AAE7B,MAAM,SAAS,GAAG,QAAQ,CAAC,EAAE,CAAC,WAAW,CAAC,CAAA;AAE1C,SAAS,YAAY,CAAC,KAAK,EAAE,OAAgB;IAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,EAAE;QACpC,2EAA2E;QAC3E,uCAAuC;QACvC,MAAM,MAAM,GAAG,IAAI,gBAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACtC,sEAAsE;QACtE,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;SACvB;QACD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAChB,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;QAC/B,0BAA0B;QAC1B,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACzC,OAAO,GAAG,CAAA;SACX;KACF;IACD,iDAAiD;IACjD,8EAA8E;IAC9E,8EAA8E;IAC9E,yFAAyF;IACzF,8EAA8E;IAC9E,oEAAoE;IACpE,+GAA+G;IAC/G,EAAE;IACF,0BAA0B;IAC1B,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,gBAAgB,CAC9B,IAAI,EACJ,OAGI,EAAE;IAEN,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAA;IAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAE/B,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACrC,IAAI,IAAI,EAAE;QACR,oDAAoD;QACpD,OAAO,UAAU,CAAA;KAClB;IACD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAC7C,4EAA4E;IAC5E,oDAAoD;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC,CAAA;IAC3C,OAAO,YAAY,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,YAAY,CAAC;SAC5D,GAAG,CAAC,UAAU,CAAC;SACf,GAAG,CAAC,KAAK,CAAC,CAAA;AACf,CAAC;AAxBD,4CAwBC;AAED,SAAgB,gCAAgC,CAAC,cAAc;IAC7D,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,cAAc,CAAC,CAAA;IAChE,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC,CAAA;IAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IACtC,OAAO,MAAM,CAAC,gBAAgB,EAAE,CAAA;AAClC,CAAC;AAND,4EAMC"}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
/// <reference types="node" />
|
||||
declare function bytesToHex(a: Iterable<number> | ArrayLike<number>): string;
|
||||
declare function hexToBytes(a: any): number[];
|
||||
declare function computePublicKeyHash(publicKeyBytes: Buffer): Buffer;
|
||||
export { bytesToHex, hexToBytes, computePublicKeyHash };
|
||||
//# sourceMappingURL=utils.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAIA,iBAAS,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAKnE;AAED,iBAAS,UAAU,CAAC,CAAC,KAAA,GAAG,MAAM,EAAE,CAM/B;AAED,iBAAS,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,CAAA"}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.computePublicKeyHash = exports.hexToBytes = exports.bytesToHex = void 0;
|
||||
const assert = __importStar(require("assert"));
|
||||
const hashjs = __importStar(require("hash.js"));
|
||||
const BN = require("bn.js");
|
||||
function bytesToHex(a) {
|
||||
return Array.from(a, (byteValue) => {
|
||||
const hex = byteValue.toString(16).toUpperCase();
|
||||
return hex.length > 1 ? hex : `0${hex}`;
|
||||
}).join('');
|
||||
}
|
||||
exports.bytesToHex = bytesToHex;
|
||||
function hexToBytes(a) {
|
||||
assert.ok(a.length % 2 === 0);
|
||||
// Special-case length zero to return [].
|
||||
// BN.toArray intentionally returns [0] rather than [] for length zero,
|
||||
// which may make sense for BigNum data, but not for byte strings.
|
||||
return a.length === 0 ? [] : new BN(a, 16).toArray(null, a.length / 2);
|
||||
}
|
||||
exports.hexToBytes = hexToBytes;
|
||||
function computePublicKeyHash(publicKeyBytes) {
|
||||
const hash256 = hashjs.sha256().update(publicKeyBytes).digest();
|
||||
const hash160 = hashjs.ripemd160().update(hash256).digest();
|
||||
return Buffer.from(hash160);
|
||||
}
|
||||
exports.computePublicKeyHash = computePublicKeyHash;
|
||||
//# sourceMappingURL=utils.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAgC;AAChC,gDAAiC;AACjC,4BAA4B;AAE5B,SAAS,UAAU,CAAC,CAAuC;IACzD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAA;QAChD,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAA;IACzC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC;AAiBQ,gCAAU;AAfnB,SAAS,UAAU,CAAC,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7B,yCAAyC;IACzC,uEAAuE;IACvE,kEAAkE;IAClE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACxE,CAAC;AASoB,gCAAU;AAP/B,SAAS,oBAAoB,CAAC,cAAsB;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAA;IAE/D,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAA;IAC3D,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC7B,CAAC;AAEgC,oDAAoB"}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "ripple-keypairs",
|
||||
"version": "1.1.5",
|
||||
"description": "Cryptographic key pairs for the XRP Ledger",
|
||||
"scripts": {
|
||||
"build": "tsc -b",
|
||||
"test": "jest --verbose false --silent=false ./test/*.test.ts",
|
||||
"clean": "rm -rf ./dist && rm -rf tsconfig.tsbuildinfo",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"prepublish": "npm run lint && npm test"
|
||||
},
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"main": "dist/",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {
|
||||
"bn.js": "^5.1.1",
|
||||
"brorand": "^1.0.5",
|
||||
"elliptic": "^6.5.4",
|
||||
"hash.js": "^1.0.3",
|
||||
"ripple-address-codec": "^4.2.5"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:XRPLF/xrpl.js.git"
|
||||
},
|
||||
"license": "ISC",
|
||||
"prettier": "@xrplf/prettier-config",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"gitHead": "b3d3bc2f99c21336c32d234026ddff79f16e8194"
|
||||
}
|
||||
Reference in New Issue
Block a user