Skip to content

Commit

Permalink
openssl integration and benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
Janis Erdmanis committed Nov 6, 2024
1 parent 00cf184 commit 3d86c3f
Show file tree
Hide file tree
Showing 16 changed files with 1,588 additions and 112 deletions.
5 changes: 3 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ShuffleProofs"
uuid = "31a120cc-b3cb-4d07-bbdb-d498660ddfd8"
authors = ["Janis Erdmanis <[email protected]>"]
version = "0.4.2"
version = "0.4.3"

[deps]
CryptoGroups = "bc997328-bedd-407e-bcd3-5758e064a52d"
Expand All @@ -20,6 +20,7 @@ julia = "1"
[extras]
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
OpenSSLGroups = "50771dd1-78b8-490c-a786-5ddc80ce15da"

[targets]
test = ["Test", "SafeTestsets"]
test = ["Test", "SafeTestsets", "OpenSSLGroups"]
140 changes: 67 additions & 73 deletions README.md

Large diffs are not rendered by default.

29 changes: 17 additions & 12 deletions src/prover.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ width(::Type{<:Shuffle{<:Group, N}}) where N = N

Base.length(proposition::Shuffle) = length(proposition.𝐞)

seed(verifier::Verifier, proposition::Shuffle, 𝐜; 𝐡) = nothing # optional method

struct PoSProof{G <: Group, N} <: Proof
𝐜::Vector{G}
𝐜̂::Vector{G}
Expand All @@ -41,10 +43,12 @@ import Base: ==

width(::Type{PoSProof{<:Group, N}}) where N = N

struct PoSChallenge
𝐡::Vector{<:Group} # Independent set of generators
struct PoSChallenge{G<:Group}
𝐡::Vector{G} # Independent set of generators
𝐮::Vector{BigInt} # PoS commitment challenge
c::BigInt # reencryption challenge

PoSChallenge(𝐡::Vector{G}, 𝐮::Vector{<:Integer}, c::Integer) where G <: Group = new{G}(𝐡, convert(Vector{BigInt}, 𝐮), convert(BigInt, c))
end

function verify(proposition::Shuffle, 𝐫′::Matrix{<:Integer}, 𝛙::Vector{<:Integer})
Expand Down Expand Up @@ -107,10 +111,9 @@ function gen_commitment_chain(g::Group, c0::T, 𝐮::Vector, 𝐫::Vector) where
return 𝐜
end


(𝐱, q) = mod(sum(𝐱), q) ### Need to improve
(𝐱::Vector{T}, q::T) where T <: Integer = modsum(𝐱, q) #mod(sum(𝐱), q) ### Need to improve
(𝐞::Vector{T}, q::T) where T <: Integer = modprod(𝐞, q)
(𝐱) = prod(𝐱)
(f, 𝐱) = prod(f, 𝐱)

using Random: RandomDevice

