@@ -498,15 +498,26 @@ ev is_binary(main: [a]):
498
498
enf a^2 = a
499
499
500
500
501
- ev range_check_16bit()
501
+ ev range_check_16bit(aux: [helper[6], b_range]):
502
+ enf b_range' * (alpha[0] + helper[0]) * (alpha[1] * helper[1]) * (alpha[2] + helper[2]) * (alpha[3] * helper[3]) = b_range
503
+
504
+
505
+ ev check_element_validity(aux: [helper[6]]):
506
+ let m = helper[4]
507
+ let v_hi = 2^16 * helper[3] + helper[2]
508
+ let v_lo = 2^16 * helper[1] + helper[0]
509
+ enf (1 - m * (2^32 - 1 - v_hi)) * v_lo = 0
502
510
503
511
504
512
### Stack Air Constraints #########################################################################
505
513
506
514
# Enforces the constraints on the stack.
507
515
# TODO: add docs for columns
508
- ev stack_constraints(main: [stack[16], bookkeeping[2], h0], aux: [op_bits[7], extra, hasher5, fmp, helper[3 ], clk, b_chip]):
516
+ ev stack_constraints(main: [stack[16], bookkeeping[2], h0], aux: [op_bits[7], extra, hasher5, fmp, helper[6 ], clk, b_chip, b_range ]):
509
517
let op_flags = compute_op_flags(op_bits, extra)
518
+
519
+ enf range_check_16bit([helper, b_range]) when f_u32rc([stack])
520
+
510
521
match enf:
511
522
noop([stack]) when op_flags[0]
512
523
eqz([stack, h0]) when op_flags[1]
@@ -555,7 +566,7 @@ ev stack_constraints(main: [stack[16], bookkeeping[2], h0], aux: [op_bits[7], ex
555
566
cswap([stack]) when op_flags[42]
556
567
cswapw([stack]) when op_flags[43]
557
568
mloadw([stack], [clk, b_chip]) when op_flags[44]
558
- mstore([stack], [helper[3] , clk, b_chip]) when op_flags[45]
569
+ mstore([stack], [helper, clk, b_chip]) when op_flags[45]
559
570
mstorew([stack], [clk, b_chip]) when op_flags[46]
560
571
fmpupdate([stack], [fmp]) when op_flags[47]
561
572
@@ -612,8 +623,8 @@ ev fmpadd(main: [s[16]], aux: [fmp]):
612
623
# WARNING: not sure that I got the constraint right
613
624
# What are the "helper" columns? Is it just a different name for hasher decoder columns, or they
614
625
# are unique for i/o ops?
615
- ev mload(main: [s[16]], aux: [helper[3 ], clk, b_chip]):
616
- let v = alpha[5] * s[0]' + sum([alpha[i + 5] * helper[3 - i]'])
626
+ ev mload(main: [s[16]], aux: [helper[6 ], clk, b_chip]):
627
+ let v = alpha[5] * s[0]' + sum([alpha[i + 5] * helper[3 - i]' for i in 1..4 ])
617
628
let op_mem_read = 12
618
629
let u_mem = alpha[0] + alpha[1] * op_mem_read + alpha[3] * s[0] + alpha[4] * clk + v
619
630
enf b_chip' * u_mem = b_chip
@@ -803,7 +814,7 @@ ev mloadw(main: [s[16]], aux: [clk, b_chip]):
803
814
enf b_chip' * u_mem = b_chip
804
815
enf s[i]' = s[i + 1] for i in 4..15
805
816
806
- ev mstore(main: [s[16]], aux: [helper[3 ], clk, b_chip]):
817
+ ev mstore(main: [s[16]], aux: [helper[6 ], clk, b_chip]):
807
818
let v = alpha[5] * s[0]' + sum([alpha[i + 5] * helper[3 - i]' for i in 1..4])
808
819
let op_mem_write = 4
809
820
let u_mem = alpha[0] + alpha[1] * op_mem_write + alpha[3] * s[0] + alpha[4] * clk + v
@@ -886,3 +897,56 @@ ev sdepth(main: [s[16], bookkeeping[2]]):
886
897
ev clk(main: [s[16]], aux: [clk]):
887
898
enf s[0]' = clk
888
899
enf s[i + 1]' = s[i] for i in 0..15
900
+
901
+
902
+ # u32 operations
903
+
904
+ ev u32add(main: [s[16]], aux: [helper[6]]):
905
+ enf s[0] + s[1] = 2^32 * helper[2] + 2^16 * helper[1] + helper[0]
906
+ enf s[0]' = helper[2]
907
+ enf s[1]' = 2^16 8 helper[1] + helper[0]
908
+ enf delta(s[i]) = 0 for i in 2..16
909
+
910
+ ev u32sub(main: [s[16]], aux: [helper[6]]):
911
+ enf s[1] = s[0] + s[1]' + 2^32 * s[0]'
912
+ enf (s[0]')^2 - s[0]' = 0
913
+ enf s[1]' = 2^16 * helper[1] + helper[0]
914
+ enf delta(s[i]) = 0 for i in 2..16
915
+
916
+ ev u32mul(main: [s[16]], aux: [helper[6]]):
917
+ enf s[0] * s[1] = 2^48 * helper[3] + 2^32 * helper[2] + 2^16 * helper[1] + helper[0]
918
+ enf s[1]' = 2^16 * helper[1] + helper[0]
919
+ enf s[0]' = 2^16 * helper[3] + helper[2]
920
+ enf check_element_validity([helper])
921
+ enf delta(s[i]) = 0 for i in 2..16
922
+
923
+ ev u32div(main: [s[16]], aux: [helper[6]]):
924
+ enf s[1] = s[0] * s[1]' + s[0]'
925
+ enf s[1] - s[1]' = 2^16 * helper[1] + helper[0]
926
+ enf s[0] - s[0]' - 1 = 2^16 * helper[2] + helper[3]
927
+ enf delta(s[i]) = 0 for i in 2..16
928
+
929
+ ev u32split(main: [s[16]], aux: [helper[6]]):
930
+ enf s[0] = 2^48 * helper[3] + 2^32 * helper[2] + 2^16 * helper[1] + helper[0]
931
+ enf s[1]' = 2^16 * helper[1] + helper[0]
932
+ enf s[0]' = 2^16 * helper[3] + helper[2]
933
+ enf check_element_validity([helper])
934
+ enf s[i + 1]' = s[i] for i in 1..15
935
+
936
+ ev u32assert2(main: [s[16]], aux: [helper[6]]):
937
+ enf s[0]' = 2^16 * helper[3] + helper[2]
938
+ enf s[1]' = 2^16 * helper[1] + helper[0]
939
+ enf delta(elem) = 0 for elem in s
940
+
941
+ ev u32add3(main: [s[16]], aux: [helper[6]]):
942
+ enf s[0] + s[1] + s[2] = 2^32 * helper[2] + 2^16 * helper[1] + helper[0]
943
+ enf s[0]' = helper[2]
944
+ enf s[1]' = 2^16 * helper[1] + helper[0]
945
+ enf s[i]' = s[i + 1] for i in 2..15
946
+
947
+ ev u32madd(main: [s[16]], aux: [helper[6]]):
948
+ enf s[0] * s[1] + s[2] = 2^48 * helper[3] + 2^32 * helper[2] + 2^16 * helper[1] + helper[0]
949
+ enf s[1]' = 2^16 * helper[1] + helper[0]
950
+ enf s[0]' = 2^16 * helper[3] + helper[2]
951
+ enf check_element_validity([helper])
952
+ enf s[i]' = s[i + 1] for i in 2..15
0 commit comments