fix(syn): correct flat encoder to produce identical roundtrip bytes (#233)
The flat encoder had two bugs that caused Encode(Decode(bytes)) to
produce different bytes than the original input. This broke script hash
derivation when applying parameters to compiled Plutus scripts in Go,
since the re-encoded bytes differed from what reference implementations
(Blaze SDK, Aiken) produce.
Bug 1: bits() used direct byte manipulation for multi-bit writes (3+
bits) that packed bits incorrectly across byte boundaries. Replaced with
a simple MSB-to-LSB loop delegating to one()/zero(), matching the
reference flat encoder's pushBits() approach.
Bug 2: encodeConstantType() for TList and TPair was missing the
list-continuation marker bits (one()) before each type tag. The decoder
reads constant type tags via DecodeList, which expects a 1-bit before
each tag entry, but the encoder wrote raw tags without these delimiters.
Added a roundtrip test using a synthetic UPLC program that exercises all
term types (Lambda, Apply, Var, Constant, Force, Delay, Builtin, Constr,
Case, Error) and constant types (Integer, ByteString, Bool, Data).
Signed-off-by: Pascal Grange <[email protected]>