Conversation
We noticed the possibilities of invariants inside the bip32 module. This commit Wants to cover all possible invariants of the bip32 indexes changing the enums with value to newtypes that only could be instantiated from its functionalities and constructors, especially while dealing with hardened indexes. Hardened indexes automatically defines its index while being casted, becoming infalibble to cast a Hardened index from a u32 value and the inner value is arbitrarily exposed with the accordingly value conversion, sucessfully covering cases with and without hardening notation. Naming changed, while dealing with key indexes we replaced the keyword and concept to "index" instead of number to better represent its unique function.
|
🚨 API BREAKING CHANGE DETECTED To see the changes click details on "Check semver breaks / PR Semver - stable toolchain" job then expand "Run semver checker script" and scroll to the end of the section. |
Pull Request Test Coverage Report for Build 11126557509Details
💛 - Coveralls |
|
Hey @jaoleal, thanks for tackling this. I don't know how to review this PR for a few reasons:
Also, I don't know exactly how is the best way to approach revamping this module. I definitely appreciate you working on this, the module sorely needs some love, but if I'm to have any hope of reviewing perhaps I can give you a few pointers:
This is not easy work, and anything that involves bit twidling and invariants is non-trivial to review. |
|
I understand your concern about the large diff size and appreciate your explanation. Let me refactor my idea: The extensive changes primarily stem from necessary renaming across the codebase and comprehensive documentation updates. While the diff appears substantial, the core functional changes are minimal, as evidenced by the small modifications to the examples demonstrating module usage. I acknowledge that separating these changes into multiple commits might be preferable. However, the interdependencies between the refactoring steps make it REALLY HARD to create isolated, functional commits. The primary goal here is to enhance the module's robustness by transitioning from "enums with fields" to more secure "NewType structs with getters, setters, and constructors for each case." This refactoring is crucial for improving the safety of key handling in Bip32, addressing potential vulnerabilities that could arise over time. The new design adheres to the principle of making it difficult for consumers to inadvertently misuse the API. While this PR is part of a larger improvement effort (as discussed in #3036), it stands alone as a significant enhancement to the codebase's security. I've updated the PR title to better reflect its scope. Looking ahead, I anticipate one more substantial PR implementing the NormalDerivationPath, which will build upon the security improvements introduced here. |
|
From BIP32:
So my read is that an "index" is a integer between 0 and 2^32. A number, which may be normal or hardened, is an integer between 0 and 2^31, and which index it corresponds to depends on whether it is normal or hardened. So the existing type name |
|
I understand your point, but I believe this is a somewhat superficial topic. I’ll explain my reasoning behind the decision to replace all mentions of "number" and simplify everything to "index." "Number" ends up being a generic term that appears a lot throughout the codebase, often referring to entities that have no relation to any "number" that could have an index and be used for deriving keys. Based on this, I began removing abstractions that seemed to only complicate understanding. I turned "ChildNumber" to "ChildKeyIndex" based on this thought process: "I have an extended key and I have the index of its child key, which contains a value that can be either Hardened or Normal." Two other minor points were:
It just felt more natural, but as I said, I think this is a somewhat superficial point. Naming in Bitcoin is a whole field of study in itself. I see a lot of issues with naming conventions in Bitcoin and all the alternatives always seem far from the concept. Anyway, that’s the reasoning. I just wanted to clarify so it doesn’t seem like a change without thought behind it, but you’re the maintainer @apoelstra , so it’s your call! |
For sure. I understand that you thought through the reasoning of this and are trying to simplify the concepts in the API. But I still want to stick with child number", since it's widely used, while "child index" less so, and the BIP seems to use these terms in slightly different ways (which correspond to the existing names). Weirdly, if I search for "bip32 child number" online I get many instances of the phrase "index number" which I have never heard of.
The term "child number" is the explicit name given to a field of an xkey. The term "child index" does not appear, only "index" by itself. And "index" is nearly as generic a term as "number", and in the context of a software library, is likely to appear more often in non-bip32 contexts. |
Hi guys, im splitting all the features from #3036 into some PRs so we can merge it in the lib as i mentioned before closing it.
In this PR, I implemented changes to replace the use of "numbers" with "indexes" for clarity. After reviewing the discussions and the confusion surrounding the terminology, I opted for the term “index,” as it’s consistently used in Bip32. To distinguish the u32 inside the index, I introduced the term "index value," which has worked well in practice.
Another key update addresses how we handle hardened indexes when working with index values. I’ve made two constant methods, shifted_index() and unshifted_index(), to ensure proper manipulation of these values. In Bip32, was common to see the index being directly shifted in some cases and used raw in others, so this change helps standardize that behavior.
Most of the core changes are in
bitcoin/src/bip32.rs