Class: Secp256k1::MuSig::Session
- Inherits:
-
Object
- Object
- Secp256k1::MuSig::Session
- Includes:
- Secp256k1
- Defined in:
- lib/secp256k1/musig/session.rb
Constant Summary
Constants included from Secp256k1
CONTEXT_SIGN, CONTEXT_VERIFY, EC_COMPRESSED, EC_UNCOMPRESSED, ELL_SWIFT_KEY_SIZE, FLAGS_BIT_COMPRESSION, FLAGS_BIT_CONTEXT_SIGN, FLAGS_BIT_CONTEXT_VERIFY, FLAGS_TYPE_COMPRESSION, FLAGS_TYPE_CONTEXT, FLAGS_TYPE_MASK, VERSION, X_ONLY_PUBKEY_SIZE
Instance Attribute Summary collapse
-
#agg_nonce ⇒ Object
readonly
Returns the value of attribute agg_nonce.
-
#key_agg_ctx ⇒ Object
readonly
Returns the value of attribute key_agg_ctx.
-
#msg ⇒ Object
readonly
Returns the value of attribute msg.
-
#session ⇒ Object
readonly
Returns the value of attribute session.
Instance Method Summary collapse
-
#aggregate_partial_sigs(partial_sigs) ⇒ String
Aggregates partial signatures.
-
#initialize(key_agg_ctx, agg_nonce, msg) ⇒ Session
constructor
Create signing session.
-
#partial_sign(sec_nonce, private_key) ⇒ String
Produces a partial signature for a given key pair and secret nonce.
-
#verify_partial_sig(partial_sig, pub_nonce, public_key) ⇒ Boolean
Checks that an individual partial signature verifies.
Methods included from Secp256k1
#create_keypair, #generate_key_pair, #generate_pubkey, #parse_ec_pubkey?, #sign_ecdsa, #valid_xonly_pubkey?, #verify_ecdsa, #with_context
Methods included from Secp256k1::MuSig
#aggregate_musig_nonce, #aggregate_pubkey, #generate_musig_nonce, #generate_musig_session_id
Methods included from EllSwift
#ellswift_create, #ellswift_decode, #ellswift_ecdh_xonly
Methods included from SchnorrSig
#sign_schnorr, #verify_schnorr
Methods included from Recover
Methods included from C
ellswift_xdh_hash_function_bip324
Constructor Details
#initialize(key_agg_ctx, agg_nonce, msg) ⇒ Session
Create signing session.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/secp256k1/musig/session.rb', line 16 def initialize(key_agg_ctx, agg_nonce, msg) raise ArgumentError, 'key_agg_ctx must be KeyAggContext.' unless key_agg_ctx.is_a?(KeyAggContext) validate_string!('msg', msg, 32) validate_string!('agg_nonce', agg_nonce, 66) agg_nonce = hex2bin(agg_nonce) msg = hex2bin(msg) with_context do |context| @session = FFI::MemoryPointer.new(:uchar, 133) agg66 = FFI::MemoryPointer.new(:uchar, 66).put_bytes(0, agg_nonce) agg_ptr = FFI::MemoryPointer.new(:uchar, 132) if secp256k1_musig_aggnonce_parse(context, agg_ptr, agg66) == 0 raise Error, "secp256k1_musig_aggnonce_parse failed." end msg_ptr = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, msg) if secp256k1_musig_nonce_process(context, @session, agg_ptr, msg_ptr, key_agg_ctx.pointer) == 0 raise Error, "secp256k1_musig_nonce_process arguments invalid." end end @agg_nonce = agg_nonce.unpack1('H*') @msg = msg.unpack1('H*') @key_agg_ctx = key_agg_ctx end |
Instance Attribute Details
#agg_nonce ⇒ Object (readonly)
Returns the value of attribute agg_nonce.
7 8 9 |
# File 'lib/secp256k1/musig/session.rb', line 7 def agg_nonce @agg_nonce end |
#key_agg_ctx ⇒ Object (readonly)
Returns the value of attribute key_agg_ctx.
6 7 8 |
# File 'lib/secp256k1/musig/session.rb', line 6 def key_agg_ctx @key_agg_ctx end |
#msg ⇒ Object (readonly)
Returns the value of attribute msg.
8 9 10 |
# File 'lib/secp256k1/musig/session.rb', line 8 def msg @msg end |
#session ⇒ Object (readonly)
Returns the value of attribute session.
5 6 7 |
# File 'lib/secp256k1/musig/session.rb', line 5 def session @session end |
Instance Method Details
#aggregate_partial_sigs(partial_sigs) ⇒ String
Aggregates partial signatures
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/secp256k1/musig/session.rb', line 97 def aggregate_partial_sigs(partial_sigs) raise ArgumentError, "partial_sigs must be Array." unless partial_sigs.is_a?(Array) raise ArgumentError, "partial_sigs must not be empty." if partial_sigs.empty? with_context do |context| sigs_ptr = FFI::MemoryPointer.new(:pointer, partial_sigs.length) sigs_ptr.write_array_of_pointer(partial_sigs.map{|partial_sig| parse_partial_sig(context, partial_sig)}) sig64 = FFI::MemoryPointer.new(:uchar, 64) if secp256k1_musig_partial_sig_agg(context, sig64, session, sigs_ptr, partial_sigs.length) == 0 raise Error, "secp256k1_musig_partial_sig_agg arguments invalid." end sig64.read_string(64).unpack1('H*') end end |
#partial_sign(sec_nonce, private_key) ⇒ String
Produces a partial signature for a given key pair and secret nonce.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/secp256k1/musig/session.rb', line 45 def partial_sign(sec_nonce, private_key) raise ArgumentError, 'key_agg_ctx must be KeyAggContext.' unless key_agg_ctx.is_a?(KeyAggContext) validate_string!('sec_nonce', sec_nonce, 132) validate_string!('private_key', private_key, 32) with_context do |context| partial_sig = FFI::MemoryPointer.new(:uchar, 36) sec_nonce_ptr = FFI::MemoryPointer.new(:uchar, 132).put_bytes(0, hex2bin(sec_nonce)) private_key_ptr = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, hex2bin(private_key)) key_pair = FFI::MemoryPointer.new(:uchar, 86) if secp256k1_keypair_create(context, key_pair, private_key_ptr) == 0 raise Error, "secp256k1_keypair_create invalid private_key." end if secp256k1_musig_partial_sign( context, partial_sig, sec_nonce_ptr, key_pair, key_agg_ctx.cache.pointer, session) == 0 raise Error, "secp256k1_musig_partial_sign arguments invalid or sec_nonce has already been used for signing." end out32 = FFI::MemoryPointer.new(:uchar, 32) secp256k1_musig_partial_sig_serialize(context, out32, partial_sig) out32.read_string(32).unpack1('H*') end end |
#verify_partial_sig(partial_sig, pub_nonce, public_key) ⇒ Boolean
Checks that an individual partial signature verifies.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/secp256k1/musig/session.rb', line 74 def verify_partial_sig(partial_sig, pub_nonce, public_key) validate_string!('partial_sig', partial_sig, 32) validate_string!('pub_nonce', pub_nonce, 66) validate_string!('public_key', public_key, 33) with_context do |context| sig_ptr = parse_partial_sig(context, partial_sig) public_key = FFI::MemoryPointer.new(:uchar, 33).put_bytes(0, hex2bin(public_key)) pubkey_ptr = FFI::MemoryPointer.new(:uchar, 64) raise Error, "pubkey is invalid." unless secp256k1_ec_pubkey_parse(context, pubkey_ptr, public_key, 33) == 1 pub_nonce = FFI::MemoryPointer.new(:uchar, 66).put_bytes(0, hex2bin(pub_nonce)) nonce_ptr = FFI::MemoryPointer.new(:uchar, 132) if secp256k1_musig_pubnonce_parse(context, nonce_ptr, pub_nonce) == 0 raise Error, "secp256k1_musig_pubnonce_parse failed." end secp256k1_musig_partial_sig_verify(context, sig_ptr, nonce_ptr, pubkey_ptr, key_agg_ctx.pointer, session) == 1 end end |