This commit is contained in:
nitowa
2023-08-15 22:28:03 +02:00
commit 1dae68b1c7
5529 changed files with 1659171 additions and 0 deletions
+15
View File
@@ -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
View File
@@ -0,0 +1,48 @@
# ripple-keypairs [![NPM](https://img.shields.io/npm/v/ripple-keypairs.svg)](https://npmjs.org/package/ripple-keypairs) [![Build Status](https://img.shields.io/travis/ripple/ripple-keypairs/master.svg)](https://travis-ci.org/ripple/ripple-keypairs) ![Codecov](https://img.shields.io/codecov/c/github/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.
[![NPM](https://nodei.co/npm/ripple-keypairs.png)](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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
+15
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"
}