Expand Down Expand Up @@ -153,7 +156,8 @@ function prove(proposition::Shuffle{G}, verifier::Verifier, 𝐫′::Matrix{<:In

𝐜 = gen_perm_commitment(g, 𝐡, 𝛙, 𝐫)

𝐮 = challenge_perm(verifier, proposition, 𝐜)
_seed = seed(verifier, proposition, 𝐜; 𝐡)
𝐮 = challenge_perm(verifier, proposition, 𝐜; s = _seed)

𝐮′ = 𝐮[𝛙]

Expand All @@ -162,7 +166,7 @@ function prove(proposition::Shuffle{G}, verifier::Verifier, 𝐫′::Matrix{<:In
𝐯 = Vector{BigInt}(undef, N)
𝐯[N] = 1
for i in N-1:-1:1
𝐯[i] = 𝐮′[i+1] * 𝐯[i+1]
𝐯[i] = 𝐮′[i+1] * 𝐯[i+1] % q
end

= (𝐫, q)
Expand All @@ -186,7 +190,7 @@ function prove(proposition::Shuffle{G}, verifier::Verifier, 𝐫′::Matrix{<:In

t = (t₁, t₂, t₃, t₄, 𝐭̂)

c = challenge_reenc(verifier, proposition, 𝐜, 𝐜̂, t)
c = challenge_reenc(verifier, proposition, 𝐜, 𝐜̂, t; s = _seed)

s₁ = mod(ω₁ + c * r̄, q)
s₂ = mod(ω₂ + c * r̂, q)
Expand Down Expand Up @@ -214,12 +218,13 @@ end

function verify(proposition::Shuffle{G}, proof::PoSProof{G}, verifier::Verifier) where G <: Group


#ρ = ro_prefix(verifier) # can be efficiently recomputed
𝐡 = generator_basis(verifier, G, length(proposition))
s = seed(verifier, proposition, proof.𝐜; 𝐡)

𝐮 = challenge_perm(verifier, proposition, proof.𝐜)
𝐮 = challenge_perm(verifier, proposition, proof.𝐜; s)

c = challenge_reenc(verifier, proposition, proof.𝐜, proof.𝐜̂, proof.t)
c = challenge_reenc(verifier, proposition, proof.𝐜, proof.𝐜̂, proof.t; s)

chg = PoSChallenge(𝐡, 𝐮, c)

Expand All @@ -242,7 +247,7 @@ function verify(proposition::Shuffle, proof::PoSProof, challenge::PoSChallenge;


= (𝐜) / (𝐡)
u = mod((𝐮), q)
u = (𝐮, q)

= 𝐜̂[N] / h^u
= (𝐜 .^ 𝐮)
Expand Down
25 changes: 25 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,28 @@ function Base.println(io::IO, report::Report)
end

Base.isvalid(report::Report) = report.state

function modprod(elements::Vector{T}, q::T) where T <: Integer
return reduce((x, y) -> (x * y) % q, elements; init=T(1))
end

# function modsum(elements::Vector{T}, q::T) where T <: Integer
# return reduce((x, y) -> (x + y) % q, elements; init=T(0))
# end

# Different implementations of modular sum
function modsum(elements::Vector{T}, q::T; batch_size::Int=1000) where T <: Integer
n = length(elements)
result = T(0)

# Process in batches to reduce number of modulo operations
for i in 1:batch_size:n
batch_end = min(i + batch_size - 1, n)
# Sum within batch without modulo
batch_sum = sum(@view(elements[i:batch_end]))
# Apply modulo only once per batch
result = (result + batch_sum) % q
end

return result
end
6 changes: 3 additions & 3 deletions src/verifier.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ end
leaf(x::String) = encode(Leaf(x))


function seed(spec, proposition, 𝐮;
function seed(spec::ProtocolSpec, proposition::Shuffle, 𝐮;
ρ = ro_prefix(spec),
𝐡 = generator_basis(spec, typeof(proposition.g), length(proposition.𝐞); ρ)
)
Expand Down Expand Up @@ -191,7 +191,7 @@ function challenge_reenc(spec::ProtocolSpec{G}, proposition::Shuffle{G}, 𝐜,
return challenge_reenc(spec, proposition, 𝐜, τ; ρ, s)
end

function verify(proposition::Shuffle, proof::VShuffleProof, challenge::PoSChallenge; verbose=false)
function verify(proposition::Shuffle{G}, proof::VShuffleProof{G}, challenge::PoSChallenge{G}; verbose=false) where G <: Group

𝐡, 𝐞, 𝓿 = challenge.𝐡, challenge.𝐮, challenge.c

Expand All @@ -209,7 +209,7 @@ function verify(proposition::Shuffle, proof::VShuffleProof, challenge::PoSChalle
A = prod(𝐮 .^ 𝐞)

C = prod(𝐮) / prod(𝐡)
D = 𝐁[N] * inv(𝐡[1])^prod(𝐞)
D = 𝐁[N] * inv(𝐡[1])^modprod(𝐞, order(G))

F = (𝔀 .^ 𝐞)

Expand Down
6 changes: 6 additions & 0 deletions test/benchmarks/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[deps]
CryptoGroups = "bc997328-bedd-407e-bcd3-5758e064a52d"
Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
OpenSSLGroups = "50771dd1-78b8-490c-a786-5ddc80ce15da"
ShuffleProofs = "31a120cc-b3cb-4d07-bbdb-d498660ddfd8"
SigmaProofs = "f8559b4c-f045-44a2-8db2-503e40bb7416"
158 changes: 158 additions & 0 deletions test/benchmarks/barplot.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using Luxor
# The code was produced from a few instructions with Claude
# Using a general plotting package may have been better here

function wrap_text(text, max_width, fontsize_val)
words = split(text, " ")
lines = String[]
current_line = String[]

function get_text_width(text)
return textextents(text)[3]
end

for word in words
test_line = join([current_line..., word], " ")
text_width = get_text_width(test_line)

if text_width <= max_width
push!(current_line, word)
else
if !isempty(current_line)
push!(lines, join(current_line, " "))
current_line = String[word]
else
push!(lines, word)
end
end
end

if !isempty(current_line)
push!(lines, join(current_line, " "))
end

return lines
end

function barplot(fname::String, values::Vector, implementations::Vector{String};
bar_colors = ["#A8D0E6", "#F9C784", "#F9C784"],
border_color = "#404040",
ylabel = "Time (s)",
title = "Implementation Benchmarks",
width = 400,
height = 300,
yrange = 200,
#yticks = 0:50:200,
font_scale = min(width/400, height/300)
)

step = Int(div(yrange, 5))
yticks = 0:step:(5 * step)

Drawing(width, height, fname)

scale_x = width/400
scale_y = height/300

title_size = 16 * font_scale
label_size = 12 * font_scale
value_size = 14 * font_scale #min(scale_x, scale_y) # Size for values above bars

background("white")

padding_x = 60 * scale_x #
padding_y = 50 * scale_y
translate(padding_x, height - padding_y)

bar_width = 60 * scale_x
gap = 40 * scale_x
first_bar_offset = 20 * scale_x
chart_height = 200 * scale_y

setline(2 * min(scale_x, scale_y))
setcolor(border_color)

# Y-axis
line(Point(0, 0), Point(0, -chart_height), :stroke)

# X-axis
chart_width = first_bar_offset + length(implementations) * (bar_width + gap)
line(Point(0, 0), Point(chart_width, 0), :stroke)

# Y-axis label (vertical text)
setcolor("black")
fontsize(label_size)
gsave()
translate(-40 * scale_x, -chart_height/2)
rotate(-π/2)
text(ylabel, Point(0, 0), halign=:center)
grestore()

# Y-axis labels
fontsize(label_size)
for (i, y) in enumerate(yticks)
scaled_y = (y/yrange) * chart_height
text(string(y), Point(-10 * scale_x, -scaled_y), halign=:right)
end

# Draw bars and labels
for (i, (impl, val)) in enumerate(zip(implementations, values))
x = first_bar_offset + (i-1) * (bar_width + gap)


bottom = 0
for (vi, ci) in zip(val, bar_colors[i] isa String ? (bar_colors[i], ) : bar_colors[i])
# Fill bar (representing total)

setcolor(ci) # Alternate between colors
#setcolor(bar_colors[i]) # Alternate between colors

scaled_height = (vi/yrange) * chart_height
rect(Point(x, -bottom), bar_width, -scaled_height, :fill)

bottom += scaled_height
end

# Draw border
scaled_height = (sum(val)/yrange) * chart_height
setcolor(border_color)
rect(Point(x, 0), bar_width, -scaled_height, :stroke)

# Draw value on top of bar
fontsize(value_size)
setcolor("black")
text(string(trunc(sum(val)) |> Int), Point(x + bar_width/2, -scaled_height - 10 * scale_y), halign=:center)

setcolor("black")
# Draw wrapped label
fontsize(label_size)
wrapped_lines = wrap_text(impl, bar_width * 1.1, label_size) # scale here

for (line_num, line) in enumerate(wrapped_lines)
line_y = (20 + (line_num - 1) * label_size) * scale_y
text(line, Point(x + bar_width/2, line_y), halign=:center)
end
end

# Add title
fontsize(title_size)
text(title,
Point(0.9 * chart_width/2, -(chart_height + 30 * scale_y)),
halign=:center)

finish()

end


function barplot_test(dir::String)

barplot(joinpath(dir, "simple.svg"), [150, 100, 70], ["ShuffleProofs (single core)", "Verificatum (single core)", "Verificatum (2 cores)"]; title = "PoS Verification on P-256 (N = 1 000 000)")

barplot(joinpath(dir, "modp.svg"), [80, 30, 20], ["ShuffleProofs (single core)", "Verificatum (single core)", "Verificatum (2 cores)"]; title = "PoS Verification on MODP 2048 bit (N = 10000)", yrange = 80)

barplot(joinpath(dir, "benchmark_chart.svg"), [(120, 30), 100, 70], ["ShuffleProofs (single core)", "Verificatum (single core)", "Verificatum (2 cores)"]; bar_colors = [("#3a8ad9", "#7ac0f7"), "#a5b3b3", "#a5b3b3"], title = "PoS Verification on MODP 2048 bit (N = 10000)",
border_color = "#2d2d2d", width = 600, height = 400, font_scale = 1.4
)

end
Loading

0 comments on commit 3d86c3f

Please sign in to comment.