UNPKG

moeralib

Version:

Library to interact with Moera decentralized social network

219 lines (218 loc) 8.54 kB
"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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyFingerprintSignature = exports.signFingerprint = exports.digestFingerprint = exports.fingerprintBytes = exports.rawToPrivateKey = exports.rawPrivateKey = exports.rawToPublicKey = exports.rawPublicKey = exports.mnemonicToPrivateKey = exports.generateMnemonicKey = exports.generateKey = void 0; const crypto_1 = __importDefault(require("crypto")); const util_1 = require("util"); const bip39 = __importStar(require("@scure/bip39")); const english_1 = require("@scure/bip39/wordlists/english"); const fingerprint_1 = require("./fingerprint"); const EMPTY_KEY = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; const CURVE_FIELD = BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"); /** * Generate a pair of cryptographic keys. * * @return {Promise<crypto.KeyPairKeyObjectResult>} the keys */ function generateKey() { return __awaiter(this, void 0, void 0, function* () { return (0, util_1.promisify)(crypto_1.default.generateKeyPair)("ec", { namedCurve: "secp256k1" }); }); } exports.generateKey = generateKey; /** * Generate a private cryptographic key with a mnemonic. * * @return {Promise<[string, crypto.KeyObject]>} the mnemonic and the key */ function generateMnemonicKey() { return __awaiter(this, void 0, void 0, function* () { const mnemonic = bip39.generateMnemonic(english_1.wordlist, 256); const privateKey = yield mnemonicToPrivateKey(mnemonic); return [mnemonic, privateKey]; }); } exports.generateMnemonicKey = generateMnemonicKey; /** * Restore a private key from the given mnemonic. * * @param {string} mnemonic - the mnemonic * @return {Promise<crypto.KeyObject>} the private key */ function mnemonicToPrivateKey(mnemonic) { return __awaiter(this, void 0, void 0, function* () { const seed = yield bip39.mnemonicToSeed(mnemonic); let seedValue = BigInt(0); for (let i = 0; i < seed.length; i++) { seedValue = (seedValue << BigInt(8)) + BigInt(seed[i]); } const dValue = (seedValue % CURVE_FIELD).toString(16).padStart(64, "0"); const d = Buffer.alloc(32); for (let i = 0; i < 32; i++) { d.writeUint8(parseInt(dValue.substring(i * 2, 2), 16), i); } return crypto_1.default.createPrivateKey({ format: "jwk", key: { kty: "EC", d: d.toString("base64url"), crv: "secp256k1" } }); }); } exports.mnemonicToPrivateKey = mnemonicToPrivateKey; /** * Convert a public key to the raw format used by the naming server. * * @param {crypto.KeyObject} publicKey - the public key * @return {Buffer} the raw public key */ function rawPublicKey(publicKey) { var _a, _b; const jwk = publicKey.export({ format: "jwk" }); return Buffer.concat([ Buffer.from((_a = jwk.x) !== null && _a !== void 0 ? _a : EMPTY_KEY, "base64url"), Buffer.from((_b = jwk.y) !== null && _b !== void 0 ? _b : EMPTY_KEY, "base64url") ]); } exports.rawPublicKey = rawPublicKey; /** * Restore a public key from the raw format. * * @param {Buffer} rawPublicKey - the raw public key * @return {crypto.KeyObject} the public key */ function rawToPublicKey(rawPublicKey) { const x = rawPublicKey.subarray(0, 32).toString("base64url"); const y = rawPublicKey.subarray(32, 64).toString("base64url"); return crypto_1.default.createPublicKey({ format: "jwk", key: { kty: "EC", x, y, crv: "secp256k1" } }); } exports.rawToPublicKey = rawToPublicKey; /** * Convert a private key to the raw format to pass to the client. * * @param {crypto.KeyObject} privateKey - the private key * @return {Buffer} the raw private key */ function rawPrivateKey(privateKey) { var _a; const jwk = privateKey.export({ format: "jwk" }); return Buffer.from((_a = jwk.d) !== null && _a !== void 0 ? _a : EMPTY_KEY, "base64url"); } exports.rawPrivateKey = rawPrivateKey; /** * Restore a private key from the raw format. * * @param {Buffer} rawPrivateKey - the raw private key * @return {crypto.KeyObject} the private key */ function rawToPrivateKey(rawPrivateKey) { const d = rawPrivateKey.toString("base64url"); return crypto_1.default.createPrivateKey({ format: "jwk", key: { kty: "EC", // x and y here are placeholders x: 'xJrw0U2Qb1xyoxpfwCYVwCZakhd-LbjeBvLLNGAPTEU', y: 'INp-PvmYleX19zhuXbwfnIcZO9a8RSuK7r-_4jneDGM', d, crv: "secp256k1" } }); } exports.rawToPrivateKey = rawToPrivateKey; /** * Encode a fingerprint in the binary form, using the given fingerprint data and schema. * * @param {Fingerprint} fingerprint - the fingerprint data * @param {FingerprintSchema} schema - the fingerprint schema * @return {Buffer} the fingerprint in the binary form */ function fingerprintBytes(fingerprint, schema) { const fingerprintWriter = new fingerprint_1.FingerprintWriter(); fingerprintWriter.append(fingerprint, schema); return fingerprintWriter.toBytes(); } exports.fingerprintBytes = fingerprintBytes; /** * Calculate a cryptographic digest of the fingerprint. * * @param {Buffer} fingerprint - the fingerprint * @return {Buffer} the digest */ function digestFingerprint(fingerprint) { const digest = crypto_1.default.createHash("sha3-256"); digest.update(fingerprint); return digest.digest(); } exports.digestFingerprint = digestFingerprint; /** * Sign a fingerprint with a private key. * * @param {Buffer} fingerprint - the fingerprint to be signed * @param {crypto.KeyObject} privateKey - the private key * @return {Buffer} the signature */ function signFingerprint(fingerprint, privateKey) { const sign = crypto_1.default.createSign("SHA3-256"); sign.update(fingerprint); return sign.sign(privateKey); } exports.signFingerprint = signFingerprint; /** * Verify a fingerprint signature with the given public key. * * @param {Buffer} fingerprint - the original fingerprint * @param {Buffer} signature - the signature to be verified * @param {crypto.KeyObject} publicKey - the public key for verification * @return {boolean} `true`, if the signature is correct, `false` otherwise */ function verifyFingerprintSignature(fingerprint, signature, publicKey) { const verify = crypto_1.default.createVerify("SHA3-256"); verify.update(fingerprint); return verify.verify(publicKey, signature); } exports.verifyFingerprintSignature = verifyFingerprintSignature;