SnarkJS预图像哈希验证故障排查:哈希值不匹配问题
问题描述
我首次练习SnarkJS时,尝试验证所持有的生日预图像哈希证明是否与该日期的哈希值一致。我的方法是将public.json文件中的内容与Python计算出的哈希值进行对比,但两者不匹配。请问我的方法是否存在错误?是否可以认为计算出的哈希值应该存在于public.json文件中?
Circom电路
pragma circom 2.0.0; include "../../circomlib/circuits/sha256/sha256.circom"; // Prove that we know a birthday of sha256(birthday) template Birthday(){ component SHA = Sha256(6); signal input date[6]; SHA.in <== date; signal output date_out[256]; date_out <== SHA.out; } component main = Birthday();
Python代码
import hashlib import json def calculate_hash(filename): # Read the entire JSON file with open(filename, 'r') as file: json_data = file.read() # Create a SHA-256 hash object hash_object = hashlib.sha256() # Update the hash object with the entire JSON (string needs to be encoded to bytes) hash_object.update(json_data.encode()) # Get the hash in hexadecimal hash_hex = hash_object.hexdigest() # Convert the hexadecimal hash to bits hash_bits = ''.join(format(int(c, 16), '04b') for c in hash_hex) return hash_bits def concatenate_public_json(filename): # Read the JSON file with open(filename, 'r') as file: bits = json.load(file) # Concatenate the bits into a single string concatenated_bits = ''.join(bits) return concatenated_bits # JSON file name to read data from filename = 'input.json' public = 'public.json' hash1 = calculate_hash(filename) hash2 = concatenate_public_json(public) # Compare the two bit sequences if hash1 == hash2: print("The bit sequences are equal.") else: print("The bit sequences are different.") print("Proof Hash: ", hash1) print("Calculated Hash: ", hash2)
input.json内容
{ "date": ["1", "3", "0", "3", "0", "1"] }
public.json内容
[ "1", "0", "1", "1", "1", "0", "0", "1", "1", "1", "0", "1", "1", "1", "1", "0", "1", "0", "1", "1", "1", "1", "1", "1", "0", "1", "1", "1", "1", "1", "0", "1", "0", "1", "0", "1", "0", "0", "1", "0", "1", "1", "1", "1", "0", "0", "1", "1", "0", "1", "1", "0", "1", "1", "1", "0", "0", "1", "1", "0", "0", "1", "0", "0", "0", "1", "1", "0", "1", "0", "0", "0", "1", "0", "1", "0", "0", "1", "0", "1", "0", "1", "0", "0", "1", "0", "0", "0", "0", "0", "0", "1", "0", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "1", "1", "1", "1", "1", "1", "0", "1", "0", "0", "0", "0", "0", "0", "1", "1", "1", "0", "0", "0", "1", "0", "0", "0", "1", "0", "1", "1", "0", "0", "1", "1", "0", "1", "1", "0", "0", "0", "0", "1", "1", "1", "0", "1", "0", "0", "1", "1", "0", "0", "0", "1", "1", "1", "1", "0", "1", "0", "0", "1", "1", "1", "0", "0", "0", "0", "1", "0", "0", "1", "0", "0", "0", "0", "1", "0", "1", "0", "0", "0", "0", "1", "1", "1", "0", "0", "0", "0", "1", "0", "1", "0", "1", "0", "1", "1", "1", "0", "1", "0", "1", "1", "0", "1", "1", "0", "1", "0", "0", "0", "0", "1", "0", "1", "1", "1", "1", "0", "1", "1", "1", "0", "0", "0", "0", "0", "0", "1", "0", "1", "1", "0", "1", "1", "1", "0", "0", "0", "1", "0", "1", "1", "0", "1", "0", "1", "0", "1", "0", "0", "0", "0", "1" ]
问题解答
你的方法存在两处关键错误:
- 计算对象不匹配:你用Python计算的是
input.json整个文件内容的SHA256哈希,但Circom电路中计算的是输入的6个字符("1","3","0","3","0","1")对应的ASCII字节的SHA256哈希,两者输入完全不同,结果自然无法匹配。 - 比特顺序逻辑缺失:Circom的Sha256组件输出的比特序列是按哈希值高位到低位排列,你当前的Python代码未明确对齐这一顺序,可能导致比特序列拼接方向错误。
正确的验证逻辑应该是:
- 从
input.json中提取date数组的每个字符,将其转换为对应的ASCII字节(比如"1"对应字节0x31)。 - 对这6个字节计算SHA256哈希,再将哈希值转换为和
public.json格式一致的高位到低位比特序列。
另外,你的第二个问题答案是肯定的:如果验证逻辑正确,计算出的日期哈希值的比特序列应该和public.json中的内容完全一致,因为public.json就是Circom电路输出的哈希结果。
修正后的Python代码示例
import hashlib import json def calculate_correct_hash(filename): # 读取input.json并提取date数组 with open(filename, 'r') as file: data = json.load(file) date_chars = data['date'] # 将每个字符转换为ASCII字节 input_bytes = bytes(char.encode('ascii') for char in date_chars) # 计算SHA256哈希 hash_object = hashlib.sha256(input_bytes) hash_hex = hash_object.hexdigest() # 将十六进制哈希转换为高位到低位的比特序列 hash_bits = ''.join([format(int(c, 16), '04b') for c in hash_hex]) return hash_bits def concatenate_public_json(filename): with open(filename, 'r') as file: bits = json.load(file) return ''.join(bits) filename = 'input.json' public = 'public.json' hash1 = calculate_correct_hash(filename) hash2 = concatenate_public_json(public) if hash1 == hash2: print("比特序列匹配!") else: print("比特序列不匹配。") print("正确计算的哈希比特序列:", hash1) print("public.json中的哈希比特序列:", hash2)
内容的提问来源于stack exchange,提问作者Victor do Valle Cunha
相关产品推荐
相关产品推荐

