Skip to content

Commit

Permalink
prep for release
Browse files Browse the repository at this point in the history
  • Loading branch information
Janis Erdmanis committed Sep 8, 2024
1 parent f9fb0e1 commit 734c50e
Show file tree
Hide file tree
Showing 23 changed files with 142 additions and 120 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/CodeCov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Workflow for Codecov example-julia
on: [push, pull_request]
jobs:
run:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Julia 1.10.0
uses: julia-actions/setup-julia@v1
with:
version: "1.10.0"
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
9 changes: 5 additions & 4 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.3.1"
version = "0.3.2"

[deps]
CryptoGroups = "bc997328-bedd-407e-bcd3-5758e064a52d"
Expand All @@ -13,13 +13,14 @@ SigmaProofs = "f8559b4c-f045-44a2-8db2-503e40bb7416"
SigmaProofs = {path = "SigmaProofs"}

[compat]
CryptoGroups = "0.4"
CryptoPRG = "0.1.0"
CryptoGroups = "0.5"
CryptoPRG = "0.1"
julia = "1"

[extras]
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
XMLDict = "228000da-037f-5747-90a9-8195ccbf91a5"

[targets]
test = ["Test", "XMLDict"]
test = ["Test", "SafeTestsets", "XMLDict"]
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# ShuffleProofs.jl

