cl: testing the balance commitments

This commit is contained in:
David Rusu 2024-06-03 09:52:36 -04:00
parent b2b2213bd6
commit f4f1e78d0c
6 changed files with 110 additions and 3 deletions

View File

@ -0,0 +1,20 @@
"""
This module holds the logic for building and verifying homomorphic balance commitments.
"""
from constraints import Constraint
from crypto import Field, Point, prf, hash_to_curve, pederson_commit, _str_to_vec
def balance_commitment(value: Field, blinding: Field, unit: Point):
return pederson_commit(value, blinding, unit)
def fungibility_domain(unit: str, birth_cm: Field) -> Point:
"""The fungibility domain of this note"""
return hash_to_curve("CL_NOTE_NULL", birth_cm, *_str_to_vec(unit))
def blinding(tx_rand: Field, nf_pk: Field) -> Field:
"""Blinding factor used in balance commitments"""
return prf("CL_NOTE_BAL_BLIND", tx_rand, nf_pk)

View File

@ -1,3 +1,4 @@
from py_ecc import bn128
from keum import grumpkin
import poseidon
@ -5,8 +6,11 @@ import poseidon
# !Important! The crypto primitives here must be in agreement with the proving system
# E.g. if you are using noir with the Barretenberg, we must use the Grumpkin curve.
Point = grumpkin.AffineWeierstrass
Field = grumpkin.Fq
# Point = grumpkin.AffineWeierstrass
# Field = grumpkin.Fq
Point = bn128.FQ
Field = bn128.Point2D[FQ]
def fake_algebraic_hash(data) -> Field:

View File

@ -76,7 +76,7 @@ class InnerNote:
return prf("CL_NOTE_COMM_RAND", self.rand, index)
@property
def fungibility_domain(self) -> Field:
def fungibility_domain(self) -> Point:
"""The fungibility domain of this note"""
return hash_to_curve(
"CL_NOTE_NULL", self.birth_constraint.hash(), *_str_to_vec(self.unit)

View File

@ -1,5 +1,57 @@
* 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:
#+begin_src python
# ----- 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
#+end_src
** 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.

View File

@ -0,0 +1,30 @@
from unittest import TestCase
from hypothesis import example, given, settings, strategies as st
from crypto import Field, hash_to_curve
from balance_commitment import balance_commitment
@st.composite
def field(draw):
x = draw(st.integers(min_value=0, max_value=Field.ORDER - 1))
return Field(x)
@st.composite
def point(draw):
x = draw(field())
return hash_to_curve("T", x)
class TestBalanceCommitment(TestCase):
@given(r=field(), a=field(), b=field(), unit=point())
@settings(max_examples=3)
def test_value_additive(self, r, a, b, unit):
print(r, a, b, unit)
b1 = balance_commitment(r, a, unit)
b2 = balance_commitment(r, b, unit)
b3 = balance_commitment(r, a + b, unit)
assert b1 + b2 == b3

View File

@ -12,3 +12,4 @@ toml==0.10.2 # used for noir
portalocker==2.8.2 # portable file locking
keum==0.2.0 # for CL's use of more obscure curves
poseidon-hash==0.1.4 # used as the algebraic hash in CL
hypothesis==6.103.0