jonericcook

jonericcook

Generate public/private keys and sign messages

Hello,

I am trying write elixir code to recreate the behavior from this python script.

import bech32
import ecdsa
from ecdsa.curves import SECP256k1
from ecdsa.util import sigencode_der

private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
private_key_bytes = private_key.to_string()
print("Private Key: ", private_key_bytes.hex())

verifying_key = private_key.get_verifying_key()
public_key_compressed_bytes = verifying_key.to_string("compressed")
print("Public Key: ", public_key_compressed_bytes.hex())

readdr_bytes = b"\x04" + public_key_compressed_bytes
readdr_bytes5 = bech32.convertbits(readdr_bytes, 8, 5)
wallet_address = bech32.bech32_encode("rdx", readdr_bytes5)
print("Wallet Address: ", wallet_address)

blob_to_sign = "42244f5ac531a551a8ffd6f6c9e63e481fe1cf30b7bc42676840c3149695445b"
signature_der = private_key.sign_digest(
    bytearray.fromhex(blob_to_sign), sigencode=sigencode_der).hex()
print("SignatureDER: ", signature_der)

I have this code written so far but am not able to get the same signatureDER.

defmodule Keypair do

  def sign(data, private_key) do
    {:ok, private_key} = Curvy.Util.decode(private_key, :hex)
    Curvy.sign(data, private_key, encoding: :hex)
  end

  def from_private_key(private_key) do
    {:ok, private_key} = Curvy.Util.decode(private_key, :hex)

    private_key
    |> Curvy.Key.from_privkey()
    |> format_keys()
  end

  defp format_keys(keypair) do
    public_key = Curvy.Key.to_pubkey(keypair)
    radix_address = Bech32.encode("rdx", <<4>> <> public_key)
    public_key = Curvy.Util.encode(public_key, :hex)

    private_key =
      keypair
      |> Curvy.Key.to_privkey()
      |> Curvy.Util.encode(:hex)

    %{radix_address: radix_address, public_key: public_key, private_key: private_key}
  end
end

Im using Curvy for generating keys and signing Curvy — Curvy v0.3.0 and bech32 | Hex to convert the public key to the desired address format.

Below is the console print outs.

PYTHON OUTPUT

Private Key:  2574132b032927dad619dcfe3508646e54400b6a9437ba501e78e51e488be1be
Public Key:  027d637e3a6f331ef1ff00912dd1cddf246f887522f3d805136bf1d377296e35f7
Wallet Address:  rdx1qsp86cm78fhnx8h3luqfztw3eh0jgmugw5308kq9zd4lr5mh99hrtac2dmtpr
SignatureDER:  304502210086d9d7a8a9d5f47a4bd6947cd083622c0a08bd430b6feb0e5364a9663423d16a0220479fcdcbeb6d80e697fd71846008cfa659fa724f27d5632ee1267cc8ab54cdf2

ELIXIR OUTPUT

iex(1)> Keypair.from_private_key("2574132b032927dad619dcfe3508646e54400b6a9437ba501e78e51e488be1be")
%{
  private_key: "2574132b032927dad619dcfe3508646e54400b6a9437ba501e78e51e488be1be",
  public_key: "027d637e3a6f331ef1ff00912dd1cddf246f887522f3d805136bf1d377296e35f7",
  radix_address: "rdx1qsp86cm78fhnx8h3luqfztw3eh0jgmugw5308kq9zd4lr5mh99hrtac2dmtpr"
}

iex(2)>   Keypair.sign("42244f5ac531a551a8ffd6f6c9e63e481fe1cf30b7bc42676840c3149695445b","2574132b032927dad619dcfe3508646e54400b6a9437ba501e78e51e488be1be")
"304402201b1151bff7543ef6ed3e0f76d84f22327bd6d8a34743db1f15b9f56339a9177002202be2797a2d541713aa35f5f7ddbe07974dac00e5cf4624f47d496e90338b1bac"

I also tried the Elixir sign function like this but it did not produce the same signature.

  def sign(data, private_key) do
    {:ok, private_key} = Curvy.Util.decode(private_key, :hex)
    {:ok, data} = Curvy.Util.decode(data, :hex)
    Curvy.sign(data, private_key, encoding: :hex)
  end

For more context - this endeavor started from these two doc pages.
Here he creates an address Creating a Radix Wallet Address for Development Purposes - RadixPool Technical
Here he creates an address and signs a message with it Unregister a Validator Node using the Keystore File - RadixPool Technical

I believe the issue is in how Curvy does signing? I’m leaning towards using libsecp256k1 | Hex but cant find docs on how to use it. What do y’all think? Could my goals be achieved by using libsecp256k1?

Thank you for taking the time to help :call_me_hand:

Marked As Solved

jonericcook

jonericcook

Changing the sign function to this worked!

  def sign(data, private_key) do
    {:ok, private_key} = Curvy.Util.decode(private_key, :hex)
    {:ok, data} = Curvy.Util.decode(data, :hex)
    Curvy.sign(data, private_key, encoding: :hex, hash: :none)
  end

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New

We're in Beta

About us Mission Statement