I am far from a mathematician and did not design the protocol myself. The proofs used are rather complex in nature. 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. Note: the paper's implementation uses the set of all real numbers as the cyclic group for simplicity. In this implementation, the cyclic group used is an elliptic curve.
Implementing Zero-Knowledge Authentication with Zero Knowledge by Brandon Lum Jia Jun
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.
TODO: explain how it works
The noknow
Python API is meant to be simple and intuitive:
The parameters used to initialize the Elliptic Curve within the Zero-Knowledge crypto system.
class ZKParameters(NamedTuple):
"""
The parameters required for creating the Zero-Knowledge Cryptosystem
"""
curve: str # the name of the standardized elliptic curve to use for cyclic group point generation
d: int # the large prime number used to generate an elliptic curve point and as a modulo
A cryptographic public signature created from an Elliptic Curve and a user-provided secret (ex: a password) which should be stored by the server (along with the ZKParameters
used) and can be used to validate future challenges.
class ZKSignature(NamedTuple):
"""
A cryptographic signature distinct from a hash that can be used to validate the same input in the future
"""
params: ZKParameters # the reference ZK parameters
signature: int # the calculated signature derived from the ZK curve and user secret
class ZKChallenge(NamedTuple):
"""
A cryptographic challenge created by a user based on the signature (derived from the password)
"""
params: ZKParameters # the reference ZK parameters
token: int # the server-provided random tokens
c: int # the hash derived from the signature, a random point, and the random token
z: int # a value derived from the random point and password hash
The ZKProof
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).
TODO: Include example usage
#!/usr/bin/env python3
"""
Extremely simple example of NoKnow ZK Proof implementation
"""
from noknow import ZKProof
from getpass import getpass
def main():
# the state of `zk` should be known to both Prover (Client) and Verifier (Server)
zk = ZKProof.new()
# `signature` is sent to Server along with `zk.params` for persistent storage
signature = zk.create_signature(getpass("Create Password: "))
while True:
# Server generates random token and sends to Client
token = ZKProof.random_token()
# Client generates a challenge with the token and submits to Server
challenge = zk.create_challenge(getpass("Enter Password: "), token)
# Server proves the challenge with the shared token, user-submitted challenge, and stored signature
if zk.prove_challenge(challenge, signature, token):
print("Authentication Successful!\n")
break
else:
print("Authentication Failed!\n")
if __name__ == "__main__":
main()