I have never looked into how Exodus did Byron back in the days, unfortunately.
I have found out how they do Shelley and it’s strange.
Here is my Python implementation using https://pypi.org/project/bip-utils/:
from bip_utils import (Bip39SeedGenerator,
Bip32Slip10Secp256k1,
Cip1852, Cip1852Coins, Bip32KeyData,
CardanoShelley)
from bip_utils.cardano.bip32.cardano_byron_legacy_mst_key_generator import (
CardanoByronLegacyMstKeyGenerator)
seed_phrase = ("abandon abandon abandon abandon abandon abandon "
"abandon abandon abandon abandon abandon about")
bip39_seed_bytes = Bip39SeedGenerator(seed_phrase).Generate()
cardano_bip32_key = Bip32Slip10Secp256k1.FromSeedAndPath(bip39_seed_bytes,
"m/44'/1815'/0'/0/0")
cardano_bip32_private_bytes = cardano_bip32_key.PrivateKey().Raw().ToBytes()
# Used as seed bytes for legacy Byron master key derivation:
byron_private_key, _ = (
CardanoByronLegacyMstKeyGenerator.
_CardanoByronLegacyMstKeyGenerator__HashRepeatedly(
cardano_bip32_private_bytes, 1))
# Make Cip1852 object out of it to make bip_utils happy:
cip1852 = Cip1852.FromPrivateKey(byron_private_key,
Cip1852Coins.CARDANO_ICARUS,
Bip32KeyData(5))
# Same key used for payment and stake key:
shelley_pair = CardanoShelley(cip1852, cip1852)
shelley_address = shelley_pair.PublicKeys().ToAddress()
print(f"Strange Derivation: {shelley_address}")
print("Exodus: addr1q9av2w6nz9tzv8rc3vfqs95av844gkcqxm0qeezvlf07p3r6c5a4xy"
"2kycw83zcjpqtf6c0t23dsqdk7pnjye7jlurzqm0pqxa")
So, they use the path not to derive according to BIP32-Ed25519 (https://input-output-hk.github.io/adrestia/static/Ed25519_BIP.pdf) as it is used everywhere else in Cardano, but according to BIP32-Secp256k1 as it is used in Bitcoin and friends.
Only after that they use the Byron master key derivation to derive an Ed25519 key pair using the derived private key as a seed. (And then they use that key pair for payment as well as stake part.)
That makes almost no sense. The reason for the non-hardened elements of a derivation path are that you can derive different public keys without having to know the private keys. You can forget that with this strange and non-compliant process.
It’s an abomination.
But maybe they have done something similar in Byron era. Maybe it is as simple as replacing the part after “#Make Cip1852 object
” in my code by creating a Byron address from it.
If you can make sense of my code and of bip_utils
you can try yourself. If not please ask, but I can’t promise a timely answer. More something like in a week or two.
I’d also need a test case (which could be a bit complicated/risky if you only have one with balance on it): What Byron address is supposed to be derived from what seed phrase? I just tried installing Exodus, but they seem to have removed Byron from the current version.