ultrasonic/isa/microcode.rs
1// UltraSONIC: transactional execution layer with capability-based memory access for zk-AluVM
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Designed in 2019-2025 by Dr Maxim Orlovsky <orlovsky@ubideco.org>
6// Written in 2024-2025 by Dr Maxim Orlovsky <orlovsky@ubideco.org>
7//
8// Copyright (C) 2019-2024 LNP/BP Standards Association, Switzerland.
9// Copyright (C) 2024-2025 Laboratories for Ubiquitous Deterministic Computing (UBIDECO),
10// Institute for Distributed and Cognitive Systems (InDCS), Switzerland.
11// Copyright (C) 2019-2025 Dr Maxim Orlovsky.
12// All rights under the above copyrights are reserved.
13//
14// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
15// in compliance with the License. You may obtain a copy of the License at
16//
17// http://www.apache.org/licenses/LICENSE-2.0
18//
19// Unless required by applicable law or agreed to in writing, software distributed under the License
20// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
21// or implied. See the License for the specific language governing permissions and limitations under
22// the License.
23
24use aluvm::alu::CoreExt;
25use aluvm::{fe256, RegE};
26
27use crate::{AuthToken, IoCat, StateValue, UsonicCore, VmContext};
28
29impl UsonicCore {
30 /// Checks are there more state values remain in the given category.
31 pub fn has_data(&mut self, cat: IoCat, context: &VmContext) -> bool {
32 let data = context.state_value(cat, self.ui[cat.index()]);
33 data.is_some()
34 }
35
36 /// Get the current index for a destructible input.
37 pub fn get_ui_inro(&self) -> u16 { self.ui[IoCat::IN_RO.index()] }
38
39 /// Loads next [`StateValue`] (basing on iterator position from `UI` indexes) of a given
40 /// category into the `EA`-`ED` registers, increasing `UI` iterator count.
41 pub fn load(&mut self, cat: IoCat, context: &VmContext) -> bool {
42 let data = context.state_value(cat, self.ui[cat.index()]);
43 self.load_internal(cat, data)
44 }
45
46 fn load_internal(&mut self, cat: IoCat, data: Option<StateValue>) -> bool {
47 let co = data.is_some();
48 let data = data.unwrap_or_default();
49 self.set_ea_ed(data);
50 if co {
51 self.ui[cat.index()] += 1;
52 }
53 co
54 }
55
56 /// Sets `EA` and `EB` registers to the field elements representing the given pair of values.
57 pub fn set_ed_eb(&mut self, data: Option<(AuthToken, bool)>) -> bool {
58 let co = data.is_some();
59 self.gfa.put(RegE::EA, data.map(|(at, _)| at.to_fe256()));
60 self.gfa
61 .put(RegE::EB, data.map(|(_, s)| if s { fe256::from(1u8) } else { fe256::ZERO }));
62 co
63 }
64
65 /// Sets `EA`-`ED` registers to the field elements representing the given value.
66 pub fn set_ea_ed_opt(&mut self, data: Option<StateValue>) -> bool {
67 let co = data.is_some();
68 self.set_ea_ed(data.unwrap_or_default());
69 co
70 }
71
72 /// Sets `EA`-`ED` registers to the field elements representing the given value.
73 pub fn set_ea_ed(&mut self, data: StateValue) {
74 self.gfa.put(RegE::EA, data.get(0));
75 self.gfa.put(RegE::EB, data.get(1));
76 self.gfa.put(RegE::EC, data.get(2));
77 self.gfa.put(RegE::ED, data.get(3));
78 }
79
80 /// Sets `UI` register for the destructible input to point at a specific input index.
81 pub fn set_inro_index(&mut self, index: u16) { self.ui[IoCat::IN_RO.index()] = index; }
82
83 /// Reset a value (set to zero) of the `UI` register.
84 pub fn reset(&mut self, cat: IoCat) { self.ui[cat.index()] = 0; }
85}