Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 87 additions & 17 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,23 +1,93 @@
# Git
.git
.gitignore
.dockerignore
.blst
.venv
.gitattributes
.github

# Python
__pycache__
*.pyc
*.pyo
*.pyd
*.py[cod]
*$py.class
*.so
.Python
env
venv
ENV
env.bak
venv.bak
build
dist
*.egg-info
.mypy_cache
.pytest_cache
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Virtual environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
testenv/

# Testing
.pytest_cache/
.coverage
htmlcov
.coverage.*
htmlcov/
.tox/
.nox/
coverage.xml
*.cover
.hypothesis/

# IDEs
.vscode/
.idea/
*.swp
*.swo
*.swn
.DS_Store

# Build artifacts
.blst/
*.o
*.a
*.so
*.dylib
*.dll
*.pyd
*.pyc

# Documentation
docs/_build/

# Output and temporary files
output/
*.log
*.tmp
perf/

# Docker
Dockerfile
docker-compose.yml
.dockerignore

# CI/CD
.github/
.gitlab-ci.yml
.travis.yml

# Other
*.md
!README.md
LICENSE
43 changes: 18 additions & 25 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
# Base Python image
FROM python:3.12-slim

# Set working directory
WORKDIR /app

# Install system dependencies needed for blst Python binding and Cython
RUN apt-get update && apt-get install -y \
git \
gcc \
g++ \
python3-dev \
make \
swig \
libgmp-dev \
libmpfr-dev \
libmpc-dev \
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
git gcc g++ make swig \
python3-dev libgmp-dev libmpfr-dev libmpc-dev \
&& rm -rf /var/lib/apt/lists/*

# Install uv
Expand All @@ -23,18 +14,20 @@ COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
# Copy project files
COPY . .

# Install dependencies
RUN uv sync --extra dev
# Set version for setuptools-scm
ENV SETUPTOOLS_SCM_PRETEND_VERSION=1.0.0

# Setup environment (blst + cython)
RUN uv run python scripts/setup_env.py
# Install build tools first
RUN uv pip install --system setuptools wheel Cython build

# Build blst and Cython extensions
RUN python scripts/setup_env.py

# Install project with all dependencies from pyproject.toml
RUN uv pip install --system --no-build-isolation -e ".[dev]"

# Run tests
RUN uv run pytest tests/ \
--cov=dot_ring \
--cov-report=term-missing \
--cov-report=html \
-v \
--tb=short

CMD ["uv", "run", "python"]
RUN uv run pytest tests/ -v --tb=short

# Default: run tests
CMD ["uv", "run", "pytest", "tests/", "-v"]
31 changes: 22 additions & 9 deletions docs/BENCHMARK.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,40 @@ VRF with Pedersen commitment for public key blinding.

## Ring VRF

Ring VRF with SNARK-based ring membership proof (8-member ring).
Ring VRF with SNARK-based ring membership proof.
**Proof size**: 784 bytes (constant across all ring sizes)

### 8-member ring (domain size: 512)

| Operation | Min | Mean | Stddev |
|-----------|-----|------|--------|
| Ring Root Construction | 28.07 ms | 28.28 ms | 0.14 ms |
| Proof Generation | 153.35 ms | 155.18 ms | 1.42 ms |
| Verification | 4.05 ms | 4.35 ms | 0.19 ms |

### 1023-member ring (domain size: 2048)

| Operation | Min | Mean | Stddev |
|-----------|-----|------|--------|
| Ring Root Construction | 28.11 ms | 28.54 ms | 0.42 ms |
| Proof Generation | 251.16 ms | 253.68 ms | 1.88 ms |
| Verification | 3.98 ms | 4.16 ms | 0.12 ms |
| Ring Root Construction | 330.76 ms | 334.71 ms | 5.07 ms |
| Proof Generation | 525.28 ms | 543.04 ms | 29.13 ms |
| Verification | 4.09 ms | 4.22 ms | 0.14 ms |

**Proof size**: 784 bytes

---

## Running Benchmarks

```bash
# IETF VRF
uv run python tests/bench_ietf.py
uv run python tests/benchmark/bench_ietf.py

# Pedersen VRF
uv run python tests/bench_pedersen.py
uv run python tests/benchmark/bench_pedersen.py

# Ring VRF (8-member ring, domain size 512)
uv run python tests/benchmark/bench_ring_proof.py

# Ring VRF
uv run python tests/bench_ring_proof.py
# Ring VRF (1023-member ring, domain size 2048)
uv run python tests/benchmark/bench_ring_large.py
```
3 changes: 3 additions & 0 deletions dot_ring/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
from dot_ring.keygen import secret_from_seed
from dot_ring.vrf.ietf.ietf import IETF_VRF
from dot_ring.vrf.pedersen.pedersen import PedersenVRF
from dot_ring.vrf.ring.ring_root import Ring, RingRoot
from dot_ring.vrf.ring.ring_vrf import RingVRF

# =============================================================================
Expand Down Expand Up @@ -116,4 +117,6 @@
"BLS12_381_G2_RO",
"BLS12_381_G2_NU",
"secret_from_seed",
"Ring",
"RingRoot",
]
69 changes: 1 addition & 68 deletions dot_ring/ring_proof/columns/columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dataclasses import dataclass
from typing import cast

from dot_ring.ring_proof.constants import DEFAULT_SIZE, MAX_RING_SIZE, OMEGAS, S_PRIME, Blinding_Base, PaddingPoint, SeedPoint
from dot_ring.ring_proof.constants import DEFAULT_SIZE, MAX_RING_SIZE, OMEGAS, S_PRIME, SeedPoint
from dot_ring.ring_proof.curve.bandersnatch import TwistedEdwardCurve as TE
from dot_ring.ring_proof.helpers import Helpers as H
from dot_ring.ring_proof.params import RingProofParams
Expand Down Expand Up @@ -42,73 +42,6 @@ def commit(self) -> None:
self.commitment = KZG.commit(self.coeffs)


@dataclass(slots=True)
class PublicColumnBuilder:
size: int = DEFAULT_SIZE
prime: int = S_PRIME
omega: int = OMEGAS[DEFAULT_SIZE]
max_ring_size: int = MAX_RING_SIZE
padding_rows: int = 4

@classmethod
def from_params(cls, params: RingProofParams) -> PublicColumnBuilder:
return cls(
size=params.domain_size,
prime=params.prime,
omega=params.omega,
max_ring_size=params.max_ring_size,
padding_rows=params.padding_rows,
)

def _pad_ring_with_padding_point(self, pk_ring: list[tuple[int, int]]) -> list[tuple[int, int]]:
"""Pad ring in‑place with the special padding point until size."""
# padding_sw = sw.from_twisted_edwards(PaddingPoint)
padding_sw = PaddingPoint
while len(pk_ring) < self.max_ring_size:
pk_ring.append(padding_sw)
return pk_ring

def _h_vector(self, blinding_base: tuple[int, int] = Blinding_Base) -> list[tuple[int, int]]:
"""Return `[2⁰·H, 2¹·H, …]` in short‑Weierstrass coords."""
# sw_bb = sw.from_twisted_edwards(blinding_base)
sw_bb = blinding_base
# print("Blinding Base:",sw_bb)
res = [cast(tuple[int, int], TE.mul(pow(2, i, S_PRIME), sw_bb)) for i in range(self.size)]
return res # B_Neck

def build(self, ring_pk: list[tuple[int, int]]) -> tuple[Column, Column, Column]:
"""Return (Px, Py, s) columns fully committed."""
if len(ring_pk) < self.max_ring_size:
ring_pk = self._pad_ring_with_padding_point(ring_pk)
if len(ring_pk) > self.size - self.padding_rows:
raise ValueError(f"ring size {len(ring_pk)} exceeds max supported size {self.size - self.padding_rows}")
# 1. ensure ring size
fill_count = self.size - self.padding_rows - len(ring_pk)
if fill_count > 0:
if self.size == len(_H_VEC_DEFAULT):
h_vec = _H_VEC_DEFAULT
else:
h_vec = self._h_vector()
ring_pk.extend(h_vec[:fill_count])
if self.padding_rows > 0:
ring_pk.extend([(0, 0)] * self.padding_rows)

# 2. unzip into x/y vectors
px, py = H.unzip(ring_pk)

# 3. selector vector
sel = [1 if i < self.max_ring_size else 0 for i in range(self.size)]

# 4. Columns
col_px = Column("Px", px, size=self.size)
col_py = Column("Py", py, size=self.size)
col_s = Column("s", sel, size=self.size)
for col in (col_px, col_py, col_s):
col.interpolate(self.omega, self.prime)
col.commit()
return col_px, col_py, col_s


@dataclass(slots=True)
class WitnessColumnBuilder:
ring_pk: list[tuple[int, int]]
Expand Down
Loading
Loading