PHP WebShell

Текущая директория: /usr/lib/node_modules/bitgo/node_modules/@iota/iota-sdk/dist/esm/multisig

Просмотр файла: publickey.js

import { fromBase64, toBase64 } from "@iota/bcs";
import { blake2b } from "@noble/hashes/blake2b";
import { bytesToHex } from "@noble/hashes/utils";
import { bcs } from "../bcs/index.js";
import { bytesEqual, PublicKey } from "../cryptography/publickey.js";
import {
  SIGNATURE_FLAG_TO_SCHEME,
  SIGNATURE_SCHEME_TO_FLAG
} from "../cryptography/signature-scheme.js";
import { parseSerializedSignature } from "../cryptography/signature.js";
import { normalizeIotaAddress } from "../utils/iota-types.js";
import { publicKeyFromRawBytes } from "../verify/index.js";
import { MultiSigSigner } from "./signer.js";
const MAX_SIGNER_IN_MULTISIG = 10;
const MIN_SIGNER_IN_MULTISIG = 1;
class MultiSigPublicKey extends PublicKey {
  /**
   * Create a new MultiSigPublicKey object
   */
  constructor(value) {
    super();
    if (typeof value === "string") {
      this.rawBytes = fromBase64(value);
      this.multisigPublicKey = bcs.MultiSigPublicKey.parse(this.rawBytes);
    } else if (value instanceof Uint8Array) {
      this.rawBytes = value;
      this.multisigPublicKey = bcs.MultiSigPublicKey.parse(this.rawBytes);
    } else {
      this.multisigPublicKey = value;
      this.rawBytes = bcs.MultiSigPublicKey.serialize(value).toBytes();
    }
    if (this.multisigPublicKey.threshold < 1) {
      throw new Error("Invalid threshold");
    }
    const seenPublicKeys = /* @__PURE__ */ new Set();
    this.publicKeys = this.multisigPublicKey.pk_map.map(({ pubKey, weight }) => {
      const [scheme, bytes] = Object.entries(pubKey).filter(
        ([name]) => name !== "$kind"
      )[0];
      const publicKeyStr = Uint8Array.from(bytes).toString();
      if (seenPublicKeys.has(publicKeyStr)) {
        throw new Error(`Multisig does not support duplicate public keys`);
      }
      seenPublicKeys.add(publicKeyStr);
      if (weight < 1) {
        throw new Error(`Invalid weight`);
      }
      return {
        publicKey: publicKeyFromRawBytes(scheme, Uint8Array.from(bytes)),
        weight
      };
    });
    const totalWeight = this.publicKeys.reduce((sum, { weight }) => sum + weight, 0);
    if (this.multisigPublicKey.threshold > totalWeight) {
      throw new Error(`Unreachable threshold`);
    }
    if (this.publicKeys.length > MAX_SIGNER_IN_MULTISIG) {
      throw new Error(`Max number of signers in a multisig is ${MAX_SIGNER_IN_MULTISIG}`);
    }
    if (this.publicKeys.length < MIN_SIGNER_IN_MULTISIG) {
      throw new Error(`Min number of signers in a multisig is ${MIN_SIGNER_IN_MULTISIG}`);
    }
  }
  /**
   * 	A static method to create a new MultiSig publickey instance from a set of public keys and their associated weights pairs and threshold.
   */
  static fromPublicKeys({
    threshold,
    publicKeys
  }) {
    return new MultiSigPublicKey({
      pk_map: publicKeys.map(({ publicKey, weight }) => {
        const scheme = SIGNATURE_FLAG_TO_SCHEME[publicKey.flag()];
        return {
          pubKey: { [scheme]: Array.from(publicKey.toRawBytes()) },
          weight
        };
      }),
      threshold
    });
  }
  /**
   * Checks if two MultiSig public keys are equal
   */
  equals(publicKey) {
    return super.equals(publicKey);
  }
  /**
   * Return the byte array representation of the MultiSig public key
   */
  toRawBytes() {
    return this.rawBytes;
  }
  getPublicKeys() {
    return this.publicKeys;
  }
  getThreshold() {
    return this.multisigPublicKey.threshold;
  }
  getSigner(...signers) {
    return new MultiSigSigner(this, signers);
  }
  /**
   * Return the IOTA address associated with this MultiSig public key
   */
  toIotaAddress() {
    const maxLength = 1 + (64 + 1) * MAX_SIGNER_IN_MULTISIG + 2;
    const tmp = new Uint8Array(maxLength);
    tmp.set([SIGNATURE_SCHEME_TO_FLAG["MultiSig"]]);
    tmp.set(bcs.u16().serialize(this.multisigPublicKey.threshold).toBytes(), 1);
    let i = 3;
    for (const { publicKey, weight } of this.publicKeys) {
      const bytes = publicKey.toIotaBytesForAddress();
      tmp.set(bytes, i);
      i += bytes.length;
      tmp.set([weight], i++);
    }
    return normalizeIotaAddress(bytesToHex(blake2b(tmp.slice(0, i), { dkLen: 32 })));
  }
  /**
   * Return the IOTA address associated with this MultiSig public key
   */
  flag() {
    return SIGNATURE_SCHEME_TO_FLAG["MultiSig"];
  }
  /**
   * Verifies that the signature is valid for the provided message
   */
  async verify(message, multisigSignature) {
    const parsed = parseSerializedSignature(multisigSignature);
    if (parsed.signatureScheme !== "MultiSig") {
      throw new Error("Invalid signature scheme");
    }
    const { multisig } = parsed;
    let signatureWeight = 0;
    if (!bytesEqual(
      bcs.MultiSigPublicKey.serialize(this.multisigPublicKey).toBytes(),
      bcs.MultiSigPublicKey.serialize(multisig.multisig_pk).toBytes()
    )) {
      return false;
    }
    for (const { publicKey, weight, signature } of parsePartialSignatures(multisig)) {
      if (!await publicKey.verify(message, signature)) {
        return false;
      }
      signatureWeight += weight;
    }
    return signatureWeight >= this.multisigPublicKey.threshold;
  }
  /**
   * Combines multiple partial signatures into a single multisig, ensuring that each public key signs only once
   * and that all the public keys involved are known and valid, and then serializes multisig into the standard format
   */
  combinePartialSignatures(signatures) {
    if (signatures.length > MAX_SIGNER_IN_MULTISIG) {
      throw new Error(`Max number of signatures in a multisig is ${MAX_SIGNER_IN_MULTISIG}`);
    }
    let bitmap = 0;
    const compressedSignatures = new Array(signatures.length);
    for (let i = 0; i < signatures.length; i++) {
      const parsed = parseSerializedSignature(signatures[i]);
      if (parsed.signatureScheme === "MultiSig") {
        throw new Error("MultiSig is not supported inside MultiSig");
      }
      const publicKey = parsed.publicKey;
      compressedSignatures[i] = {
        [parsed.signatureScheme]: Array.from(
          parsed.signature.map((x) => Number(x))
        )
      };
      let publicKeyIndex;
      for (let j = 0; j < this.publicKeys.length; j++) {
        if (bytesEqual(publicKey, this.publicKeys[j].publicKey.toRawBytes())) {
          if (bitmap & 1 << j) {
            throw new Error("Received multiple signatures from the same public key");
          }
          publicKeyIndex = j;
          break;
        }
      }
      if (publicKeyIndex === void 0) {
        throw new Error("Received signature from unknown public key");
      }
      bitmap |= 1 << publicKeyIndex;
    }
    const multisig = {
      sigs: compressedSignatures,
      bitmap,
      multisig_pk: this.multisigPublicKey
    };
    const bytes = bcs.MultiSig.serialize(multisig, { maxSize: 8192 }).toBytes();
    const tmp = new Uint8Array(bytes.length + 1);
    tmp.set([SIGNATURE_SCHEME_TO_FLAG["MultiSig"]]);
    tmp.set(bytes, 1);
    return toBase64(tmp);
  }
}
function parsePartialSignatures(multisig) {
  const res = new Array(multisig.sigs.length);
  for (let i = 0; i < multisig.sigs.length; i++) {
    const [signatureScheme, signature] = Object.entries(multisig.sigs[i]).filter(
      ([name]) => name !== "$kind"
    )[0];
    const pkIndex = asIndices(multisig.bitmap).at(i);
    const pair = multisig.multisig_pk.pk_map[pkIndex];
    const pkBytes = Uint8Array.from(Object.values(pair.pubKey)[0]);
    if (signatureScheme === "MultiSig") {
      throw new Error("MultiSig is not supported inside MultiSig");
    }
    const publicKey = publicKeyFromRawBytes(signatureScheme, pkBytes);
    res[i] = {
      signatureScheme,
      signature: Uint8Array.from(signature),
      publicKey,
      weight: pair.weight
    };
  }
  return res;
}
function asIndices(bitmap) {
  if (bitmap < 0 || bitmap > 1024) {
    throw new Error("Invalid bitmap");
  }
  const res = [];
  for (let i = 0; i < 10; i++) {
    if ((bitmap & 1 << i) !== 0) {
      res.push(i);
    }
  }
  return Uint8Array.from(res);
}
export {
  MAX_SIGNER_IN_MULTISIG,
  MIN_SIGNER_IN_MULTISIG,
  MultiSigPublicKey,
  parsePartialSignatures
};
//# sourceMappingURL=publickey.js.map

Выполнить команду


Для локальной разработки. Не используйте в интернете!