Skip to content

Instantly share code, notes, and snippets.

@bitcoinwarrior1
Last active November 10, 2021 22:24
Show Gist options
  • Save bitcoinwarrior1/aaa70b46f7a57b4c4fc8380e1beefba5 to your computer and use it in GitHub Desktop.
Save bitcoinwarrior1/aaa70b46f7a57b4c4fc8380e1beefba5 to your computer and use it in GitHub Desktop.

dot-notes-path-and-replay

How does polkadot.js derive keys?

“Subkey and Polkadot-JS based wallets use the BIP39 dictionary for mnemonic generation, but use the entropy byte array to generate the private key, while full BIP39 wallets (like Ledger) use 2048 rounds of PBKDF2 on the mnemonic. The same mnemonic may generate different private keys on other wallets due to the various cryptographic algorithms used.” - https://wiki.polkadot.network/docs/learn-accounts#derivation-paths

The default derivation path for polkadot.js is ///. This derivation path will derive keys via the hard derivation method as opposed to the soft method. You can test this out by going to here > advanced and adding on /// to the path, this will generate the same key as the one originally shown. Note that this is quite different to a typical derivation path which looks more like this: m/44’/60’/0’/0.

If a user wishes to add a passphrase to their derivation they would simply append it to the path like so: /password/MY_PASSWORD, however this is not standardised on polkadot.js and forgetting your custom path will result in the user being unable to regenerate their keys.

Parity signer difference

Parity signer appends a network identifier to the derivation path for a user that specifies a network e.g. //polkadot but this is not standard and not well thought out for keys that are used on multiple networks. You can see more about this confusion here.

Differences with ledger

Ledger uses the ed25519 curve to generate keys and does 2048 rounds of PBKDF2 for added security. The polkadot.js wallet uses the sr25519 curve and has removed the 2048 rounds because they believe it provides no security benefit.

While the ed25519 curve is compatible with many cryptographic operations in the polkadot ecosystem, it might not be as comprehensive as the sr25519 curve that polkadot.js uses.

Ledger also uses a different derivation path to generate keys and uses a separate path for kusama. You can see this difference here. The rationale behind this difference is unclear and means that users cannot derive the same key on kusama and polkadot. Ledger users will also generate totally different keys than the ones they would on polkadot.js with the same seed phrase.

Why does ledger use a different curve?

The reason ledger uses a different curve relates to the limitations of its hardware. There is little that can be done to change this and talisman should follow the example of polkadot.js and not ledger as ledger uses a non standard approach.

Hard vs Soft derivation

Hard derivation allows a user that holds the root private key to generate N number of child keys but doesn't allow child public keys to be derived from the root public key.

Soft derivation allows a user to generate both public and private keys from the root public and private key. This is a risk as it can expose the relationship between child keys and the root key.

Polkadot.js defaults to hard derivation but allows users to customise their paths if they want to use soft derivation. The user would start with a single / if they want to use soft derivation.

What about replay attacks?

Gavin Wood has created an issue here that mentions the risk of replay attacks for accounts that fall below the ED threshold and get reaped. Reaping results in the nonce being discarded for an account and opens up the possibility of a past transaction being replayed.

This can be easily mitigated in talisman however by simply confining the lifetime of the transaction (mortal) to a small block range.

To the best of my knowledge there is no reason to worry about replay attacks across parachains because each parachain has a unique identifier (genesis block hash) that would make a transaction invalid if it were replayed on another chain. See here for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment