Cardano Improvement Proposals


CIP 3 - Annexe

Icarus key format

Note: Also supports setting an extra passphrase as an arbitrary byte array of any size (sometimes called a mnemonic password). This passphrase acts as a second factor applied to cryptographic key retrieval. When the seed comes from an encoded recovery phrase, the password can therefore be used to add extra protection in case where the recovery phrase were to be exposed.

Code

function generateMasterKey(seed, password) {
        let data = PBKDF2
            ( kdf=HMAC-SHA512
            , iter=4096
            , salt=seed
            , password=password
            , outputLen=96
            );
    
        return tweakBits(data);
    }
    
    function tweakBits(data) {
        // on the ed25519 scalar leftmost 32 bytes:
        // * clear the lowest 3 bits
        // * clear the highest bit
        // * clear the 3rd highest bit
        // * set the highest 2nd bit
        data[0]  &= 0b1111_1000;
        data[31] &= 0b0001_1111;
        data[31] |= 0b0100_0000;
    
        return data;
    }
    

Test vectors

No passphrase

recovery phrase

  eight country switch draw meat scout mystery blade tip drift useless good keep usage title
    

master key

  c065afd2832cd8b087c4d9ab7011f481ee1e0721e78ea5dd609f3ab3f156d245d176bd8fd4ec60b4731c3918a2a72a0226c0cd119ec35b47e4d55884667f552a23f7fdcd4a10c6cd2c7393ac61d877873e248f417634aa3d812af327ffe9d620
    


With passphrase

recovery phrase

  eight country switch draw meat scout mystery blade tip drift useless good keep usage title
    

passphrase

  foo (as utf8 bytes)
    

master key

  70531039904019351e1afb361cd1b312a4d0565d4ff9f8062d38acf4b15cce41d7b5738d9c893feea55512a3004acb0d222c35d3e3d5cde943a15a9824cbac59443cf67e589614076ba01e354b1a432e0e6db3b59e37fc56b5fb0222970a010e
    

Trezor

When used < 24 words, the algorithm is the same as Icarus

When using 24 words, due to incorrect removal of the BIP-39 entropy checksum bits (via integer division by 8, incorrectly assuming the entropy checksum is always less than 8 bits), the entropy bytes are passed into the generateMasterKey() function together with the checksum which for 24-word mnemonics happens to be 8 bits = 1 byte. This bug has been identified and documented in the following Trezor firmware pull request: https://github.com/trezor/trezor-firmware/pull/1388

Note: Trezor also allows users to set an additional passphrase that works exactly the same as Icarus passphrase