Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: require signatures to prove control of signer-key in pox #4277

Merged
merged 34 commits into from Feb 8, 2024

Conversation

hstove
Copy link
Contributor

@hstove hstove commented Jan 23, 2024

This closes #4247, which is to ensure that all Signers are using signing keys that they either control, or are controlled by the account they're delegating to.

This is done by adding a signer-sig param to:

  • stack-stx
  • delegate-stack-stx
  • stack-aggregation-commit

The signature follows SIP018 for signed structured data. Following SIP018 has the benefit of built-in wallet support, so signers can use hardware wallets and apps to generate these signatures.

Following SIP018, the structured data is { reward-cycle, reward-cycle }, where reward-cycle is the current stacking cycle where the transaction is made. The domain is { app: "pox-4-signer", version: "1.0.0", chain-id }.

Because we'll almost certainly be building the ability for stacks-signer to generate these signatures (ie via CLI), I added a SIP18 util library at /stacksib/src/lib_util/signed_structured_data. That library has tests that validate the functionality based on the test vectors in SIP018.

I added a function to_rsv to MessageSignature to match the byte order that Clarity uses for signatures.

Note that I added the new signer-sig param as the second-to-last argument because of other conversations around expected argument order, but I'm not really familiar with the requirements there. I also am not sure what other touch points use these functions where the arguments need to be updated. cc @zone117x regarding param order

Copy link

codecov bot commented Jan 23, 2024

Codecov Report

Attention: 18 lines in your changes are missing coverage. Please review.

Comparison is base (d8136bc) 58.59% compared to head (e577816) 77.07%.

Files Patch % Lines
...tackslib/src/chainstate/stacks/boot/pox_4_tests.rs 98.77% 11 Missing ⚠️
stackslib/src/util_lib/signed_structured_data.rs 97.65% 7 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             next    #4277       +/-   ##
===========================================
+ Coverage   58.59%   77.07%   +18.47%     
===========================================
  Files         445      446        +1     
  Lines      317218   318455     +1237     
===========================================
+ Hits       185882   245435    +59553     
+ Misses     131336    73020    -58316     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@hstove
Copy link
Contributor Author

hstove commented Jan 23, 2024

Do we need to add the signature check to delegate-stack-increase and delegate-stack-extend?

@hstove
Copy link
Contributor Author

hstove commented Jan 23, 2024

After further thought, I think we should follow SIP018 (signed structured data) for this. That also unlocks the ability for signers to use a web app to request signatures from a wallet.

@friedger
Copy link
Collaborator

#4247 is about delegating signer duties, not delegating stx. As far as I understand.

Pool operators can already refuse to delegate-stack-stx for a pool member.

@hstove
Copy link
Contributor Author

hstove commented Jan 23, 2024

@friedger @kantai is it better to describe this ticket as "delegates and delegators need to prove ownership of the signing key"? For delegates, this is proving that the signer they're delegating to has control over the signing key.

@jcnelson
Copy link
Member

Everyone needs to prove ownership of their signing key. This goes for solo stackers as well, via stack-stx and stack-extend. Basically, anywhere you see a signing key as an argument, you need to also require a signature argument and a signature verification (that should be stack-stx, delegate-stack-stx, stack-extend, and delegate-stack-extend).

@hstove hstove force-pushed the feat/signer-delegate-control branch from 2b4b228 to 89d8a7f Compare January 24, 2024 21:16
@hstove hstove marked this pull request as ready for review January 24, 2024 21:26
@friedger
Copy link
Collaborator

Instead of delegate stack stx, pool operators now provide the key in stack aggregation-* function calls.

See #4274

@hstove
Copy link
Contributor Author

hstove commented Jan 24, 2024

Instead of delegate stack stx, pool operators now provide the key in stack aggregation-* function calls.

See #4274

Good to know - and I'll have to change this to build off the change from signer-key to signer too.

@hstove hstove changed the title feat: require signature from signer in delegate-stx feat: require signatures to prove control of signer-key in pox Jan 24, 2024
@hstove
Copy link
Contributor Author

hstove commented Jan 24, 2024

Everyone needs to prove ownership of their signing key. This goes for solo stackers as well, via stack-stx and stack-extend. Basically, anywhere you see a signing key as an argument, you need to also require a signature argument and a signature verification (that should be stack-stx, delegate-stack-stx, stack-extend, and delegate-stack-extend).

👍 that's reflected in the current state of the PR

@hstove
Copy link
Contributor Author

hstove commented Jan 24, 2024

