npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@silencelaboratories/ecdsa-tss

v1.1.3

Published

ECDSA TSS(2,2) library

Downloads

504

Readme

ECDSA secp256k1 TSS(2,2) JS library

Actions

The library provides the following actions:

  • 2-party ECDSA secp256k1: generation and signing
  • Key share refresh

Benchmarking and Performance

Apple M1, 8GB RAM (node v18.4.0)

KeyGen no pre-generated Paillier keys x 0 ops/sec @ 1275ms/op ± 15.34% (min: 712ms, max: 2178ms)
KeyGen with pre-generated Paillier keys x 2 ops/sec @ 399ms/op
Signature x 10 ops/sec @ 98ms/op

RAM: rss=175.1mb heap=46.1mb used=22.6mb ext=0.9mb arr=0.5mb

Intel i5-6500, 32GB RAM (Windows 10, node v18.7.0)

KeyGen no pre-generated Paillier keys x 0 ops/sec @ 6209ms/op ± 16.78% (min: 3331ms, max: 10618ms)
KeyGen with pre-generated Paillier keys x 0 ops/sec @ 2025ms/op
Signature x 1 ops/sec @ 539ms/op

RAM: rss=68.5mb heap=30.4mb used=17.1mb ext=1.1mb arr=0.7mb

Installation

npm install @silencelaboratories/ecdsa-tss

Then either require (Node.js CommonJS):

const ecdsaTSS = require("@silencelaboratories/ecdsa-tss");

or import (JavaScript ES module):

import * as ecdsaTSS from "@silencelaboratories/ecdsa-tss";

An example of KeyGen:

import {
  IP1KeyShare,
  IP2KeyShare,
  P1KeyGen,
  P2KeyGen,
  randBytes,
} from "@silencelaboratories/ecdsa-tss";

export async function performKeygen(): Promise<
  [IP1KeyShare, IP2KeyShare] | null
> {
  const sessionId = "some session id";
  const x1 = await randBytes(32);
  const x2 = await randBytes(32);

  const p1 = new P1KeyGen(sessionId, x1);
  await p1.init();
  const p2 = new P2KeyGen(sessionId, x2);

  // Round 1
  const msg1 = await p1.processMessage(null);
  const msg2 = await p2.processMessage(msg1.msg_to_send);

  // Round 2
  const msg3 = await p1.processMessage(msg2.msg_to_send);
  const p1KeyShare = msg3.p1_key_share;

  let msg4 = await p2.processMessage(msg3.msg_to_send);
  const p2KeyShare = msg4.p2_key_share;

  if (!p1KeyShare || !p2KeyShare) {
    return null;
  }

  return [p1KeyShare, p2KeyShare];
}

An example of Sign:

import {
  P1Signature,
  P2Signature,
  IP1KeyShare,
  IP2KeyShare,
  randBytes,
  IP1SignatureResult,
  IP2SignatureResult,
} from "@silencelaboratories/ecdsa-tss";

async function signature() {
  const keyshares = await performKeygen();
  if (keyshares === null) {
    throw new Error("Keygen failed");
  }

  const sessionId = "session id for signature";
  const messageHash = await randBytes(32);
  const p1 = new P1Signature(sessionId, messageHash, keyshares[0]);
  const p2 = new P2Signature(sessionId, messageHash, keyshares[1]);

  // Round 1
  const msg1 = await p1.processMessage(null);
  const msg2 = await p2.processMessage(msg1.msg_to_send);

  // Round 2
  const msg3 = await p1.processMessage(msg2.msg_to_send);
  const msg4 = await p2.processMessage(msg3.msg_to_send);

  // Round 3
  const msg5 = await p1.processMessage(msg4.msg_to_send);
  const p1Sign = msg5.signature;
  const msg6 = await p2.processMessage(msg5.msg_to_send);
  const p2Sign = msg6.signature;

  if (!p1Sign || !p2Sign) {
    return null;
  }

  console.log("p1Sign", "0x" + p1Sign);
  console.log("p2Sign", "0x" + p2Sign);
}

An example of Key Refresh:

import {
  P1KeyGen,
  P2KeyGen,
  IP1KeyShare,
  IP2KeyShare,
  randBytes,
  IP1KeyGenResult,
  IP2KeyGenResult,
} from "@silencelaboratories/ecdsa-tss";

async function refresh() {
  const keyshares = await performKeygen();

  if (!keyshares) {
    throw new Error("Failed to generate keyshares");
  }

  console.log("P1 keyshare pubkey:", "0x" + keyshares[0].public_key);
  console.log("P2 keyshare pubkey:", "0x" + keyshares[1].public_key);

  const sessionId = "session id for key generation action";

  /// Initialize with old keyshare
  const p1 = P1KeyGen.getInstanceForKeyRefresh(sessionId, keyshares[0]);
  await p1.init();

  /// Initialize with old keyshare
  const p2 = P2KeyGen.getInstanceForKeyRefresh(sessionId, keyshares[1]);

  // Round 1
  const msg1 = await p1.processMessage(null);
  const msg2 = await p2.processMessage(msg1.msg_to_send);

  // Round 2
  const msg3 = await p1.processMessage(msg2.msg_to_send);
  const p1KeyShare = msg3.p1_key_share;
  let msg4 = await p2.processMessage(msg3.msg_to_send);
  const p2KeyShare = msg4.p2_key_share;

  if (!p1KeyShare || !p2KeyShare) {
    return null;
  }

  console.log("Successfully refreshed keyshares!");
  console.log(
    "Public key after refresh (should remain the same as before): ",
    p1KeyShare.public_key
  );
}