zorch.byte_transcript¶
Byte-oriented Fiat-Shamir transcript: the ByteTranscript seam and a
Merlin-over-hash duplex (ByteHashTranscript) parameterized by a ByteHash.
This is the HOST-side, byte-oriented sibling of the device-resident algebraic
DuplexTranscript (transcript.py). The two form a taxonomy (see
docs/blocks/transcript.md): an algebraic sponge whose observe/sample are device
ops fused into the round body, vs a byte hash whose Fiat-Shamir chain is strictly
sequential and runs on the host.
ByteHashTranscript holds a bytes buffer and an injected ByteHash
(hash/byte_hash.py); the digest substrate — host HostSha256 or the device
Sha256 marker — is a value it carries, not a class it hardcodes. Its
has_dedicated_fusion delegates to that hash, exactly as DuplexSponge delegates
to its Permutation. So the same construction backs both a host byte challenger
(inject HostSha256()) and the device-byte row of the taxonomy (inject
Sha256()); the two are byte-identical.
The construction — op-tagged absorb, HASH(buffer || ctr) counter-squeeze (SHA-256
is not an XOF), and re-absorb of the squeezed bytes — is a standard Merlin-style
duplex, byte-identical to the canonical SHA-256 Fiat-Shamir transcript used by
binary-field provers (e.g. succinctlabs/flock's FsChallenger). zorch owns the
wire framing on OPAQUE bytes; a consumer supplies only its field<->bytes
serialization (see flock-zorch's challenger.py, an F128 (16-byte lo||hi) surface).
ByteTranscript ¶
Bases: Protocol
Byte-oriented Fiat-Shamir seam. observe_* append tagged, length-prefixed
bytes; sample_* squeeze raw bytes (the consumer reinterprets to field
elements). Distinct from transcript.Transcript, which is field-element- and
device-oriented.
Source code in zorch/byte_transcript.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 | |
ByteHashTranscript
dataclass
¶
Merlin-style byte duplex over an injected ByteHash. Functional: every op
returns a new transcript whose buffer is the running absorbed-byte stream. A
host object (a bytes buffer, not a jit-traced pytree); the ByteHash chooses
the squeeze substrate — HostSha256 (host hashlib) or Sha256 (the
hash_frx.sha256 device marker). Byte-identical whichever is injected.
Source code in zorch/byte_transcript.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | |
new
classmethod
¶
new(
domain: bytes, byte_hash: ByteHash
) -> ByteHashTranscript
Seed with a length-prefixed domain so prefix domains can't collide:
[OP_DOMAIN] || len8(domain) || domain.
Source code in zorch/byte_transcript.py
110 111 112 113 114 | |
grind_pow ¶
grind_pow(bits: int) -> tuple[ByteHashTranscript, int]
Lowest u64 nonce whose PoW passes (0 if bits==0), then absorb it via
observe_bytes so subsequent challenges bind to it.
Source code in zorch/byte_transcript.py
195 196 197 198 199 200 | |
verify_pow ¶
verify_pow(
nonce: int, *, bits: int
) -> tuple[ByteHashTranscript, bool]
Verifier mirror: check the PoW (bits==0 requires the canonical nonce 0), then absorb the nonce REGARDLESS so the transcript stays in lockstep.
Source code in zorch/byte_transcript.py
202 203 204 205 206 207 208 209 210 211 212 213 | |