Module: Schnorr::MuSig
- Defined in:
- lib/schnorr/mu_sig.rb,
lib/schnorr/mu_sig/session.rb
Overview
Defined Under Namespace
Classes: Session
Constant Summary collapse
- TAG =
SHA256(“MuSig coefficient”)
['74894a2bec01af68225002cae9b0430ab63151ede5d31f641791976c7140b57b'].pack('H*')
Class Method Summary collapse
- .compute_ell(public_keys) ⇒ String
-
.partial_sig_combine(combined_nonce, signatures) ⇒ Schnorr::Signature
Combine the partial signatures to obtain a complete signature.
-
.pubkey_combine(public_keys, ell: nil) ⇒ String
Combine public keys.
-
.session_initialize(session_id, private_key, message, combined_pubkey, ell, index, num_signers) ⇒ Schnorr::MuSig::Session
Initialize session to signer starts the session.
Class Method Details
.compute_ell(public_keys) ⇒ String
16 17 18 |
# File 'lib/schnorr/mu_sig.rb', line 16 def compute_ell(public_keys) Digest::SHA256.digest(public_keys.join) end |
.partial_sig_combine(combined_nonce, signatures) ⇒ Schnorr::Signature
Combine the partial signatures to obtain a complete signature.
73 74 75 76 77 78 |
# File 'lib/schnorr/mu_sig.rb', line 73 def partial_sig_combine(combined_nonce, signatures) point_r = ECDSA::Format::PointOctetString.decode(combined_nonce, ECDSA::Group::Secp256k1) field = ECDSA::PrimeField.new(ECDSA::Group::Secp256k1.order) signature = signatures.inject{|sum, s|field.mod(sum + s)} Schnorr::Signature.new(point_r.x, signature) end |
.pubkey_combine(public_keys, ell: nil) ⇒ String
Combine public keys.
23 24 25 26 27 28 29 30 31 |
# File 'lib/schnorr/mu_sig.rb', line 23 def pubkey_combine(public_keys, ell: nil) ell = compute_ell(public_keys) unless ell points = public_keys.map.with_index do |p, idx| xi = ECDSA::Format::PointOctetString.decode(p, ECDSA::Group::Secp256k1) xi.multiply_by_scalar(coefficient(ell, idx)) end sum = points.inject(:+) ECDSA::Format::PointOctetString.encode(sum, compression: true) end |
.session_initialize(session_id, private_key, message, combined_pubkey, ell, index, num_signers) ⇒ Schnorr::MuSig::Session
Initialize session to signer starts the session.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/schnorr/mu_sig.rb', line 51 def session_initialize(session_id, private_key, , combined_pubkey, ell, index, num_signers) raise ArgumentError, 'session_id must be 32 bytes.' if session_id && session_id.bytesize != 32 raise ArgumentError, 'message must be 32 bytes.' unless .bytesize == 32 raise ArgumentError, 'combined_pubkey must be 33 bytes.' unless combined_pubkey.bytesize == 33 raise ArgumentError, 'ell must be 32 bytes.' unless ell.bytesize == 32 secret = ECDSA::Format::IntegerOctetString.encode(private_key, ECDSA::Group::Secp256k1.byte_length) field = ECDSA::PrimeField.new(ECDSA::Group::Secp256k1.order) session = Schnorr::MuSig::Session.new(session_id, num_signers) coefficient = coefficient(ell, index) session.secret_key = field.mod(private_key * coefficient) session.secret_nonce = Digest::SHA256.digest(session.id + + combined_pubkey + secret).unpack('H*').first.to_i(16) raise ArgumentError, 'secret nonce must be an integer in the ragen 1..n-1' unless field.include?(session.secret_nonce) point_r = ECDSA::Group::Secp256k1.new_point(session.secret_nonce) session.nonce = ECDSA::Format::PointOctetString.encode(point_r, compression: true) session end |