1- use crate :: scan_state:: currency:: { self , Amount , Balance , Fee , Magnitude , MinMax , Sgn , Signed } ;
1+ use crate :: {
2+ proofs:: field:: CircuitVar ,
3+ scan_state:: currency:: { self , Amount , Balance , Fee , Magnitude , MinMax , Sgn , Signed } ,
4+ } ;
25use std:: { cell:: Cell , cmp:: Ordering :: Less } ;
36
47use crate :: proofs:: {
4245 T : CheckedCurrency < F > ,
4346{
4447 pub magnitude : T ,
45- pub sgn : Sgn ,
48+ pub sgn : CircuitVar < Sgn > ,
4649 pub value : Cell < Option < F > > ,
4750}
4851
6568 F : FieldWitness + std:: fmt:: Debug ,
6669 T : CheckedCurrency < F > + std:: fmt:: Debug ,
6770{
68- pub fn create ( magnitude : T , sgn : Sgn , value : Option < F > ) -> Self {
71+ pub fn create ( magnitude : T , sgn : CircuitVar < Sgn > , value : Option < F > ) -> Self {
6972 Self {
7073 magnitude,
7174 sgn,
@@ -77,32 +80,46 @@ where
7780 let value = magnitude. to_field ( ) ;
7881 Self {
7982 magnitude,
80- sgn : Sgn :: Pos ,
83+ sgn : CircuitVar :: Constant ( Sgn :: Pos ) ,
8184 value : Cell :: new ( Some ( value) ) ,
8285 }
8386 }
8487
8588 pub fn zero ( ) -> Self {
86- Self :: of_unsigned ( T :: zero ( ) )
89+ Self {
90+ magnitude : T :: zero ( ) ,
91+ sgn : CircuitVar :: Constant ( Sgn :: Pos ) ,
92+ value : Cell :: new ( None ) ,
93+ }
94+ }
95+
96+ // https://github.com/MinaProtocol/mina/blob/ca9c8c86aa21d3c346d28ea0be7ad4cb0c22bf7f/src/lib/transaction_snark/transaction_snark.ml#L1891-L1892
97+ // https://github.com/MinaProtocol/mina/blob/ca9c8c86aa21d3c346d28ea0be7ad4cb0c22bf7f/src/lib/currency/currency.ml#L579
98+ pub fn constant_zero ( ) -> Self {
99+ Self {
100+ magnitude : T :: zero ( ) ,
101+ sgn : CircuitVar :: Constant ( Sgn :: Pos ) ,
102+ value : Cell :: new ( Some ( T :: zero ( ) . to_field ( ) ) ) ,
103+ }
87104 }
88105
89106 pub fn negate ( self ) -> Self {
90107 Self {
91108 magnitude : self . magnitude ,
92- sgn : self . sgn . negate ( ) ,
109+ sgn : self . sgn . map ( |sgn| sgn . negate ( ) ) ,
93110 value : Cell :: new ( self . value . get ( ) . map ( |f| f. neg ( ) ) ) ,
94111 }
95112 }
96113
97114 pub fn is_neg ( & self ) -> Boolean {
98- match self . sgn {
115+ match self . sgn . value ( ) {
99116 Sgn :: Pos => Boolean :: False ,
100117 Sgn :: Neg => Boolean :: True ,
101118 }
102119 }
103120
104121 pub fn is_pos ( & self ) -> Boolean {
105- match self . sgn {
122+ match self . sgn . value ( ) {
106123 Sgn :: Pos => Boolean :: True ,
107124 Sgn :: Neg => Boolean :: False ,
108125 }
@@ -112,7 +129,7 @@ where
112129 match self . value . get ( ) {
113130 Some ( x) => x,
114131 None => {
115- let sgn: F = self . sgn . to_field ( ) ;
132+ let sgn: F = self . sgn . value ( ) . to_field ( ) ;
116133 let magnitude: F = self . magnitude . to_field ( ) ;
117134 let value = w. exists_no_check ( magnitude * sgn) ;
118135 self . value . replace ( Some ( value) ) ;
@@ -125,7 +142,7 @@ where
125142 match self . value . get ( ) {
126143 Some ( x) => x,
127144 None => {
128- let sgn: F = self . sgn . to_field ( ) ;
145+ let sgn: F = self . sgn . value ( ) . to_field ( ) ;
129146 let magnitude: F = self . magnitude . to_field ( ) ;
130147 magnitude * sgn
131148 }
@@ -136,7 +153,7 @@ where
136153 match self . value . get ( ) {
137154 Some ( _) => { }
138155 None => {
139- let sgn: F = self . sgn . to_field ( ) ;
156+ let sgn: F = self . sgn . value ( ) . to_field ( ) ;
140157 let magnitude: F = self . magnitude . to_field ( ) ;
141158 self . value . replace ( Some ( magnitude * sgn) ) ;
142159 }
@@ -150,7 +167,7 @@ where
150167 fn unchecked ( & self ) -> currency:: Signed < T :: Inner > {
151168 currency:: Signed {
152169 magnitude : self . magnitude . to_inner ( ) ,
153- sgn : self . sgn ,
170+ sgn : * self . sgn . value ( ) ,
154171 }
155172 }
156173
@@ -185,7 +202,7 @@ where
185202
186203 let res = Self {
187204 magnitude : res_magnitude,
188- sgn,
205+ sgn : CircuitVar :: Var ( sgn ) ,
189206 value : Cell :: new ( Some ( res_value) ) ,
190207 } ;
191208 ( res, overflow)
@@ -211,19 +228,22 @@ where
211228
212229 range_check :: < F , CURRENCY_NBITS > ( magnitude, w) ;
213230
214- Self :: create ( T :: from_field ( magnitude) , sgn, Some ( res_value) )
231+ Self :: create (
232+ T :: from_field ( magnitude) ,
233+ CircuitVar :: Var ( sgn) ,
234+ Some ( res_value) ,
235+ )
215236 }
216237
217238 pub fn equal ( & self , other : & Self , w : & mut Witness < F > ) -> Boolean {
218- // We decompose this way because of OCaml evaluation order
219- let t2 = other. value ( w) ;
220239 let t1 = self . value ( w) ;
240+ let t2 = other. value ( w) ;
221241 field:: equal ( t1, t2, w)
222242 }
223243
224244 pub fn const_equal ( & self , other : & Self , w : & mut Witness < F > ) -> Boolean {
225- let t2 = other. value ( w) ;
226245 let t1 = self . value ( w) ;
246+ let t2 = other. value ( w) ;
227247 field:: equal ( t1, t2, w)
228248 }
229249}
@@ -497,7 +517,7 @@ macro_rules! impl_currency {
497517 pub fn to_checked<F : FieldWitness >( & self ) -> CheckedSigned <F , $name<F >> {
498518 CheckedSigned {
499519 magnitude: self . magnitude. to_checked( ) ,
500- sgn: self . sgn,
520+ sgn: CircuitVar :: Var ( self . sgn) ,
501521 value: Cell :: new( None ) ,
502522 }
503523 }
0 commit comments