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