44
55import base64
66import binascii
7- import hashlib
87import unicodedata
98from collections .abc import Iterable , Sequence
109from typing import Annotated , Literal , Self
1817 model_validator ,
1918)
2019
21- from jacobian .canonical import canonicalize_json
20+ from jacobian .canonical import canonicalize_json , sha256_digest
2221from jacobian .contracts .capabilities import (
2322 CapabilityProviderAvailability ,
2423 CapabilityProviderRuntime ,
5251_PROOF_FORMAT_VERSION : Literal ["drat-text/v1" ] = "drat-text/v1"
5352
5453
55- def _sha256 (value : bytes ) -> str :
56- return f"sha256:{ hashlib .sha256 (value ).hexdigest ()} "
57-
58-
5954class SatVariableBinding (ContractModel ):
6055 """One deterministic symbolic-name to DIMACS-ID binding."""
6156
@@ -126,7 +121,7 @@ def require_canonical_instance(self) -> Self:
126121 raise ValueError ("clauses must be unique and canonically ordered" )
127122 if self .variable_map_digest != sat_variable_map_digest (self .variables ):
128123 raise ValueError ("variable-map digest does not match the canonical map" )
129- if self .dimacs_digest != _sha256 (self .to_dimacs_bytes ()):
124+ if self .dimacs_digest != sha256_digest (self .to_dimacs_bytes ()):
130125 raise ValueError (
131126 "DIMACS digest does not match the deterministic projection"
132127 )
@@ -378,7 +373,7 @@ def require_exact_raw_proof(self) -> Self:
378373 raw = _decode_base64 (self .proof_base64 )
379374 if self .proof_base64 != base64 .b64encode (raw ).decode ("ascii" ):
380375 raise ValueError ("proof bytes must use canonical base64" )
381- if self .proof_digest != _sha256 (raw ):
376+ if self .proof_digest != sha256_digest (raw ):
382377 raise ValueError ("raw proof digest does not match the preserved bytes" )
383378 _require_available_producer (self .producer )
384379 return self
@@ -397,7 +392,7 @@ def from_bytes(
397392 return cls (
398393 cnf = cnf ,
399394 proof_base64 = base64 .b64encode (proof ).decode ("ascii" ),
400- proof_digest = _sha256 (proof ),
395+ proof_digest = sha256_digest (proof ),
401396 producer = producer ,
402397 resource_budget = resource_budget ,
403398 )
@@ -473,7 +468,7 @@ def bind_exact_bytes(self) -> Self:
473468 raw = _decode_base64 (self .proof_base64 )
474469 if self .proof_base64 != base64 .b64encode (raw ).decode ("ascii" ):
475470 raise ValueError ("LRAT proof must use canonical base64" )
476- if self .proof_digest != _sha256 (raw ) or self .proof_byte_count != len (raw ):
471+ if self .proof_digest != sha256_digest (raw ) or self .proof_byte_count != len (raw ):
477472 raise ValueError ("LRAT proof digest or byte count does not match" )
478473 if len (raw ) > self .limits .max_proof_bytes :
479474 raise ValueError ("LRAT proof exceeds its declared byte limit" )
@@ -490,7 +485,7 @@ def from_bytes(
490485 return cls (
491486 cnf = cnf ,
492487 proof_base64 = base64 .b64encode (proof ).decode ("ascii" ),
493- proof_digest = _sha256 (proof ),
488+ proof_digest = sha256_digest (proof ),
494489 proof_byte_count = len (proof ),
495490 limits = limits ,
496491 )
@@ -613,7 +608,7 @@ def canonicalize_cnf(
613608 variables = variables ,
614609 clauses = clause_models ,
615610 variable_map_digest = sat_variable_map_digest (variables ),
616- dimacs_digest = _sha256 (_dimacs_bytes (len (variables ), clause_models )),
611+ dimacs_digest = sha256_digest (_dimacs_bytes (len (variables ), clause_models )),
617612 )
618613
619614
@@ -626,7 +621,7 @@ def sat_variable_map_digest(
626621 "variable_map_format" : "jacobian.sat.variable-map/v1" ,
627622 "variables" : [variable .model_dump (mode = "json" ) for variable in variables ],
628623 }
629- return _sha256 (canonicalize_json (payload ))
624+ return sha256_digest (canonicalize_json (payload ))
630625
631626
632627def _literal_sort_key (literal : int ) -> tuple [int , bool ]:
0 commit comments