Module: FROST::DKG
- Defined in:
- lib/frost/dkg.rb,
lib/frost/dkg/package.rb
Overview
Distributed Key Generation feature.
Defined Under Namespace
Classes: Package
Class Method Summary collapse
-
.compute_group_pubkey(polynomial, received_packages) ⇒ ECDSA::Point
Compute Group public key.
-
.compute_signing_share(polynomial, received_shares) ⇒ FROST::SecretShare
Compute signing share using received shares from other participants.
-
.gen_proof_of_knowledge(identifier, polynomial) ⇒ FROST::Signature
Generate proof of knowledge for secret.
-
.generate_secret(identifier, min_signers, max_signers, group) ⇒ Array
Performs the first part of the DKG.
-
.verify_proof_of_knowledge(package) ⇒ Boolean
Verify proof of knowledge for received commitment.
Class Method Details
.compute_group_pubkey(polynomial, received_packages) ⇒ ECDSA::Point
Compute Group public key.
75 76 77 78 |
# File 'lib/frost/dkg.rb', line 75 def compute_group_pubkey(polynomial, received_packages) raise ArgumentError, "polynomial must be FROST::Polynomial." unless polynomial.is_a?(FROST::Polynomial) received_packages.inject(polynomial.verification_point) {|sum, package| sum + package.commitments.first } end |
.compute_signing_share(polynomial, received_shares) ⇒ FROST::SecretShare
Compute signing share using received shares from other participants
62 63 64 65 66 67 68 69 |
# File 'lib/frost/dkg.rb', line 62 def compute_signing_share(polynomial, received_shares) raise ArgumentError, "polynomial must be FROST::Polynomial." unless polynomial.is_a?(FROST::Polynomial) identifier = received_shares.first.identifier s_id = received_shares.sum {|share| share.share} field = ECDSA::PrimeField.new(polynomial.group.order) FROST::SecretShare.new( identifier, field.mod(s_id + polynomial.gen_share(identifier).share), polynomial.group) end |
.gen_proof_of_knowledge(identifier, polynomial) ⇒ FROST::Signature
Generate proof of knowledge for secret.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/frost/dkg.rb', line 30 def gen_proof_of_knowledge(identifier, polynomial) raise ArgumentError, "identifier must be Integer." unless identifier.is_a?(Integer) raise ArgumentError, "polynomial must be FROST::Polynomial." unless polynomial.is_a?(FROST::Polynomial) k = SecureRandom.random_number(polynomial.group.order - 1) r = polynomial.group.generator * k a0 = polynomial.coefficients.first a0_g = polynomial.group.generator * a0 msg = FROST.encode_identifier(identifier, polynomial.group) + [a0_g.to_hex + r.to_hex].pack("H*") challenge = Hash.hdkg(msg, polynomial.group) field = ECDSA::PrimeField.new(polynomial.group.order) s = field.mod(k + a0 * challenge) FROST::Signature.new(r, s) end |
.generate_secret(identifier, min_signers, max_signers, group) ⇒ Array
Performs the first part of the DKG. Participant generate key and commitments, proof of knowledge for secret.
14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/frost/dkg.rb', line 14 def generate_secret(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(package) ⇒ Boolean
Verify proof of knowledge for received commitment.
48 49 50 51 52 53 54 55 56 |
# File 'lib/frost/dkg.rb', line 48 def verify_proof_of_knowledge(package) raise ArgumentError, "package must be FROST::DKG::Package." unless package.is_a?(FROST::DKG::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 |