From 3771d12f765a432acc92d383a35822a380f89c70 Mon Sep 17 00:00:00 2001 From: logicalmechanism Date: Mon, 17 Mar 2025 22:49:55 -0700 Subject: [PATCH 1/2] everything should be typed now --- README.md | 5 +++++ py/README.md | 2 +- py/src/blake2b_224.py | 2 +- py/src/bls12_381.py | 2 +- py/src/commitment.py | 14 +++++++------- py/src/element.py | 15 +++++++-------- py/src/range.py | 10 +++++----- py/tests/test_range.py | 2 +- py/zk_interval.py | 4 ++-- 9 files changed, 30 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 31197f1..592719b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,11 @@ The zkInterval protocol proves the statement $a \geq d \geq b$ where $a$ and $b$ Python code for generating the proofs and Aiken code for on-chain validation of the proofs. The on-chain Cardano form of the proof is about 2.2 Kb. +```bash +# Prove: 100 >= 42 >= 0 +python3 zk_interval.py --value 42 --lower 0 --upper 100 --file_path datum.json +``` + Current memory and steps estimate with Aiken: ``` diff --git a/py/README.md b/py/README.md index 89acc47..6028d18 100644 --- a/py/README.md +++ b/py/README.md @@ -22,6 +22,6 @@ pytest Use `zk_interval.py` to generate proofs. ```bash -# Example: Prove 100 >= 42 >= 0 +# Prove: 100 >= 42 >= 0 python3 zk_interval.py --value 42 --lower 0 --upper 100 --file_path datum.json ``` \ No newline at end of file diff --git a/py/src/blake2b_224.py b/py/src/blake2b_224.py index be2fc7c..c5c295d 100644 --- a/py/src/blake2b_224.py +++ b/py/src/blake2b_224.py @@ -2,7 +2,7 @@ from hashlib import blake2b -def hash_function(): +def hash_function() -> type[blake2b]: """ Assigns sha3_256 as a hash function for the hash to g2 function inside the bls12-381 module. diff --git a/py/src/bls12_381.py b/py/src/bls12_381.py index 0ece04d..04d3c42 100644 --- a/py/src/bls12_381.py +++ b/py/src/bls12_381.py @@ -141,7 +141,7 @@ def pair(g2_element: str, g1_element: str, final_exponentiate: bool = True) -> F return pairing(uncompress(g2_element), uncompress(g1_element), final_exponentiate) -def hash_to_g2(message: str): +def hash_to_g2(message: str) -> str: """ Generate a G2 point from a hex message string. diff --git a/py/src/commitment.py b/py/src/commitment.py index d6f3803..2de6b67 100644 --- a/py/src/commitment.py +++ b/py/src/commitment.py @@ -1,5 +1,5 @@ from dataclasses import dataclass, field - +from typing import Self from src.blake2b_224 import generate from src.bls12_381 import field_order, g1_point, rng from src.element import Element @@ -28,7 +28,7 @@ class Commitment: c: Element = field(init=False) - def __post_init__(self): + def __post_init__(self) -> None: # this are fixed inside of a commitment g = Element(g1_point(1)) h = Element(g1_point(2)) @@ -40,10 +40,10 @@ def __post_init__(self): def hash(self) -> str: return generate(self.c.value) - def __str__(self): + def __str__(self) -> str: return f"Commitment(c={self.c}, r={self.r}, v={self.v})" - def __add__(self, other): + def __add__(self, other) -> Self: if not isinstance(other, Commitment): return NotImplemented # Add the r values @@ -53,7 +53,7 @@ def __add__(self, other): # Create a new Commitment instance with combined values return Commitment(combined_v, combined_r) - def __sub__(self, other): + def __sub__(self, other) -> Self: if not isinstance(other, Commitment): return NotImplemented # Add the r values @@ -63,12 +63,12 @@ def __sub__(self, other): # Create a new Commitment instance with combined values return Commitment(combined_v, combined_r) - def __eq__(self, other): + def __eq__(self, other) -> bool: if not isinstance(other, Commitment): return NotImplemented return self.c == other.c and self.r == other.r and self.v == other.v - def prove_knowledge_of_r(self, value: int): + def prove_knowledge_of_r(self, value: int) -> bool: v_commitment = Commitment(value, 0) r_commitment = self - v_commitment alpha = rng() diff --git a/py/src/element.py b/py/src/element.py index 0c2f942..bfaf885 100644 --- a/py/src/element.py +++ b/py/src/element.py @@ -1,6 +1,5 @@ -# src/Registry/element.py from dataclasses import dataclass - +from typing import Self from src.blake2b_224 import generate from src.bls12_381 import combine, compress, invert, scale, uncompress @@ -18,26 +17,26 @@ def uncompressed(self) -> tuple: def hash(self) -> str: return generate(self.value) - def __str__(self): + def __str__(self) -> str: return self.value - def __add__(self, other): + def __add__(self, other) -> Self: if not isinstance(other, Element): return NotImplemented return Element(combine(self.value, other.value)) - def __mul__(self, other): + def __mul__(self, other) -> Self: if not isinstance(other, int): return NotImplemented return Element(scale(self.value, other)) - def __rmul__(self, other): + def __rmul__(self, other) -> Self: return self.__mul__(other) - def __invert__(self): + def __invert__(self) -> Self: return Element(invert(self.value)) - def __eq__(self, other): + def __eq__(self, other) -> bool: if not isinstance(other, Element): return NotImplemented return self.value == other.value diff --git a/py/src/range.py b/py/src/range.py index fff8b17..d52e41c 100644 --- a/py/src/range.py +++ b/py/src/range.py @@ -38,7 +38,7 @@ class Range: Q: Element = field(init=False) QI: Element = field(init=False) - def __post_init__(self): + def __post_init__(self) -> None: # if upper bound is not set then it becomes field prime minus one if self.upper_bound is None: self.upper_bound = field_order - 1 @@ -80,10 +80,10 @@ def __post_init__(self): self.right = Commitment(0, self.A_commit.r + self.B_commit.r + self.W_commit.r) self.left = Commitment(0, self.Y_commit.r + self.D_commit.r + self.D_commit.r) - def __str__(self): + def __str__(self) -> str: return f"Range(\nY={self.Y_commit.c},\n{(self.D_commit + self.D_commit).c},\nR={self.right.c},\nW={self.W_commit.c},\nL={self.left.c}\n)" - def schnorr(self, z_a, a_c, flag): + def schnorr(self, z_a, a_c, flag) -> bool: if flag is True: r_commitment = self.A_commit - Commitment(self.upper_bound, 0) else: @@ -104,7 +104,7 @@ def prove(self, z_a, a_c, z_b, b_c) -> bool: # Verifying that the commitments are consistent with the expected range proof return check_p and check_a and check_b - def generate_proof(self): + def generate_proof(self) -> dict: # do the schnorr proofs r_upper_commitment = self.A_commit - Commitment(self.upper_bound, 0) r_lower_commitment = self.B_commit - Commitment(self.lower_bound, 0) @@ -141,7 +141,7 @@ def generate_proof(self): return data @staticmethod - def verify_proof(proof, lower_bound, upper_bound): + def verify_proof(proof, lower_bound, upper_bound) -> bool: # # Verify A # diff --git a/py/tests/test_range.py b/py/tests/test_range.py index 16ce5c8..39c3ab2 100644 --- a/py/tests/test_range.py +++ b/py/tests/test_range.py @@ -165,7 +165,7 @@ def test_lower_range_value(): def test_null_range_value(): lower = 0 - upper = 0 # oldest ever is 122 + upper = 0 age = 0 r = Range(secret_value=age, lower_bound=lower, upper_bound=upper) diff --git a/py/zk_interval.py b/py/zk_interval.py index 1df8a5a..e778975 100644 --- a/py/zk_interval.py +++ b/py/zk_interval.py @@ -42,7 +42,7 @@ def zk_data(proof: dict, lower: int, upper: int, file_path: str) -> None: save_proof_to_json(data, file_path) -def main(): +def main() -> None: parser = argparse.ArgumentParser( description=( "Generate a range proof based on a value, lower bound, and upper bound.\n\n" @@ -75,7 +75,7 @@ def main(): args = parser.parse_args() # Create Range object and generate proof - print(f"Prove {args.upper} >= {args.value} >= {args.lower}") + print(f"Prove: {args.upper} >= {args.value} >= {args.lower}") r = Range(secret_value=args.value, lower_bound=args.lower, upper_bound=args.upper) proof = r.generate_proof() print(f"Is the Proof Valid? {r.verify_proof(proof, args.lower, args.upper)}") From 354a6fcf976bf20d4a4bc3fec3f0798d872277dd Mon Sep 17 00:00:00 2001 From: logicalmechanism Date: Mon, 17 Mar 2025 22:55:17 -0700 Subject: [PATCH 2/2] improving readme --- README.md | 4 ++-- py/README.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 592719b..25658fb 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ python3 zk_interval.py --value 42 --lower 0 --upper 100 --file_path datum.json Current memory and steps estimate with Aiken: -``` +```bash [mem: 100336, cpu: 2226339408] 0.0577 * 100336 + 0.0000721 * 2226339408 = 166308 ``` -Estimate cost is about 167,000 Lovelace to compute on-chain. +Estimate cost is about 166,308 Lovelace to compute on-chain. ## The Paper diff --git a/py/README.md b/py/README.md index 6028d18..4ca1474 100644 --- a/py/README.md +++ b/py/README.md @@ -1,6 +1,6 @@ # zkInterval Proof Generation -# Setup +## Setup ```bash python3 -m venv venv @@ -8,7 +8,7 @@ source venv/bin/activate pip install -r requirements.txt ``` -# Test +## Test Use `pytest` for testing. @@ -17,9 +17,9 @@ pytest ``` -# Use +## Generation -Use `zk_interval.py` to generate proofs. +Use `zk_interval.py` to generate proofs for Cardano. ```bash # Prove: 100 >= 42 >= 0