Skip to main content

miden_objects/conversion/
primitives.rs

1use alloc::collections::BTreeMap;
2use alloc::format;
3use alloc::vec::Vec;
4
5use miden_protocol::crypto::dsa::ecdsa_k256_keccak::{PublicKey, Signature};
6use miden_protocol::crypto::merkle::store::MerkleStore;
7use miden_protocol::utils::serde::{Deserializable, DeserializationError, Serializable};
8use miden_protocol::vm::{AdviceInputs, AdviceMap, AdviceStack, ExecutionProof};
9use miden_protocol::{Felt, MastForest, Word};
10
11use crate::{ConversionError, proto};
12
13#[cfg(test)]
14mod tests;
15
16// FELT
17// ================================================================================================
18
19impl From<Felt> for proto::primitives::Felt {
20    fn from(value: Felt) -> Self {
21        Self { value: value.as_canonical_u64() }
22    }
23}
24
25impl From<&Felt> for proto::primitives::Felt {
26    fn from(value: &Felt) -> Self {
27        Self { value: value.as_canonical_u64() }
28    }
29}
30
31impl TryFrom<proto::primitives::Felt> for Felt {
32    type Error = ConversionError;
33
34    fn try_from(value: proto::primitives::Felt) -> Result<Self, Self::Error> {
35        Self::try_from(&value)
36    }
37}
38
39impl TryFrom<&proto::primitives::Felt> for Felt {
40    type Error = ConversionError;
41
42    fn try_from(value: &proto::primitives::Felt) -> Result<Self, Self::Error> {
43        value.decode_value(|value| Self::try_from(*value))
44    }
45}
46
47// WORD
48// ================================================================================================
49
50impl From<Word> for proto::primitives::Word {
51    fn from(value: Word) -> Self {
52        Self { encoded: value.to_bytes() }
53    }
54}
55
56impl From<&Word> for proto::primitives::Word {
57    fn from(value: &Word) -> Self {
58        Self { encoded: value.to_bytes() }
59    }
60}
61
62impl TryFrom<proto::primitives::Word> for Word {
63    type Error = ConversionError;
64
65    fn try_from(value: proto::primitives::Word) -> Result<Self, Self::Error> {
66        Self::try_from(&value)
67    }
68}
69
70impl TryFrom<&proto::primitives::Word> for Word {
71    type Error = ConversionError;
72
73    fn try_from(value: &proto::primitives::Word) -> Result<Self, Self::Error> {
74        value.decode_value(|encoded| {
75            if encoded.len() != Word::SERIALIZED_SIZE {
76                return Err(DeserializationError::InvalidValue(format!(
77                    "expected exactly {} bytes, got {}",
78                    Word::SERIALIZED_SIZE,
79                    encoded.len()
80                )));
81            }
82            Self::read_from_bytes(encoded)
83        })
84    }
85}
86
87// EXECUTION PROOF
88// ================================================================================================
89
90impl From<&ExecutionProof> for proto::primitives::ExecutionProof {
91    fn from(value: &ExecutionProof) -> Self {
92        Self { encoded: value.to_bytes() }
93    }
94}
95
96impl From<ExecutionProof> for proto::primitives::ExecutionProof {
97    fn from(value: ExecutionProof) -> Self {
98        (&value).into()
99    }
100}
101
102impl TryFrom<proto::primitives::ExecutionProof> for ExecutionProof {
103    type Error = ConversionError;
104
105    fn try_from(value: proto::primitives::ExecutionProof) -> Result<Self, Self::Error> {
106        Self::try_from(&value)
107    }
108}
109
110impl TryFrom<&proto::primitives::ExecutionProof> for ExecutionProof {
111    type Error = ConversionError;
112
113    fn try_from(value: &proto::primitives::ExecutionProof) -> Result<Self, Self::Error> {
114        value.decode_value(|encoded| Self::read_from_bytes(encoded))
115    }
116}
117
118// MAST FOREST
119// ================================================================================================
120
121impl From<&MastForest> for proto::primitives::MastForest {
122    fn from(value: &MastForest) -> Self {
123        Self { encoded: value.to_bytes() }
124    }
125}
126
127impl From<MastForest> for proto::primitives::MastForest {
128    fn from(value: MastForest) -> Self {
129        (&value).into()
130    }
131}
132
133// ADVICE INPUTS
134// ================================================================================================
135
136impl From<&AdviceStack> for proto::primitives::AdviceStack {
137    fn from(value: &AdviceStack) -> Self {
138        Self {
139            values: value.iter().map(Into::into).collect(),
140        }
141    }
142}
143
144impl From<&AdviceMap> for proto::primitives::AdviceMap {
145    fn from(value: &AdviceMap) -> Self {
146        Self {
147            entries: value
148                .iter()
149                .map(|(key, values)| proto::primitives::AdviceMapEntry {
150                    key: Some(key.into()),
151                    values: values.iter().map(Into::into).collect(),
152                })
153                .collect(),
154        }
155    }
156}
157
158impl From<&MerkleStore> for proto::primitives::MerkleStore {
159    fn from(value: &MerkleStore) -> Self {
160        let default_nodes = MerkleStore::new()
161            .inner_nodes()
162            .map(|node| (node.value, (node.left, node.right)))
163            .collect::<BTreeMap<_, _>>();
164        let mut nodes = value
165            .inner_nodes()
166            .filter(|node| default_nodes.get(&node.value) != Some(&(node.left, node.right)))
167            .collect::<Vec<_>>();
168        nodes.sort_by_key(|node| node.value);
169
170        Self {
171            nodes: nodes
172                .into_iter()
173                .map(|node| proto::primitives::MerkleStoreNode {
174                    value: Some(node.value.into()),
175                    left: Some(node.left.into()),
176                    right: Some(node.right.into()),
177                })
178                .collect(),
179        }
180    }
181}
182
183impl From<&AdviceInputs> for proto::primitives::AdviceInputs {
184    fn from(value: &AdviceInputs) -> Self {
185        Self {
186            advice_stack: Some((&value.stack()).into()),
187            advice_map: Some(value.map().into()),
188            merkle_store: Some(value.store().into()),
189        }
190    }
191}
192
193// PUBLIC KEY
194// ================================================================================================
195
196impl From<&PublicKey> for proto::primitives::PublicKey {
197    fn from(value: &PublicKey) -> Self {
198        Self {
199            key: Some(proto::primitives::public_key::Key::EcdsaK256Keccak(value.to_bytes())),
200        }
201    }
202}
203
204impl From<PublicKey> for proto::primitives::PublicKey {
205    fn from(value: PublicKey) -> Self {
206        (&value).into()
207    }
208}
209
210// SIGNATURE
211// ================================================================================================
212
213impl From<&Signature> for proto::primitives::Signature {
214    fn from(value: &Signature) -> Self {
215        Self {
216            signature: Some(proto::primitives::signature::Signature::EcdsaK256Keccak(
217                value.to_bytes(),
218            )),
219        }
220    }
221}
222
223impl From<Signature> for proto::primitives::Signature {
224    fn from(value: Signature) -> Self {
225        (&value).into()
226    }
227}
228
229// Canonical representation adapter; domain interpretation is left to the containing record.
230impl crate::DecodeMessage for proto::primitives::Word {
231    type Decoded = miden_protocol::Word;
232}
233
234// Canonical representation adapter; domain interpretation is left to the containing record.
235impl crate::DecodeMessage for proto::primitives::Felt {
236    type Decoded = miden_protocol::Felt;
237}
238
239// Canonical representation adapter; domain interpretation is left to the containing record.
240impl crate::DecodeMessage for proto::primitives::ExecutionProof {
241    type Decoded = miden_protocol::vm::ExecutionProof;
242}