Module: FROST::DKG
- Defined in:
- lib/frost/dkg.rb,
lib/frost/dkg/package.rb,
lib/frost/dkg/secret_package.rb
Overview
Distributed Key Generation feature.
Defined Under Namespace
Classes: Package, SecretPackage
Class Method Summary collapse
-
.compute_group_pubkey(secret_package, received_packages) ⇒ ECDSA::Point
Compute Group public key.
-
.compute_signing_share(secret_package, 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) ⇒ FROST::DKG::SecretPackage
Performs the first part of the DKG.
-
.verify_proof_of_knowledge(secret_package, received_package) ⇒ Boolean
Verify proof of knowledge for received commitment.
Class Method Details
.compute_group_pubkey(secret_package, received_packages) ⇒ ECDSA::Point
Compute Group public key.
82 83 84 85 86 87 |
# File 'lib/frost/dkg.rb', line 82 def compute_group_pubkey(secret_package, received_packages) raise ArgumentError, "polynomial must be FROST::DKG::SecretPackage." unless secret_package.is_a?(FROST::DKG::SecretPackage) raise FROST::Error, "Invalid number of received_packages." unless secret_package.max_signers - 1 == received_packages.length received_packages.inject(secret_package.verification_point) {|sum, package| sum + package.commitments.first } end |
.compute_signing_share(secret_package, received_shares) ⇒ FROST::SecretShare
Compute signing share using received shares from other participants
67 68 69 70 71 72 73 74 75 76 |
# File 'lib/frost/dkg.rb', line 67 def compute_signing_share(secret_package, received_shares) raise ArgumentError, "polynomial must be FROST::DKG::SecretPackage." unless secret_package.is_a?(FROST::DKG::SecretPackage) raise FROST::Error, "Invalid number of received_shares." unless secret_package.max_signers - 1 == received_shares.length identifier = received_shares.first.identifier s_id = received_shares.sum {|share| share.share} field = ECDSA::PrimeField.new(secret_package.group.order) FROST::SecretShare.new( identifier, field.mod(s_id + secret_package.gen_share(identifier).share), secret_package.group) end |
.gen_proof_of_knowledge(identifier, polynomial) ⇒ FROST::Signature
Generate proof of knowledge for secret.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/frost/dkg.rb', line 32 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) ⇒ FROST::DKG::SecretPackage
Performs the first part of the DKG. Participant generate key and commitments, proof of knowledge for secret.
15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/frost/dkg.rb', line 15 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, "min_signers must be Integer." unless min_signers.is_a?(Integer) raise ArgumentError, "max_singers must be Integer." unless max_signers.is_a?(Integer) raise ArgumentError, "max_signers must be greater than or equal to min_signers." if max_signers < min_signers secret = FROST::SigningKey.generate(group) polynomial = secret.gen_poly(min_signers - 1) SecretPackage.new(identifier, min_signers, max_signers, polynomial) end |
.verify_proof_of_knowledge(secret_package, received_package) ⇒ Boolean
Verify proof of knowledge for received commitment.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/frost/dkg.rb', line 51 def verify_proof_of_knowledge(secret_package, received_package) raise ArgumentError, "secret_package must be FROST::DKG::SecretPackage." unless secret_package.is_a?(FROST::DKG::SecretPackage) raise ArgumentError, "received_package must be FROST::DKG::Package." unless received_package.is_a?(FROST::DKG::Package) raise FROST::Error, "Invalid number of commitments in package." unless secret_package.min_signers == received_package.commitments.length verification_key = received_package.verification_key msg = FROST.encode_identifier(received_package.identifier, verification_key.group) + [verification_key.to_hex + received_package.proof.r.to_hex].pack("H*") challenge = Hash.hdkg(msg, verification_key.group) received_package.proof.r == verification_key.group.generator * received_package.proof.s + (verification_key * challenge).negate end |