Skip to content

Conversation

@lescuer97
Copy link
Contributor

@lescuer97 lescuer97 commented Nov 8, 2025

Description

Changes the signatory keyset generation and updates the proto spec to follow this pr

1- Generates new keysets with the correct derivations paths.
2- returns the derivation_index as version
3- add test vectors from remote signer


Notes to the reviewers

This should not affect any already created keyset.


Suggested CHANGELOG Updates

CHANGED

ADDED

REMOVED

FIXED


Checklist

@lescuer97 lescuer97 changed the title bring signatory up to date with the signatory spec bring signatory up to date with the remote signer spec Nov 8, 2025
@lescuer97 lescuer97 force-pushed the signatory_up_to_spec branch from e44ec92 to 4e26d87 Compare November 8, 2025 19:21
@thesimplekid thesimplekid requested a review from crodas November 11, 2025 15:59
@thesimplekid thesimplekid added this to the 0.14.0 milestone Nov 12, 2025
Comment on lines 582 to 613
/// Big endian encoded integer of the first 4 bytes of the sha256 hash of the unit string.
pub fn derivation_index(&self) -> u32 {
use bitcoin::hashes::sha256;

let unit_str = self.to_string().to_lowercase();
let bytes = <sha256::Hash as BitcoinHash>::hash(unit_str.as_bytes());
// Take the first 4 bytes and convert to u32 (big endian) make sure the integer
u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) & !(1 << 31)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this spec'd? @vnprc has been working on something similar. #1004

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, it has always been part of the remote signer spec: https://github.com/cashubtc/nuts/pull/250/files.

The only new addition is the modulo on the sha256sum. @lollerfirst had a look at that and gave me some thumbs up on it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lescuer97 This will be a breaking change for the known types, how are planning to address that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I have open PRs to cdk and the NUTs repo to implement deterministic derivation paths
cdk PR #1181
NUTs PR cashubtc/nuts#292

Copy link
Contributor Author

@lescuer97 lescuer97 Nov 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I have open PRs to cdk and the NUTs repo to implement deterministic derivation paths cdk PR #1181 NUTs PR cashubtc/nuts#292

I was not aware of this PRs. @vnprc would you like to use mine? they seems to be equally as effective.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lescuer97 This will be a breaking change for the known types, how are planning to address that?

you are right, it would break it for library users. I could make a new version and make a deprecation warning for the older function. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crodas I added back and depracted the original index function.

Comment on lines +583 to +587
#[deprecated(
since = "0.14.0",
note = "This function is outdated; use `hashed_derivation_index` instead."
)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should deprecate this. Instead we keep the hard coded for the ones we already have and then hash anything else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that would be a good idea. It would not make cdk spec compliant.

I don't think breaking types here is a big deal thought.

As an alternative, I can also just do a simple hack and return Some(u32). even thought there is no option. This would mantain type consistent

@thesimplekid
Copy link
Collaborator

Are there still open questions on this should we bump it to 0.15?

Comment on lines 597 to 615
/// Big endian encoded integer of the first 4 bytes of the sha256 hash of the unit string.
pub fn hashed_derivation_index(&self) -> u32 {
use bitcoin::hashes::sha256;

let unit_str = self.to_string().to_lowercase();
let bytes = <sha256::Hash as BitcoinHash>::hash(unit_str.as_bytes());
// Take the first 4 bytes and convert to u32 (big endian) make sure the integer
u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) & !(1 << 31)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am concerned that this is not a hardened solution. It would derive different derivation indexes for currency unit strings that are almost but not quite the same:

  • leading and trailing whitespace
  • capitalization differences
  • functionally equivalent unicode character combinations

The version in this PR also doesn't include a reserved range for the existing hard coded currency units. Over a long enough timeframe this will introduce derivation path conflicts with sats, millisats, USD, and EUR.

As written in this PR, the hashed_derivation_index function would open the door to bugs and exploits. Resolving those issues in a backward compatible way would be more complex and difficult than just addressing the issues now before any hashed currency unit derivation paths are introduced in the wild.

I just removed the draft setting on #1181. I will rebase it to the latest commit on main. I think we should get 1181 merged and rebase this commit on top of it. Y'all should also review the NUT spec PR: cashubtc/nuts#292. Once I get some feedback on it I would be happy to open a PR to nutshell to get the spec finalized.

@thesimplekid thesimplekid removed this from the 0.14.0 milestone Nov 17, 2025
@lescuer97 lescuer97 force-pushed the signatory_up_to_spec branch from 891ac38 to 473d6c1 Compare December 3, 2025 14:13
@lescuer97
Copy link
Contributor Author

@vnprc @crodas could you take a look at this pr again pls. I think it is ready now

@lescuer97 lescuer97 requested a review from vnprc December 5, 2025 12:43
@lescuer97
Copy link
Contributor Author

@crodas could you re run the test? I think there was an error

@thesimplekid
Copy link
Collaborator

@crodas could you re run the test? I think there was an error

Its not an error. Cargo.lock file needs to be updated since you added a dep.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants