ExSecp256k1 (ExSecp256k1 v0.3.3) View Source

ExSecp256k1

Hex.pm Hex.pm Hex.pm Github.com

Rust Native Implemented Function (NIF) that wraps a couple functions from the libsecp256k1 Rust library.

Installation

ex_secp256k1 requires Rust to be installed.

The package can be installed by adding ex_secp256k1 to your list of dependencies in mix.exs:

  [
    {:ex_secp256k1, "~> 0.3"}
  ]

Usage

To create a public key from a private key use ExSecp256k1.create_public_key/1. The result is uncompressed public key:

{:ok, _binary} = ExSecp256k1.create_public_key(<<120, 128, 174, 201, 52, 19,
241, 23, 239, 20, 189, 78, 109, 19, 8, 117, 171, 44, 125, 125, 85, 160, 100,
250, 195, 194, 247, 189, 81, 81, 99, 128>>)

{:error, :wrong_private_key_size} = ExSecp256k1.create_public_key(<<1>>)

To sign a message use ExSecp256k1.sign/2. It returns a tuple with {:ok, {r, s, recovery_id}} on success and {:error, reason_atom} on error:

message =
  <<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 2>>

private_key =
  <<120, 128, 174, 201, 52, 19, 241, 23, 239, 20, 189, 78, 109, 19, 8, 117,
  171, 44, 125, 125, 85, 160, 100, 250, 195, 194, 247, 189, 81, 81, 99, 128>>

{:ok {r_binary, s_binary, recovery_id_int}} = ExSecp256k1.sign(message, private_key)

{:ok {signature_bin, recovery_id_int}} = ExSecp256k1.sign_compact(message, private_key)

To recover a public key from signed message use ExSecp256k1.recover/4 or ExSecp256k1.recover_compact/3:

hash =
     <<218, 245, 167, 121, 174, 151, 47, 151, 33, 151, 48, 61, 123, 87, 71, 70, 199, 239, 131,
       234, 218, 192, 242, 121, 26, 210, 61, 185, 46, 76, 142, 83>>

r =
     <<40, 239, 97, 52, 11, 217, 57, 188, 33, 149, 254, 83, 117, 103, 134, 96, 3, 225, 161, 93,
       60, 113, 255, 99, 225, 89, 6, 32, 170, 99, 98, 118>>

s =
     <<103, 203, 233, 216, 153, 127, 118, 26, 236, 183, 3, 48, 75, 56, 0, 204, 245, 85, 201,
       243, 220, 100, 33, 75, 41, 127, 177, 150, 106, 59, 109, 131>>

recovery_id = 0

{:ok, _public_key_binary} = ExSecp256k1.recover(hash, r, s, recovery_id)
{:error, :recovery_failure} = ExSecp256k1.recover(hash, r, s, 2)


{:ok, _public_key_binary} = ExSecp256k1.recover_compact(hash, r <> s, recovery_id)

Additive tweaking of public key (ExSecp256k1.public_key_tweak_add/2):

private_key = :crypto.strong_rand_bytes(32)
{:ok, public_key} = ExSecp256k1.create_public_key(private_key)


{:ok, _result} = ExSecp256k1.public_key_tweak_add(public_key, private_key)

Public key decompression (ExSecp256k1.public_key_decompress/1):

compressed_key =
  <<2, 204, 170, 92, 229, 234, 207, 153, 33, 250, 27, 208, 37, 71, 183, 155, 104, 155, 45,
    114, 7, 156, 83, 199, 245, 83, 32, 128, 45, 174, 96, 24, 38>>

{:ok, _uncompressed_key} = ExSecp256k1.public_key_decompress(compressed_key)

Public key compression (ExSecp256k1.public_key_compress/1):

uncompressed_key =
        <<4, 204, 170, 92, 229, 234, 207, 153, 33, 250, 27, 208, 37, 71, 183, 155, 104, 155, 45,
          114, 7, 156, 83, 199, 245, 83, 32, 128, 45, 174, 96, 24, 38, 220, 210, 198, 20, 132,
          174, 75, 63, 131, 95, 120, 101, 186, 93, 179, 95, 14, 206, 46, 48, 6, 129, 8, 146, 40,
          135, 251, 42, 71, 4, 83, 222>>

assert {:ok, _compressed_key} = ExSecp256k1.public_key_compress(uncompressed_key)

All nif functions will fail with ArgumentError if parameters of wrong types are provided:

assert_raise ArgumentError, fn ->
  ExSecp256k1.sign(message, nil)
end

Contributing

  1. Fork it!
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Link to this section Summary

Link to this section Functions

Link to this function

create_public_key(private_key)

View Source
Link to this function

public_key_compress(public_key)

View Source
Link to this function

public_key_decompress(public_key)

View Source
Link to this function

public_key_tweak_add(public_key, tweak_key)

View Source
Link to this function

recover(hash, r, s, recovery_id)

View Source
Link to this function

recover_compact(hash, signature, recovery_id)

View Source
Link to this function

sign(message, private_key)

View Source
Link to this function

sign_compact(message, private_key)

View Source