2024-06-03 09:52:36 -04:00

3.8 KiB
Raw Blame History

Open Issues

Do we need both Public, Secret and Inner Note?

Can't we simply have a Note (currently InnerNote) and the partial transaction will introduce a wrapper over the Note struct that will have the extra fields necessary for using notes within a transaction system:

  # ----- note.py -----

  @dataclass(unsafe_hash=True)
  class Note:
      value: Field
      unit: str
      birth_constraint: Constraint
      death_constraints: list[Constraint]
      state: Field
      nonce: Field
      rand: Field

      def verify_death(self, death_cm: Field, death_proof: Proof) -> bool:
          pass

      def verify_birth(self, birth_proof: Proof) -> bool:
          pass

      def verify_value(self) -> bool:
          pass

      def fungibility_domain(self) -> Field:
          pass

  # ----- partial_transaction.py -----

  @dataclass
  class InputNote:
      note: Note
      nullifier: Note
      death_cm: Field
      death_proof: Proof
      balance_cm: Point

  @dataclass
  class OutputNote:
      note: PublicNote
      birth_proof: Proof
      balance_cm: Point

provided commitment to zero may removing the blinding of the pederson commitment

Since you can subtract the randomness from the commitment to get just the binding part.

Ok, lets deal with these zero commitments.

In place of zero commitments, we can have the solver prove that the value part of a pederson commitment is zero.

Rename transaction randonmness to tx_rand and commitment randomness to cm_rand

Currently they are both called "rand" and it's confusing.

Why does PartialTransaction have a "blinding"?

I believe it should only have a derived balance field.

Poseidon Constants for Grumpkin Field

Generating the poseidon constants for the Grumpkin curve is very slow, like takes 1 minute.

I need to pre-generate these to make the curve work.

  • I tried the other large curve where the params are already generated and it is still slow. Need to dig into this.

Solvers need the value of a note in order to solve it

  • do users provide a merkle proof showing the value is legit?
  • merkle proofs also reveal positional information.
  • if we are to reveal partial information to solvers we will need to blind the other leaf nodes of the tree:

    Note = VALUE || UNIT || …

    com = ..root.. / \ h(h(V), h(U)) … / \ h(VALUE) h(UNIT)

    VALUE UNIT

    Revealing the value's merkle path would reveal h(UNIT) and since UNIT is well known, h(UNIT) is also easily computable.

    Thus each component of the Note should have a blinding factor Note = (r1, VALUE) || (r1, UNIT) || ….

Transferring requires recipients sk

We need to be able to create a partial transaction where we don't know the output note's nullifier.

What we need: A public note + balance commitment

balance commitment is computed as

``` value <- known by transaction builder unit <- known by transaction builder blinding <- PRF_r(nullifier) !!!! < this is where the issue is funge <- hash_to_curve(Unit) balance_commit <- pedersen_commit(value, blinding, funge) ```

Why is the blinding a PRF of the nullifier? Can't we simply use the randomness of the transaction to derive a blinding factor?

How does zcash solve this?

They provide specific randomness for this when building the transaction.

Note Unit should be a string hashed to curve point when needed.

We want human readable units (i.e. "ETH" "NMO")

I've gone and denoted it as bytes.

Solved

Note.verify() should take a proof

We should have two variants, verifyDeath(deathProof) verifyBirth(birthProof)

Do we need note.randomness?

It's currently used in the note commitment. But perhaps it's not really necessary?

  • it allows you to get away form content based addressing, this may be necessary for total privacy.

Yes, we need this