Module: Secp256k1::SchnorrSig

Included in:
Secp256k1
Defined in:
lib/secp256k1/schnorrsig.rb

Overview

SchnorrSig module

Examples:

include Secp256k1

sk, pk = generate_key_pair

# sign and verify (Schnorr)
signature = sign_schnorr(msg, sk)
verify_schnorr(msg, signature, pk[2..-1]) # public key must be 32 bytes

Instance Method Summary collapse

Instance Method Details

#sign_schnorr(data, private_key, aux_rand = nil) ⇒ String

Sign to data using schnorr.

Parameters:

  • data (String)

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

  • private_key (String)

    a private key with hex format using sign.

  • aux_rand (String) (defaults to: nil)

    The 32-byte extra entropy.

Returns:

  • (String)

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

Raises:

  • (ArgumentError)

    If invalid arguments specified.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/secp256k1/schnorrsig.rb', line 20

def sign_schnorr(data, private_key, aux_rand = nil)
  validate_string!("data", data, 32)
  validate_string!("private_key", private_key, 32)
  validate_string!("aux_rand", aux_rand, 32) if aux_rand
  raise ArgumentError, "aux_rand must be String." if !aux_rand.nil? && !aux_rand.is_a?(String)
  private_key = hex2bin(private_key)
  data = hex2bin(data)

  with_context do |context|
    keypair = [create_keypair(private_key)].pack('H*')
    keypair = FFI::MemoryPointer.new(:uchar, 96).put_bytes(0, keypair)
    signature = FFI::MemoryPointer.new(:uchar, 64)
    msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, data)
    aux_rand = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, aux_rand) if aux_rand
    raise Error, 'Failed to generate schnorr signature.' unless secp256k1_schnorrsig_sign32(context, signature, msg32, keypair, aux_rand) == 1
    signature.read_string(64)
  end
end

#verify_schnorr(data, signature, pubkey) ⇒ Boolean

Verify ecdsa 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.

Returns:

  • (Boolean)

    verification result.

Raises:

  • (ArgumentError)

    If invalid arguments specified.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/secp256k1/schnorrsig.rb', line 45

def verify_schnorr(data, signature, pubkey)
  validate_string!("data", data, 32)
  validate_string!("signature", signature, 64)
  validate_string!("pubkey", pubkey, 32)
  data = hex2bin(data)
  pubkey = hex2bin(pubkey)
  signature = hex2bin(signature)
  with_context do |context|
    return false if data.bytesize == 0
    pubkey = [full_pubkey_from_xonly_pubkey(pubkey)].pack('H*')
    xonly_pubkey = FFI::MemoryPointer.new(:uchar, pubkey.bytesize).put_bytes(0, pubkey)
    signature = FFI::MemoryPointer.new(:uchar, signature.bytesize).put_bytes(0, signature)
    msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, data)
    result = secp256k1_schnorrsig_verify(context, signature, msg32, 32, xonly_pubkey)
    result == 1
  end
end