-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
module FROST | ||
# Distributed Key Generation feature. | ||
module DKG | ||
|
||
autoload :Package, "frost/dkg/package" | ||
|
||
module_function | ||
|
||
# Performs the first part of the DKG. | ||
# Participant generate key and commitments, proof of knowledge for secret. | ||
# @param [Integer] identifier | ||
# @param [ECDSA::Group] group Group of elliptic curve. | ||
# @return [Array] The triple of polynomial and public package(FROST::DKG::Package) | ||
def part1(identifier, min_signers, max_signers, group) | ||
raise ArgumentError, "identifier must be Integer" unless identifier.is_a?(Integer) | ||
raise ArgumentError, "identifier must be greater than 0." if identifier < 1 | ||
raise ArgumentError, "group must be ECDSA::Group." unless group.is_a?(ECDSA::Group) | ||
raise ArgumentError, "max_signers must be greater than or equal to min_signers." if max_signers < min_signers | ||
|
||
secret = FROST::SigningKey.generate(group) | ||
# Every participant P_i samples t random values (a_{i0}, ..., a_{i(t−1)}) ← Z_q | ||
polynomial = secret.gen_poly(min_signers - 1) | ||
[polynomial, Package.new(identifier, polynomial.gen_commitments, polynomial.gen_proof_of_knowledge(identifier))] | ||
end | ||
|
||
# Verify proof of knowledge for received commitment. | ||
# @param [FROST::DKG::Package] package Received package. | ||
# @return [Boolean] | ||
def verify_proof_of_knowledge(package) | ||
verification_key = package.verification_key | ||
msg = FROST.encode_identifier(package.identifier, verification_key.group) + | ||
[verification_key.to_hex + package.proof.r.to_hex].pack("H*") | ||
challenge = Hash.hdkg(msg, verification_key.group) | ||
package.proof.r == verification_key.group.generator * package.proof.s + (verification_key * challenge).negate | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
module FROST | ||
module DKG | ||
class Package | ||
attr_reader :identifier | ||
attr_reader :commitments | ||
attr_reader :proof | ||
|
||
# Constructor | ||
# @param [Integer] identifier | ||
# @param [Array] commitments The list of commitment. | ||
# @param [FROST::Signature] proof | ||
def initialize(identifier, commitments, proof) | ||
raise ArgumentError, "identifier must be Integer." unless identifier.is_a?(Integer) | ||
raise ArgumentError, "identifier must be greater than 0." if identifier < 1 | ||
raise ArgumentError, "proof must be FROST::Signature." unless proof.is_a?(FROST::Signature) | ||
|
||
@identifier = identifier | ||
@commitments = commitments | ||
@proof = proof | ||
end | ||
|
||
# Get verification key for this proof. | ||
# @return [ECDSA::Point] | ||
def verification_key | ||
commitments.first | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe FROST::DKG do | ||
|
||
let(:group) { ECDSA::Group::Secp256k1 } | ||
|
||
describe "sign with dkg" do | ||
it do | ||
max_signer = 5 | ||
min_signer = 3 | ||
|
||
secrets = {} | ||
round1_outputs = {} | ||
# Round 1: For each participant, perform the first part of the DKG protocol. | ||
1.upto(max_signer) do |i| | ||
polynomial, package = FROST::DKG.part1(i, min_signer, max_signer, group) | ||
secrets[i] = polynomial | ||
round1_outputs[i] = package | ||
end | ||
|
||
# Each participant send 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| | ||
packages.each do |package| | ||
expect(FROST::DKG.verify_proof_of_knowledge(package)).to be true | ||
end | ||
end | ||
end | ||
end | ||
|
||
end |