[![codecov](https://codecov.io/gh/PeaceFounder/ShuffleProofs.jl/graph/badge.svg?token=4VCLLS1YEF)](https://codecov.io/gh/PeaceFounder/ShuffleProofs.jl)

Cryptography is often looked at as a tool to secure and make communications confidential. It only requires to have a digital signature algorithm (DSA), Diffie Hellman key exchange (computation) and a good block cypher to satisfy the security requirements of 99% (metaphorically) of current online marketplaces and internet banking. However, security with those tools comes with a price of privacy and the necessity to trust the other end to keep your transactions private.

A much more difficult case is present for systems that do require a high order of privacy and transparency, such as voting and auctions where an authority can not be blindly trusted, either with security or privacy. Complex multiparty protocols can be structured so that security and privacy do not lie in the hands of few. However, eliminating the effects of dishonest participants does require synchronous interactions between participants and thus is not scalable.
Expand Down
7 changes: 4 additions & 3 deletions SigmaProofs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ CryptoPRG = "d846c407-34c1-46cb-aa27-d51818cc05e2"
CryptoUtils = "04afed74-ac16-11e9-37b6-1352e3e05830"

[compat]
CryptoGroups = "0.4.1"
CryptoPRG = "0.1.0"
CryptoGroups = "0.5.0"
CryptoPRG = "0.1.1"
CryptoUtils = "0.1.1"
Test = "1.11.0"

[extras]
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["Test", "SafeTestsets"]
5 changes: 3 additions & 2 deletions SigmaProofs/src/ElGamal.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module ElGamal

using CryptoGroups.Utils: @check
using CryptoGroups: Group
import Base: *, ^

Expand Down Expand Up @@ -89,12 +90,12 @@ end


function (enc::Enc{G})(m::AbstractVector{<:ElGamalRow{G}}, r::AbstractMatrix{<:Integer}) where G <: Group
@assert length(r[:, 1]) == length(m[1]) "Dimensions not equal"
@check length(r[:, 1]) == length(m[1]) "Dimensions not equal"
return [enc(mi, tuple(ri...)) for (mi, ri) in zip(m, eachcol(r))]
end

function (enc::Enc{G})(m::AbstractVector{<:NTuple{N, G}}, r::AbstractMatrix{<:Integer}) where {N, G <: Group}
@assert length(r[:, 1]) == N "Dimensions not equal"
@check length(r[:, 1]) == N "Dimensions not equal"
return [enc(mi, tuple(ri...)) for (mi, ri) in zip(m, eachcol(r))]
end

Expand Down
26 changes: 17 additions & 9 deletions SigmaProofs/src/GeneratorBasis.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module GeneratorBasis

using CryptoGroups: modulus, order, bitlength
using CryptoGroups.Utils: @check
using CryptoGroups: modulus, order, bitlength, Group, spec
using CryptoGroups.Specs: MODP, ECP
#using ..CryptoGroups.CSPRG: PRG, RO
using CryptoPRG.Verificatum: PRG, RO
using CryptoUtils: is_quadratic_residue, sqrt_mod_prime

Expand All @@ -20,6 +20,8 @@ function modp_generator_basis(prg::PRG, p::Integer, q::Integer, N::Integer; nr::
return 𝐡
end

modp_generator_basis(prg::PRG, spec::MODP, N::Integer; nr::Integer = 0) = modp_generator_basis(prg, modulus(spec), order(spec), N; nr)

function ecp_generator_basis(prg::PRG, (a, b)::Tuple{Integer, Integer}, p::Integer, q::Integer, N::Integer; nr::Integer = 0)

np = bitlength(p) # 1
Expand Down Expand Up @@ -66,17 +68,23 @@ function ecp_generator_basis(prg::PRG, (a, b)::Tuple{Integer, Integer}, p::Integ
return 𝐡
end

# ToDo: consider deprecating and redirect to generator_basis function
function Base.rand(prg::PRG, spec::MODP, N::Integer; nr::Integer = 0)
function ecp_generator_basis(prg::PRG, spec::ECP, N::Integer; nr::Integer = 0)
(; a, b) = spec
return ecp_generator_basis(prg, (a, b), modulus(spec), order(spec), N; nr)
end

p = modulus(spec)
q = order(spec)

@assert !isnothing(q) "Order of the group must be known"
# For pattern matching
_generator_basis(prg::PRG, spec::MODP, N::Integer; nr) = modp_generator_basis(prg, spec, N; nr)
_generator_basis(prg::PRG, spec::ECP, N::Integer; nr) = ecp_generator_basis(prg, spec, N; nr)

return modp_generator_basis(prg, p, q, N; nr)
function generator_basis(prg::PRG, ::Type{G}, N::Integer; nr::Integer = 0) where G <: Group
@check !isnothing(order(G)) "Order of the group must be known"
_spec = spec(G)
g_vec = _generator_basis(prg, _spec, N; nr)
return G.(g_vec)
end

Base.rand(prg::PRG, spec::ECP, N::Integer; nr::Integer = 0) = ecp_generator_basis(prg, (spec.a, spec.b), modulus(spec), order(spec), N; nr)
export generator_basis

end
23 changes: 23 additions & 0 deletions SigmaProofs/src/ShamirLagrange.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module ShamirLagrange

# Shamir secret sharing via Lagrange interpolation offers a natural way to split a secret generated by a dealer
# among multiple participants in a verifiable manner. The verifiability enables to everyone participate in the
# protocol as a dealer;

# 1) The protocol starts by generating a list of coordinates x_i at which polynomial is to be evaluated on a buletin board; they
# can be choosen as independent generators for convinience
# 2) The protocol starts by a dealer generating a polynomial coeficients f(x) = \sum_i a_i x^i (over a field of integers of order q)
# 3) The dealer genreates a commitment for each polynom coefficient Com(a_j) = g^{a_j} h^{r_j}
# 4) The dealer evaluates d_i = f(x_i) and forms commitment for each value Com(d_i) (randomness is reaused from previous steps); Everyone can verify that commitment for d_i to be consistent for its evaluation with polynomial as Com(d_i) = Com(f(x_i)) = \prod (Com(a_j))^{x_i^j};
# 5) The participant receives secret d_i from the dealer confidnetially and can verify it to be consistent with pulbic commitment
# also knowing publicallly listed h^{r_i} and g^d_i; At this point participants are equiped to particpate in decryption ceremony


# Threshold decryption

# 1) Coordinates at which polynomial evaluations happen are published on the buletin board as well as g^d_i
# 2) Every participant simultanously receives cyphertexts and performs decryption P_i = C_2^d_i and provides
# coresponding logarithmic equality proofs; The partial decryptions are published on the buletin board
# 3) At the end the shares can be combined via lagrange interpolation l_i = prod x_j/(x_j - x_i) and computed decryption as M = C_1 * \prod_i P_i^l_i

end
22 changes: 5 additions & 17 deletions SigmaProofs/test/elgamal.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Test
import CryptoGroups
import CryptoGroups: PGroup, concretize_type, generator, PGroup, ECGroup
import CryptoGroups: @PGroup, concretize_type, generator, ECGroup, @ECGroup
import SigmaProofs.ElGamal: Enc, Dec

function elgamal_test(g)
Expand Down Expand Up @@ -54,12 +54,7 @@ end


let
q = 11
p = 2*q + 1

G = PGroup(p, q)
g = G(3)

g = @PGroup{p = 23, q = 11}(3)
elgamal_test(g)
end

Expand All @@ -69,26 +64,19 @@ import CryptoGroups: concretize_type, generator, PGroup, ECGroup, Specs


let
spec = Specs.MODP_1024
G = concretize_type(PGroup, spec)
g = G(generator(spec))

g = @PGroup{RFC5114_1024}()
elgamal_test(g)
end


let
spec = Specs.Curve_P_256

G = concretize_type(ECGroup, spec; name = :P_192)
g = G(generator(spec))

g = @ECGroup{P_192}()
elgamal_test(g)
end


let
spec = Specs.Curve_B_163_PB
spec = CryptoGroups.Specs.Curve_B_163_PB
G = concretize_type(ECGroup, spec; name = :B_163_PB)
g = G(generator(spec))

Expand Down
7 changes: 3 additions & 4 deletions SigmaProofs/test/gbasis.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module BasisTest

using Test
import CryptoGroups: PGroup, concretize_type, value, MODP
import SigmaProofs.GeneratorBasis: modp_generator_basis
import CryptoGroups.Specs: MODP
import CryptoPRG.Verificatum: HashSpec, ROPRG

tobig(x) = parse(BigInt, bytes2hex(reverse(x)), base=16)
Expand Down Expand Up @@ -32,8 +33,6 @@ prghash = HashSpec("sha256")

ρ = hex2bytes("15e6c97600bbe30125cbc08598dcde01a769c15c8afe08fe5b7f5542533159e9")

# Need to unmarchal this into numbers

# group_spec = "00000000020100000020636f6d2e766572696669636174756d2e61726974686d2e4d6f645047726f757000000000040100000041009a91c3b704e382e0c772fa7cf0e5d6363edc53d156e841555702c5b6f906574204bf49a551b695bed292e0218337c0861ee649d2fe4039174514fe2c23c10f6701000000404d48e1db8271c17063b97d3e7872eb1b1f6e29e8ab7420aaab8162db7c832ba1025fa4d2a8db4adf69497010c19be0430f7324e97f201c8ba28a7f1611e087b3010000004100300763b0150525252e4989f51e33c4e6462091152ef2291e45699374a3aa8acea714ff30260338bddbb48fc7446b273aaada90e3ee8326f388b582ea8a073502010000000400000001"

p = 8095455969267383450536091939011431888343052744233774808515030596297626946131583007491317242326621464546135030140184007406503191036604066436734360427237223
Expand All @@ -51,7 +50,7 @@ prg = roprg(UInt8[]) # d is a better argument than x

sp = MODP(p; q)

𝐡′ = rand(prg, sp, 10; nr)
𝐡′ = modp_generator_basis(prg, sp, 10; nr)

@test 𝐡 == 𝐡′

Expand Down
13 changes: 3 additions & 10 deletions SigmaProofs/test/gecbasis.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module ECBasisTest

using Test
import CryptoGroups: ECGroup, concretize_type, value, Specs
import SigmaProofs.GeneratorBasis: ecp_generator_basis
import CryptoGroups: spec
import CryptoPRG.Verificatum: HashSpec, ROPRG

tobig(x) = parse(BigInt, bytes2hex(reverse(x)), base=16)
Expand Down Expand Up @@ -41,28 +42,20 @@ prghash = HashSpec("sha256")

ρ = hex2bytes("355806458d6cd42655a52be242705c8e824584ccdb6b1c016cad36c591413de4")

# Need to unmarchal this into numbers

# This one I need to validate in ShuffleProofs.jl
#group_spec = "com.verificatum.arithm.ECqPGroup(P-256)::00000000020100000020636f6d2e766572696669636174756d2e61726974686d2e4543715047726f75700100000005502d323536"


h_str = "((760858b410b6fd5b5329457488f93eefd76f74753fc018a88a04e0d1015ccced, 750609534db7741d4ffd1f721dfca0cb3a190fba73ad71652999b6846ff6cc6e),(1bb070702fd72beb7d1d019c46bd55db16b510fcaf56ad1cf5d8f2ab46e47703, 017b045263708a3a42b81c67f2aeb0750b90693d7f177f40bb0ab71aaca2a7c7),(cca2a9b54997b340951ff8a80caffd332fc2d18cdbf10b29863960ead8754297, 2536dab68d208a689845b597bfa1cfd06ae859d381babf4afefbc49893dc55de),(19c089238d119fb04034c61481f0032cb9746b569e4ce6fdf9f8bfb019b9c300, 2737321900c4be759486508e4bec21e1850792bbbc98bc0207b992079a46c4ea),(150beafe47a388cbf6b7b62af3de801cf5f39b6c2aa07df15a14870195325d66, 4f0d59a61036e071600050a896a7206bd660b675793ae0bfefcc594157821fa9),(58d18ce2c66aedd896031d6cd791eed6cbb4fe38c805971e465ea44ff436ad, 5e93996474cf43b5f2e02c077334d2ac16120385b67f193d26dd4748252aaeb2),(cb44deb0a87c8154c7f49a3d128c60bf32825e391d09a1c604a2a8d35b110e58, 33d3316d12f822e047f48520ee774d558d3edbbfa9f5d782023f4aa22683873d),(9d378038b627c4ad3e97726bdd7189fdca7b964d842bb5b0b9eafccd84baced7, 1fb99e6bb8bdc5518dd1c8a06a925a9999e72bf74664ee9c2df76959af9b95ef),(5e6c2170c6176600bedb2efd5ef02a72a7561142754f29217b4ebfcc39fe725b, 3c1ff9ce2ac3516928cb2486e7426851ef7fd50d492907494bb275b11081d41a),(b161c3cb307823857de3c032b7c8570a93ceda3f4d8d53837907b517cba92ac9, 27736dfef353719a3d4d7b7a004e62a9e39a32ddff6a525b80b8023bfac469dd),)"


a = split(replace(h_str, "("=>"", ")"=>"", " "=>""), ",")[1:end-1]
numbers = interpret.(BigInt, a)
𝐡 = collect(zip(numbers[1:2:end], numbers[2:2:end]))


d =..., leaf("generators")...]
roprg = ROPRG(d, rohash, prghash)
prg = roprg(UInt8[]) # d is a better argument than x

G = concretize_type(ECGroup, Specs.Curve_P_192)


𝐡′ = rand(prg, Specs.Curve_P_256, 10; nr)
𝐡′ = ecp_generator_basis(prg, spec(:P_256), 10; nr)

@test 𝐡 == 𝐡′

Expand Down
11 changes: 8 additions & 3 deletions SigmaProofs/test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using Test
using SafeTestsets

@testset "Testing ElGamal" begin
@safetestset "Testing ElGamal" begin
include("elgamal.jl")
end

@testset "Testing Generator Basis" begin
@safetestset "Testing PGroup Generator Basis" begin
include("gbasis.jl")
end

@safetestset "Testing ECGroup Generator Basis" begin
include("gecbasis.jl")
end


8 changes: 4 additions & 4 deletions src/io.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
using CryptoGroups.Utils: @check
using CryptoGroups: Group, PGroup

Base.write(io::IO, tree::Tree) = write(io, encode(tree))
Base.write(f::AbstractString, tree::Tree) = write(f, encode(tree))

Base.string(tree::Tree) = bytes2hex(encode(tree))


function unmarshal_full_public_key(g::Group, tree::Tree)

G = typeof(g)

g′, y = convert(Tuple{G, G}, tree)

@assert g′ == g
@check g′ == g

return y
end
Expand All @@ -28,7 +28,7 @@ function unmarshal_publickey(tree::Tree; relative::Bool = false)
g′, y = convert(Tuple{G, G}, tree.x[2])

if !relative
@assert g′ == g "Generator does not match specification of the group. Perhaps intentioanl, if so pass `relative=true` as keyword argument."
@check g′ == g "Generator does not match specification of the group. Perhaps intentioanl, if so pass `relative=true` as keyword argument."
end

return y, g′
Expand Down Expand Up @@ -56,7 +56,7 @@ function marshal_privatekey(g::Group, s::BigInt)

q = order(g)

@assert s < q "Secret key must be with in the order of the group"
@check s < q "Secret key must be with in the order of the group"

sleaf = Leaf(s, bytelength(q))

Expand Down
5 changes: 2 additions & 3 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ function marshal(g::ECGroup)
java_name = "com.verificatum.arithm.ECqPGroup"

# generator is not a group
# @assert spec(g) == spec(name(g)) "wrong group name"
# @check spec(g) == spec(name(g)) "wrong group name"

v_name = normalize_ecgroup_name(name(g))

Expand Down Expand Up @@ -271,8 +271,7 @@ function _unmarshal_pgroup(x::Node)

(p, q, g, e) = convert(Tuple{BigInt, BigInt, BigInt, UInt32}, x)

G = PGroup(p, q)

G = concretize_type(PGroup, p, q)
x = G(g)

return x
Expand Down
Loading

0 comments on commit 734c50e

Please sign in to comment.