Skip to content

Commit

Permalink
55 add vdf2 plots (#18)
Browse files Browse the repository at this point in the history
* optimazation

* cli tool

* refactor

* mock creation of directories in the tests

* VDF2 plots

* renamino

* double plots

* clean

* readme
  • Loading branch information
programmingAthlete authored Jan 28, 2024
1 parent ba84786 commit 2a2a3d5
Show file tree
Hide file tree
Showing 18 changed files with 778 additions and 46 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ crypto_VDF.egg-info
.pytest_cache
**/__pycache__/

data/pietrzak/*
data/pietrzak/*
data/wesolowski/*
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,10 @@ Delay of 2^(20)

<code>cryptoVDF wesolowski full-vdf-naive --delay 1048576 --security-parameter 128 --trapdoor</code>

<code>cryptoVDF wesolowski full-vdf --delay 1048576 --security-parameter 128 --trapdoor</code>
<code>cryptoVDF wesolowski full-vdf --delay 1048576 --security-parameter 128 --trapdoor</code>

# Plots
</code>cryptoVDF wesolowski plots --max-delay-exp 10 --iterations 20 --show</code>

</code>cryptoVDF pietrzak plots-2 --max-delay-exp 10 --iterations 20 --show</code>

5 changes: 4 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ orjson>=3.9.10
sympy>=1.12
matplotlib>=3.8.2
numpy>=1.26.3
pandas>=2.1.4
pandas>=2.1.4
PyQt5-Qt5>=5.15.2
PySide2>=5.15.2.1
shiboken2>=5.15.2.1
61 changes: 61 additions & 0 deletions src/crypto_VDF/clis/pietrzak.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
from time import strftime, gmtime
from typing import Annotated

import pandas as pd
import typer
from orjson import orjson

from crypto_VDF.custom_errors.custom_exceptions import NotAQuadraticResidueException
from crypto_VDF.data_transfer_objects.dto import PublicParams
from crypto_VDF.data_transfer_objects.plotter import InputType, VDFName
from crypto_VDF.utils.grapher import Grapher
from crypto_VDF.plotter.pietrazk_grapher import PietrzakGrapher
from crypto_VDF.utils.logger import get_logger
from crypto_VDF.utils.number_theory import NumberTheory
from crypto_VDF.verifiable_delay_functions.pietrzak import PietrzakVDF
from time import time as t

app = typer.Typer(pretty_exceptions_show_locals=False, no_args_is_help=True)

Expand Down Expand Up @@ -109,3 +115,58 @@ def cmd_eval_function(x: int, delay: int = 100, modulus: int = 100):
pp = PublicParams(delay=delay, modulus=modulus)
y = PietrzakVDF.eval_function(public_params=pp, input_param=x)
print("Output of Eval:", y)


@app.command(name="plots")
def cmd_complexity_plots(
max_delay_exp: Annotated[int, typer.Option(help="Maximum exponent of delay")] = 20,
iterations: Annotated[int, typer.Argument(help="Number of iterations")] = 10
):
s = t()
Grapher.collect_pietrzak_complexity_data(number_of_delays=max_delay_exp, iterations=iterations)
print(f"the operation took {t() - s} seconds or {strftime('%H:%M:%S', gmtime(t() - s))}")


@app.command(name="plots-2")
def cmd_complexity_plots_2(
security_param: Annotated[int, typer.Option(help="Security parameter")] = 128,
max_delay_exp: Annotated[int, typer.Option(help="Maximum exponent of delay")] = 20,
iterations: Annotated[int, typer.Option(help="Number of iterations")] = 10,
fix_input: Annotated[bool, typer.Option(help="Run with fixed input")] = False,
store_measurements: Annotated[bool, typer.Option(help="Store the measurement")] = True,
re_measure: Annotated[
bool, typer.Option(help="Re-run the VDF instead of using past measurement to plot")] = True,
show: Annotated[bool, typer.Option(help="Show the plot")] = False,
verbose: Annotated[bool, typer.Option(help="Show Debug Logs")] = False
):
s = t()
input_type = InputType.RANDOM_INPUT if fix_input is False else InputType.FIX_INPUT
grapher = PietrzakGrapher(number_of_delays=max_delay_exp, number_ot_iterations=iterations, input_type=input_type,
security_param=security_param)
title = f"Pietrzak VDF complexity (mean after {grapher.number_ot_iterations} iterations)"
if re_measure is False and not grapher.paths.macrostate_file_name.is_file():
_log.warning(f"File {grapher.paths.macrostate_file_name} does not exist, will re-take the measurements by"
f" re-running the VDF")
re_measure = True
if re_measure is False:
data_means = pd.read_csv(str(grapher.paths.macrostate_file_name))
plot = grapher.plot_data(
data=data_means,
title=title,
fname=grapher.paths.plot_file_name,
vdf_name=VDFName.PIETRZAK
)

else:
result = grapher.collect_pietrzak_complexity_data(fix_input=fix_input, _verbose=verbose,
store_measurements=store_measurements)

plot = grapher.plot_data(
data=result.means,
title=title,
fname=grapher.paths.plot_file_name,
vdf_name=VDFName.PIETRZAK
)
print(f"the operation took {t() - s} seconds or {strftime('%H:%M:%S', gmtime(t() - s))}")
if show:
plot.show()
51 changes: 49 additions & 2 deletions src/crypto_VDF/clis/wesolowski.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
import typer
from orjson import orjson

from crypto_VDF.data_transfer_objects.plotter import InputType, VDFName
from crypto_VDF.plotter.wesolowski_grapher import WesolowskiGrapher
from crypto_VDF.utils.logger import get_logger
from crypto_VDF.utils.utils import square_sequences_v2
from crypto_VDF.verifiable_delay_functions.wesolowski import WesolowskiVDF
import pandas as pd
from time import time as t, strftime, gmtime

app = typer.Typer(pretty_exceptions_show_locals=False, no_args_is_help=True)

Expand Down Expand Up @@ -69,7 +73,50 @@ def cmd_check_alg(delay: Annotated[int, typer.Option(help="Delay of the VDF")] =
g = WesolowskiVDF.gen(setup=pp)
prime_l = WesolowskiVDF.flat_shamir_hash(security_param=pp.delay, g=g, y=2)
# verif = g ** (2 ** pp.delay // l) % pp.n
alg_4 = WesolowskiVDF.alg_4_base(delay=pp.delay, prime_l=prime_l, input_var=g, n=pp.n)
alg_4 = WesolowskiVDF.alg_4_original(delay=pp.delay, prime_l=prime_l, input_var=g, n=pp.n)
out = square_sequences_v2(a=g, steps=pp.delay, n=pp.n)
r = WesolowskiVDF.alg_4(n=pp.n, prime_l=prime_l, delay=pp.delay, output_list=out[1])
r = WesolowskiVDF.alg_4_revisited(n=pp.n, prime_l=prime_l, delay=pp.delay, output_list=out[1])
assert r == alg_4[0]


@app.command(name="plots")
def cmd_complexity_plots(
max_delay_exp: Annotated[int, typer.Option(help="Maximum exponent of delay")] = 20,
iterations: Annotated[int, typer.Option(help="Number of iterations")] = 10,
fix_input: Annotated[bool, typer.Option(help="Run with fixed input")] = False,
store_measurements: Annotated[bool, typer.Option(help="Store the measurement")] = True,
re_measure: Annotated[
bool, typer.Option(help="Re-run the VDF instead of using past measurement to plot")] = True,
show: Annotated[bool, typer.Option(help="Show the plot")] = False,
verbose: Annotated[bool, typer.Option(help="Show Debug Logs")] = False
):
s = t()
input_type = InputType.RANDOM_INPUT if fix_input is False else InputType.FIX_INPUT
grapher = WesolowskiGrapher(number_of_delays=max_delay_exp, number_ot_iterations=iterations, input_type=input_type)
title = f"Wesolowski VDF complexity (mean after {grapher.number_ot_iterations} iterations)"
if re_measure is False and not grapher.paths.macrostate_file_name.is_file():
_log.warning(f"File {grapher.paths.macrostate_file_name} does not exist, will re-take the measurements by"
f" re-running the VDF")
re_measure = True
if re_measure is False:
data_means = pd.read_csv(str(grapher.paths.macrostate_file_name))
plot = grapher.plot_data(
data=data_means,
title=title,
fname=grapher.paths.plot_file_name,
vdf_name=VDFName.WESOLOWSKI
)

else:
result = grapher.collect_pietrzak_complexity_data(fix_input=fix_input, _verbose=verbose,
store_measurements=store_measurements)

plot = grapher.plot_data(
data=result.means,
title=title,
fname=grapher.paths.plot_file_name,
vdf_name=VDFName.WESOLOWSKI
)
print(f"the operation took {t() - s} seconds or {strftime('%H:%M:%S', gmtime(t() - s))}")
if show:
plot.show()
30 changes: 30 additions & 0 deletions src/crypto_VDF/data_transfer_objects/plotter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import enum
from pathlib import Path

import pandas as pd
import pydantic


class GetPaths(pydantic.BaseModel):
dir_path: Path
plot_file_name: Path
measurements_file_name: Path
macrostate_file_name: Path


class CollectVDFData(pydantic.BaseModel):
measurements: pd.DataFrame
means: pd.DataFrame

class Config:
arbitrary_types_allowed = True


class InputType(enum.Enum):
RANDOM_INPUT = 'random_input'
FIX_INPUT = 'fix_input'


class VDFName(enum.Enum):
PIETRZAK = 'pietrzak'
WESOLOWSKI = 'wesolowski'
Empty file.
71 changes: 71 additions & 0 deletions src/crypto_VDF/plotter/grapher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from pathlib import Path
from typing import List

import numpy as np
import matplotlib.pyplot as plt

from crypto_VDF.data_transfer_objects.plotter import GetPaths, VDFName, InputType
from crypto_VDF.utils.utils import create_path_to_data_folder_v2
import pandas as pd


class Grapher:

def __init__(self, number_of_delays: int, number_ot_iterations: int):
self.number_of_delays = number_of_delays
self.number_ot_iterations = number_ot_iterations

def plot_data(self, data, title, fname: str, vdf_name: VDFName):
delays_list = np.asarray(data['delay'])
y_time_eval = np.asarray(data[f'eval time means for {self.number_ot_iterations} iterations (s)'])
y_time_verif = np.asarray(data[f"verify time means for {self.number_ot_iterations} iterations (s)"])
fig, (ax1, ax2) = plt.subplots(2)
fig.suptitle(title)
ax1.set_title("Eval and Verify")
ax1.plot(delays_list, y_time_eval, 'r--', label="Eval func complexity (mean)", marker='x')
ax1.plot(delays_list, y_time_verif, 'b-', label="Verify func complexity (mean)", marker='o')
ax1.set_ylabel('Execution Time')
ax1.legend()
ax1.grid()
ax2.set_title("Verify function")
ax2.plot(delays_list, y_time_verif, 'b-', label="Verify func complexity (mean)", marker='o')
ax2.set_ylabel('Execution Time')
if vdf_name == VDFName.WESOLOWSKI:
ax2.set_ylim(0, 0.2)
ax2.legend()
ax2.grid()

plt.tight_layout()

plt.savefig(str(fname) + ".png")
print("\nfigure saved successfully!\n")
return plt

@staticmethod
def create_directories(directories: List[Path]) -> None:
for directory in directories:
directory.mkdir(exist_ok=True)

@classmethod
def get_paths(cls, delay_sub_dir: str, iterations: int, input_type: InputType, vdf_name: VDFName) -> GetPaths:
data_path = create_path_to_data_folder_v2()
vdf_path = data_path / str(vdf_name.value)
input_path = vdf_path / str(input_type.value)
input_type_path = vdf_path / str(input_type.value)
sub_dir = input_type_path / delay_sub_dir

# create the directories for data
cls.create_directories([vdf_path, input_path, sub_dir])

input_file_name = f"repeated_{iterations}_times.csv"
macrostate_input_file = f"macrostate_repeated_{iterations}_times.csv"
file_path = sub_dir / input_file_name
macrostate_file_path = sub_dir / macrostate_input_file
figure_name = f"data_mean_over_{iterations}_iterations"
figure_path = sub_dir / figure_name
return GetPaths(dir_path=sub_dir, plot_file_name=figure_path, measurements_file_name=file_path,
macrostate_file_name=macrostate_file_path)

@staticmethod
def store_data(filename: Path, data: pd.DataFrame) -> None:
data.to_csv(str(filename))
Loading

0 comments on commit 2a2a3d5

Please sign in to comment.