How do I proove in Python that an integer is within a certain range without having to reveal it [zero-knowledge proofs]?

52 Views Asked by At

The following program is meant to verify that the age of the client is within the required range, without the server having to know the age of that client. I mean to use zero knowledge proofs to accomplish that. Sadly, the program tells me that the age is not within the range for the numbers such as 15, 25, 75.

#!/usr/bin/env python3

from Cryptodome.Util import number
from Cryptodome.Hash import SHA256


def main():
    print(
        "This is happening client-side. There are secrets here such as my private key and my age."
    )
    private_key, public_key = generate_key_pair()
    print("Private Key:", private_key)
    print("Public Key:", public_key)
    age_to_prove = int(input("Your age?"))
    print("Age to Prove:", age_to_prove)
    commitment, response = prove_age(private_key, age_to_prove)
    print("Proof Generated - Commitment:", commitment)
    print("Proof Generated - Response:", response)
    age_range_to_verify = (18, 70)
    verification_result = verify_age(
        public_key, commitment, response, age_range_to_verify
    )
    if verification_result:
        print(
            f"Your age is within {age_range_to_verify[0]} to {age_range_to_verify[1]} range."
        )
    else:
        print(
            f"Your age is not within {age_range_to_verify[0]} to {age_range_to_verify[1]} range."
        )


def generate_key_pair():
    # Generate a key pair (private key, public key)
    private_key = number.getRandomRange(1, 2**256)
    public_key = pow(2, private_key, 2**256 + 1)
    return private_key, public_key


def prove_age(private_key, age):
    # Step 1: Generate a random value
    r = number.getRandomRange(1, 2**256)
    # Step 2: Compute commitment
    commitment = pow(2, r, 2**256 + 1)
    # Step 3: Hash commitment and age
    challenge_input = str(commitment) + str(age)
    c = int.from_bytes(SHA256.new(challenge_input.encode("utf-8")).digest(), "big") % (
        2**256
    )
    # Step 4: Compute response
    s = (r + private_key * c) % (2**256)
    # Return the proof (commitment, response)
    return commitment, s


def verify_age(public_key, commitment, response, age_range):
    print(
        "This is happening server-side. I am not supposed to get to know the age of the client."
    )
    challenge_input = str(commitment) + str(age_range[0]) + str(age_range[1])
    c = int.from_bytes(SHA256.new(challenge_input.encode("utf-8")).digest(), "big") % (
        2**256
    )
    verification_lhs = pow(2, response, 2**256 + 1)
    verification_rhs = (commitment * pow(public_key, c, 2**256 + 1)) % (2**256 + 1)

    return verification_lhs == verification_rhs


if __name__ == "__main__":
    main()

What is wrong with this code? How do I prove in Python that an integer variable is within a certain range without having to reveal it zero-knowledge proofs? I would like to use bulletproofs for this - non-interactive zero-knowledge proofs.

0

There are 0 best solutions below