arcis_interface/types.rs
1/// Represents the kind of scalar value (signed vs unsigned integer).
2///
3/// This enum distinguishes between signed and unsigned integer types in circuit interfaces,
4/// allowing the system to properly serialize/deserialize values and generate correct Rust types.
5///
6/// # Examples
7///
8/// ```
9/// use arcis_interface::{Value, ScalarKind};
10///
11/// // Unsigned 32-bit integer (u32)
12/// let unsigned = Value::Scalar {
13/// size_in_bits: 32,
14/// kind: ScalarKind::Unsigned
15/// };
16///
17/// // Signed 32-bit integer (i32)
18/// let signed = Value::Scalar {
19/// size_in_bits: 32,
20/// kind: ScalarKind::Signed
21/// };
22/// ```
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
24pub enum ScalarKind {
25 /// Unsigned integer type (u8, u16, u32, u64, u128).
26 ///
27 /// This is the default for backward compatibility with existing circuits
28 /// that were created before signed integer support was added.
29 #[default]
30 Unsigned,
31
32 /// Signed integer type (i8, i16, i32, i64, i128).
33 ///
34 /// Signed integers use two's complement representation in the MPC protocol.
35 Signed,
36}
37
38/// Circuit interface value types.
39///
40/// Represents all possible types that can be used as inputs or outputs in Arcium circuits.
41#[derive(Debug, Clone, PartialEq, Eq)]
42pub enum Value {
43 MScalar {
44 size_in_bits: usize,
45 },
46 MFloat {
47 size_in_bits: usize,
48 },
49 MBool,
50 /// Plaintext scalar value (integer).
51 ///
52 /// # Fields
53 /// * `size_in_bits` - Bit width of the scalar (8, 16, 32, 64, or 128)
54 /// * `kind` - Whether the scalar is signed or unsigned
55 ///
56 /// # Examples
57 /// * `Scalar { size_in_bits: 32, kind: ScalarKind::Unsigned }` represents u32
58 /// * `Scalar { size_in_bits: 64, kind: ScalarKind::Signed }` represents i64
59 Scalar {
60 size_in_bits: usize,
61 kind: ScalarKind,
62 },
63 Float {
64 size_in_bits: usize,
65 },
66 Bool,
67 Ciphertext {
68 size_in_bits: usize,
69 },
70 ArcisX25519Pubkey,
71 Point,
72 Array(Vec<Value>),
73 Tuple(Vec<Value>),
74 Struct(Vec<Value>),
75}
76
77impl Value {
78 /// Returns the number of scalar field elements this value occupies.
79 ///
80 /// For primitive types (Scalar, Bool, Float, etc.), this returns 1.
81 /// For composite types (Array, Tuple, Struct), this recursively counts all scalar fields.
82 ///
83 /// # Examples
84 ///
85 /// ```
86 /// use arcis_interface::{Value, ScalarKind};
87 ///
88 /// let scalar = Value::Scalar { size_in_bits: 32, kind: ScalarKind::Unsigned };
89 /// assert_eq!(scalar.size_in_scalars(), 1);
90 ///
91 /// let tuple = Value::Tuple(vec![
92 /// Value::Scalar { size_in_bits: 32, kind: ScalarKind::Unsigned },
93 /// Value::Bool,
94 /// ]);
95 /// assert_eq!(tuple.size_in_scalars(), 2);
96 /// ```
97 pub fn size_in_scalars(&self) -> usize {
98 match self {
99 Self::MScalar { .. } => 1,
100 Self::MFloat { .. } => 1,
101 Self::Scalar { .. } => 1,
102 Self::Float { .. } => 1,
103 Self::MBool { .. } => 1,
104 Self::Bool { .. } => 1,
105 Self::Ciphertext { .. } => 1,
106 Self::ArcisX25519Pubkey => 1,
107 Self::Point => 1,
108 Self::Array(c) | Self::Tuple(c) | Self::Struct(c) => {
109 c.iter().fold(0, |acc, x| acc + x.size_in_scalars())
110 }
111 }
112 }
113
114 /// Flattens composite types into a vector of primitive values.
115 ///
116 /// For primitive types, returns a single-element vector containing self.
117 /// For composite types (Array, Tuple, Struct), recursively flattens all nested values
118 /// into a flat vector of primitives.
119 ///
120 /// # Examples
121 ///
122 /// ```
123 /// use arcis_interface::{Value, ScalarKind};
124 ///
125 /// let scalar = Value::Scalar { size_in_bits: 32, kind: ScalarKind::Unsigned };
126 /// assert_eq!(scalar.flatten().len(), 1);
127 ///
128 /// let tuple = Value::Tuple(vec![
129 /// Value::Scalar { size_in_bits: 32, kind: ScalarKind::Unsigned },
130 /// Value::Tuple(vec![Value::Bool, Value::Bool]),
131 /// ]);
132 /// assert_eq!(tuple.flatten().len(), 3); // u32, bool, bool
133 /// ```
134 pub fn flatten(&self) -> Vec<Value> {
135 match self {
136 Self::Array(c) | Self::Tuple(c) | Self::Struct(c) => {
137 let mut v = Vec::new();
138 for a in c {
139 v.extend(a.flatten());
140 }
141 v
142 }
143 _ => vec![self.clone()],
144 }
145 }
146}
147
148#[derive(Debug, serde::Serialize)]
149pub struct CircuitInterface {
150 pub name: String,
151 pub inputs: Vec<Value>,
152 pub outputs: Vec<Value>,
153}
154
155impl CircuitInterface {
156 pub fn new(name: String, inputs: Vec<Value>, outputs: Vec<Value>) -> Self {
157 Self {
158 name,
159 inputs,
160 outputs,
161 }
162 }
163
164 pub fn serialize(&self) -> Result<String, serde_json::Error> {
165 serde_json::to_string(self)
166 }
167
168 pub fn from_json(input: &str) -> Result<Self, serde_json::Error> {
169 serde_json::from_str(input)
170 }
171}