Proof of Knowledge

This Julia code example demonstrates the implementation of a non-interactive zero-knowledge proof of knowledge (NIZKPoK) for the discrete logarithm problem. The code showcases how to prove knowledge of an exponent $x$ for a given $y = g^x$ without revealing the secret $x$ itself, using group-agnostic methods.

The implementation provides both simple proof by disclosure and a more secure non-interactive zero-knowledge proof, along with their corresponding verification functions. By leveraging Julia's multiple dispatch and parametric types, the code is designed to work with any abstract group Group, making it flexible and applicable to various cryptographic settings. For demonstration we use P-192 elliptic curve group, but the core functions are written to be compatible with any group provided by CryptoGroups.

using Test
using CryptoGroups
using CryptoGroups.Utils: int2octet
using CryptoPRG: HashSpec, Verificatum

verify(g::G, y::G, x::Integer) where G <: Group = g^x == y # proof by disclousure


function challenge(g::G, y::G, R::G) where G <: Group

    # the encoding is deserializable as `octet` returns fixed length output that depends on unerlying group
    # nevertheless it is recommended to use a proper canoncial encoding for this purpose which we shall skip
    prg = Verificatum.PRG(HashSpec("sha256"), [octet(g)..., octet(y)..., octet(R)...])

    return rand(prg, 2:order(G) - 1)
end

function prove(g::G, y::G, x::Integer) where G <: Group

    # we can construct proof deterministically without relying on randomness source
    prg = Verificatum.PRG(HashSpec("sha256"), [octet(y)..., int2octet(x)...])

    r = rand(prg, 2:order(G) - 1)

    R = g^r

    c = challenge(g, y, R)

    s = (r + c * x) % order(G)

    return R, s
end

function verify(g::G, y::G, R::G, s::Integer) where G <: Group

    c = challenge(g, y, R)

    return g^s == R * y^c
end


g = @ECGroup{P_192}()

x = 21
y = g^x

@test verify(g, y, x)

proof = prove(g, y, x)
@test verify(g, y, proof...)
Test Passed

This page was generated using Literate.jl.