satoshilabs / slips Goto Github PK
View Code? Open in Web Editor NEWSatoshiLabs Improvement Proposals
License: Creative Commons Attribution Share Alike 4.0 International
SatoshiLabs Improvement Proposals
License: Creative Commons Attribution Share Alike 4.0 International
I'd appreciate if trezor command line tool supported signing of (big) files, e. g. Virtual Machine images.
AFAIK right now this goal can be achieved in multiple ways:
trezorctl sign-message
Signing via trezorctl is more lightweight and preferable to me, since, for example, it can be easily and quickly performed from freshly created Python-virtual-environment that may be destroyed right after that.
Problem with point nr. 2 is, there is still too much freedom. I have to specify BIP32 key derivation path, coin and script-type. None of those features are relevant for this purpose.
Therefore I suggest to create another SLIP for this.
Trivial solution may be, for example, to use directly BIP39 seed generated using PBKDF2 with different salt (instead of "mnemonic + passphrase" use, say, "trezor signed data").
Or may involve some more complex operation using HD-features that are either deterministic or that would be dumped as part of the signature metadata.
Ideas?
With RS(1024), the 30 bits of checksum can only automatically recover from 1-word error. However hand-writing is rather error prone and study shows an error rate as high as 0.9% per word (http://panko.shidler.hawaii.edu/HumanErr/Basic.htm). So it seems not uncommon to have 2-word errors in a SSS share.
I am not sure if there are any other studies in this field. But I'd like to suggest that 40 bits used for checksum so that 2-word errors could be automatically recovered.
(There are other aspects in BIP/SLIP-0039 that needs improvements in my opinion but I will bring that up in the mail list for a broader audience.)
Should I change this constant to use a different path?
Thank!
https://github.com/bitpay/bitcore-lib/blob/master/lib/hdprivatekey.js#L613
https://github.com/bitpay/bitcore-lib/blob/master/lib/hdpublickey.js#L464
I'd implementing it in Jaxx, and am going to use index 137 for this. Thanks :D
Number: SLIP-0048
Title: Deterministic key hierarchy for Graphene-based networks
Type: Informational
Status: Draft
Authors: Fabian Schuh <[email protected]>
Created: 2016-10-18
This SLIP defines the logical hierarchy for deterministic wallets using Graphene technology.
The key derivation structure defined in BIP-0044/SLIP-0044 does not properly represent the possibilities available to Graphene based networks. For this reason, we defined this SLIP and provide a standard for hierarchies on those networks.
Graphene-based blockchains (such as BitShares, Steem, Peerplays, MUSE, etc.) do not use the UTXO model. Instead, there are accounts registered on the blockchains that have a (modifiable) permission scheme attached to each of them. The actual permissions depend on the use case of the network but most of them constitute an owner
and an active
permission among others. Usually, the only difference between owner
and active
permission is that the owner
can change the owner
permission, while the active
cannot, and thus represents some kind of cold storage or super-admin permissions.
Technically, each permission can consist of multiple (weighted) keys or other accounts to facilitate hierarchical weighted permissions on the blockchain.
Wallets are supposed to have at least one key installed that is associated with the account's owner permission (i.e. the owner
key) to allow recovery.
The memo
key is different in that it is not a permissions but a single key that is assigned to an account. This key is used for private (encrypted) messaging to derive a shared secret between sender and receiver.
m / purpose' / network' / account-index' / permission'
Each level has a special meaning, described in the chapters below. Apostrophe in the path indicates that BIP32 hardened derivation is used.
Purpose is a constant set to 48' (or 0x80000030) following the BIP43 recommendation. It indicates that the subtree of this node is used according to this specification.
Hardened derivation is used at this level.
One master node (seed) can be used for unlimited number of independent keys which can be used in different networks such as BitShares, Steem, PeerPlays and others. However, sharing the same space for various networks has some disadvantages.
This level creates a separate subtree for every network, avoiding reusing addresses across networks and improving privacy issues.
network
is a constant, set for each network. Developers may ask for registering unused number for their project.
The list of already allocated networks is in the chapter "Registered networks" below.
Hardened derivation is used at this level.
Since hierarchical key derivation can be used to obtain an infinite amount of keys, we allow users to store keys for an infinite amount of accounts by using account indices. This means that account-index 0, derives a subkey to obtain multiple keys associated with account A, while account-index 2 does the same for account B. Note that the public keys cannot be associated with each other unless a common parent node in the tree is published.
Software needs to discover all used accounts after importing the seed from an external source. Such an algorithm is described in "Account discovery" chapter.
Thus, software should prevent a update of an account with a specific key (see below) if a previous key does not have an account associated with it.
Each account can be associated with its own keys. To distinguish different permissions, a permissions id is used to obtain a specific sub tree. Since each Graphene-based network can have it's own specific set of permissions, the actually used permission indices are provided in the section "Registered networks", below.
Hardened derivation is used at this level.
When the master seed is imported from an external source the software should start to discover the accounts in the following manner (for a specific permission, e.g. active
):
This algorithm is successful because software should disallow creation of new accounts if previous one has no associated account.
Public Key gap limit is currently set to 5. If the software hits 5 unused public keys in a row, it expects there are no used accounts beyond this point and stops searching the public key chain.
Wallet software should allow the advanced user to manually search beyond the gap limit of 5.
This paragraph describes how to onboard an existing account into this standard, e.g. for hardware wallets. Later it will be possible to create (and register) new accounts, given a funded account is already available through this specifications (account creation costs a fee on most networks).
The procedure to onboard an account involves two transactions and works as follows:
account_update
operation in order to replace the existing permissions for sole access to the account by keys following this specification.The advantages of this procedure are:
account_update
operation.Disadvantages are:
Index | Network | Permissions |
---|---|---|
0x00000000 | Steem | 0x0 : owner, 0x1 : active, 0x3 : memo, 0x4 : posting |
0x00000001 | BitShares | 0x0 : owner, 0x1 : active, 0x3 : memo |
0x00000002 | PeerPlays | 0x0 : owner, 0x1 : active, 0x3 : memo |
0x00000003 | Muse | 0x0 : owner, 0x1 : active, 0x3 : memo |
Network | Account-index | Permissions | Path |
---|---|---|---|
Steem | first | active | m / 48' / 0' / 0' / 1' |
BitShares | forth | owner | m / 48' / 1' / 3' / 0' |
purpose
to 48
5 byte/40 bit secret
82 bits
9 words
6 byte/48 bit secret
90 bits
9 words
If I have generated a share where the master secret is for example, 5 bytes(40 bits) or 6 bytes(48 bits), a valid multiple of 8 bits, I will end up creating a secret share of size 82 bits and 90 bits respectively when accounting for additional checksum data and index/threshold data.
However, both of these secret sizes will create a secret share of 9 words. This means that when using these shares as input into the master secret recovery function, there is not enough information to automatically determine the secret size 100% of the time (at least so far as I can tell). There is only enough information to detect that the secret size is "at most X bits", meaning given random data size, you would only be accurate 50% of the time.
Assuming I haven't overlooked something, I see there being 3 possible options to deal with this:
I personally like options 2 and 3, but please let me know what you think or if there are other options and solutions that would be better.
It would be useful to have list of requirements for a future replacement of the standards around hierarchical deterministic wallets and other uses of deriving keys from a mnemonic. Let me know if this is not the right place.
In order to turn it into a BIP / SLIP it needs more feedback and I'll need to make it bit less opinionated :-)
A good place to start is the mnemonic word list. @Arachnid suggested several improvements a while ago (see below). Even though an updated word list will have overlap with the BIP39 list, new mnemonics can be generated in such a way to guarantee incompatibility with existing wallets. This intentional incompatibility provides an opportunity to change other rules.
I do not believe this is urgent, so there's time to do this thoroughly and develop a standard that last for a while.
Criteria @Arachnid used in his word list generator draft:
Wallets need to be able to distinguish between the old and new standard, so un-upgraded BIP 39 wallets should consider all new mnemonics invalid. At the same time, some new wallets may not wish to support BIP39. They shouldn't be burdened with storing the old word list.
A solution is to sort the new word list such that reused words appear first. When generating a mnemonic, at least one new word must be present. A wallet only needs to know the index of the last BIP39 overlapping word. They reject a proposed mnemonic if none of the elements use a word with a higher index.
BIP 44 is too detailed. E.g. it doesn't make much sense for non-UTXO coins such as Ethereum. It's also not very flexible, leading to the creation of BIP49 to add SegWit support. BIP43 on the other hand is too permissive. This makes it difficult for wallets to properly advertise their compatibility.
The community for each coin is probably most suited to figure out their own derivation scheme below the coin type level. I propose the following rules for coins to be accepted into the standard and for wallets to be able to claim compatibility.
See also SLIP-0010 for non-secp256k1 coins.
The rules for which addresses to scan should be coin specific.
This discussion might be more appropriate for a BIP proposal, but I'm just putting it out there.
In my own experience the current limit of 20 has downsides. It may be a reasonable performance trade-off, but this should be evaluated.
There is often a delay between when a wallet user sends an address and when they receive payment. Sometimes they never receive payment. There are services such as exchanges which require you to give them an address, but you may end up never using it. For privacy reasons a wallet should not reuse such an address anywhere else.
As with BIP 44, change addresses don't need a GAP limit. Unless someone objects.
It would be a better user experience is empty accounts can be allowed, e.g. max 3 (again, assuming there's no unacceptable performance issue).
Perhaps by the time this standard goes live, all wallets default to SegWit. But if not, I suggest that when a wallet scans:
Again, more of an EIP discussion, but just one thought: consider hardened derivation for each independent "account". Private keys can be exported and this is often useful when different wallets have strongly differentiated features and development is in flux.
Can this can be improved? @sipa might have some ideas regarding error correction. Representing the words as integer values rather than literal strings might add more flexibility. I like how bech32 allows a wallet to pinpoint the location of a typo. Similarly it would be nice if it can pinpoint which word is wrong and suggest the right one. For 12 word mnemonics it's surprisingly easy to type a wrong word and still get a valid mnemonic (but an empty wallet).
The minimum number of words could also be reconsidered, but there is a trade-off regarding the likeliness that someone actually writes it down.
12-24 word mnemonics are great for new users, but they're not great if someone gets their hand on your piece of paper. It would be nice if the seed can also be exported in a BIP38-like encrypted fashion, perhaps printed as a QR code. More generally, it should be possible to take advantage of hierarchical deterministic wallets without having to use the mnemonic.
Can this be improved?
I vaguely remember some Bitcoin Core developers having doubts . @luke-jr do you remember who / why?
Personally I'm skeptical about this feature and I think it just confuses people. For duress, wouldn't it be better for software to suggest a slight variant of the mnemonic that's easy enough to remember?
Removing that feature would allow more flexibly in the derivation algorithm.
I don't think it's a good idea to map word lists in other languages directly to the seed. This could create accidental vendor lock-in if only one wallet supports a certain language. I suggest mapping each word to English or directly to an integer value. It doesn't have to be the same meaning.
If a foreign language mnemonic supporting wallet ever becomes abandoned, the community can create a printable sheet with the mapping of each foreign word to the corresponding English word (again, meanings don't have to match at all).
In addition to a list of universal criteria, it may be useful to have an approval process for each new language. For example some sort of testimony from a linguist, or a native speaker with significant experience in bitcoin. Every language has its quirks which leads to things to avoid (e.g. tons of homonyms in Mandarin) and things to embrace (e.g. many 2 character words in Mandarin).
E.g.:
There should be a way to plug these new applications in. Perhaps through redefining "coin type" as "coin or application type"?
I would suggest giving this standard a name that's as easy to recognize as USB. BIP44 caught on a little bit within the bitcoin tech savvy community, but it's not great to have a name tied to a specific BIP/SLIP number, even with versioning.
What else should be considered?
Can you add link to JavaScript module bip44-constants (npm) to SLIP-0044? Thanks!
240 | 0x800000f0 | HDAC | HDAC
Hi, i'm new to cryptography and cryptocurrency and thought this would be a cool way to learn more and get involved. I have a few questions about this SLIP. Here is a link to my rough code base that I'm working on if you're interested. Thanks.
From this value, every byte is mapped to the specified field in a little-endian fashion (i.e. the first bit maps to a_7, the last bit maps to a_0). For each such field element, N-share field elements are generated and mapped back to bytes. Each participating party receives the following data:
What does little-endian mean in this case? If i currently have a byte array representing the secret+checksum, do I need to iterate over the bytes in reverse while creating the secret pieces? I don't understand how little-endian is relevant here if I am simply doing bitwise operations/log table lookups on a byte using GF 256 math over the Rijndael field.
This structure is then converted into a mnemonic passphrase by splitting it up by 10 bits which correspond as an index to the a word list containing exactly 1024 words
I'm unclear on how to "split up" the 298 bits in the case of a 256 bit secret. Let's say I want to split up the following bytes into 10 bit chunks:
list := []byte{5, 10, 255, 199} // 0b00000101 0b00001010 0b11111111 0b11000111
Given that "little-endian" was mentioned prior, would my output into 10 bit chunks look like this using LSB bit numbering:
1010000001 0100001111 1111111000 11 // 641, 271, 1016, 3
or using MSB bit numbering:
0000010100 0010101111 1111110001 11 // 20, 175, 1009, 3
curve.png no longer accurately depicts the process:
When any T points are provided, they exactly define the polynomial. The polynomial's value of f(0) = PMS is called the pre-master secret. More details on SSS can be found on Wikipedia.
I believe the image will need to be re-generated to show f(0) as "Pre-master secret"
Any suggestion for the ETC coin type index? How about 160 (ETH is 60)?
180 | 0x800000b4 | MarteXcoin
https://github.com/martexcoin/slips/commit/8761667e5af18bca48712b5151fd57d7fdf10646
As with SLIP-44 (registered coin types) and SLIP-173 (registered human-readable bech32 prefixes), we need some place to catalog BIP-32 version bytes. For Bitcoin mainnet, this is 0x0488B21E
which produces the xpub
prefix on HD public seeds when Base58 encoded.
Even @prusnak's BIP-84 fails to document the version bytes needed to reach zpub
in the HD serialization. I did find a post on the mailing list proposing the xpub
, ypub
, zpub
version bytes, but I don't think this is recorded anywhere else except the source code of wallets. (Please correct me if I'm wrong on this count)
The issue I've found is that multiple values of the version bytes will produce the same ASCII prefix when Base58 encoded. It would be nice to maintain a registry of those version bytes here.
As a side note: I'm hopeful that the adoption of SLIP-32 encoding of HD seeds will make this request redundant, but I don't see wallet adoption happening soon.
Just glanced over the list and noticed that slips/slip-0044.md:177 lists an incorrect HexAddress for Defcoin. Looks like a copy-paste error from Ripple two lines above. Should be 0x80000000 + 1337 = 0x80000539.
Feathercoin uses the prefix of fc for SLIP-0173, the list here was just brought to my attention and the fact that our Bech32 address clashes with Fujicoin. Is it possible to have duplicates on the list?
I wanted to know what my private key would my seed-phrase generate for NEO. But since I could not find NEO in the list of registered coins, I figure this is not possible at this time?
What's the process for adding a new coin? i.e. Can I request adding NEO
This spec defines coin_type
to use hardened derivation. The result is that this specification can't be used to share a "milti-coin master seed", which could be useful.
For instance, assume a service where the user generates a xpriv and corresponding xpub. They give the xpub to the service, and then sends the service $1000 worth of bitcoin. The service then generates an LTC address using the xpub and sends $200 to that address. It also generates a Dash address from the xpub and sends $200 to that address, and so on... The user who has the xpriv can generate the private keys to actually spend these funds.
Basically it's like a ShapeShift Prism, except using HD keys instead of a smart contract. Unfortunately, because the BIP44 specification specifies hardened derivation for coin_type, this is not possible.
There should be an extension to Bip44 (or maybe another bip) that uses the same coin index as defined in slip44, but with non-hardened derivation.
It makes literally no sense whatsoever.. if we want Jaxx (or any other wallet) to have testnet support, we certainly aren't going to derive all of the testnets off the same HD branch. Maybe not a huge deal for (most) current blockchains, but ETH/ETC has already caused conflicts in this way with competing address space on an HD tree.
ETH testnet and ETC testnet should not be from branch 1. Similarly, and other further coins that share the same bitcoin-like configurations in order to preserve database/blockchain compatibility should also have their own HD branch paths.
So, what I'd propose is to make BTC the special case (with perhaps a list of wallet-compatible testnets) and augment this spec with the following:
All testnets are the base coin's HD branch # + (some other large number)
base + 177337 or some such thing :)
I wanted to clarify the usage of the string concatenation operator ||
when used with the master secret derivation functions.
Based on the short explanation found in the notation table, it makes sense to use that operator whenever we are doing the big-endian binary string concatenations.
However, for the PBKDF2 derivation functions, I noticed that this operator is also being used, despite the following paragraph that implies that string concatenation is not used, but instead a specific encoding must be followed in order to create the salt for the function.
Each of the master secret derivation functions uses the key derivation function PBKDF2. Whenever the random identifier value id or the threshold T is an input to PBKDF2, it is encoded in the following manner. The random identifier value is split into three 10-bit integers each encoded as two bytes in little-endian byte order. The threshold is encoded as one byte.
Example confusing usage:
key = PBKDF2(PRF = HMAC-SHA256, Password = passphrase, Salt = ("slip0039" || id || T), iterations = 20000, dkLen = 256 bits)
I suggest slightly improving the terminology in this document. The data structure is defined as {N, I, M, SSS, C}, where the SSS part (being acronym for Shamir's secret share) is called "Share" and the actual cryptographic Share is produced by hashing serialized data structure. The words-encoded data structure, although this is not directly stated in this document, might also, for convenience, be called share by users. This is quite confusing.
I suggest to call the current SSS part in data structure as "share enthropy", the data structure itself as "share object" or "share mnemonic" and the final hash as "raw share" or "shamir's secret share".
The unhardened indexes in the worked example are incorrect, as far as I can tell.
I have attached two implementations of the worked example. The output is:
A = 490267344
A' = 2637750992
B = 697598796
B' = 2845082444
C = 1613620211
C' = 3761103859
D = 1858012177
D' = 4005495825
However, according to the worked example, the expected output is:
@@ -1,8 +1,8 @@
-A = 490267344
+A = 221831888
A' = 2637750992
-B = 697598796
+B = 160727884
B' = 2845082444
-C = 1613620211
+C = 3007475
C' = 3761103859
-D = 1858012177
+D = 247399441
D' = 4005495825
/cc @gary-rowe
/cc @joaojoyce #107
/* Little-endian only */
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "sha2.h"
int main(int argc, char **argv) {
(void) argc;
(void) argv;
uint32_t index = 0;
const char *uri = "https://[email protected]/login";
SHA256_CTX ctx;
sha256_Init(&ctx);
sha256_Update(&ctx, (const uint8_t *) &index, sizeof(index));
sha256_Update(&ctx, (const uint8_t *) uri, strlen(uri));
uint8_t hash[SHA256_DIGEST_LENGTH];
sha256_Final(&ctx, hash);
const uint32_t *fingerprint = (const uint32_t *) hash;
for (size_t i = 0; i < 4; i++) {
uint32_t index = fingerprint[i];
char name = 'A' + i;
printf("%c = %"PRIu32"\n", name, index & ~0x80000000);
printf("%c' = %"PRIu32"\n", name, index | 0x80000000);
}
}
from __future__ import print_function
import hashlib, string, struct
index = 0
uri = b"https://[email protected]/login"
h = hashlib.sha256()
h.update(struct.pack("<L", index))
h.update(uri)
hash = h.digest()
fingerprint = struct.unpack_from("<4L", hash)
for name, index in zip(string.ascii_uppercase, fingerprint):
print("{} = {}".format(name, index & ~0x80000000))
print("{}' = {}".format(name, index | 0x80000000))
The SLIP0013 reference document should provide an example of the expected values for A, B, C, D for a given set of example URIs and index values. These should include optional values (e.g. is a missing "user" field treated as empty string or null) and so on.
Adding these reference values will make supporting the feature much easier.
Here is some Java code to illustrate:
// See https://github.com/trezor/python-trezor/blob/ca45019918bc4c54f1ace899a9acf397c8f4d92f/tests/test_msg_signidentity.py#L27 for details
URI identityUri = URI.create("https://[email protected]/login");
List<Integer> addressN = IdentityUtils.buildAddressN(identityUri, 0);
// m/2147483661/2637750992/2845082444/3761103859/4005495825
assertThat(addressN.size()).isEqualTo(5);
// Remove the hardening to see the underlying value
assertThat(addressN.get(0) & 0x0fffffff).isEqualTo(13); // 2147483661L
assertThat(addressN.get(1) & 0x0fffffff).isEqualTo(221831888); // 2637750992L
assertThat(addressN.get(2) & 0x0fffffff).isEqualTo(160727884); // 2845082444L
assertThat(addressN.get(3) & 0x0fffffff).isEqualTo(3007475); // 3761103859
assertThat(addressN.get(4) & 0x0fffffff).isEqualTo(247399441); // 4005495825
The derivation of A,B,C,D should also be specified as little endian for the avoidance of doubt.
Hi, we need to add OOT to Coinomi wallet; and they asked to include the coin in the SLIP-0044.
The values would be the same as for KMD, since our code is the same, just independent chain.
How should we proceed? Would the index number be the same?
Thanks in advance.
{{admin:public_key_secret_access_token}}
Hello,
I described my idea here:
https://bitcointalk.org/index.php?topic=1497943.0
I am very interested by your opinion :)
Best regards, Perlover
Slip132 defines
Litecoin Testnet 0x0436f6e1 - ttub 0x0436ef7d - ttpv P2PKH or P2SH
yet the litecoin source code has for testnet:
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
so where is 0x0436f6e1 and 0x0436ef7d coming from?
See discussion here.
edit: the same applies to Litecoin mainnet:
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
vs
Litecoin 0x019da462 - Ltub 0x019d9cfe - Ltpv P2PKH or P2SH
Where the does the discrepancy come from? thx.
@prusnak if coin removed from list or allocate new constant, can we mark previous constant as not available for another coins? I often see such issues in bitcoinjs/bip44-constants, for example in last PR: bitcoinjs/bip44-constants#19
BTV
changed their constant at February in #216 and at June old constant was reused by GOD
-- #298 =(
Can we add note to SLIP that constant can not be reused? I think this also will be good left coin with old value in table but mark coin as crossed out with symbol ~
https://github.com/satoshilabs/slips/blob/master/slip-0132.md
I noticed in a discussion recently that this is meant to follow electrum in the prefixes used. I had made the mistake of assuming the P2SH, P2WSH, P2SH|P2WSH types referred to P2PKH inside the respective script type, but no, that it was for multisig.
Could the document be updated to reflect that they refer to multisig? The term isn't mentioned anywhere. I started implementing P2PKH inside these types as 'slip132' assuming they all referred to key hash types.
Can someone explain to me next questions regarding slip44
hexa
stands for ?0x8000003c
if in javascript converting(60).toString(16)
gives "3c"
60
to 0x8000003c
and in opposite direction in javascript ?looking at this, it seems sorta weird that testnet is the same for all coins. I'd have guessed that it would be a (large) integer addition that would be done with the regular coin type as the basis.
Hi,
Bitcoin Cash's CashAddr defines a specification for encoding legacy P2SH bitcoin addresses ("1...") with bech32, making addresses that look like: "bitcoincash:..." (as opposed to bitcoin's new bech32 address format, "bc1...")
I'm glad I found this work. I've built a tool that can use a standard like this. It currently applies its own conventions for passphrase encrypting and dividing cryptocurrency private keys using SSS. I would like to use interoperable standards but it appears they are being developed now, which is great and I look forward to being able to incorporate them when they're ready.
Feel free to close this. Just wanted to connect people doing similar things and share that this is ready to be applied. The development version is hosted at https://cryptostorage.com/experimental if anyone is inclined to review how the tool works now. Thanks.
In general if you have a large seed integer x
and want to create an integer d
in the range 1 ... n-1
, where n
is the group order, you can just do the following:
d = 1 + (x mod (n-1))
or alternatively if no addition is desired:
d = x mod (n-1)
if d == 0: d = n-1
The current SLIP-0010 uses d = x mod n
which creates the need for a retry sequence in the rare case where the resulting d
is zero. Is there some reason why mod(n) would be easier than mod(n-1) ?
Is there a reason why the address space starts that big ( example BTC: 0x80000000 )?
It just breaks int32, unit32 would work, but on some architectures/languages that might become unhandy.
That space includes (2^31)-1 coin derivations, a few less leading bits would do it too.
I was reviewing the changes to this SLIP when I saw the checksum is now done through Bech32. However according to the BIP, a "human readable part" is required to create the checksum.
Should the SLIP be updated to include a constant HRP?
My project, Factom, has been contacted by a wallet manufacturer to create a BIP-44 standardized compatible derivation. The only snag is that our internal token uses ed25519 signatures rather than the BIP-32 standard secp256k1.
I don't see any examples of another project on the BIP44 list having this problem as a precedent. Monero uses curve25519 and is listed here, but their code shows them using the electrum style seed.
https://github.com/monero-project/monero/blob/master/src/mnemonics/electrum-words.h#L62
nxt also used curve25519 and uses their own word list:
https://github.com/Blackcomb/nxt/blob/master/html/ui/js/crypto/passphrasegenerator.js#L43
BIP44 only uses hardened keys, so being able to publicly derive new pubkeys is off the table regardless.
Ed25519 can take in any length value for its private key, so it doesn't matter BIP44 generates 32 or 33 byte long keys.
Koinify used BIP-32 when they coded up the token sale: https://github.com/FactomProject/FactomDocs/tree/master/token_sale
Also, our project has two distinct tokens, one trade-able and the other not. They are Factoids and Entry Credits. Would it make sense to have a registered coin type for each?
I've developed a method to check if a mnemonic is also valid when the words are put into reverse order (not the entropy), where a given 12 or 24-word mnemonic could be valid both in little endian and big endian format. I've coined these Palindromic Mnemonics, but perhaps more user-friendly is "reversible mnemonics."
Purpose:
A checksum-valid reversible mnemonic allows two separate vaults to be connected to the same string of words, where all a users must do is enter the words in reverse order (the last word becomes first, second to last becomes second, and so on) to access the secondary (reversed words) vault. This utility could provide multiple users cases, including related to combinations with passphrases and plausible deniability, as well as conveniences for those wishing to use a separate vault tied to the same string of words.
Security
For any randomly generated 12-word mnemonic (128-bits of security) the chances of it also being reversible are 1/16, as a total of 4 bit positions must be identical (4 bits from the normal mnemonic, and another 4 bits from the reversed string). For 24-word mnemonics those values increase to 8 bits that need to match 8 bits from the reversed, leading to about 1 in every 256 mnemonics also being reversible. While the message space of valid reversible mnemonics should be 2^124 for 12 words, that search must still be conducted over a field of 2^128, as the hash-derived checksum values otherwise prevent a way to deterministically find valid reversible mnemonics without first going through invalid reversible ones to check. I think others should chime in on whether they believe there is any security loss, in terms of bits. I estimate at most it would be 4-bits for a 12-word mnemonic, but only if an attacker had a way to search only the space of valid reversible mnemonics (2^124). There could also be errors in my above assumptions, this is a work in progress and sharing it here to solicit feedback.
The following code can be used for testing, and run from terminal/command prompt it is pretty fast to find a valid reversible mnemonics, whereas on IDLE in Python on a 32-bit and 64-bit machine it could take a few seconds for 12 words and sometimes 10 minutes to find a valid 24-word reversible mnemonic: https://github.com/hatgit/BIP39_mnemonic_creation_light_python/blob/master/Palindromic_Mnemonic_experiment.py
Example randomly generated 12-word palindromic (reversible mnemonic):
Entropy length as hex without 0x pad: 32
Initial entropy as hex without pad: 39b2904bf37a267daf618fa03e5395a5
bytearray(b'9\xb2\x90K\xf3z&}\xafa\x8f\xa0>S\x95\xa5') <--- Entropy as bytes
Length of initial entropy as bytearray: 16
8dde9837e6f66605b28edb38573b76fff3504d74d94cb605f20a8061c88ddb9a <--- SHA-256 hash digest of entropy bytes
8 <--- Partial fragment of initial "byte" of hash
8 <--- First n bits of hash to convert to hex
1000 <--- Checksum (hex to bits)
Initial entropy + checksum = total bits: 001110011011001010010000010010111111001101111010001001100111110110101111011000011000111110100000001111100101001110010101101001011000
Length of total bits: 132
['00111001101', '10010100100', '00010010111', '11100110111', '10100010011', '00111110110', '10111101100', '00110001111', '10100000001', '11110010100', '11100101011', '01001011000']
Optional backup hex: 0x39b2904bf37a267daf618fa03e5395a5
Optional backup hex with checksum: 0x39b2904bf37a267daf618fa03e5395a58
Hash digest of initial entropy bytes: 8dde9837e6f66605b28edb38573b76fff3504d74d94cb605f20a8061c88ddb9a
[461, 1188, 151, 1847, 1299, 502, 1516, 399, 1281, 1940, 1835, 600]
defy nest base tragic pen disagree rural cradle parent verb tornado enrich
1101 <--- Last 4 bits of the first word to compare with checksum of mnemonic reverse order (hex to bits)
Palindromic mnemonic phase
['01001011000', '11100101011', '11110010100', '10100000001', '00110001111', '10111101100', '00111110110', '10100010011', '11100110111', '00010010111', '10010100100', '00111001101']
enrich tornado verb parent cradle rural disagree pen tragic base nest defy
Words reverse order = total bits: 010010110001110010101111110010100101000000010011000111110111101100001111101101010001001111100110111000100101111001010010000111001101
Words reverse order without last 4 bits = total bits: 01001011000111001010111111001010010100000001001100011111011110110000111110110101000100111110011011100010010111100101001000011100
gcc: 32
Entropy length as hex without 0x pad: 32
Initial entropy as hex without pad: 4b1cafca50131f7b0fb513e6e25e521c
bytearray(b'K\x1c\xaf\xcaP\x13\x1f{\x0f\xb5\x13\xe6\xe2^R\x1c') <--- Entropy as bytes
Length of initial entropy as bytearray: 16
dbbaacbd2043322a3247e7569af740193eb0db03d79923b83fecbf0de0b00465 <--- SHA-256 hash digest of entropy bytes
d <--- Partial fragment of initial "byte" of hash
d <--- First n bits of hash to convert to hex
1101 <--- Checksum reverse order (hex to bits)
1101 is equal to 1101. It is a palindromic mnemonic
references: https://github.com/trezor/python-trezor/issues
Please explain why the fixed salt in the passphrase section is no hazard? It appears to me that either this creates a vulnerability to rainbow tables, or that PBKDF2 isn't necessary at all.
Referencing to #180, I actually understood now that the coin-type definitions for BIP-0044 are all defined as the hardened version of the coin-type ID.
So I guess.
hardened:
index | hexa | symbol | coin |
---|---|---|---|
0 | 0x80000000 | BTC | Bitcoin |
Versus nonhardened:
index | hexa | symbol | coin |
---|---|---|---|
0 | 0x0 | BTC | Bitcoin |
Please, correct if I am wrong with that assumption.
Otherwhise I would propose to state that clearly within SLIP-0044 and BIP-0044, since this is not very clear to the reader.
Hi,
I'm not sure if this is the place to ask for such a question, so forgive me if I'm not using the correct channel.
I started to implement a python command-line tool that share some of the features of SatoshiLabs' password manager.
I stumbled upon SLIP-0016 and saw that there is already a python implementation.
It seems to me such code could be handy for third-party developers, and could be moved into the python api, maybe in the tools
subdirectory. Is such a thing a project? Would you be interested on a PR?
Moreover, I could not find any license information associated with the code in pwdreader.py
, so I don't know if I may use this code as a base for my own tool?
Thank you.
Thibault.
Hi,
I'm trying to implement https://github.com/satoshilabs/slips/blob/master/slip-0013.md in PHP but I'm having some problems with the example presented:
In particular I'm not finding the correct result for this example:
index + uri=0 + https://[email protected]/login
sha256(index + uri) = d0e2389d4c8394a9f3e32de01104bf6e8db2d9e2bb0905d60fffa5a18fd696db
In my PHP code I'm doing:
$url = "https://[email protected]/login";
$index = 0;
//This gives me the hash 59550cf1de0625bcc6a368e5fd3395c917d6e368fa8b908df96797f349d10e02
echo hash("sha256",$index . $url);
Could someone confirm the correctness of the example? Could this be an encoding problem or something similar?
Thank you very much.
Re: https://github.com/satoshilabs/slips/blob/master/slip-0039.md
(copied from https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-September/016418.html)
I and a number of companies & communities I am involved with are very
interested in this.
A challenge is that Shamir Secret Sharing has subtleties. To quote Greg
Maxwell:
I think Shamir Secret Sharing (and a number of other things, RNGs for
example), suffer from a property where they are just complex enough that
people are excited to implement them often for little good reason, and then
they are complex enough (or have few enough reasons to invest significant
time) they implement them poorly”.
Some questions for you:
What other teams or communities besides Trezor are committed to
standardizing a Shamir Secret Sharing Scheme? I can say that the
#RebootingWebOfTrust community (meeting again for the 7th time next week in
Toronto https://rwot7.eventbrite.com) are very interested.
Where do you want to hold discussions on this? Do people object to having
this discussion on this mailing list? Or should it be issues in SLIPS repo
or on some other mailing list?
Presuming a successful split of secrets, I don’t know all the adversarial
problems that are associated with recovery of a SSS. As this would be an
interactive event, I presume an attacker can DOS a request to reassemble
keys (so maybe some the of integrity of each share vs all is required). And
of course there are the biggest problems: impersonation of a reassembly
request and a MitM of a reassembly request. Are there other attacks? Are
you trying to mitigate any of these?
Two comments:
The Lightning Network community has added to their BIP32 mnemonics the
ability to have a birthday in the seed, to make it easier to scan the
blockchain for keys, as well as a byte with some way to know how to derive
keys paths for it. I don’t seee a BOLT for this (it was mentioned in
https://bitcoin.stackexchange.com/questions/74805/what-is-birthday-in-the-context-of-bip39-lightning-seed-generation)
I would suggest that you also get some of their latest thoughts and
incorporate them.
I worked with Chris Vickery while at Blockstrham on various possible ways
to improve mnemonic word lists. I’m not suggesting that you necessarily go
as far as we did to try to create a mnemonic that is iambic pentameter
poetry (inspired by
https://www.isi.edu/natural-language/mt/memorize-random-60.pdf), however,
we did find sources for words that are concrete (for example table is more
concrete than truth
http://crr.ugent.be/papers/Brysbaert_Warriner_Kuperman_BRM_Concreteness_ratings.pdf
) or have strong emotional valence attachment (truth is more emotional than
table), both of which make can words more memorable. I also found lists of
words that are hard to pronounce unless you are English native, and
eliminated them from my own list.
Among the results of this was a new BIP-39 2048 word compatible word list
filtered for memorability (concreteness & emotional valence) and
suitability for iambic pentameter, which is located:
https://github.com/ChristopherA/iambic-mnemonic/blob/master/word-lists/iambic-wordlist.json
…which was created from the repo at
https://github.com/ChristopherA/password_poem
You can a number of other word lists that I’ve collected here
https://github.com/ChristopherA/iambic-mnemonic/blob/master/word-lists/
If you want to replicate what we did with your own criteria, you may want
to incorporate information from the CMU dictitionary
http://www.speech.cs.cmu.edu/cgi-bin/cmudict, the top 5000 words
https://github.com/ChristopherA/password_poem/blob/master/top5000.json,
concrete word lists
http://crr.ugent.be/papers/Concreteness_ratings_Brysbaert_et_al_BRM.txt and
emotional words (valence) http://crr.ugent.be/archives/1003
Jaxx is going to use 134.
Im not necessarily implementing it with full hd style like our ethereum implementation, this is purely for using the entropy at this node point to be able to generate an address
I came accross other approach of standardizing Shamir's secret sharing for use in bitcoin. I think in context of Bitcoin several points could be worth mentioning:
I'd also find quite nice, if the mapping message <-> shares were unambiguous for any message, not just BIP39 enthropy, so I thought some smarter padding could be used, e. g. append '1' and bunch of zeros to fill the word. If 11-bit words were used (using (2) from above), than any standard BIP39 enthropy length (3, 6, 9, 12, 15, 18, 21 or 24 mnemonic words) inside share won't fill whole last word (30 mnemonic phrases would fill), so no additional dummy block will be needed. On the other hand, if somebody wanted to use this technique for any other purpose, it would work unambiguously. In worst case additional dummy word would be appended (|1000 0000 000|bin)
In case those remarks have not been implemented on purpose, please, is there some reference to that discussion? I'd like to see pros and cons of why this particular design has been used.
The List: Registered coin types within slip-0044.md is missing the currency abbreviations lice BTX ETH XRP ... and so on.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.