There are a number of tests outside of the pox-4 tests related to nakamoto that are failing because of the change to stack-stx, I'm working on those still but the pox-4 code is ready for review.


/// Generate a message hash for signing structured Clarity data.
/// Reference [SIP018](https://github.com/stacksgov/sips/blob/main/sips/sip-018/sip-018-signed-structured-data.md) for more information.
pub fn structured_data_message_hash(structured_data: Value, domain: Value) -> Sha256Sum {
Copy link
Member

Choose a reason for hiding this comment

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

Why does this belong in util_lib? Isn't this only used in testing? If so, then please remove this file altogether and put this into stackslib/src/chainstate/stacks/boot/mod.rs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At the moment it's only used in tests, but we'll add it (in a separate PR) to stacks-signer so we can expose a CLI function like:

stacks-signer create-stacking-signature --stacker S --reward-cycle R

I don't have a strong opinion whether it should live here or not, and I'm not the best person to know. But I think it is helpful to expose somewhere that isn't just for tests.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds like this belongs in libsigner then. libsigner can be a dev-dependency for stackslib.

Copy link
Collaborator

@setzeus setzeus left a comment

Choose a reason for hiding this comment

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

Generally pox_4.clar updates LGTM minus a few syntax issues & one ERR constant inconsistency.

stackslib/src/chainstate/stacks/boot/pox-4.clar Outdated Show resolved Hide resolved
stackslib/src/chainstate/stacks/boot/pox-4.clar Outdated Show resolved Hide resolved
stackslib/src/chainstate/stacks/boot/pox-4.clar Outdated Show resolved Hide resolved
stackslib/src/chainstate/stacks/boot/pox-4.clar Outdated Show resolved Hide resolved
@hstove hstove requested a review from setzeus January 25, 2024 23:33
@hstove
Copy link
Contributor Author

hstove commented Jan 26, 2024

FYI I'm going to rebase/build this off of #4269, because that changes the function signatures in pox-4. Shouldn't be too much work and then I'll move the ticket back to review.

Copy link
Member

@zone117x zone117x left a comment

Choose a reason for hiding this comment

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

I'm approving the pox4 function signature and synthetic event changes, thanks @hstove!

At least 2 others should approve the pox4 behavioral changes because I'm not in a position to validate those changes.

@hstove hstove requested a review from jcnelson February 6, 2024 23:58
@hstove
Copy link
Contributor Author

hstove commented Feb 6, 2024

I've updated this PR with changes since receiving Jude's feedback. Tagging @jcnelson @setzeus @MarvinJanssen @friedger for reviews.

  • The signature message hash now includes two new fields
    • topic: one of stack-stx, stack-extend, or agg-commit. This prevents re-using signatures across methods
    • period: a uint reflecting lock-period for stacking or extend-count for extending. For stack-aggregation-commit, this value is u1.
  • The get-signer-key-message-hash now takes all hash fields as args, instead of dynamically calling get-current-reward-cycle. This allows signers to easily call this read-only method to generate a message hash.
  • In stack-aggregation-commit, the message hash uses the reward cycle provided as user input instead of the current reward cycle.

I've also added some code in util_lib::signed_structured_data::pox4 to allow re-using the Rust code for generating these signatures instead of re-writing a helper function in different places.

Copy link
Member

@kantai kantai left a comment

Choose a reason for hiding this comment

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

This LGTM -- I'd just suggest using the define_named_enum! macro for the topics, and you should add another unit test that asserts equality between the rust message hash constructor and the contract's read-only fn.

stackslib/src/util_lib/signed_structured_data.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@setzeus setzeus left a comment

Choose a reason for hiding this comment

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

Included a formatting/syntax NIT but outside of that LGTM! Great job on this @hstove.

stackslib/src/chainstate/stacks/boot/pox-4.clar Outdated Show resolved Hide resolved
@hstove hstove requested a review from kantai February 8, 2024 18:53
Copy link
Member

@kantai kantai left a comment

Choose a reason for hiding this comment

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

LGTM -- just see if the ...Old enum can be removed.

@hstove
Copy link
Contributor Author

hstove commented Feb 8, 2024

LGTM -- just see if the ...Old enum can be removed.

Ah crap, thanks for catching that. CI should pass and then I think this is good to merge!

@hstove hstove dismissed stale reviews from jcnelson and friedger February 8, 2024 19:05

The message hash function now includes topic and period

@hstove hstove merged commit 2dcdb02 into next Feb 8, 2024
2 checks passed
@hstove hstove deleted the feat/signer-delegate-control branch February 8, 2024 21:18
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.

Signer should control which stackers can delegate to the signer
6 participants