feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "bizinikiwi-bip39"
|
||||
version = "0.4.7"
|
||||
license = "Apache-2.0"
|
||||
description = "Converting BIP39 entropy to valid Bizinikiwi (sr25519) SecretKeys"
|
||||
documentation = "https://docs.rs/bizinikiwi-bip39"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
hmac = { workspace = true }
|
||||
pbkdf2 = { workspace = true }
|
||||
schnorrkel = { workspace = true }
|
||||
sha2 = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bip39 = { workspace = true, default-features = true }
|
||||
rustc-hex = { workspace = true, default-features = true }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"hmac/std",
|
||||
"pbkdf2/std",
|
||||
"schnorrkel/std",
|
||||
"sha2/std",
|
||||
"zeroize/alloc",
|
||||
"zeroize/std",
|
||||
]
|
||||
@@ -0,0 +1,55 @@
|
||||
# Bizinikiwi BIP39
|
||||
|
||||
This is a crate for deriving secret keys for Ristretto compressed Ed25519 (should be compatible with Ed25519 at this
|
||||
time) from BIP39 phrases.
|
||||
|
||||
## Why?
|
||||
|
||||
The natural approach here would be to use the 64-byte seed generated from the BIP39 phrase, and use that to construct
|
||||
the key. This approach, while reasonable and fairly straight forward to implement, also means we would have to inherit
|
||||
all the characteristics of seed generation. Since we are breaking compatibility with both BIP32 and BIP44 anyway (which
|
||||
we are free to do as we are no longer using the Secp256k1 curve), there is also no reason why we should adhere to BIP39
|
||||
seed generation from the mnemonic.
|
||||
|
||||
BIP39 seed generation was designed to be compatible with user supplied brain wallet phrases as well as being extensible
|
||||
to wallets providing their own dictionaries and checksum mechanism. Issues with those two points:
|
||||
|
||||
1. Brain wallets are a horrible idea, simply because humans are bad entropy generators. It's next to impossible to
|
||||
educate users on how to use that feature in a secure manner. The 2048 rounds of PBKDF2 is a mere inconvenience that
|
||||
offers no real protection against dictionary attacks for anyone equipped with modern consumer hardware. Brain wallets
|
||||
have given users false sense of security. _People have lost money_ this way and wallet providers today tend to stick
|
||||
to CSPRNG supplied dictionary phrases.
|
||||
|
||||
2. Providing own dictionaries felt into the _you ain't gonna need it_ anti-pattern category on day 1. Wallet providers
|
||||
(be it hardware or software) typically want their products to be compatible with other wallets so that users can
|
||||
migrate to their product without having to migrate all their assets.
|
||||
|
||||
To achieve the above phrases have to be precisely encoded in _The One True Canonical Encoding_, for which UTF-8 NFKD was
|
||||
chosen. This is largely irrelevant (and even ignored) for English phrases, as they encode to basically just ASCII in
|
||||
virtually every character encoding known to mankind, but immediately becomes a problem for dictionaries that do use
|
||||
non-ASCII characters. Even if the right encoding is used and implemented correctly, there are still [other caveats
|
||||
present for some non-english dictionaries](https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md),
|
||||
such as normalizing spaces to a canonical form, or making some latin based characters equivalent to their base in
|
||||
dictionary lookups (eg. Spanish `ñ` and `n` are meant to be interchangeable). Thinking about all of this gives me a
|
||||
headache, and opens doors for disagreements between buggy implementations, breaking compatibility.
|
||||
|
||||
BIP39 does already provide a form of the mnemonic that is free from all of these issues: the entropy byte array. Since
|
||||
verifying the checksum requires that we recover the entropy from which the phrase was generated, no extra work is
|
||||
actually needed here. Wallet implementors can encode the dictionaries in whatever encoding they find convenient (as
|
||||
long as they are the standard BIP39 dictionaries), no harm in using UTF-16 string primitives that Java and JavaScript
|
||||
provide. Since the dictionary is fixed and known, and the checksum is done on the entropy itself, the exact character
|
||||
encoding used becomes irrelevant, as are the precise codepoints and amount of whitespace around the words. It is thus
|
||||
much harder to create a buggy implementation.
|
||||
|
||||
PBKDF2 was kept in place, along with the password. Using 24 words (with its 256 bits entropy) makes the extra hashing
|
||||
redundant (if you could brute force 256 bit entropy, you can also just brute force secret keys), however some users
|
||||
might be still using 12 word phrases from other applications. There is no good reason to prohibit users from recovering
|
||||
their old wallets using 12 words that I can see, in which case the extra hashing does provide _some_ protection.
|
||||
Passwords are also a feature that some power users find useful - particularly for creating a decoy address with a small
|
||||
balance with empty password, while the funds proper are stored on an address that requires a password to be entered.
|
||||
|
||||
## Why not ditch BIP39 altogether?
|
||||
|
||||
Because there are hardware wallets that use a single phrase for the entire device, and operate multiple accounts on
|
||||
multiple networks using that. A completely different wordlist would make their life much harder when it comes to
|
||||
providing future Bizinikiwi support.
|
||||
@@ -0,0 +1,231 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate alloc;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::string::String;
|
||||
|
||||
use hmac::Hmac;
|
||||
use pbkdf2::pbkdf2;
|
||||
use schnorrkel::keys::MiniSecretKey;
|
||||
use sha2::Sha512;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub enum Error {
|
||||
InvalidEntropy,
|
||||
}
|
||||
|
||||
/// `entropy` should be a byte array from a correctly recovered and checksumed BIP39.
|
||||
///
|
||||
/// This function accepts slices of different length for different word lengths:
|
||||
///
|
||||
/// + 16 bytes for 12 words.
|
||||
/// + 20 bytes for 15 words.
|
||||
/// + 24 bytes for 18 words.
|
||||
/// + 28 bytes for 21 words.
|
||||
/// + 32 bytes for 24 words.
|
||||
///
|
||||
/// Any other length will return an error.
|
||||
///
|
||||
/// `password` is analog to BIP39 seed generation itself, with an empty string being default.
|
||||
pub fn mini_secret_from_entropy(entropy: &[u8], password: &str) -> Result<MiniSecretKey, Error> {
|
||||
let seed = seed_from_entropy(entropy, password)?;
|
||||
Ok(MiniSecretKey::from_bytes(&seed[..32]).expect("Length is always correct; qed"))
|
||||
}
|
||||
|
||||
/// Similar to `mini_secret_from_entropy`, except that it provides the 64-byte seed directly.
|
||||
pub fn seed_from_entropy(entropy: &[u8], password: &str) -> Result<[u8; 64], Error> {
|
||||
if entropy.len() < 16 || entropy.len() > 32 || !entropy.len().is_multiple_of(4) {
|
||||
return Err(Error::InvalidEntropy);
|
||||
}
|
||||
|
||||
let mut salt = String::with_capacity(8 + password.len());
|
||||
salt.push_str("mnemonic");
|
||||
salt.push_str(password);
|
||||
|
||||
let mut seed = [0u8; 64];
|
||||
|
||||
pbkdf2::<Hmac<Sha512>>(entropy, salt.as_bytes(), 2048, &mut seed)
|
||||
.map_err(|_| Error::InvalidEntropy)?;
|
||||
|
||||
salt.zeroize();
|
||||
|
||||
Ok(seed)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use bip39::{Language, Mnemonic};
|
||||
use rustc_hex::FromHex;
|
||||
|
||||
// phrase, entropy, seed, expanded secret_key
|
||||
//
|
||||
// ALL SEEDS GENERATED USING "Bizinikiwi" PASSWORD!
|
||||
static VECTORS: &[[&str; 3]] = &[
|
||||
[
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
"00000000000000000000000000000000",
|
||||
"44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453",
|
||||
],
|
||||
[
|
||||
"legal winner thank year wave sausage worth useful legal winner thank yellow",
|
||||
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
||||
"4313249608fe8ac10fd5886c92c4579007272cb77c21551ee5b8d60b780416850f1e26c1f4b8d88ece681cb058ab66d6182bc2ce5a03181f7b74c27576b5c8bf",
|
||||
],
|
||||
[
|
||||
"letter advice cage absurd amount doctor acoustic avoid letter advice cage above",
|
||||
"80808080808080808080808080808080",
|
||||
"27f3eb595928c60d5bc91a4d747da40ed236328183046892ed6cd5aa9ae38122acd1183adf09a89839acb1e6eaa7fb563cc958a3f9161248d5a036e0d0af533d",
|
||||
],
|
||||
[
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong",
|
||||
"ffffffffffffffffffffffffffffffff",
|
||||
"227d6256fd4f9ccaf06c45eaa4b2345969640462bbb00c5f51f43cb43418c7a753265f9b1e0c0822c155a9cabc769413ecc14553e135fe140fc50b6722c6b9df",
|
||||
],
|
||||
[
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
"000000000000000000000000000000000000000000000000",
|
||||
"44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453",
|
||||
],
|
||||
[
|
||||
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will",
|
||||
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
||||
"cb1d50e14101024a88905a098feb1553d4306d072d7460e167a60ccb3439a6817a0afc59060f45d999ddebc05308714733c9e1e84f30feccddd4ad6f95c8a445",
|
||||
],
|
||||
[
|
||||
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always",
|
||||
"808080808080808080808080808080808080808080808080",
|
||||
"9ddecf32ce6bee77f867f3c4bb842d1f0151826a145cb4489598fe71ac29e3551b724f01052d1bc3f6d9514d6df6aa6d0291cfdf997a5afdb7b6a614c88ab36a",
|
||||
],
|
||||
[
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"8971cb290e7117c64b63379c97ed3b5c6da488841bd9f95cdc2a5651ac89571e2c64d391d46e2475e8b043911885457cd23e99a28b5a18535fe53294dc8e1693",
|
||||
],
|
||||
[
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453",
|
||||
],
|
||||
[
|
||||
"legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title",
|
||||
"7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
||||
"3037276a5d05fcd7edf51869eb841bdde27c574dae01ac8cfb1ea476f6bea6ef57ab9afe14aea1df8a48f97ae25b37d7c8326e49289efb25af92ba5a25d09ed3",
|
||||
],
|
||||
[
|
||||
"letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless",
|
||||
"8080808080808080808080808080808080808080808080808080808080808080",
|
||||
"2c9c6144a06ae5a855453d98c3dea470e2a8ffb78179c2e9eb15208ccca7d831c97ddafe844ab933131e6eb895f675ede2f4e39837bb5769d4e2bc11df58ac42",
|
||||
],
|
||||
[
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote",
|
||||
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"047e89ef7739cbfe30da0ad32eb1720d8f62441dd4f139b981b8e2d0bd412ed4eb14b89b5098c49db2301d4e7df4e89c21e53f345138e56a5e7d63fae21c5939",
|
||||
],
|
||||
[
|
||||
"ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic",
|
||||
"9e885d952ad362caeb4efe34a8e91bd2",
|
||||
"f4956be6960bc145cdab782e649a5056598fd07cd3f32ceb73421c3da27833241324dc2c8b0a4d847eee457e6d4c5429f5e625ece22abaa6a976e82f1ec5531d",
|
||||
],
|
||||
[
|
||||
"gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog",
|
||||
"6610b25967cdcca9d59875f5cb50b0ea75433311869e930b",
|
||||
"fbcc5229ade0c0ff018cb7a329c5459f91876e4dde2a97ddf03c832eab7f26124366a543f1485479c31a9db0d421bda82d7e1fe562e57f3533cb1733b001d84d",
|
||||
],
|
||||
[
|
||||
"hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length",
|
||||
"68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c",
|
||||
"7c60c555126c297deddddd59f8cdcdc9e3608944455824dd604897984b5cc369cad749803bb36eb8b786b570c9cdc8db275dbe841486676a6adf389f3be3f076",
|
||||
],
|
||||
[
|
||||
"scheme spot photo card baby mountain device kick cradle pact join borrow",
|
||||
"c0ba5a8e914111210f2bd131f3d5e08d",
|
||||
"c12157bf2506526c4bd1b79a056453b071361538e9e2c19c28ba2cfa39b5f23034b974e0164a1e8acd30f5b4c4de7d424fdb52c0116bfc6a965ba8205e6cc121",
|
||||
],
|
||||
[
|
||||
"horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave",
|
||||
"6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3",
|
||||
"23766723e970e6b79dec4d5e4fdd627fd27d1ee026eb898feb9f653af01ad22080c6f306d1061656d01c4fe9a14c05f991d2c7d8af8730780de4f94cd99bd819",
|
||||
],
|
||||
[
|
||||
"panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside",
|
||||
"9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863",
|
||||
"f4c83c86617cb014d35cd87d38b5ef1c5d5c3d58a73ab779114438a7b358f457e0462c92bddab5a406fe0e6b97c71905cf19f925f356bc673ceb0e49792f4340",
|
||||
],
|
||||
[
|
||||
"cat swing flag economy stadium alone churn speed unique patch report train",
|
||||
"23db8160a31d3e0dca3688ed941adbf3",
|
||||
"719d4d4de0638a1705bf5237262458983da76933e718b2d64eb592c470f3c5d222e345cc795337bb3da393b94375ff4a56cfcd68d5ea25b577ee9384d35f4246",
|
||||
],
|
||||
[
|
||||
"light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access",
|
||||
"8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0",
|
||||
"7ae1291db32d16457c248567f2b101e62c5549d2a64cd2b7605d503ec876d58707a8d663641e99663bc4f6cc9746f4852e75e7e54de5bc1bd3c299c9a113409e",
|
||||
],
|
||||
[
|
||||
"all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform",
|
||||
"066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad",
|
||||
"a911a5f4db0940b17ecb79c4dcf9392bf47dd18acaebdd4ef48799909ebb49672947cc15f4ef7e8ef47103a1a91a6732b821bda2c667e5b1d491c54788c69391",
|
||||
],
|
||||
[
|
||||
"vessel ladder alter error federal sibling chat ability sun glass valve picture",
|
||||
"f30f8c1da665478f49b001d94c5fc452",
|
||||
"4e2314ca7d9eebac6fe5a05a5a8d3546bc891785414d82207ac987926380411e559c885190d641ff7e686ace8c57db6f6e4333c1081e3d88d7141a74cf339c8f",
|
||||
],
|
||||
[
|
||||
"scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump",
|
||||
"c10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05",
|
||||
"7a83851102849edc5d2a3ca9d8044d0d4f00e5c4a292753ed3952e40808593251b0af1dd3c9ed9932d46e8608eb0b928216a6160bd4fc775a6e6fbd493d7c6b2",
|
||||
],
|
||||
[
|
||||
"void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold",
|
||||
"f585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f",
|
||||
"938ba18c3f521f19bd4a399c8425b02c716844325b1a65106b9d1593fbafe5e0b85448f523f91c48e331995ff24ae406757cff47d11f240847352b348ff436ed",
|
||||
]
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn vectors_are_correct() {
|
||||
for vector in VECTORS {
|
||||
let phrase = vector[0];
|
||||
|
||||
let expected_entropy: Vec<u8> = vector[1].from_hex().unwrap();
|
||||
let expected_seed: Vec<u8> = vector[2].from_hex().unwrap();
|
||||
|
||||
let mnemonic = Mnemonic::parse_in(Language::English, phrase).unwrap();
|
||||
let seed = seed_from_entropy(&mnemonic.to_entropy(), "Bizinikiwi").unwrap();
|
||||
let secret = mini_secret_from_entropy(&mnemonic.to_entropy(), "Bizinikiwi")
|
||||
.unwrap()
|
||||
.to_bytes();
|
||||
|
||||
assert_eq!(
|
||||
mnemonic.to_entropy(),
|
||||
&expected_entropy[..],
|
||||
"Entropy is incorrect for {phrase}"
|
||||
);
|
||||
assert_eq!(&seed[..], &expected_seed[..], "Seed is incorrect for {phrase}");
|
||||
assert_eq!(&secret[..], &expected_seed[..32], "Secret is incorrect for {phrase}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user