Address

Generate Ethereum Address from Public Key

To try this example, you need to have access to an existing ECDSA client for a TSM, as shown here https://docs.sepior.com/docs/tsm-sdk

curveName := "secp256k1"
keyID, err := ecdsaClient.Keygen(curveName)
if err != nil {
	panic(err)
}

chainPath := []uint32{1, 2, 3, 4}
derPublicKey, err := ecdsaClient.PublicKey(keyID, chainPath)
if err != nil {
	panic(err)
}

publicKey, err := ecdsaClient.ParsePublicKey(derPublicKey)
if err != nil {
	panic(err)
}

msg := make([]byte, 2*32)
publicKey.X.FillBytes(msg[0:32])
publicKey.Y.FillBytes(msg[32:64])

h := sha3.NewLegacyKeccak256()
_, err = h.Write(msg)
if err != nil {
	panic(err)
}
hashValue := h.Sum(nil)

// Ethereum address is rightmost 160 bits of the hash value
ethAddress := hex.EncodeToString(hashValue[len(hashValue)-20:])
fmt.Println("Ethereum address: ", ethAddress)
final String keyID = sdk.ecdsaKeygenWithSessionID(sdk.generateSessionID(),"secp256k1");

final int[] chainPath = new int[] {1,2,3,4};
final byte[] derPublicKey = sdk.ecdsaPublicKey(keyID, chainPath);

Security.addProvider(new BouncyCastleProvider());
final X509EncodedKeySpec spec = new X509EncodedKeySpec(derPublicKey);
final KeyFactory kf = KeyFactory.getInstance("EC", "BC");

final ECPublicKey publicKey = (ECPublicKey) kf.generatePublic(spec);
final ECPoint w = publicKey.getW();
final BigInteger x = w.getAffineX();
final BigInteger y = w.getAffineY();
        
byte[] xBytes = x.toByteArray();
if (xBytes.length != 32) {
  // TODO: Implement: Remove leading zeros if >32, add leading zeroes if < 32
  throw RuntimeException("Not implemented")
}
byte[] yBytes = y.toByteArray();
if (yBytes.length != 32) {
  // TODO: Implement: Remove leading zeros if >32, add leading zeroes if < 32
  throw RuntimeException("Not implemented")
}
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(xBytes, 0, xBytes.length);
baos.write(yBytes, 0, yBytes.length);

final MessageDigest md = MessageDigest.getInstance("KECCAK-256", "BC");
md.update(baos.toByteArray());
final byte[] digest = md.digest();

final byte[] addressBytes = Arrays.copyOfRange(digest, 12, 32);
final String address = HexFormat.of().formatHex(addressBytes);

System.out.println("Ethereum address: 0x" + address);

The chainPath is the bip-32 derivation path.