1package merkle23import "crypto/sha256"45// encodeSlices renders items in the wire shape crypto/merkle.HashFromByteSlices6// expects: a 4-byte big-endian count, then per item a 4-byte big-endian length7// followed by its bytes. The native side decodes this back into [][]byte; gno8// cannot hand a slice of slices to a native directly.9func encodeSlices(items [][]byte) []byte {10 n := 011 for _, it := range items {12 n += 4 + len(it)13 }14 out := make([]byte, 0, 4+n)15 out = appendBE32(out, len(items))16 for _, it := range items {17 out = appendBE32(out, len(it))18 out = append(out, it...)19 }20 return out21}2223func appendBE32(dst []byte, n int) []byte {24 return append(dst, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))25}2627// hashSortedPair is the commutative node hash: SHA256 over the two children in28// ascending byte order, so a proof needs no left/right flag. Used only by29// VerifySorted.30func hashSortedPair(a, b []byte) []byte {31 d := make([]byte, 0, len(a)+len(b))32 if less(a, b) {33 d = append(append(d, a...), b...)34 } else {35 d = append(append(d, b...), a...)36 }37 h := sha256.Sum256(d)38 return h[:]39}4041// less reports a < b in lexicographic byte order. gno's bytes package is42// available, but keeping the comparison here keeps this package import-light.43func less(a, b []byte) bool {44 n := len(a)45 if len(b) < n {46 n = len(b)47 }48 for i := 0; i < n; i++ {49 if a[i] != b[i] {50 return a[i] < b[i]51 }52 }53 return len(a) < len(b)54}5556func equal(a, b []byte) bool {57 if len(a) != len(b) {58 return false59 }60 for i := range a {61 if a[i] != b[i] {62 return false63 }64 }65 return true66}67Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.