A Rust implementation of BIP-0039

Overview

bip39-rs

Build Status

A Rust implementation of BIP0039

Changes

See the changelog file, or the Github releases for specific tags.

Documentation

Add bip39 to your Cargo file, and then refer to the documentation for use.

Only an English wordlist is included at the moment, but support for other languages is already present in the code.

A set of simple tests have been written but they only generate new mnemonics and validate a selection of known valid mnemonics generated by other tools

Comments
  • WIP: Regression of seed generation between v0.5.1 and v0.6.0-beta.1

    WIP: Regression of seed generation between v0.5.1 and v0.6.0-beta.1

    I have cross-checked the seeds generated from the mnemonics with some other BIP39 wallets. I found that although the relation between English mnemonics and entropy conforms the BIP-0039 standard, the seed generation did not match even when only using ASCII (0..127) characters in the password (I know the UTF-8 normalization is still missing there).

    I have added failing tests, but could not get them pass yet.

    To manually cross-check the test-cases I have added based on the Trezor test-vector referenced from the standard, please

    • visit https://iancoleman.io/bip39/
    • Fill the "BIP39 Passphrase" field with "TREZOR" (all caps)
    • tick the "Show entropy details" checkbox
    • copy the entropy from a test-item in the test vector and paste it into "Entropy" field
    • compare the "BIP39 Seed" field with the seed in the test-item. They should be identical

    I think the problem should be somehow in the crpyto::pbkdf2 implementation, but could not narrow it down.

    opened by wigy-opensource-developer 14
  • Further Refactoring

    Further Refactoring

    I did some minor refactoring on top of #14

    Includes the API improvements, fixes, and most of the performance boosts from #14 but uses newer dependencies based on recent advances in the Rust ecosystem.

    • replaces FxHashMap with hashbrown for ~2x the performance boost (~8x performance boost on top of the original hashmap). hashbrown is also going to be merged into the rust std so it will allow for the dependency to be dropped in the future.

    • removes ring as a dependency in favor of smaller specialized crypto libs that have came out of rust crypto recently. No longer depends on ssl implementations.

    opened by QuestofIranon 9
  • Rethink API?

    Rethink API?

    Hi, first of all, thanks for providing this crate. I'm here to ask a question and complain about the API a bit. Sorry. :D

    My question is: how to generate a mnemonic from existing key? Bip39 describes the general conversion of encoding a key into a human-friendly string. It could be used outside of Bitcoin, etc. and that was my plan. I already have a key generated.

    struct Bip39 seems confusing. There is no such object as Bip39. There could be bip39:: Mnemnonic , but clamping all the functions into a struct doesn't seem to serve any purpose.

    The whole crate could be just couple two functions:

    fn mnemonic_to_key(&str) -> Result<Vec<u8>> and fn key_to_mnemonic(&[u8]) -> Result<String> + bit39::Result error types. Lenght of the string/vec already provides KeyType? The lang stuff could be skipped until someone actually makes an effort to implement it? :)

    Please let me know what you think, etc. I am planing to use this crate for some stuff, so I was just wondering: maybe I could make a PR or something.

    opened by dpc 4
  • Documentations Link in ReadMe goes to outdated version

    Documentations Link in ReadMe goes to outdated version

    I noticed that when you click in the documentation you get taken to the instructions for version 0.5.1, which has examples that aren't in compliance with the most up to date version of this crate. Since the actual link being used is https://docs.rs/bip39, I think this problem is with docs.rs, and nothing in the actual repository.

    opened by josh-kean 1
  • Refactor

    Refactor

    Disclaimer: This is a really big PR and I'm happy to make a fork of the crate and maintain it on crates.io if you'd rather not change the API as much as I've done here.

    • Reworked most of the API surface, removed methods dealing with hex-encoded strings, added LowerHex and UpperHex trait implementations to both Mnemonic and Seed for printing those out as hex. In general, I don't think parsing hex-encoded strings is within the scope of the library.
    • Added remaining languages.
    • wordlist now operates on &'static str instead of allocating Strings. When retrieved from Language, it returns a &'static [&'static str] instead of a &'static Vec<String>.
    • Similarly, WordMap is a newtype wrapping around FxHashMap<&'static str, u16> (which is just a regular HashMap using fast hashing algo from rustc, it's not as secure in terms of collisions as the default, but since we aren't allowing any insertions it shouldn't matter).
    • Replaced Result<T, Error> with custom Result<T> and switched to using the bail! macro from error_chain to reduce some boiler plate.
    • Removed bit-vec, bitreader and data-encoding dependencies.
    • Added benchmarks (rustup run nightly cargo bench) and a bunch new tests when necessary.

    Performance:

    • Validating phrases is now ~6x faster.
    • Creating a new Mnemonic from entropy is way faster (I don't have the original figures) due to reduced number of allocations (worst case scenario is 2-4 depending on the length of the key).
    • Generating a new Mnemonic (skipping Seed generation) from random entropy is now 20x+ faster.
    test from_entropy ... bench:         418 ns/iter (+/- 229)
    test new_mnemonic ... bench:         560 ns/iter (+/- 347)
    test new_seed     ... bench:   1,404,971 ns/iter (+/- 397,740)
    test validate     ... bench:         657 ns/iter (+/- 591)
    

    Generating a Seed is obviously most expensive due to the 2048 pbkdf2 rounds.

    opened by maciejhirsz 1
  • Performance and Rust idiomatic improvements

    Performance and Rust idiomatic improvements

    • Removed bitvec dependency, wrote a quick BitWriter struct that allows pushing 11 bits onto a Vec<u8> at once.
    • Removed a bunch of unnecessary allocations. This results in some (not all) functions that used to take generic S: Into<String> to take &str, which is more idiomatic although it is a breaking change on the API surface. Functions that need allocated strings (constructors that return owned structs mostly) remained unaffected.
    • wordlist and wordmap work using &'static str instead of Strings to avoid unnecessary allocations (not very critical).
    • Replaced Result<T, Error> with custom Result<T> from error_chain.
    • Bunch of smaller idiomatic changes that I likely can't recall here.
    • Added benchmarks (rustup run nightly cargo bench). Phrase validation time has been cut to nearly a quarter of original time.
    opened by maciejhirsz 1
  • error: no packages found with binaries or examples

    error: no packages found with binaries or examples

    I've clone repo and tried to install, but cargo doesn't see it as valid package.

    bip39-rs $ cargo install
    error: no packages found with binaries or examples
    $ cargo install --path .
    error: no packages found with binaries or examples
    $ cargo install --git https://github.com/infincia/bip39-rs
        Updating git repository `https://github.com/infincia/bip39-rs`
    error: no packages found with binaries or examples   
    $ cargo --version
    cargo 0.25.0
    

    Other packages work fine, e.g.

    $ cargo install --git https://github.com/rigelrozanski/dicedemon
        Updating git repository `https://github.com/rigelrozanski/dicedemon`
      Installing dicedemon v0.1.0 (https://github.com/rigelrozanski/dicedemon#02fcdf40)
    
    opened by kenorb 1
  • Add Mnemonic::from_entropy and Mnemonic::from_entropy_hex

    Add Mnemonic::from_entropy and Mnemonic::from_entropy_hex

    This is the opposite of get_entropy and get_entropy_hex, it's needed if you want to go from the entropy to the mnemonic.

    I noticed there was some related discussion in #5, so I'm not sure if that was ever resolved.

    opened by meh 1
  • cache word list+word map using lazy_static! & introduce to_entropy/to_entropy_hex

    cache word list+word map using lazy_static! & introduce to_entropy/to_entropy_hex

    cache word list+word map using lazy_static!

    The current implementation parses the word list over and over again. Using lazy_static! we can do the operation only once and use it directly the next time the crate is used.

    introduce to_entropy / to_entropy_hex

    other bip39 implementations all feature the to_entropy call, which converts a mnemonic to the original entropy value. to_entropy_hex returns a hex formatted string of the entropy bytes.

    Feedback about the API

    Generally, I agree with #4 and the API for this crate should by different. Seed and MNemonic should be distinct types that can be initialized by calling ::from(String) or ::new, expose functions to convert between each other and and to/from entropy, as well as each providing their own .as_hex() etc. . This way using the create would be a lot easier and intuitive.

    opened by yannleretaille 1
  • Doesn't pass BIP-0039 test vectors

    Doesn't pass BIP-0039 test vectors

    This crate has a bug. I noticed it doesn't have any unit test that verifies the implementation against the test vectors in the BIP39 spec.

        #[test]
        fn test_bip39() {
            let v_entropy = "68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c";
            let v_mnem = "hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length";
            let v_seed = "64c87cde7e12ecf6704ab95bb1408bef047c22db4cc7491c4271d170a1b213d20b385bc1588d9c7b38f1b39d415665b8a9030c9ec653d75e65f847d8fc1fc440";
            let v_passphrase = "TREZOR";
    
    
            let mnem = bip39::Mnemonic::from_phrase(v_mnem, bip39::Language::English).unwrap();
            let seed = bip39::Seed::new(&mnem, "TREZOR");
            assert_eq!(v_seed, &hex::encode(&seed.as_bytes()));
    
        }
    

    That example is director from the spec and it fails.

    opened by stevenroose 5
  • Review notes

    Review notes

    Hi,

    I've reviewed this crate using cargo-crev.

    Some notes:

    • maybe you should not implement Debug for Seed and Mnemonic. Debug makes it easy to accidentally log them somewhere and thus leak them.
    • there are multiple issues that cargo clippy will point out - nothing serious, but it is a good idea to just do what Clippy says. :)
    opened by dpc 2
  • Use own Error type instead of failure

    Use own Error type instead of failure

    Using failure might be easy internally, it's really annoying for external users not using failure. There is no way to catch the error and convert in another type while keeping some information intact.

    opened by stevenroose 0
  • Standard vectors fix

    Standard vectors fix

    This PR applies the fix @maciejhirsz mentioned in #17 (giving co-author credit). It also includes @wigy-opensource-developer's test and reverts back to using the rust only crypto crates.

    Fixes #17

    opened by QuestofIranon 8
  • Argon2, etc.

    Argon2, etc.

    Any opinion on whether this crate would be a good home for incompatible improvements to BIP32, provided the improvements are dramatic enough?

    Argon2 would be an obvious improvement over PBKDF2.

    If I understand, BIP32 already requires the same wordlist for checksums, yes? I could imagine either (a) improving that to actual error correction, which sounds very user friendly but requires the same wordlist, or (b) making the checksum work without the original wordlist, but doing both (a) and (b) together sounds hard.

    Any idea if anyone ever considered the wordlist size question? I know diceware recommends a larger wordlist with like 12.9 bits per word, but not sure if such a wordlist can easily avoid confusables in all desired languages.

    opened by burdges 4
Releases(v0.5.1)
  • v0.5.1(Apr 30, 2018)

    No source changes, minor version bump due to the addition of license files, which are included when packaging a crate.

    The license specified in the Cargo manifest is still correct.

    Changes

    • Add license files (#12) [c9beb96]
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Nov 7, 2017)

  • v0.4.1(Nov 8, 2017)

    Should be source compatible with v0.4.0, only the crate dependencies have changed.

    Changes

    • Update ring, bitreader, and error-chain [ae9bdfa]
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Nov 8, 2017)

    Mostly source compatible with v0.3.0, except for the additional error kind, and guarding against invalid entropy lengths being used to create a Mnemonic.

    Changes

    • Add failure test for Mnemonic::from_entropy() [4be7216]
    • Return error when invalid entropy is used [becd7b1]
    • Add error type for invalid entropy length [cd28a0b]
    • Implement std::fmt::Display for MnemonicType [0b7edf2]
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Nov 8, 2017)

    Completely refactored internal design and public API for ergonomics as well as to ensure safe usage. A number of std traits have been implemented for crate types as well.

    Public API

    There is now a Mnemonic type that is the "main" type in the crate, it can only be created by generating a new one, or supplying valid (proper length) entropy to re-create an existing mnemonic (see warning below).

    Once you have a Mnemonic, you can get a Seed from it for deriving HD wallet addresses, but for safety it cannot be created directly. You must obtain the Seed from a valid Mnemonic instance.

    From crate docs:

    Because it is not possible to create a Mnemonic instance that is invalid, it is
    therefore impossible to have a Seed instance that is invalid. This guarantees
    that only a valid, intact mnemonic phrase can be used to derive HD wallet addresses.
    

    Warning

    If you supply your own entropy to create a Mnemonic rather than generating a new one or using Mnemonic::from_string(), the Mnemonic instance you get back is by definition valid as far as the BIP39 standard is concerned, even if it doesn't correspond to the phrase you thought it would.

    The BIP39 checksum only covers the actual phrase as a string, if you somehow corrupt the entropy when storing or transmitting it outside this crate, you will get a different but still valid phrase the next time you use it.

    You should think very carefully before storing or using entropy values directly rather than the mnemonic string, they are generally not useful except in advanced use cases and cannot be used for HD wallet addresses (that's what the Seed is for, which is not the same thing).

    Changes

    • Better documentation
      • Add quick start example to docs in crate root [4e3b097]
    • Better public API
      • Rename Bip39 struct to Mnemonic [89de089]
      • Add a Seed type [22d9a68]
      • Add Mnemonic::from_entropy and Mnemonic::from_entropy_hex (#9) [cbec489]
      • Add Mnemonic::to_entropy & Mnemonic::to_entropy_hex (#7) [63dec97]
      • Allow Mnemonic to be used as a borrowed or owned string [c6d0162]
      • Implement AsRef for Mnemonic, gets the phrase as a string [e99b4bd]
      • Implement Default for Language and MnemonicType [01d2f46]
      • Derive Clone on Mnemonic and Seed [bdf9933]
      • Derive Copy and Clone for KeyType [9544ded]
      • Derive Copy and Clone for Language [13e3ddb]
      • Use consistent rules for KeyType and Language params, don't require refs [3992510]
    • Better error handling
      • Use error-chain (#6) [e878c67]
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Nov 8, 2017)

  • v0.2.0(May 11, 2017)

    Should be source compatible with older versions, none of the public interfaces have changed, only internal organization and crate dependencies.

    Changes

    • Removes rustc-serialize dependency in favor of data-encoding
      • to_hex() is now directly part of the Bip39 struct rather than the ToHex trait
    • Replaces rust-crypto with ring
    • Removes binary from crate
    Source code(tar.gz)
    Source code(zip)
  • 0.1.1(Nov 8, 2017)

    Minor changes to public API, but also removes a panic!() call

    Changes

    • Implement std::error::Error and std:fmt::Display on Bip39Error
    • Use Into for public function arguments
    • Don’t panic if words aren’t found in word list during validation
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Nov 8, 2017)

Owner
Infincia LLC
Consulting agency located in central Ohio, specializing in iPhone, iPad, and Mac development
Infincia LLC
Marvin-Blockchain-Rust: A Rust-based blockchain implementation, part of the Marvin blockchain project.

Marvin Blockchain - Rust Implementation Welcome to the Rust implementation of the Marvin Blockchain. This project is part of a comparative study on bu

João Henrique Machado Silva 3 Sep 6, 2024
IBC modules and relayer - Formal specifications and Rust implementation

ibc-rs Rust implementation of the Inter-Blockchain Communication (IBC) protocol. This project comprises primarily four crates: The ibc crate defines t

Informal Systems 296 Dec 31, 2022
Official Rust implementation of the Nimiq protocol

Nimiq Core implementation in Rust (core-rs) Rust implementation of the Nimiq Blockchain Core Nimiq is a frictionless payment protocol for the web. Thi

Nimiq 72 Sep 23, 2022
Rust implementation of Zcash protocol

The Parity Zcash client. Gitter Blog: Parity teams up with Zcash Foundation for Parity Zcash client Installing from source Installing the snap Running

Parity Technologies 183 Sep 8, 2022
A (mostly) pure-Rust implementation of various cryptographic algorithms.

Rust-Crypto A (mostly) pure-Rust implementation of various common cryptographic algorithms. Rust-Crypto seeks to create practical, auditable, pure-Rus

null 1.2k Dec 27, 2022
A pure-Rust implementation of group operations on Ristretto and Curve25519

curve25519-dalek A pure-Rust implementation of group operations on Ristretto and Curve25519. curve25519-dalek is a library providing group operations

dalek cryptography 611 Dec 25, 2022
[INACTIVE] TLS 1.2 implementation in Rust

suruga is Rust implementation of TLS 1.2. It currently implements some core parts of TLS 1.2, NIST P-256 ECDHE and chacha20-poly1305. Usage extern cra

klutzy/defunct 123 Dec 27, 2022
A prototype implementation of the Host Identity Protocol v2 for bare-metal systems, written in pure-rust.

Host Identity Protocol for bare-metal systems, using Rust I've been evaluating TLS replacements in constrained environments for a while now. Embedded

null 31 Dec 12, 2022
An implementation of the FP-Growth algorithm in pure Rust.

fp-growth-rs An implementation of the FP-Growth algorithm in pure Rust, which is inspired by enaeseth/python-fp-growth. Usage Add this to your Cargo.t

JmPotato 13 Dec 20, 2022
A pure-Rust implementation of various threshold secret sharing schemes

Threshold Secret Sharing Efficient pure-Rust library for secret sharing, offering efficient share generation and reconstruction for both traditional S

Snips 137 Dec 29, 2022
A Rust implementation of the Message Layer Security group messaging protocol

Molasses An extremely early implementation of the Message Layer Security group messaging protocol. This repo is based on draft 4 of the MLS protocol s

Trail of Bits 109 Dec 13, 2022
Pure Rust implementation of the RNCryptor cryptographic format by Rob Napier

rncryptor Rust Implementation of the RNCryptor spec This library implements the specification for the RNCryptor encrypted file format by Rob Napier. d

null 7 Jun 29, 2022
Implementation of the Web Cryptography specification in Rust.

[wip] webcrypto Implementation of the Web Cryptography specification in Rust. This crate hopes to ease interoperability between WASM and native target

Divy Srivastava 5 Mar 7, 2022
Implementation of Plonk by Hand in rust

plonk-by-fingers This is a toy implementation of the excellent Joshua Fitzgerald Plonk by hand (part2) (part3) tutorial all written from scratch, do n

adria0.eth 34 Dec 19, 2022
A Rust implementation of Trojan with QUIC tunnel, Lite-TLS and more.

Trojan-Oxide A Rust implementation of Trojan with QUIC tunnel, Lite-TLS and more. Overview Full support for the original Trojan Protocol, including TC

null 13 Oct 17, 2022
Pure Rust implementation of the Leighton Micali Signature scheme.

Leighton-Micali Hash-Based Signatures LMS implementation in Rust according to the IETF RFC 8554. This implementation is binary compatible with the ref

Fraunhofer AISEC 6 Jun 2, 2022
Rust implementation of Shamir's Secret Sharing

Horcrux - Rust implementation of Shamir's Secret Sharing This program is an example implementation of Shamir's Secret Sharing in Rust. You can find mo

null 13 Dec 29, 2022
Rust implementation of CAIP standards

Rust CAIP Standard Utilities Chain Agnostic Improvement Proposals (CAIP) is a set of standards for multi-chain interoperability. CAIP-2: Chain ID use

Public Awesome 6 Dec 12, 2022
Implementation of Yao's Millionare problem in Rust

Yao's Millionaire Problem Two millionaires wish to know who is richer; however, they do not want to find out inadvertently any additional information

Daniel Ramos 2 Jul 2, 2022