Skip to main content

Non-Interactive Zero-Knowledge Proof Implementation in Pure Python

Project description

NoKnow

Zero-Knowledge Proof implementation in pure python

Experimental
Built with ❤︎ by Austin Archer :)

Table of Contents

Credits

This is a slightly modified implementation of Schnorr's protocol that utilizes a state seed. The proofs used are rather complex in nature, but I will do my best to explain its functionality, but please refer to the research papers on which this implementation is based as it does a far more complete job with explanation than I.

Elliptic Curve Based Zero Knowledge Proofs and Their Applicability on Resource Constrained Devices by Ioannis Chatzigiannakis, Apostolos Pyrgelis, Paul G. Spirakis, and Yannis C. Stamatiou

Purpose

Zero-Knowledge Proofs are undoubtedly the future of authentication security within various IT and application development industrires. The ability to verify the veracity of a claim (ex: proving that you know a secret password), without divulging any information about the claim itself (ex: passwords or hashes), allows for servers to guarantee secure AAA operations (authentication, authorization, and accounting) without exposing private information. NoKnow is an implementation of a Non-Interactive Zero-Knowledge Proof protocol specifically designed for verifying text-based secrets, which is ideal for passwords or other authentication means.

How It Works

TODO: explain how it works

API

The noknow Python API is meant to be simple and intuitive:

Core Components

noknow.core.ZKParameters:

The parameters used to initialize the Zero-Knowledge crypto system.

class ZKParameters(NamedTuple):
    """
    Parameters used to construct a ZK proof state using an curve and a random salt
    """
    alg: str                    # Hashing algorithm name
    curve: str                  # Standard Elliptic Curve name to use
    s: int                      # Random salt for the state

noknow.core.ZKSignature:

A crytographic, zero-knowledge signature that can be used to verify future messages.

class ZKSignature(NamedTuple):
    """
    Cryptographic public signature used to verify future messages
    """
    params: ZKParameters        # Reference ZK Parameters
    signature: int              # The public key derived from your original secret

noknow.core.ZKProof:

A cryptograpgic proof that can be verified against a signature.

class ZKProof(NamedTuple):
    """
    Non-deterministic cryptographic zero-knowledge proof that can be verified to ensure the
    private key used to create the proof is the same key used to generate the signature
    """
    params: ZKParameters        # Reference ZK Parameters
    c: int                      # The hash of the signed data and random point, R
    m: int                      # The offset from the secret `r` (`R=r*g`) from c * Hash(secret)

noknow.core.ZKData

Wrapper that contains a proof and the necessary data to validate the proof against a signature.

class ZKData(NamedTuple):
    """
    Wrapper to contain data and a signed proof using the data
    """
    data: Union[str, bytes, int]
    proof: ZKProof

ZK

The ZK class is the central component of NoKnow and its state (defined by ZKParameters) should be inherently known to both the Client (Prover) and Server (Verifier).

instance methods

Method Parameters Role Purpose
create_signature secret: Union[str, bytes] Prover Create a cryptographic signature derived from the value secret to be generated during initial registration and stored for subsequent challenge proofs
sign secret: Union[str, bytes]
data: Union[str, bytes, int]
Prover Create a ZKData object using the secret and any additional data
verify challenge: Union[ZKData, ZKProof]
signature: ZKSignature
data: Optional[Union[str, bytes, int]]
Verifier Verify the user-provided challenge against the stored signature and randomly generated token to verify the validity of the challenge

Install

NoKnow is available from PyPi! Simply run:

pip install -U noknow

Example Usage

TODO: Include example usage

Example 1

"""
Extremely simple example of NoKnow ZK Proof implementation
"""
from getpass import getpass
from noknow.core import ZK, ZKSignature, ZKParameters, ZKData, ZKProof
from queue import Queue
from threading import Thread


def client(iq: Queue, oq: Queue):
    client_zk = ZK.new(curve_name="secp256k1", hash_alg="sha3_256")

    # Create signature and send to server
    signature = client_zk.create_signature(getpass("Enter Password: "))
    oq.put(signature.dump())

    # Receive the token from the server
    token = iq.get()

    # Create a proof that signs the provided token and sends to server
    proof = client_zk.sign(getpass("Enter Password Again: "), token).dump()

    # Send the token and proof to the server
    oq.put(proof)

    # Wait for server response!
    print("Success!" if iq.get() else "Failure!")


def server(iq: Queue, oq: Queue):
    # Set up server component
    server_password = "SecretServerPassword"
    server_zk = ZK.new(curve_name="secp384r1", hash_alg="sha3_512")
    server_signature: ZKSignature = server_zk.create_signature("SecureServerPassword")

    # Load the received signature from the Client
    sig = iq.get()
    client_signature = ZKSignature.load(sig)
    client_zk = ZK(client_signature.params)

    # Create a signed token and send to the client
    token = server_zk.sign("SecureServerPassword", client_zk.token())
    oq.put(token.dump(separator=":"))

    # Get the token from the client
    proof = ZKData.load(iq.get())
    token = ZKData.load(proof.data, ":")

    # In this example, the server signs the token so it can be sure it has not been modified
    if not server_zk.verify(token, server_signature):
        oq.put(False)
    else:
        oq.put(client_zk.verify(proof, client_signature, data=token))


def main():
    q1, q2 = Queue(), Queue()
    threads = [
        Thread(target=client, args=(q1, q2)),
        Thread(target=server, args=(q2, q1)),
    ]
    for func in [Thread.start, Thread.join]:
        for thread in threads:
            func(thread)


if __name__ == "__main__":
    main()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

noknow-0.2.0.tar.gz (10.4 kB view details)

Uploaded Source

Built Distribution

noknow-0.2.0-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

File details

Details for the file noknow-0.2.0.tar.gz.

File metadata

  • Download URL: noknow-0.2.0.tar.gz
  • Upload date:
  • Size: 10.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.8.1

File hashes

Hashes for noknow-0.2.0.tar.gz
Algorithm Hash digest
SHA256 55f09cb33ae26a6702275cd2604ac9bb0ae7e3b03ac265ae628bf4e72251b0ca
MD5 f4fda2c93181170bcb685ff8f43b9e14
BLAKE2b-256 d005e1405255f1d91c595e223cb890f01cfbdba0f5ce11c43180647a876582c0

See more details on using hashes here.

File details

Details for the file noknow-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: noknow-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 17.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/44.0.0 requests-toolbelt/0.9.1 tqdm/4.41.1 CPython/3.8.1

File hashes

Hashes for noknow-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8e55da9fa22cdf74ded0a5b20e4d3d2a8fb24710e960a0cd3db6ce6aef6e24e7
MD5 e6279d36f08f00a69646603f154b7752
BLAKE2b-256 9330c1478c4c77f952515e828afe416d20ec8c7b534f45531ba74b8d8b36089b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page