Module: Bitcoin::Secp256k1::Native

Extended by:
Secp256k1
Defined in:
lib/bitcoin/secp256k1/native.rb

Overview

binding for secp256k1 (https://github.com/bitcoin-core/secp256k1/) tag: v0.8.0, which secp256k1rb 0.8.0 binds the public API of. An older library is missing symbols the gem attaches, such as secp256k1_ec_pubkey_sort and the musig module. this is not included by default, to enable set shared object path to ENV for linux, ENV = '/usr/local/lib/libsecp256k1.so' or '/usr/lib64/libsecp256k1.so' for mac,

Class Method Summary collapse

Class Method Details

.generate_key(compressed: true) ⇒ Object

generate bitcoin key object



27
28
29
30
# File 'lib/bitcoin/secp256k1/native.rb', line 27

def generate_key(compressed: true)
  privkey, pubkey = generate_key_pair(compressed: compressed)
  Bitcoin::Key.new(priv_key: privkey, pubkey: pubkey, compressed: compressed)
end

.native?Boolean

Whether this module is native c wrapper or not?

Returns:

  • (Boolean)


22
23
24
# File 'lib/bitcoin/secp256k1/native.rb', line 22

def native?
  true
end

.recover_compact(data, signature, compressed) ⇒ Bitcoin::Key

Recover public key from compact signature.

Parameters:

  • data (String)

    message digest using signature.

  • signature (String)

    signature with binary format(65 bytes).

  • compressed (Boolean)

    whether compressed public key or not.

Returns:



46
47
48
49
# File 'lib/bitcoin/secp256k1/native.rb', line 46

def recover_compact(data, signature, compressed)
  pubkey = recover(data, signature, compressed)
  Bitcoin::Key.new(pubkey: pubkey, compressed: compressed)
end

.sign_compact(data, privkey) ⇒ Array[signature, recovery id]

Sign data with compact format.

Parameters:

  • data (String)

    a data to be signed with binary format

  • privkey (String)

    a private key using sign with hex format

Returns:

  • (Array[signature, recovery id])


36
37
38
39
# File 'lib/bitcoin/secp256k1/native.rb', line 36

def sign_compact(data, privkey)
  sig, rec_id = sign_recoverable(data, privkey)
  [ECDSA::Signature.new(sig[0...64].to_i(16), sig[64..-1].to_i(16)), rec_id]
end

.sign_data(data, private_key, extra_entropy = nil, algo: :ecdsa) ⇒ String

Sign to data.

Parameters:

  • data (String)

    The 32-byte message hash being signed with binary format.

  • private_key (String)

    a private key with hex format using sign.

  • extra_entropy (String) (defaults to: nil)

    a extra entropy with binary format for rfc6979.

  • algo (Symbol) (defaults to: :ecdsa)

    signature algorithm. ecdsa(default) or schnorr.

Returns:

  • (String)

    signature data with binary format. If unsupported algorithm specified, return nil.

Raises:

  • (ArgumentError)

    If invalid arguments specified.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/bitcoin/secp256k1/native.rb', line 58

def sign_data(data, private_key, extra_entropy = nil, algo: :ecdsa)
  case algo
  when :ecdsa
    begin
      sign_ecdsa(data, private_key, extra_entropy)
    rescue ArgumentError
      false
    end
  when :schnorr
    begin
      sign_schnorr(data, private_key, extra_entropy)
    rescue ArgumentError
      false
    end
  else
    raise ArgumentError, "unknown algo: #{algo}"
  end
end

.sp_available?Boolean

Whether the loaded library supports BIP-352 silent payments. The module exists in libsecp256k1 v0.8.0 or later.

Returns:

  • (Boolean)


106
107
108
# File 'lib/bitcoin/secp256k1/native.rb', line 106

def sp_available?
  silentpayments_available?
end

.sp_create_label(scan_key, m) ⇒ Array

Create the label and the label tweak of the m th label of scan_key.

Parameters:

  • scan_key (String)

    The recipient's scan private key with hex format(32 bytes).

  • m (Integer)

    The label index.

Returns:

  • (Array)

    The serialized label(33 bytes) and its tweak(32 bytes), both with hex format.



128
129
130
# File 'lib/bitcoin/secp256k1/native.rb', line 128

def sp_create_label(scan_key, m)
  silentpayments_create_label(scan_key, m)
end

.sp_create_outputs(recipients, outpoint_smallest, plain_seckeys: [], taproot_seckeys: []) ⇒ Array

Create the silent payment outputs for recipients. format(33 bytes). A recipient may appear more than once. with hex format(36 bytes).

Parameters:

  • recipients (Array)

    An array of [scan public key, spend public key], both with hex

  • outpoint_smallest (String)

    The lexicographically smallest outpoint of the tx inputs

  • plain_seckeys (Array) (defaults to: [])

    Private keys of the non-taproot inputs with hex format.

  • taproot_seckeys (Array) (defaults to: [])

    Private keys of the taproot inputs with hex format.

Returns:

  • (Array)

    An x-only public key with hex format for each recipient, in the same order.

Raises:

  • (Secp256k1::Error)

    If the outputs could not be created.



119
120
121
122
# File 'lib/bitcoin/secp256k1/native.rb', line 119

def sp_create_outputs(recipients, outpoint_smallest, plain_seckeys: [], taproot_seckeys: [])
  silentpayments_sender_create_outputs(
    recipients, outpoint_smallest, plain_seckeys: plain_seckeys, taproot_seckeys: taproot_seckeys)
end

.sp_scan_outputs(tx_outputs, scan_key, outpoint_smallest, spend_pubkey, plain_pubkeys: [], xonly_pubkeys: [], labels: {}) ⇒ Array

Scan tx_outputs for the silent payment outputs of the recipient. with hex format(36 bytes).

Parameters:

  • tx_outputs (Array)

    The x-only public key of each taproot output with hex format.

  • scan_key (String)

    The recipient's scan private key with hex format(32 bytes).

  • outpoint_smallest (String)

    The lexicographically smallest outpoint of the tx inputs

  • spend_pubkey (String)

    The recipient's spend public key with hex format(33 bytes).

  • plain_pubkeys (Array) (defaults to: [])

    Public keys of the non-taproot inputs with hex format(33 bytes).

  • xonly_pubkeys (Array) (defaults to: [])

    X-only public keys of the taproot inputs with hex format.

  • labels (Hash) (defaults to: {})

    A serialized label to label tweak map, both with hex format.

Returns:

  • (Array)

    A hash per found output, with the :output, :tweak and :label keys.

Raises:

  • (Secp256k1::Error)

    If the tx is not a silent payment transaction.



143
144
145
146
147
148
149
# File 'lib/bitcoin/secp256k1/native.rb', line 143

def sp_scan_outputs(tx_outputs, scan_key, outpoint_smallest, spend_pubkey,
                    plain_pubkeys: [], xonly_pubkeys: [], labels: {})
  summary = silentpayments_create_prevouts_summary(
    outpoint_smallest, plain_pubkeys: plain_pubkeys, xonly_pubkeys: xonly_pubkeys)
  silentpayments_scan_outputs(
    tx_outputs, scan_key, summary, spend_pubkey, labels: labels.empty? ? nil : labels)
end

.verify_sig(data, signature, pubkey, algo: :ecdsa) ⇒ Boolean

Verify signature.

Parameters:

  • data (String)

    The 32-byte message hash assumed to be signed.

  • signature (String)

    signature data with binary format

  • pubkey (String)

    a public key with hex format using verify.

  • algo (Symbol) (defaults to: :ecdsa)

    signature algorithm. ecdsa(default) or schnorr.

Returns:

  • (Boolean)

    verification result.

Raises:

  • (ArgumentError)

    If invalid arguments specified.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/bitcoin/secp256k1/native.rb', line 84

def verify_sig(data, signature, pubkey, algo: :ecdsa)
  case algo
  when :ecdsa
    begin
      verify_ecdsa(data, signature, pubkey)
    rescue ArgumentError
      false
    end
  when :schnorr
    begin
      verify_schnorr(data, signature, pubkey)
    rescue ArgumentError
      false
    end
  else
    raise ArgumentError, "unknown algo: #{algo}"
  end
end