moeralib
Version:
Library to interact with Moera decentralized social network
219 lines (218 loc) • 8.54 kB
JavaScript
;
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;