2个版本

0.1.1 2021年8月28日
0.1.0 2021年8月28日

#68 in #seed

MIT/Apache

80KB
527

PktSeed

这是PktWallet使用的种子算法。

为什么还需要另一个种子算法?!

  1. 版本:BIP-39没有版本号,因此无法更新
  2. 加密:种子可以选择使用经过Argon2拉伸的密码进行加密,以提高安全性。BIP-39也允许使用密码,但密码是散列与种子,而不是用于加密,因此BIP-39密码永远不会更改,但PKT密码可以随时更改,这将仅导致种子的新基于单词的表示。
  3. 校验和:一个错误的单词可以快速检测到,而不会导致令人困惑的解密失败。生日还充当额外的几个校验和位,因为声明生日早于此种子算法首次发布或未来日期的种子将被拒绝。
  4. 生日:种子包含一个日期戳,表示种子(钱包)创建的日期,因此钱包实现可以重新同步种子而无需扫描整个区块链历史。
  5. 约定优于配置:所有PKT种子短语正好15个单词长,提供136位的保护,这是加密社区认可的足够安全级别。BIP-39定义了12、15、18、21和24个单词的种子,将适当安全级别的问题留给最终用户,其中许多人如果提供200个单词的种子,他们会选择。

如何做?

创建加密种子并输出单词

use rand::Rng;
use pktseed::{Seed, SeedEnc};
fn main() {
    let mut rng = rand::thread_rng();
    let seed = Seed::new(rng.gen::<[u8; 17]>());
    let seed_enc = seed.encrypt(Some(b"password"));
    println!("Encrypted seed words: {}", seed_enc.words("english"));
}

创建非加密种子

use rand::Rng;
use pktseed::{Seed, SeedEnc};
fn main() {
    let mut rng = rand::thread_rng();
    let seed = Seed::new(rng.gen::<[u8; 17]>());
    let seed_enc = seed.encrypt(None);
    println!("Unencrypted seed words: {}", seed_enc.words("english"));
}

检查种子是否加密

use pktseed::SeedEnc;
fn main() {
    let seed_enc = SeedEnc::from_words(
        "mom blanket bulk draw clip wolf bread erupt merry skin cable infant word exchange animal",
    ).unwrap();
    println!("Is seed encrypted? {}", seed_enc.is_encrypted());
}

解密种子

use pktseed::SeedEnc;
fn main() {
    let seed_enc = SeedEnc::from_words(
        "mom blanket bulk draw clip wolf bread erupt merry skin cable infant word exchange animal",
    ).unwrap();
    let seed = seed_enc.decrypt(b"password", false).unwrap();
    println!("Decrypted seed bytes: {}", hex::encode(&seed.bytes[..]));
}

C API

重新生成头文件:cargo build --release --features generate-capi

语言

要编译带有额外语言支持,可以使用

cargo build --release --features lang-spanish lang-french lang-czech

许可证

Apache2 OR MIT,任选其一。

依赖

~1.2–2.3MB
~35K SLoC