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 610
/// 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 +584
#[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

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 that would be a good idea. It would not make cdk spec compliant.

There is no merged spec so this is not an issue.

I still have concerns about removing support of the legacy method for known units. Both nutshell and cdk use the same paths now even though it is not spec'd. So it would be possible to keep that in the spec as a legacy path. The known units keep the current method anything else goes this way.

Right now if only the signatory db is lost from before this spec where there are legacy keysets after this change these keysets would not be recoverable and the mint could not sign or verify ecash from them.

@thesimplekid
Copy link
Collaborator

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

Comment on lines 597 to 612
/// 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.

@thesimplekid
Copy link
Collaborator

@crodas tests are now passing can you review?

@crodas
Copy link
Collaborator

crodas commented Jan 6, 2026

Absolutely!

crodas
crodas previously approved these changes Jan 9, 2026
@lescuer97
Copy link
Contributor Author

@thesimplekid rebased.

I will do some final tests around compatibility and it should be ready

crodas
crodas previously approved these changes Jan 14, 2026
@lescuer97
Copy link
Contributor Author

lescuer97 commented Jan 16, 2026

demo of the spec:

remote_signer_demo_compresed_free_convert.mp4

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

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

4 participants