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

multi: add new v2 version of GKR based on Pedersen commitments #1290

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Roasbeef
Copy link
Member

@Roasbeef Roasbeef commented Jan 10, 2025

In this PR, we add a new internal package that can be used to create
and verify Pedersen commitments. We aim to make the API very simple to
use, while providing configuration that's useful for tests and a general
set of use cases.

We also add property based tests to achieve 100% test coverage of all
relevant invariants.

We then this that to add a new version of the new more flexible GKR type.
This version uses an OP_CHECKSIG with an un-spendable public key. We
derive such a public key by using the Pedersen commitment of the asset
ID, or blank message (for the dummy leaf case). As a Pedersen commitment
uses an aux generator H, that no one knows the private key to, it's
impossible to generate a signature using the commitment point.

An informal sketch of a proof by contradiction goes something like:

  • Starting with a Pedersen commitment, P = m*G + r*H.
  • Let's assume that we can actually sign with P. This means that
    there's some x, where P = x*G that we know.
  • If we re-write x in terms of our commitment, we have: P = m*G + r*H.
  • Wlog, we'll simplify by removing r, the blinding factor, so: P = m*G + H.
  • In terms of private values we have x*G = m*G + H
  • If we solve for H, then we have H = (x-m)*G
  • If this is a Pedersen commitment, then the private key of H must be
    unknown to all parties.
  • If we can sign with P, then this means that we know the value (x-m).
  • However, since this is a Pedersen commitment, it's impossible to
    know the value x, which is a function of the private value H of
    the Pedersen commitment (P= (x-m)*G). This is a contradiction, as
    we see the that if we know x-m, then we also know h.

In this commit, we add a new internal package that can be used to create
and verify Pedersen commitments. We aim to make the API very simple to
use, while providing configuration that's useful for tests and a general
set of use cases.

We also add property based tests to achieve 100% test coverage of all
relevant invariants.
In this commit, we add a new version of the new more flexible GKR type.
This version uses an `OP_CHECKSIG` with an un-spendable public key. We
derive such a public key by using the Pedersen commitment of the asset
ID, or blank message (for the dummy leaf case). As a Pedersen commitment
uses an aux generator H, that no one knows the private key to, it's
impossible to generate a signature using the commitment point.

An informal sketch of a proof by contradiction goes something like:
  * Starting with a Pedersen commitment, P = m*G + r*H.
  * Let's assume that we can actually sign with P. This means that
    there's some x, where P = x*G that we know.
  * If we re-write x in terms of our commitment, we have: P = m*G + r*H.
  * Wlog, we'll simplify by removing `r`, the blinding factor, so: P =
    m*G + H.
  * In terms of private values we have x*G = m*G + H
  * If we solve for H, then we have H = (x-m)*G
  * If this is a Pedersen commitment, then the private key of H must be
    unknown to all parties.
  * If we can sign with P, then this means that we know the value (x-m).
  * However, since this is a Pedersen commitment, it's impossible to
    know the value `x`, which is a function of the private value H of
    the pedersen commitment (h*H = (x-m)*G. This is a contradiction, as
    we see the that if we know x-m, then we also know h.
@Roasbeef Roasbeef requested a review from ffranr January 10, 2025 21:40
@dstadulis
Copy link
Collaborator

dstadulis commented Jan 10, 2025

Wlog, we'll simplify by removing r, the blinding factor, so: P = m*G + H.

Does Wlog = WLOG?
aka "without loss of generality"

data []byte) (txscript.TapLeaf, error) {

var firstOp byte
switch version {
Copy link
Collaborator

Choose a reason for hiding this comment

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

helpful switch to create flexibility

Comment on lines +957 to +959
// The script leaf is made non-spendable by including an OP_RETURN/OP_CHECKSIG
// opcode at the start of the script. While the script can still be executed, it
// will always fail and cannot be used to spend funds.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thinking abstractly, about failsafe methods to prevent any accidental insertion of a NUMS without the OP_CHECKSIG:

maybe: a mutex that's called obtained when NUMS generation occurs and then is only released after prefixing the key with OP_CHECKSIG?

Comment on lines +981 to +983
// Construct a script builder and add the firstOp opcode to the start of
// the script to ensure that the script is non-executable.
scriptBuilder := txscript.NewScriptBuilder().AddOp(firstOp)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sound defensive positioning

NUMs fn.Option[btcec.PublicKey]
}

// Commitment is a Pederson commitment of the form: m*G + r*H, where:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// Commitment is a Pederson commitment of the form: m*G + r*H, where:
// Commitment is a Pedersen commitment of the form: m*G + r*H, where:

branch is also labeled son rather than sen

// remains computationally binding.
Mask fn.Option[[sha256.Size]byte]

// NUMs is an optional value that should be used to verify the
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// NUMs is an optional value that should be used to verify the
// NUMS is an optional value that should be used to verify the

Comment on lines +72 to +74
// WithCustomNUMs is a functional option that can be used to set a custom NUMs
// point.
func WithCustomNUMs(h btcec.PublicKey) commitOpt {
Copy link
Collaborator

Choose a reason for hiding this comment

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

WRT NUMS style is traditional acronym style preferred of capitalizing every letter of the acronym?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 👀 In review
Development

Successfully merging this pull request may close these issues.

2 participants