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}