Ethereum addressing in cosmos-sdk


#1

i want to import the ethereum account address system in cosmos for its validators , what i mean by that is i want to have validator account public and private address to be like ethereum addresses not “cosmosaccaddr…” . Any ideas how i can do that ? I want to do this because i want to verify signatures of cosmos validators on ethereum smart contract using ecrecover


#2

Our validator set uses ed25519 for signatures, I don’t believe Ethereum has a precompile for ed25519 yet.

In general to convert from the encoded format into bytes, just use your favorite bech32 decoder. We have an accessible one in gaiahack in the repo, but theres basically one written in every language.


#3

HI, you would need to modify Tendermint to secp256k1 signatures which should be relatively simple to verify consensus signatures in an Ethereum smart contract.


#4

For this use case, the forth coming change to how singatures work in Tendermint would nice.


#5

@zaki I’ve already changed secp256k1 to support Ethereum addresses:

Would be great if you can take a quick look and review.

@vaibhavchellani Next step would be to change the Tendermint header and validate in solidity. For that, we may need to change header encoding if possible and add extra information.


#6

It would be great if we could try and get this into a state where secp256k1 support consensus signatures could be merged into master.

Some of these changes seem unnecessary to me. I don’t see why consensus addresses need to be ethereum addresses or why you need to use ecrecover to verify signatures.

It would be simple to write a utility to convert a standard ecdsa signatures to ethereum style signatures.


#7

Perhaps priv_validator.go could use a parameter from the genesis file to know what kind of keys to generate.


#8

Yes @jdkanani and i were already thinking along that lines


#9

why consensus addresses need to be Ethereum addresses

Well, you don’t have to but it’s easy to verify addresses on Mainchain (Ethereum) if consensus addresses are same as Ethereum addresses (heavily depends on our usecase).

why you need to use ecrecover to verify signatures

No need. Using VerifySignature would also work:

func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig []byte) bool {
	hash := ethCrypto.Keccak256(msg)
	return ethCrypto.VerifySignature(pubKey[:], hash, sig[:64])

	// p, err := ethCrypto.Ecrecover(hash, sig)
	// if err != nil {
	// 	return false
	// }

	// return bytes.Equal(pubKey[:], p[:])
}

convert a standard ecdsa signature to ethereum style signatures

Here is what you want - https://github.com/tendermint/tendermint/compare/master...jdkanani:ecdsa

It converts ecdsa sig to ethereum style sig. You don’t need to add in secp256k1.go in fact. I was just checking if it works or not. One can append 1B/1C byte to any tendermint signature and make it work.

OR change ecrecovery in solidity without converting to ETH style sig:

function ecrecovery(
    bytes32 hash,
    bytes sig
  ) public pure returns (address) {
    bytes32 r;
    bytes32 s;

    if (sig.length != 64) {
      return 0;
    }

    assembly {
      r := mload(add(sig, 32))
      s := mload(add(sig, 64))
    }

    // get address out of hash and signature
    address result = ecrecover(hash, 28, r, s);

    return result;
}

#10

Adding parameter to genesis file (or tendermint init and gen_validator) would be great.


#11

Awesome work @jdkanani !


#12

So secp256k1.go is not constant time but we do support constant time signatures in kms. Just FYI