You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"
]
问题解答

你的方法存在两处关键错误:

  1. 计算对象不匹配:你用Python计算的是input.json整个文件内容的SHA256哈希,但Circom电路中计算的是输入的6个字符("1","3","0","3","0","1")对应的ASCII字节的SHA256哈希,两者输入完全不同,结果自然无法匹配。
  2. 比特顺序逻辑缺失: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:07:03