-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Comments:BIP 0039
Source: http://docs.electrum.org/en/latest/seedphrase.html (as of 2017-1-27)
BIP39 was introduced two years after Electrum. BIP39 seeds include a checksum, in order to help users figure out typing errors. However, BIP39 suffers the same shortcomings as early Electrum seed phrases:
-
A fixed wordlist is still required. Following our recommendation, BIP39 authors decided to derive keys and addresses in a way that does not depend on the wordlist. However, BIP39 still requires the wordlist in order to compute its checksum, which is plainly inconsistent, and defeats the purpose of our recommendation. This problem is exacerbated by the fact that BIP39 proposes to create one wordlist per language. This threatens the portability of BIP39 seed phrases.
-
BIP39 seed phrases do not include a version number. This means that software should always know how to generate keys and addresses. BIP43 suggests that wallet software will try various existing derivation schemes within the BIP32 framework. This is extremely inefficient and rests on the assumption that future wallets will support all previously accepted derivation methods. If, in the future, a wallet developer decides not to implement a particular derivation method because it is deprecated, then the software will not be able to detect that the corresponding seed phrases are not supported, and it will return an empty wallet instead. This threatens users funds.
For these reasons, Electrum does not generate BIP39 seeds.
Author: Liraz Siri 2017-1-27
BIP39 requires a minimum 128-bits of entropy. Some people are suggesting this means deterministic Wallet creation procedures cannot output BIP39 because the user may provide less than 128 bits of entropy (e.g., in a passphrase). Another problem is that what constitutes true entropy in this context is not well defined. You can verify conformity to mnemonics and checksums, but it's hard to verify how much source entropy is in the process that generates the 128/256 bits you feed into a BIP39 compliant generation procedure. A CSPRNG is not necessarily better than a user supplied passphrase fed into a KDF, and may be worse. It depends on the amount of source entropy that goes into the CSPRNG and whether the CSPRNG is operating correctly. Whether something is or isn't conforming to BIP39 shouldn't depend on unverifiable premises.
--
The lack of versioning is a serious design flaw in this proposal. On this basis alone I would recommend against use of this proposal. The general design is a thinly disguised brainwallet. Experience with user behavior shows that the user of user passphrases is more or less unconditionally unsafe and yet very attractive to users. If this proposal is implemented it should not be implemented without the checksum enforced. Without it this proposal is an attractive nuisance which has directly caused funds loss.-- Greg Maxwell 2017-03-14
There are alternative binary-to-word encodings, e.g. PGP word list (a.k.a biometric Word List), EEF Word Lists (https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases), RFC-1760 2048 words (a.k.a. S/KEY 6-Words ). There aren't adventages and disadvantages of BIP-39 in comparison to the alternatives described. --Greg Tonoski, 2023-09-13
Inflexibility: entropy of 128, 160, 192, 224, 256 bit length limit is imposed instead of accepting any length (between 128-256).
--Greg Tonoski, 2023-09-13
Are there any benefits of SHA-256-derived checksum requirement? User ends up in the same situation if they input incorrect words - irrespectively of the checksum appended. Typing errors are not prevented. --Greg Tonoski, 2023-09-13
Key generation techniques may vary and co-exist. They are not dependent on Bitcoin protocol and vice-versa. While there are benefits of interoperability (e.g. standardized format of keys), the key generation techniques (e.g. PBKDF2, "The iteration count is set to 2048", source of randomness) may be treated separately and individually. --Greg Tonoski, 2023-09-13
Shells may interpret some words as reserved ones if not quoted, e.g. time, then, select, until. --Greg Tonoski, 2023-09-14
`
BIP: 119 Layer: Consensus (soft fork) Title: CHECKTEMPLATEVERIFY Author: Jeremy Rubin j@rubin.io Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0119 Status: Draft Type: Standards Track Created: 2020-01-06 License: BSD-3-Clause
==Abstract==
This BIP proposes a new opcode, OP_CHECKTEMPLATEVERIFY, to be activated as a change to the semantics of OP_NOP4.
==Summary==
OP_CHECKTEMPLATEVERIFY uses opcode OP_NOP4 (0xb3) as a soft fork upgrade.
OP_CHECKTEMPLATEVERIFY does the following:
- There is at least one element on the stack, fail otherwise
- The element on the stack is 32 bytes long, NOP otherwise
- The DefaultCheckTemplateVerifyHash of the transaction at the current input index is equal to the element on the stack, fail otherwise
The DefaultCheckTemplateVerifyHash commits to the serialized version, locktime, scriptSigs hash (if any non-null scriptSigs), number of inputs, sequences hash, number of outputs, outputs hash, and currently executing input index.
The recommended standardness rules additionally:
- Reject non-32 byte as SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS.
==Motivation==
This BIP introduces a transaction template, a simple spending restriction that pattern matches a transaction against a hashed transaction specification. OP_CHECKTEMPLATEVERIFY reduces many of the trust, interactivity, and storage requirements inherent with the use of pre-signing in applications. For more details on applications, please see the references.
==Detailed Specification==
The below code is the main logic for verifying CHECKTEMPLATEVERIFY, described in pythonic pseudocode. The canonical specification for the semantics of OP_CHECKTEMPLATEVERIFY as implemented in C++ in the context of Bitcoin Core can be seen in the reference implementation.
The execution of the opcode is as follows:
# CTV always requires at least one stack argument
if len(self.stack) < 1:
return self.errors_with(errors.script_err_invalid_stack_operation)
# CTV only verifies the hash against a 32 byte argument
if len(self.stack[-1]) == 32:
# Ensure the precomputed data required for anti-DoS is available,
# or cache it on first use
if self.context.precomputed_ctv_data == None:
self.context.precomputed_ctv_data = self.context.tx.get_default_check_template_precomputed_data()
# If the hashes do not match, return error
if stack[-1] != self.context.tx.get_default_check_template_hash(self.context.nIn, self.context.precomputed_ctv_data):
return self.errors_with(errors.script_err_template_mismatch)
return self.return_as_nop()
# future upgrade can add semantics for this opcode with different length args
# so discourage use when applicable
if self.flags.script_verify_discourage_upgradable_nops:
return self.errors_with(errors.script_err_discourage_upgradable_nops)
else:
return self.return_as_nop()
The computation of this hash can be implemented as specified below (where self is the transaction type). Care must be taken that in any validation context, the precomputed data must be initialized to prevent Denial-of-Service attacks. Any implementation must cache these parts of the hash computation to avoid quadratic hashing DoS. All variable length computations must be precomputed including hashes of the scriptsigs, sequences, and outputs. See the section "Denial of Service and Validation Costs" below. This is not a performance optimization.
def ser_compact_size(l): r = b"" if l < 253: # Serialize as unsigned char r = struct.pack("B", l) elif l < 0x10000: # Serialize as unsigned char 253 followed by unsigned 2 byte integer (little endian) r = struct.pack("<BH", 253, l) elif l < 0x100000000: # Serialize as unsigned char 254 followed by unsigned 4 byte integer (little endian) r = struct.pack("<BI", 254, l) else: # Serialize as unsigned char 255 followed by unsigned 8 byte integer (little endian) r = struct.pack("<BQ", 255, l) return r
def ser_string(s): return ser_compact_size(len(s)) + s
class CTxOut: def serialize(self): r = b"" # serialize as signed 8 byte integer (little endian) r += struct.pack("<q", self.nValue) r += ser_string(self.scriptPubKey) return r
def get_default_check_template_precomputed_data(self): result = {} # If there are no s`**