Skip to content

Commit

Permalink
fixed public/private key stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
izelnakri committed Aug 30, 2017
1 parent 0f7fe0e commit 1882521
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
23 changes: 13 additions & 10 deletions lib/eth/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,38 @@ defmodule ETH.Utils do
end

def get_public_key(<< private_key :: binary-size(32) >>) do
{public_key, ^private_key} = :crypto.generate_key(:ecdh, :secp256k1, private_key)
{:ok, public_key} = :libsecp256k1.ec_pubkey_create(private_key, :uncompressed)
public_key
end
def get_public_key(<< encoded_private_key :: binary-size(64) >>) do
private_key = Base.decode16!(encoded_private_key, case: :mixed)
{public_key, ^private_key} = :crypto.generate_key(:ecdh, :secp256k1, private_key)
{:ok, public_key} = :libsecp256k1.ec_pubkey_create(private_key, :uncompressed)
public_key
end

def get_address(<< private_key :: binary-size(32) >>) do
public_key = private_key |> get_public_key()
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(public_key)
<< 4 :: size(8), key :: binary-size(64) >> = private_key |> get_public_key()
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(key)
"0x#{Base.encode16(eth_address)}"
end
def get_address(<< encoded_private_key :: binary-size(64) >>) do
public_key = Base.decode16!(encoded_private_key, case: :mixed) |> get_public_key()
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(public_key)
<< 4 :: size(8), key :: binary-size(64) >> = Base.decode16!(encoded_private_key) |> get_public_key()
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(key)
"0x#{Base.encode16(eth_address)}"
end
def get_address(<< public_key :: binary-size(65) >>) do
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(public_key)
def get_address(<< 4 :: size(8), key :: binary-size(64) >>) do
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(key)
"0x#{Base.encode16(eth_address)}"
end
def get_address(<< encoded_public_key :: binary-size(130) >>) do
public_key = Base.decode16!(encoded_public_key, case: :mixed)
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(public_key)
<< 4 :: size(8), key :: binary-size(64) >> = Base.decode16!(encoded_public_key)
<< _ :: binary-size(12), eth_address :: binary-size(20) >> = keccak256(key)
"0x#{Base.encode16(eth_address)}"
end

def keccak256(data), do: :keccakf1600.hash(:sha3_256, data)
defp encode16(value), do: Base.encode16(value, case: :lower)
end

# NOTE: old version that is error-prone:
# {public_key, ^private_key} = :crypto.generate_key(:ecdh, :secp256k1, private_key)
5 changes: 5 additions & 0 deletions test/eth/utils_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ defmodule ETH.UtilsTest do
assert public_key |> byte_size == 65
assert public_key == ETH.Utils.get_public_key(private_key)
assert public_key != ETH.Utils.get_public_key(another_private_key)

1..1000 |> Enum.each(fn(x) ->
private_key = :crypto.strong_rand_bytes(32)
ETH.Utils.get_public_key(private_key)
end)
end

test "get_public_key/1 works for encoded private keys" do
Expand Down

0 comments on commit 1882521

Please # to comment.