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.



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/secp256k1/ellswift.rb', line 47

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:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/secp256k1/ellswift.rb', line 66

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

#ellswift_encode(pubkey, rnd = nil) ⇒ String

Encode a public key into an ElligatorSwift public key.

Parameters:

  • pubkey (String)

    public key with hex format.

  • rnd (String) (defaults to: nil)

    (Optional)32-byte randomness with binary format. If omitted, random bytes are used.

Returns:

  • (String)

    ElligatorSwift public key with hex format(64 bytes).

Raises:

  • (Secp256k1::Error)

    If encoding failed.

  • (ArgumentError)

    If invalid arguments specified.



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

def ellswift_encode(pubkey, rnd = nil)
  raise ArgumentError, "pubkey must be String." unless pubkey.is_a?(String)
  validate_string!("rnd", rnd, 32) if rnd
  pubkey = hex2bin(pubkey)
  rnd = rnd ? hex2bin(rnd) : SecureRandom.random_bytes(32)
  with_context do |context|
    internal = parse_pubkey_internal(context, pubkey)
    ell64 = FFI::MemoryPointer.new(:uchar, 64)
    rnd32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, rnd)
    raise Error, 'Failed to encode ElligatorSwift public key.' unless secp256k1_ellswift_encode(context, ell64, internal, rnd32) == 1
    ell64.read_string(64).unpack1('H*')
  end
end