telltale_runtime/heap/
encoding.rs1pub const HEAP_ENCODING_MAGIC: [u8; 4] = *b"TTHP";
9
10pub const HEAP_ENCODING_VERSION: u16 = 1;
12
13const TAG_MESSAGE_PAYLOAD: u8 = 0x10;
14const TAG_CHANNEL_STATE: u8 = 0x20;
15const TAG_MESSAGE: u8 = 0x30;
16const TAG_RESOURCE_CHANNEL: u8 = 0x40;
17const TAG_RESOURCE_MESSAGE: u8 = 0x41;
18const TAG_RESOURCE_SESSION: u8 = 0x42;
19const TAG_RESOURCE_VALUE: u8 = 0x43;
20const TAG_RESOURCE_ID_PREIMAGE: u8 = 0x50;
21const TAG_RESOURCE_LEAF_PREIMAGE: u8 = 0x51;
22const TAG_NULLIFIER_LEAF_PREIMAGE: u8 = 0x52;
23const TAG_MERKLE_NODE_PREIMAGE: u8 = 0x53;
24const TAG_HEAP_COMMITMENT_PREIMAGE: u8 = 0x54;
25
26pub trait CanonicalHeapEncoding {
31 fn encode_canonical_body(&self, encoder: &mut CanonicalHeapEncoder);
33
34 fn canonical_tag(&self) -> u8;
36
37 fn to_canonical_bytes(&self) -> Vec<u8> {
39 let mut encoder = CanonicalHeapEncoder::new(self.canonical_tag());
40 self.encode_canonical_body(&mut encoder);
41 encoder.finish()
42 }
43}
44
45#[derive(Debug, Clone, Default)]
47pub struct CanonicalHeapEncoder {
48 bytes: Vec<u8>,
49}
50
51impl CanonicalHeapEncoder {
52 pub fn new(tag: u8) -> Self {
54 let mut bytes = Vec::new();
55 bytes.extend_from_slice(&HEAP_ENCODING_MAGIC);
56 bytes.extend_from_slice(&HEAP_ENCODING_VERSION.to_le_bytes());
57 bytes.push(tag);
58 Self { bytes }
59 }
60
61 pub fn nested<T: CanonicalHeapEncoding>(&mut self, value: &T) {
63 self.bytes.extend_from_slice(&value.to_canonical_bytes());
64 }
65
66 pub fn string(&mut self, value: &str) {
68 self.bytes
69 .extend_from_slice(&(value.len() as u32).to_le_bytes());
70 self.bytes.extend_from_slice(value.as_bytes());
71 }
72
73 pub fn bytes(&mut self, value: &[u8]) {
75 self.bytes
76 .extend_from_slice(&(value.len() as u32).to_le_bytes());
77 self.bytes.extend_from_slice(value);
78 }
79
80 pub fn u32(&mut self, value: u32) {
82 self.bytes.extend_from_slice(&value.to_le_bytes());
83 }
84
85 pub fn u64(&mut self, value: u64) {
87 self.bytes.extend_from_slice(&value.to_le_bytes());
88 }
89
90 pub fn finish(self) -> Vec<u8> {
92 self.bytes
93 }
94}
95
96pub(crate) const fn tag_message_payload() -> u8 {
97 TAG_MESSAGE_PAYLOAD
98}
99
100pub(crate) const fn tag_channel_state() -> u8 {
101 TAG_CHANNEL_STATE
102}
103
104pub(crate) const fn tag_message() -> u8 {
105 TAG_MESSAGE
106}
107
108pub(crate) const fn tag_resource_channel() -> u8 {
109 TAG_RESOURCE_CHANNEL
110}
111
112pub(crate) const fn tag_resource_message() -> u8 {
113 TAG_RESOURCE_MESSAGE
114}
115
116pub(crate) const fn tag_resource_session() -> u8 {
117 TAG_RESOURCE_SESSION
118}
119
120pub(crate) const fn tag_resource_value() -> u8 {
121 TAG_RESOURCE_VALUE
122}
123
124pub fn resource_id_preimage(resource_bytes: &[u8], counter: u64) -> Vec<u8> {
126 let mut encoder = CanonicalHeapEncoder::new(TAG_RESOURCE_ID_PREIMAGE);
127 encoder.bytes(resource_bytes);
128 encoder.u64(counter);
129 encoder.finish()
130}
131
132pub fn resource_leaf_preimage(resource_id_bytes: &[u8], resource_bytes: &[u8]) -> Vec<u8> {
134 let mut encoder = CanonicalHeapEncoder::new(TAG_RESOURCE_LEAF_PREIMAGE);
135 encoder.bytes(resource_id_bytes);
136 encoder.bytes(resource_bytes);
137 encoder.finish()
138}
139
140pub fn nullifier_leaf_preimage(resource_id_bytes: &[u8]) -> Vec<u8> {
142 let mut encoder = CanonicalHeapEncoder::new(TAG_NULLIFIER_LEAF_PREIMAGE);
143 encoder.bytes(resource_id_bytes);
144 encoder.finish()
145}
146
147pub fn merkle_node_preimage(left: &[u8], right: &[u8]) -> Vec<u8> {
149 let mut encoder = CanonicalHeapEncoder::new(TAG_MERKLE_NODE_PREIMAGE);
150 encoder.bytes(left);
151 encoder.bytes(right);
152 encoder.finish()
153}
154
155pub fn heap_commitment_preimage(
157 resource_root: &[u8],
158 nullifier_root: &[u8],
159 counter: u64,
160) -> Vec<u8> {
161 let mut encoder = CanonicalHeapEncoder::new(TAG_HEAP_COMMITMENT_PREIMAGE);
162 encoder.bytes(resource_root);
163 encoder.bytes(nullifier_root);
164 encoder.u64(counter);
165 encoder.finish()
166}