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.