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

Onchain secp256k1 signatures operations #1134

Closed
lgalabru opened this issue Oct 4, 2019 · 4 comments
Closed

Onchain secp256k1 signatures operations #1134

lgalabru opened this issue Oct 4, 2019 · 4 comments
Assignees
Labels

Comments

@lgalabru
Copy link
Member

lgalabru commented Oct 4, 2019

A decentralized solution / app is usually a combination of on-chain and off-chain logic.
One common way to achieve an on-chain settlement of operations being performed off-chain is to rely on signatures verifications.

If we want to see this kind of hybrid solutions running on Stacks v2, I'd suggest exposing the following native functions in clarity:

  • (secp256k1-recover (buff 32) (buff 64)) -> (response principal): take the message and the signature (compact format), return the recovered principal, or err.
  • (secp256k1-verify (buff 32) (buff 64) (buff 33)) -> (bool): take the message, the signature (compact format) and the public key, return a boolean.

Buffers lengths are consistent with https://docs.rs/crate/secp256k1/0.15.5/source/src/constants.rs

@lgalabru lgalabru assigned lgalabru and unassigned jcnelson and kantai Nov 5, 2019
@lgalabru lgalabru modified the milestones: Stacks V2 SP2, Stacks V2 SP3 Nov 5, 2019
@lgalabru lgalabru changed the title Proposal: secp256k1 signatures operations Onchain secp256k1 signatures operations Nov 5, 2019
@diwakergupta diwakergupta removed this from the Stacks V2 SP3 milestone Jan 14, 2020
@psq
Copy link
Contributor

psq commented Jun 13, 2020

@lgalabru I spent some time yesterday researching the underlying functions available in rust and javascript. Definitely something doable, and useful, although I'd like to suggest a few things.

First of all, to be recoverable, the signature needs 64 bytes plus a recovery id, which can be 0, 1, 2, or 3 (so 2 extra bits really). This has something to do with the way you recover the signature, which, roughly speaking as I understand it, requires calculating the intersection of a line with the secp256k1 curve, which can have up to 4 possible solutions. So we'd either need an extra parameter for the secp256k1-recover function, or append a 65th byte to the buffer. There is little explanation on the rust module as to why, but the rust api or js api make the need for that extra byte explicit in compact form. That extra byte is not needed to verify a signed message.

I'd prefer having an extra parameter, but as appending data is already something that is done for the compressed private keys used by blockstack, this might be an option that keeps the api simpler.

Second, as the public key used by these 2 functions can be used to generate the principal address, but that you can not calculate the public key from the principal, in order to be useful in contracts, we are going to need a function to calculate the principal from the public key. Something like:

(principal-of (buff 33)) -> (response principal)

Otherwise, if contracts are unable to correlate the public key to data they understand will make these functions of limited use.

Lastly, the version of secp256k1 used at the moment (0.11.5) is 18 months old and I'm wondering whether it would make sense to upgrade before mainnet. The main changes seem to be minor api changes, and location of where you find what as I was able to get the same results with 0.11.5 and 0.17.2 with the appropriate code changes.

If the above makes sense, I could create a PR within a few days (excluding secp256k1, which should be done separately if it makes sense to do it).

@vishalgupta96
Copy link

Hello, I am trying to do a signature message verification on blockstack but got to see that we're still working on verify function.

Can someone guide me to find the methods for generating an address (may be a way to generate it from backend) and signing a msg.

@psq
Copy link
Contributor

psq commented Sep 7, 2020

@vishalgupta96 the code to support verifying signatures is still work in progress (#1832).

for now you may have to piece together the various pieces from https://github.com/blockstack/stacks-blockchain/pull/1832/files#diff-78e6590bb3d50b94e4288d5acfc9d4dbR173-R181 (shows how to generate the stacks address from the private key, but you need the private key to sign) and https://github.com/rust-bitcoin/rust-secp256k1/blob/master/examples/sign_verify.rs (shows how to sign and verify a message).

Eventually, there'll be some examples, although contributions welcome!

@kantai
Copy link
Member

kantai commented Sep 24, 2020

This was merged in #1832, and is live as of the krypton testnet release.

@kantai kantai closed this as completed Sep 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants