1use crate::types::{CircuitInterface, ScalarKind, Value};
2use serde::{
3 de::{self, MapAccess, Visitor},
4 Deserialize,
5 Deserializer,
6 Serialize,
7};
8use serde_json::{json, Value as JsonValue};
9use std::fmt;
10
11#[derive(Serialize, Deserialize, Debug)]
12pub struct ManticoreInterface {
13 pub inputs: Vec<String>,
14 pub outputs: Vec<String>,
15}
16
17impl ManticoreInterface {
18 pub fn new(inputs: Vec<String>, outputs: Vec<String>) -> Self {
19 Self { inputs, outputs }
20 }
21
22 pub fn serialize(&self) -> Result<String, serde_json::Error> {
23 serde_json::to_string(self)
24 }
25
26 pub fn from_json(input: &str) -> Result<Self, serde_json::Error> {
27 serde_json::from_str(input)
28 }
29}
30
31impl<'de> Deserialize<'de> for CircuitInterface {
32 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
33 where
34 D: Deserializer<'de>,
35 {
36 enum Field {
37 Name,
38 Inputs,
39 Outputs,
40 }
41
42 impl<'de> Deserialize<'de> for Field {
43 fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
44 where
45 D: Deserializer<'de>,
46 {
47 struct FieldVisitor;
48
49 impl Visitor<'_> for FieldVisitor {
50 type Value = Field;
51
52 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53 formatter.write_str("`name`, `inputs`, or `outputs`")
54 }
55
56 fn visit_str<E>(self, value: &str) -> Result<Field, E>
57 where
58 E: de::Error,
59 {
60 match value {
61 "name" => Ok(Field::Name),
62 "inputs" => Ok(Field::Inputs),
63 "outputs" => Ok(Field::Outputs),
64 _ => Err(de::Error::unknown_field(value, FIELDS)),
65 }
66 }
67 }
68
69 deserializer.deserialize_identifier(FieldVisitor)
70 }
71 }
72
73 struct CircuitInterfaceVisitor;
74
75 impl<'de> Visitor<'de> for CircuitInterfaceVisitor {
76 type Value = CircuitInterface;
77
78 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
79 formatter.write_str("struct CircuitInterface")
80 }
81
82 fn visit_map<V>(self, mut map: V) -> Result<CircuitInterface, V::Error>
83 where
84 V: MapAccess<'de>,
85 {
86 let mut name = None;
87 let mut inputs = None;
88 let mut outputs = None;
89
90 while let Some(key) = map.next_key()? {
91 match key {
92 Field::Name => {
93 if name.is_some() {
94 return Err(de::Error::duplicate_field("name"));
95 }
96 name = Some(map.next_value()?);
97 }
98 Field::Inputs => {
99 if inputs.is_some() {
100 return Err(de::Error::duplicate_field("inputs"));
101 }
102 inputs = Some(map.next_value()?);
103 }
104 Field::Outputs => {
105 if outputs.is_some() {
106 return Err(de::Error::duplicate_field("outputs"));
107 }
108 outputs = Some(map.next_value()?);
109 }
110 }
111 }
112
113 let name = name.ok_or_else(|| de::Error::missing_field("name"))?;
114 let inputs = inputs.ok_or_else(|| de::Error::missing_field("inputs"))?;
115 let outputs = outputs.ok_or_else(|| de::Error::missing_field("output"))?;
116
117 Ok(CircuitInterface {
118 name,
119 inputs,
120 outputs,
121 })
122 }
123 }
124
125 const FIELDS: &[&str] = &["name", "inputs", "outputs"];
126 deserializer.deserialize_struct("CircuitInterface", FIELDS, CircuitInterfaceVisitor)
127 }
128}
129
130impl Value {
131 fn get_scalar_type_name(size_in_bits: usize, kind: ScalarKind) -> &'static str {
137 match kind {
138 ScalarKind::Unsigned => match size_in_bits {
139 8 => "u8",
140 16 => "u16",
141 32 => "u32",
142 64 => "u64",
143 128 => "u128",
144 _ => "scalar",
145 },
146 ScalarKind::Signed => match size_in_bits {
147 8 => "i8",
148 16 => "i16",
149 32 => "i32",
150 64 => "i64",
151 128 => "i128",
152 _ => "signed_integer",
153 },
154 }
155 }
156}
157
158impl Serialize for Value {
159 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
160 where
161 S: serde::Serializer,
162 {
163 let json_value = match self {
164 Value::MScalar { size_in_bits } => json!({
165 "type": "mscalar",
166 "size_in_bits": size_in_bits
167 }),
168 Value::MFloat { size_in_bits } => json!({
169 "type": "mfloat",
170 "size_in_bits": size_in_bits
171 }),
172 Value::MBool => json!({
173 "type": "mbool"
174 }),
175 Value::Scalar { size_in_bits, kind } => json!({
176 "type": Value::get_scalar_type_name(*size_in_bits, *kind),
177 "size_in_bits": size_in_bits
178 }),
179 Value::Float { size_in_bits } => json!({
180 "type": "float",
181 "size_in_bits": size_in_bits
182 }),
183 Value::Bool => json!({
184 "type": "bool"
185 }),
186 Value::Ciphertext { size_in_bits } => json!({
187 "type": "ciphertext",
188 "size_in_bits": size_in_bits
189 }),
190 Value::ArcisX25519Pubkey => json!({
191 "type": "arcis_x25519_pubkey",
192 }),
193 Value::Point => json!({
194 "type": "point"
195 }),
196 Value::UnsynchronizedBools { count } => json!({
197 "type": "unsynchronized_bools",
198 "count": count
199 }),
200 Value::AesCiphertextByte => json!({
201 "type": "aes_ciphertext_byte"
202 }),
203 Value::Array(vec) => json!({
204 "type": "array",
205 "content": vec
206 }),
207 Value::Tuple(vec) => json!({
208 "type": "tuple",
209 "content": vec
210 }),
211 Value::Struct(vec) => json!({
212 "type": "struct",
213 "content": vec
214 }),
215 };
216 json_value.serialize(serializer)
217 }
218}
219
220impl<'de> Deserialize<'de> for Value {
221 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
222 where
223 D: serde::Deserializer<'de>,
224 {
225 let json_value = JsonValue::deserialize(deserializer)?;
226
227 match json_value {
228 JsonValue::Object(map) => {
229 let type_ = map
230 .get("type")
231 .and_then(JsonValue::as_str)
232 .ok_or_else(|| serde::de::Error::missing_field("type"))?;
233
234 match type_ {
235 "mscalar" => {
236 let size_in_bits = map
237 .get("size_in_bits")
238 .and_then(JsonValue::as_u64)
239 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
240 Ok(Value::MScalar {
241 size_in_bits: size_in_bits as usize,
242 })
243 }
244 "mfloat" => {
245 let size_in_bits = map
246 .get("size_in_bits")
247 .and_then(JsonValue::as_u64)
248 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
249 Ok(Value::MFloat {
250 size_in_bits: size_in_bits as usize,
251 })
252 }
253 "mbool" => Ok(Value::MBool),
254 "u8" => Ok(Value::Scalar {
255 size_in_bits: 8,
256 kind: ScalarKind::Unsigned,
257 }),
258 "u16" => Ok(Value::Scalar {
259 size_in_bits: 16,
260 kind: ScalarKind::Unsigned,
261 }),
262 "u32" => Ok(Value::Scalar {
263 size_in_bits: 32,
264 kind: ScalarKind::Unsigned,
265 }),
266 "u64" => Ok(Value::Scalar {
267 size_in_bits: 64,
268 kind: ScalarKind::Unsigned,
269 }),
270 "u128" => Ok(Value::Scalar {
271 size_in_bits: 128,
272 kind: ScalarKind::Unsigned,
273 }),
274 "i8" => Ok(Value::Scalar {
275 size_in_bits: 8,
276 kind: ScalarKind::Signed,
277 }),
278 "i16" => Ok(Value::Scalar {
279 size_in_bits: 16,
280 kind: ScalarKind::Signed,
281 }),
282 "i32" => Ok(Value::Scalar {
283 size_in_bits: 32,
284 kind: ScalarKind::Signed,
285 }),
286 "i64" => Ok(Value::Scalar {
287 size_in_bits: 64,
288 kind: ScalarKind::Signed,
289 }),
290 "i128" => Ok(Value::Scalar {
291 size_in_bits: 128,
292 kind: ScalarKind::Signed,
293 }),
294 "scalar" => {
295 let size_in_bits = map
296 .get("size_in_bits")
297 .and_then(JsonValue::as_u64)
298 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
299 Ok(Value::Scalar {
300 size_in_bits: size_in_bits as usize,
301 kind: ScalarKind::Unsigned,
302 })
303 }
304 "signed_integer" => {
305 let size_in_bits = map
306 .get("size_in_bits")
307 .and_then(JsonValue::as_u64)
308 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
309 Ok(Value::Scalar {
310 size_in_bits: size_in_bits as usize,
311 kind: ScalarKind::Signed,
312 })
313 }
314 "ciphertext" => {
315 let size_in_bits = map
316 .get("size_in_bits")
317 .and_then(JsonValue::as_u64)
318 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
319 Ok(Value::Ciphertext {
320 size_in_bits: size_in_bits as usize,
321 })
322 }
323 "arcis_x25519_pubkey" => Ok(Value::ArcisX25519Pubkey),
324 "point" => Ok(Value::Point),
325 "unsynchronized_bools" => {
326 let count = map
327 .get("count")
328 .and_then(JsonValue::as_u64)
329 .ok_or_else(|| serde::de::Error::missing_field("count"))?;
330 Ok(Value::UnsynchronizedBools {
331 count: count as usize,
332 })
333 }
334 "float" => {
335 let size_in_bits = map
336 .get("size_in_bits")
337 .and_then(JsonValue::as_u64)
338 .ok_or_else(|| serde::de::Error::missing_field("size_in_bits"))?;
339 Ok(Value::Float {
340 size_in_bits: size_in_bits as usize,
341 })
342 }
343 "bool" => Ok(Value::Bool),
344 "aes_ciphertext_byte" => Ok(Value::AesCiphertextByte),
345 "array" | "tuple" | "struct" => {
346 let content = map
347 .get("content")
348 .ok_or_else(|| serde::de::Error::missing_field("content"))?;
349 let vec: Vec<Value> =
350 serde_json::from_value(content.clone()).map_err(|e| {
351 serde::de::Error::custom(format!(
352 "Failed to deserialize content: {}",
353 e
354 ))
355 })?;
356 match type_ {
357 "array" => Ok(Value::Array(vec)),
358 "tuple" => Ok(Value::Tuple(vec)),
359 "struct" => Ok(Value::Struct(vec)),
360 _ => unreachable!(),
361 }
362 }
363 _ => Err(serde::de::Error::unknown_variant(
364 type_,
365 &[
366 "mscalar",
367 "mfloat",
368 "mbool",
369 "u8",
370 "u16",
371 "u32",
372 "u64",
373 "u128",
374 "i8",
375 "i16",
376 "i32",
377 "i64",
378 "i128",
379 "scalar",
380 "signed_integer",
381 "float",
382 "bool",
383 "array",
384 "tuple",
385 "struct",
386 "ciphertext",
387 "arcis_x25519_pubkey",
388 "point",
389 "unsynchronized_bools",
390 "aes_ciphertext_byte",
391 ],
392 )),
393 }
394 }
395 _ => Err(serde::de::Error::invalid_type(
396 serde::de::Unexpected::Other("non-object"),
397 &"object",
398 )),
399 }
400 }
401}
402
403#[cfg(test)]
404mod tests {
405 use super::*;
406 use serde_json::json;
407
408 #[test]
409 fn test_mscalar_serialization() {
410 let value = Value::MScalar { size_in_bits: 32 };
411 let serialized = serde_json::to_value(value).unwrap();
412 assert_eq!(
413 serialized,
414 json!({
415 "type": "mscalar",
416 "size_in_bits": 32
417 })
418 );
419 }
420
421 #[test]
422 fn test_unsynchronized_bools_round_trips() {
423 let value = Value::UnsynchronizedBools { count: 1568 };
424 let serialized = serde_json::to_value(value.clone()).unwrap();
425 assert_eq!(
426 serialized,
427 json!({
428 "type": "unsynchronized_bools",
429 "count": 1568
430 })
431 );
432 assert_eq!(serde_json::from_value::<Value>(serialized).unwrap(), value);
433 }
434
435 #[test]
436 fn test_aes_ciphertext_byte_round_trips() {
437 let value = Value::AesCiphertextByte;
438 let serialized = serde_json::to_value(value.clone()).unwrap();
439 assert_eq!(serialized, json!({ "type": "aes_ciphertext_byte" }));
440 assert_eq!(serde_json::from_value::<Value>(serialized).unwrap(), value);
441 }
442
443 #[test]
446 fn test_unsynchronized_bools_is_one_value() {
447 assert_eq!(
448 Value::UnsynchronizedBools { count: 1568 }.size_in_scalars(),
449 1
450 );
451 }
452
453 #[test]
454 fn test_mbool_serialization() {
455 let value = Value::MBool;
456 let serialized = serde_json::to_value(value).unwrap();
457 assert_eq!(
458 serialized,
459 json!({
460 "type": "mbool"
461 })
462 );
463 }
464
465 #[test]
466 fn test_bool_serialization() {
467 let value = Value::Bool;
468 let serialized = serde_json::to_value(value).unwrap();
469 assert_eq!(
470 serialized,
471 json!({
472 "type": "bool"
473 })
474 );
475 }
476
477 #[test]
478 fn test_array_serialization() {
479 let value = Value::Array(vec![
480 Value::Scalar {
481 size_in_bits: 60,
482 kind: ScalarKind::Unsigned,
483 },
484 Value::Bool,
485 ]);
486 let serialized = serde_json::to_value(value).unwrap();
487 assert_eq!(
488 serialized,
489 json!({
490 "type": "array",
491 "content": [
492 {
493 "type": "scalar",
494 "size_in_bits": 60
495 },
496 {
497 "type": "bool"
498 }
499 ]
500 })
501 );
502 }
503
504 #[test]
505 fn test_nested_structure_serialization() {
506 let value = Value::Struct(vec![
507 Value::Tuple(vec![Value::MScalar { size_in_bits: 32 }, Value::MBool]),
508 Value::Array(vec![
509 Value::Scalar {
510 size_in_bits: 64,
511 kind: ScalarKind::Unsigned,
512 },
513 Value::Bool,
514 ]),
515 ]);
516 let serialized = serde_json::to_string(&value).unwrap();
517 let deserialized: Value = serde_json::from_str(&serialized).unwrap();
518 assert_eq!(value, deserialized);
519 }
520
521 #[test]
522 fn test_mscalar_deserialization() {
523 let json = r#"{"type": "mscalar", "size_in_bits": 32}"#;
524 let deserialized: Value = serde_json::from_str(json).unwrap();
525 assert_eq!(deserialized, Value::MScalar { size_in_bits: 32 });
526 }
527
528 #[test]
529 fn test_array_deserialization() {
530 let json = r#"
531 {
532 "type": "array",
533 "content": [
534 {"type": "scalar", "size_in_bits": 64},
535 {"type": "bool"}
536 ]
537 }"#;
538 let deserialized: Value = serde_json::from_str(json).unwrap();
539 assert_eq!(
540 deserialized,
541 Value::Array(vec![
542 Value::Scalar {
543 size_in_bits: 64,
544 kind: ScalarKind::Unsigned,
545 },
546 Value::Bool,
547 ])
548 );
549 }
550
551 #[test]
552 fn test_invalid_type_deserialization() {
553 let json = r#"{"type": "invalid_type"}"#;
554 let result: Result<Value, _> = serde_json::from_str(json);
555 assert!(result.is_err());
556 }
557
558 #[test]
559 fn test_missing_size_in_bits_deserialization() {
560 let json = r#"{"type": "mscalar"}"#;
561 let result: Result<Value, _> = serde_json::from_str(json);
562 assert!(result.is_err());
563 }
564
565 #[test]
566 fn test_plaintext_type_serialization() {
567 let test_cases = [
569 (
570 Value::Scalar {
571 size_in_bits: 8,
572 kind: ScalarKind::Unsigned,
573 },
574 "u8",
575 ),
576 (
577 Value::Scalar {
578 size_in_bits: 16,
579 kind: ScalarKind::Unsigned,
580 },
581 "u16",
582 ),
583 (
584 Value::Scalar {
585 size_in_bits: 32,
586 kind: ScalarKind::Unsigned,
587 },
588 "u32",
589 ),
590 (
591 Value::Scalar {
592 size_in_bits: 64,
593 kind: ScalarKind::Unsigned,
594 },
595 "u64",
596 ),
597 (
598 Value::Scalar {
599 size_in_bits: 128,
600 kind: ScalarKind::Unsigned,
601 },
602 "u128",
603 ),
604 (
606 Value::Scalar {
607 size_in_bits: 24,
608 kind: ScalarKind::Unsigned,
609 },
610 "scalar",
611 ),
612 ];
613
614 for (value, expected_type) in test_cases {
615 let serialized = serde_json::to_value(&value).unwrap();
617 let expected = match &value {
618 Value::Scalar { size_in_bits, .. } => json!({
619 "type": expected_type,
620 "size_in_bits": size_in_bits
621 }),
622 Value::Bool => json!({
623 "type": expected_type
624 }),
625 _ => unreachable!(),
626 };
627 assert_eq!(serialized, expected);
628
629 let json = serde_json::to_string(&expected).unwrap();
631 let deserialized: Value = serde_json::from_str(&json).unwrap();
632 assert_eq!(deserialized, value);
633 }
634 }
635
636 #[test]
637 fn test_signed_integer_serialization() {
638 let test_cases = [
639 (
640 Value::Scalar {
641 size_in_bits: 8,
642 kind: ScalarKind::Signed,
643 },
644 "i8",
645 ),
646 (
647 Value::Scalar {
648 size_in_bits: 16,
649 kind: ScalarKind::Signed,
650 },
651 "i16",
652 ),
653 (
654 Value::Scalar {
655 size_in_bits: 32,
656 kind: ScalarKind::Signed,
657 },
658 "i32",
659 ),
660 (
661 Value::Scalar {
662 size_in_bits: 64,
663 kind: ScalarKind::Signed,
664 },
665 "i64",
666 ),
667 (
668 Value::Scalar {
669 size_in_bits: 128,
670 kind: ScalarKind::Signed,
671 },
672 "i128",
673 ),
674 (
675 Value::Scalar {
676 size_in_bits: 24,
677 kind: ScalarKind::Signed,
678 },
679 "signed_integer",
680 ),
681 ];
682
683 for (value, expected_type) in test_cases {
684 let serialized = serde_json::to_value(&value).unwrap();
686 let expected = json!({
687 "type": expected_type,
688 "size_in_bits": match &value {
689 Value::Scalar { size_in_bits, .. } => size_in_bits,
690 _ => unreachable!(),
691 }
692 });
693 assert_eq!(serialized, expected);
694
695 let json = serde_json::to_string(&expected).unwrap();
697 let deserialized: Value = serde_json::from_str(&json).unwrap();
698 assert_eq!(deserialized, value);
699 }
700 }
701
702 #[test]
703 fn test_backward_compatibility() {
704 let old_json_cases = [
706 (r#"{"type": "u8", "size_in_bits": 8}"#, 8),
707 (r#"{"type": "u16", "size_in_bits": 16}"#, 16),
708 (r#"{"type": "u32", "size_in_bits": 32}"#, 32),
709 (r#"{"type": "u64", "size_in_bits": 64}"#, 64),
710 (r#"{"type": "u128", "size_in_bits": 128}"#, 128),
711 (r#"{"type": "scalar", "size_in_bits": 24}"#, 24),
712 ];
713
714 for (json, expected_size) in old_json_cases {
715 let deserialized: Value = serde_json::from_str(json).unwrap();
716 assert_eq!(
717 deserialized,
718 Value::Scalar {
719 size_in_bits: expected_size,
720 kind: ScalarKind::Unsigned
721 }
722 );
723 }
724 }
725
726 #[test]
727 fn test_mixed_signed_unsigned_serialization() {
728 let unsigned = Value::Scalar {
730 size_in_bits: 32,
731 kind: ScalarKind::Unsigned,
732 };
733 let signed = Value::Scalar {
734 size_in_bits: 32,
735 kind: ScalarKind::Signed,
736 };
737
738 let unsigned_json = serde_json::to_value(&unsigned).unwrap();
739 let signed_json = serde_json::to_value(&signed).unwrap();
740
741 assert_eq!(
742 unsigned_json,
743 json!({
744 "type": "u32",
745 "size_in_bits": 32
746 })
747 );
748 assert_eq!(
749 signed_json,
750 json!({
751 "type": "i32",
752 "size_in_bits": 32
753 })
754 );
755
756 assert_ne!(unsigned_json, signed_json);
758 }
759}