Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

salt.gno

2.13 Kb · 86 lines
 1package zkgm
 2
 3import (
 4	"crypto/keccak256"
 5	"encoding/binary"
 6
 7	u256 "gno.land/p/onbloc/math/uint256"
 8)
 9
10func DeriveBatchSalt(index *u256.Uint, salt [32]byte) [32]byte {
11	var input [64]byte
12
13	putUint256BE(input[:32], index)
14	copy(input[32:], salt[:])
15
16	return keccak256.Sum256(input[:])
17}
18
19func TintForwardSalt(salt [32]byte) [32]byte {
20	var out [32]byte
21	for i := range salt {
22		out[i] = salt[i] | FORWARD_SALT_MAGIC[i]
23	}
24
25	return out
26}
27
28func IsForwardedPacket(salt [32]byte) bool {
29	for i := range salt {
30		if salt[i]&FORWARD_SALT_MAGIC[i] != FORWARD_SALT_MAGIC[i] {
31			return false
32		}
33	}
34
35	return true
36}
37
38func DeriveForwardSalt(salt [32]byte) [32]byte {
39	hash := keccak256.Sum256(salt[:])
40	return TintForwardSalt(hash)
41}
42
43// Uint256ToBytes32 returns the big-endian 32-byte encoding of x.
44func Uint256ToBytes32(x *u256.Uint) [32]byte {
45	var out [32]byte
46
47	putUint256BE(out[:], x)
48
49	return out
50}
51
52// DeriveSenderSalt computes:
53//
54//	keccak256((sender, salt).abi_encode())
55//
56// matching Union's alloy-sol-types encoding of a top-level dynamic tuple.
57// Callers must pass the raw UTF-8 bytes of the bech32 account string.
58func DeriveSenderSalt(sender []byte, salt [32]byte) [32]byte {
59	// ABI layout for alloy `(bytes, bytes32).abi_encode()`:
60	//
61	//   word 0: offset to top-level tuple body (0x20)
62	//   word 1: offset to sender data within tuple body (0x40)
63	//   word 2: salt
64	//   word 3: len(sender)
65	//   word 4+: sender bytes, right-padded to a 32-byte boundary
66	//
67	// The inner offset is relative to the start of the tuple body.
68	pad := (32 - len(sender)%32) % 32
69	buf := make([]byte, 4*32+len(sender)+pad)
70	buf[31] = 0x20
71	buf[63] = 0x40
72	copy(buf[64:96], salt[:])
73	binary.BigEndian.PutUint64(buf[120:128], uint64(len(sender)))
74	copy(buf[128:], sender)
75
76	return keccak256.Sum256(buf)
77}
78
79// NOTE: depends on gnoswap/uint256's internal [4]uint64 layout (mirror of
80// SetBytes32). Replace with the upstream Bytes32() method once it exists.
81func putUint256BE(dst []byte, x *u256.Uint) {
82	binary.BigEndian.PutUint64(dst[0:8], x[3])
83	binary.BigEndian.PutUint64(dst[8:16], x[2])
84	binary.BigEndian.PutUint64(dst[16:24], x[1])
85	binary.BigEndian.PutUint64(dst[24:32], x[0])
86}