Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

frostrb

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

frostrb

  • 0.3.0
  • Rubygems
  • Socket score

Version published
Maintainers
1
Created
Source

FROST for Ruby Build Status

This library is ruby implementations of 'Two-Round Threshold Schnorr Signatures with FROST'.

Note: This library has not been security audited and tested widely, so should not be used in production.

The cipher suites currently supported by this library are:

Installation

Add this line to your application's Gemfile:

gem 'frostrb', require: 'frost'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install frostrb

Usage

require 'frost'

group = ECDSA::Group::Secp256k1

# Dealer generate secret.
secret = FROST::SigningKey.generate(group)
group_pubkey = secret.to_point

# Generate polynomial(f(x) = ax + b)
polynomial = secret.gen_poly(1)

# Calculate secret shares.
share1 = polynomial.gen_share(1)
share2 = polynomial.gen_share(2)
share3 = polynomial.gen_share(3)

# Round 1: Generate nonce and commitment
## each party generate hiding and binding nonce.
hiding_nonce1 = FROST::Nonce.gen_from_secret(share1)
binding_nonce1 = FROST::Nonce.gen_from_secret(share1)
hiding_nonce3 = FROST::Nonce.gen_from_secret(share3)
binding_nonce3 = FROST::Nonce.gen_from_secret(share3)

comm1 = FROST::Commitments.new(1, hiding_nonce1.to_point, binding_nonce1.to_point)
comm3 = FROST::Commitments.new(3, hiding_nonce3.to_point, binding_nonce3.to_point)
commitment_list = [comm1, comm3]

msg = ["74657374"].pack("H*")

# Round 2: each participant generates their signature share(1 and 3)
sig_share1 = FROST.sign(share1, group_pubkey, [hiding_nonce1, binding_nonce1], msg, commitment_list)
sig_share3 = FROST.sign(share3, group_pubkey, [hiding_nonce3, binding_nonce3], msg, commitment_list)

# verify signature share
FROST.verify_share(1, share1.to_point, sig_share1, commitment_list, group_pubkey, msg)
FROST.verify_share(3, share3.to_point, sig_share3, commitment_list, group_pubkey, msg)

# Aggregation
sig = FROST.aggregate(commitment_list, msg, group_pubkey, [sig_share1, sig_share3])

# verify final signature
FROST.verify(sig, group_pubkey, msg)

Using DKG

DKG can be run as below.

max_signer = 5
min_signer = 3

secret_packages = {}
round1_outputs = {}
# Round 1:
# For each participant, perform the first part of the DKG protocol.
1.upto(max_signer) do |i|
  secret_package = FROST::DKG.generate_secret(i, min_signer, max_signer, group)
  secret_packages[i] = secret_package
  round1_outputs[i] = secret_package.public_package
end

# Each participant sends their commitments and proof to other participants.
received_package = {}
1.upto(max_signer) do |i|
  received_package[i] = round1_outputs.select { |k, _| k != i }.values
end

# Each participant verify knowledge of proof in received package.
received_package.each do |id, packages|
  secret_package = secret_packages[id]
  packages.each do |package|
    expect(FROST::DKG.verify_proof_of_knowledge(secret_package, package)).to be true
  end
end

# Round 2:
# Each participant generate share for other participants and send it.
received_shares = {}
1.upto(max_signer) do |i|
  secret_package = secret_packages[i] # own secret
  1.upto(max_signer) do |o|
    next if i == o
    received_shares[o] ||= []
    received_shares[o] << [i, secret_package.gen_share(o)]
  end
end

# Each participant verify received shares.
1.upto(max_signer) do |i|
  received_shares[i].each do |send_by, share|
    target_package = received_package[i].find { |package| package.identifier == send_by }
    expect(target_package.verify_share(share)).to be true
  end
end

# Each participant compute signing share.
signing_shares = {}
1.upto(max_signer) do |i|
  shares = received_shares[i].map { |_, share| share }
  signing_shares[i] = FROST::DKG.compute_signing_share(secret_packages[i], shares)
end

# Participant 1 compute group public key.
group_pubkey = FROST::DKG.compute_group_pubkey(secret_packages[1], received_package[1])

# The subsequent signing phase is the same as above with signing_shares as the secret.

Share repair

Using FROST::Repairable module, you can repair existing (or new) participant's share with the cooperation of T participants.

# Dealer generate shares.
FROST::SigningKey.generate(ECDSA::Group::Secp256k1)
polynomial = dealer.gen_poly(min_signers - 1)
shares = 1.upto(max_signers).map {|identifier| polynomial.gen_share(identifier) }

# Signer 2 will lose their share
# Signers (helpers) 1, 4 and 5 will help signer 2 (participant) to recover their share
helper1 = shares[0]
helper4 = shares[3]
helper5 = shares[4]
helper_shares = [helper1, helper4, helper5]
helpers = helper_shares.map(&:identifier)
participant_share = shares[1]

# Each helper computes delta values.
received_values = {}
helper_shares.each do |helper_share|
  delta_values = FROST::Repairable.step1(helpers, participant_share.identifier, helper_share)
  delta_values.each do |target_id, value|
    received_values[target_id] ||= []
    received_values[target_id] << value
  end
end

# Each helper send sum value to participant.
participant_received_values = []
received_values.each do |_, values|
  participant_received_values << FROST::Repairable.step2(values, ECDSA::Group::Secp256k1)
end

# Participant can obtain his share.
repair_share = FROST::Repairable.step3(2, participant_received_values, ECDSA::Group::Secp256k1)

FAQs

Package last updated on 22 Feb 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc