@helium/crypto
Version:
Cryptography utilities including mnemonics, keypairs and base58-check encoding
105 lines • 4.28 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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const address_1 = __importStar(require("@helium/address"));
const utils_1 = require("./utils");
const KeySignature_1 = __importDefault(require("./KeySignature"));
const PUBLIC_KEY_LENGTH = 33;
class MultisigSignature {
constructor(addresses, signatures) {
this.addresses = address_1.utils.sortAddresses(addresses);
this.signatures = signatures;
}
async isValid(address) {
if (address.M > this.signatures.length) {
return false;
}
if (address.N !== this.addresses.length) {
return false;
}
const thisAddress = await address_1.MultisigAddress.create(this.addresses, address.M, address.netType);
if (thisAddress.publicKey !== address.publicKey) {
return false;
}
return true;
}
async verify(message) {
const verifiedSignatures = await Promise.all(this.signatures.map((sig) => (0, utils_1.verify)(sig.signature, message, this.addresses[sig.index].publicKey)));
return verifiedSignatures.filter((isVerified) => isVerified === true).length;
}
get bin() {
return new Uint8Array([...this.serializedAddresses(), ...this.serlializedSignatures()]);
}
static fromBin(multisigAddress, input) {
const addresses = this.addressesFromBin(multisigAddress.N, input);
const signatures = this.signaturesFromBin(input.slice(PUBLIC_KEY_LENGTH * multisigAddress.N));
return new MultisigSignature(addresses, signatures);
}
static isValid(multisigAddress, input) {
try {
MultisigSignature.fromBin(multisigAddress, input);
return true;
}
catch (error) {
return false;
}
}
serializedAddresses() {
return this.addresses.reduce((acc, curVal) => new Uint8Array([...acc, ...curVal.bin]), new Uint8Array());
}
serlializedSignatures() {
return this.signatures
.sort((a, b) => (a.bin > b.bin ? 1 : -1))
.reduce((acc, curVal) => new Uint8Array([...acc, ...curVal.bin]), new Uint8Array());
}
static addressesFromBin(N, input) {
return Array(N)
.fill(null)
.map((_, i) => address_1.default.fromBin(Buffer.from(input.slice(PUBLIC_KEY_LENGTH * i, PUBLIC_KEY_LENGTH * (i + 1)))));
}
static signaturesFromBin(input) {
let index = 0;
const signatureList = [];
do {
const addressIndex = input[index];
const start = index + 2;
const end = start + input[index + 1];
signatureList.push(new KeySignature_1.default(addressIndex, input.slice(start, end)));
index += input[index + 1] + 2;
} while (index < input.length);
return signatureList;
}
async sign(message) {
if (await this.verify(message) < 1) {
throw new Error('no valid signatures for message');
}
return this.bin;
}
}
exports.default = MultisigSignature;
//# sourceMappingURL=MultisigSignature.js.map