Java 来自BIP39助记符的种子不匹配测试向量

Java 来自BIP39助记符的种子不匹配测试向量,java,bitcoin,pbkdf2,Java,Bitcoin,Pbkdf2,我正在编写比特币BIP39的Java实现。到目前为止,我的代码能够正确地生成随机生成的助记符短语。但是,当将12字助记符短语转换为512位种子时,结果值与来自的结果不匹配 首先,SecureRandom对象生成一个随机的512位熵值(ENT)。使用SHA256对ENT值进行散列,以计算校验和值(CS),这是散列的前4位。校验和连接到ENT的末尾以给出ENT\u CS。ENT_CS被分成每个11位的部分,11位的对应整数值用作索引号,以从单词列表中获取单词。这就产生了我的12个单词的记忆短语。到目

我正在编写比特币BIP39的Java实现。到目前为止,我的代码能够正确地生成随机生成的助记符短语。但是,当将12字助记符短语转换为512位种子时,结果值与来自的结果不匹配

首先,SecureRandom对象生成一个随机的512位熵值(ENT)。使用SHA256对ENT值进行散列,以计算校验和值(CS),这是散列的前4位。校验和连接到ENT的末尾以给出ENT\u CS。ENT_CS被分成每个11位的部分,11位的对应整数值用作索引号,以从单词列表中获取单词。这就产生了我的12个单词的记忆短语。到目前为止,所有步骤都符合上述BIP39工具的预期结果

为了创建种子,我将PBKDF2与HmacSHA512一起使用,将迭代设置为2048,密钥大小设置为512位(64字节)。我已经针对这些、Google的“crypto”包实现和NovaCrypto的Java BIP39实现测试了我的PBKDF2实现。除分隔符外,助记符词与
“助记符”+密码一起用作输入,如所示

PBKDF2函数
公共静态字节[]PBKDF2(字符串助记符,字符串salt){
试一试{
字节[]fixedSalt=(“助记符”+salt).getBytes(StandardCharsets.UTF_8);
KeySpec spec=new-PBEKeySpec(助记符.toCharArray(),fixedSalt,2048512);
SecretKeyFactory f=SecretKeyFactory.getInstance(“PBKDF2WithHmacSHA512”);
返回f.generateScret(spec).getEncoded();
}捕获(NoSuchAlgorithmException | InvalidKeySpecException ex){
抛出新的运行时异常(ex);
}
}
生成助记符函数
public静态字符串[]generateMnemonic(){
//为熵生成128位随机数
字节[]ENT=getEntropy();
//散列熵值
字节[]散列=SHA256(ENT);
//将哈希的前4位复制为校验和
boolean[]CS=Arrays.copyOfRange(bytesToBits(HASH),0,4);
//将校验和添加到熵位的末尾
boolean[]ENT_CS=Arrays.copyOf(bytesToBits(ENT),bytesToBits(ENT).length+CS.length);
数组复制(CS,0,ENT_CS,bytesToBits(ENT).length,CS.length);
//将ENT_CS拆分为11位的组,并为其创建字符串数组
//记忆词
字符串[]助记符单词=新字符串[12];
对于(int i=0;i<12;i++){
boolean[]numBits=Arrays.copyOfRange(ENT_CS,i*11,i*11+11);
助记符单词[i]=wordList.get(bitsToInt(numBits));
}
返回记忆词;
}
辅助函数
//返回随机生成的16字节数字
公共静态字节[]getEntropy(){
字节[]ent=新字节[16];
高级新字节(耳鼻喉科);
返回耳鼻喉科;
}
//返回字节数组的位表示形式
公共静态布尔[]bytesToBits(字节[]数据){
boolean[]位=新的boolean[data.length*8];
对于(int i=0;i>4];
hexChars[j*2+1]=hexArray[v&0x0F];
}
返回新字符串(hexChars);
}
//返回输入数据的SHA256哈希值
公共静态字节[]SHA256(字节[]数据){
试一试{
MessageDigest=MessageDigest.getInstance(“SHA-256”);
System.out.println(Arrays.toString(data));
返回摘要。摘要(数据);
}捕获(nosuchalgorithmex异常){
抛出新的运行时异常(ex);
}
}
//返回位数组的int值
公共静态整型位整型(布尔[]位){
int n=0,l=bit.length;
对于(int i=0;in=(n看起来我能回答我自己的问题。
在我的程序中,我使用

字符串助记符短语=”;
for(字符串字:助记符字)
助记符短语+=单词;
但这不是正确的格式,因为要包含空格。更改此代码块以添加空格:

字符串助记符短语=”;

对于(inti=0;我能告诉我们Q?@MS90什么的Q吗?我还没有尝试从种子创建密钥对,只是尝试从一个助记短语生成一个正确的种子。
    My Program Trial
Entropy (hex): 3CCB62D9AF76F1E8DB113E66B2D84656
Checksum bits: 1100
Raw Binary: 00111100110 01011011000 10110110011 01011110111 01101111000 11110100011 01101100010 00100111110 01100110101 10010110110 00010001100 1010110
Mnemonic: devote force reopen galaxy humor virtual hobby chief grit nothing bag pulse
Seed: 013FFA714C57AA26C59DC215880D9C2398A8B38D10D7E41A882CF98C35976F0BF26BCC08B0B196945DE8778C7FD561FB0F20A8B9BAD46B12196C963A85E3B40E

    Expected Results (Derived from same Entropy)
Entropy (hex): 3CCB62D9AF76F1E8DB113E66B2D84656
Checksum bits: 1100
Raw Binary: 00111100110 01011011000 10110110011 01011110111 01101111000 11110100011 01101100010 00100111110 01100110101 10010110110 00010001100 1010110
Mnemonic: devote force reopen galaxy humor virtual hobby chief grit nothing bag pulse
Seed: 0c3c5f9ae724a2a3ed70aeb24919c10506e4962223a5375f70164be8b897d615ec9bf9f3e64a889cff03318cc5d0b3c8378ba0264d198e307c609632016ddd01