rsnark_core/variable.rs
1//! Variable types and constant value support for circuit construction.
2//!
3//! This module provides the foundation for rSnark's flexible variable system,
4//! including support for BigInt constants and automatic type conversion.
5//!
6//! # Key Features
7//!
8//! - **Automatic constant conversion**: Primitive types are automatically converted to BigInt constants
9//! - **Type safety**: Strong typing ensures correct variable usage in circuits
10//! - **Generic support**: Works with generic circuit structures
11//! - **BigInt precision**: Support for arbitrary precision arithmetic
12//!
13//! # Supported Constant Types
14//!
15//! The following primitive types are automatically converted to circuit constants:
16//! - Unsigned integers: `u8`, `u16`, `u32`, `u64`, `u128`
17//! - Signed integers: `i8`, `i16`, `i32`, `i64`, `i128`
18//! - Boolean: `bool`
19//!
20//! # Usage in Circuits
21//!
22//! ```rust,ignore
23//! impl Circuit for MyCircuit {
24//! fn define(&self, api: &mut impl API) {
25//! // All these literals are automatically converted to BigInt constants
26//! let result = api.add(&self.input, &42_u32);
27//! let scaled = api.mul(&result, &1000_i64);
28//! let flag = api.select(&true, &result, &0);
29//! }
30//! }
31//! ```
32
33use std::marker::PhantomData;
34
35use num::BigInt;
36
37use crate::types::VariableType;
38
39/// A trait that defines types that can be used as API parameters in circuit construction.
40///
41/// This trait enables various types to be used interchangeably in circuit operations,
42/// including public variables, private variables, local variables, and constant values.
43/// Each implementor must provide its variable type representation.
44pub trait Variable {
45 /// Returns the variable type representation for this variable.
46 /// This is used internally by the circuit builder to track variable usage.
47 fn ty(&self) -> VariableType;
48}
49
50impl Variable for VariableType {
51 fn ty(&self) -> VariableType {
52 self.clone()
53 }
54}
55
56pub struct CircuitVariable<T> {
57 variable: VariableType,
58 marker: PhantomData<T>,
59}
60
61impl<T> Variable for CircuitVariable<T> {
62 fn ty(&self) -> VariableType {
63 self.variable.clone()
64 }
65}
66
67impl<T> From<VariableType> for CircuitVariable<T> {
68 fn from(variable: VariableType) -> Self {
69 Self {
70 variable,
71 marker: PhantomData,
72 }
73 }
74}
75
76/// Macro to automatically implement Variable trait for primitive types.
77///
78/// This macro generates implementations that convert primitive values to BigInt constants.
79/// The conversion preserves the original value's precision and sign, enabling seamless
80/// integration of literal values in circuit operations.
81///
82/// # Generated Implementation
83///
84/// For each type `T`, this generates:
85/// ```rust,ignore
86/// impl Variable for T {
87/// fn ty(&self) -> VariableType {
88/// let x = BigInt::from(*self);
89/// VariableType::Constant(x)
90/// }
91/// }
92/// ```
93macro_rules! define_variable_for_from_u256 {
94 ($t:ident) => {
95 impl Variable for $t {
96 fn ty(&self) -> VariableType {
97 let x = BigInt::from(*self);
98 VariableType::Constant(x)
99 }
100 }
101 };
102}
103
104define_variable_for_from_u256!(u128);
105define_variable_for_from_u256!(u64);
106define_variable_for_from_u256!(u32);
107define_variable_for_from_u256!(u16);
108define_variable_for_from_u256!(u8);
109define_variable_for_from_u256!(i128);
110define_variable_for_from_u256!(i64);
111define_variable_for_from_u256!(i32);
112define_variable_for_from_u256!(i16);
113define_variable_for_from_u256!(i8);
114define_variable_for_from_u256!(bool);