Module: Secp256k1::EllSwift

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

Instance Method Summary collapse

Instance Method Details

#ellswift_create(private_key) ⇒ String

Compute an ElligatorSwift public key for a secret key.

Parameters:

  • private_key (String)

    private key with hex format

Returns:

  • (String)

    ElligatorSwift public key with hex format.

Raises:

  • (Secp256k1::Error)

    If failed to create elligattor swhift public key.

  • (ArgumentError)

    If invalid arguments specified.



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/secp256k1/ellswift.rb', line 27

def ellswift_create(private_key)
  validate_string!("private_key", private_key, 32)
  private_key = hex2bin(private_key)
  with_context(flags: CONTEXT_SIGN) do |context|
    ell64 = FFI::MemoryPointer.new(:uchar, 64)
    seckey32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, private_key)
    result = secp256k1_ellswift_create(context, ell64, seckey32, nil)
    raise Error, 'Failed to create ElligatorSwift public key.' unless result == 1
    ell64.read_string(64).unpack1('H*')
  end
end

#ellswift_decode(ell_key, compressed: true) ⇒ String

Decode ellswift public key.

Parameters:

  • ell_key (String)

    ElligatorSwift key with binary format.

  • compressed (Boolean) (defaults to: true)

    Whether to compress the public key or not.

Returns:

  • (String)

    Decoded public key with hex format.

Raises:

  • (Secp256k1::Error)

    If decode failed.

  • (ArgumentError)

    If invalid arguments specified.



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/secp256k1/ellswift.rb', line 10

def ellswift_decode(ell_key, compressed: true)
  validate_string!("ell_key", ell_key, ELL_SWIFT_KEY_SIZE)
  ell_key = hex2bin(ell_key)
  with_context do |context|
    ell64 = FFI::MemoryPointer.new(:uchar, ell_key.bytesize).put_bytes(0, ell_key)
    internal = FFI::MemoryPointer.new(:uchar, 64)
    result = secp256k1_ellswift_decode(context, internal, ell64)
    raise Error, 'Decode failed.' unless result == 1
    serialize_pubkey_internal(context, internal, compressed)
  end
end

#ellswift_ecdh_xonly(their_ell_pubkey, our_ell_pubkey, private_key, initiating) ⇒ String

Compute X coordinate of shared ECDH point between elswift pubkey and private_key.

Parameters:

  • their_ell_pubkey (String)

    Their EllSwift public key.

  • our_ell_pubkey (String)

    Our EllSwift public key.

  • private_key (String)

    private key with hex format.

  • initiating (Boolean)

    Whether your initiator or not.

Returns:

  • (String)

    x coordinate with hex format.

Raises:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/secp256k1/ellswift.rb', line 46

def ellswift_ecdh_xonly(their_ell_pubkey, our_ell_pubkey, private_key, initiating)
  validate_string!("their_ell_pubkey", their_ell_pubkey, ELL_SWIFT_KEY_SIZE)
  validate_string!("our_ell_pubkey", our_ell_pubkey, ELL_SWIFT_KEY_SIZE)
  validate_string!("private_key", private_key, 32)
  their_ell_pubkey = hex2bin(their_ell_pubkey)
  our_ell_pubkey = hex2bin(our_ell_pubkey)
  private_key = hex2bin(private_key)

  with_context(flags: CONTEXT_SIGN) do |context|
    output = FFI::MemoryPointer.new(:uchar, 32)
    our_ell_ptr = FFI::MemoryPointer.new(:uchar, 64).put_bytes(0, our_ell_pubkey)
    their_ell_ptr = FFI::MemoryPointer.new(:uchar, 64).put_bytes(0, their_ell_pubkey)
    seckey32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, private_key)
    hashfp = C.ellswift_xdh_hash_function_bip324
    result = secp256k1_ellswift_xdh(context, output,
                                    initiating ? our_ell_ptr : their_ell_ptr,
                                    initiating ? their_ell_ptr : our_ell_ptr,
                                    seckey32,
                                    initiating ? 0 : 1,
                                    hashfp, nil)
    raise Error, "secret was invalid or hashfp returned 0." unless result == 1
    output.read_string(32).unpack1('H*')
  end
end