bitcoinjs/bip39

The seed buffer is not always consistent

firstfan opened this issue · 3 comments

Sample test code:
`
import * as bip39 from 'bip39';

async function main() {
const mnemonic = 'teach grab street first maze tip assault family unfold mistake mean weasel';
let lastBuffer = null;
for (let i=0;i<300;i++) {
let seed = bip39.mnemonicToSeedSync(mnemonic);
let seedBuffer = new Uint8Array(seed.buffer);
console.log(i + " " + seed.toString('hex')+ " seed buffer length:" + seedBuffer.length);
if (lastBuffer != null) {
for (let j = 0; j < lastBuffer.length && j < seedBuffer.length; j++) {
if (seedBuffer[j] !== lastBuffer[j]) {
console.log("The same prefix length:" + j);
break;
}
}
}
lastBuffer = seedBuffer;
}
}

await main();
`

Run the sample code, and search 'The same prefix length' in the log, it may occurs several times.
This happens after v3.1.0, and may cause very serious issues.
Check this issue caused by that: ipfs-shipyard/js-human-crypto-keys#28
Check my article that caused real problem:
'How a Simple Code Mistake Cost Me 2400 AR Coins in Just a Few Seconds'

If you don't want applications use the seed.buffer method, but only use seed.toString('hex') way, please mark the buffer field as private.

let seedBuffer = await bip39.mnemonicToSeed(mnemonic);
let seed = new Uint8Array(seedBuffer.buffer);

This is a simple incorrect usage of the Buffer class in NodeJS.

スクリーンショット 2024-06-13 16 33 22

https://nodejs.org/api/buffer.html#bufbuffer

please mark the buffer field as private.

I can't mark the buffer field as private.

Buffer is a NodeJS primitive.

btw: You can covert a Buffer into a Uint8Array by just writing Uint8Array.from(seed)