Address

Examples of how to integrate the TSM with Ethereum

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.