@@ -487,7 +487,7 @@ impl BasicSnippet for FriSnippet {
487
487
488
488
// Loop's end condition is determined by pointer values, so we don't need a loop counter value
489
489
// All pointers are traversed from highest address to lowest
490
- // INVARIANT: _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elements *a_indices *b_elements *b_indices
490
+ // INVARIANT: _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elements *a_indices *b_elements *b_indices
491
491
{ compute_c_values_loop} :
492
492
493
493
// evaluate termination criterion
@@ -498,128 +498,135 @@ impl BasicSnippet for FriSnippet {
498
498
skiz return
499
499
500
500
// Strategy:
501
- // 1. Calculate `a_y`
501
+ // 1. Read `a_y`
502
502
// 2. Calculate `a_x`
503
- // 3. Calculate `-b_x`
504
- // 4. Calculate `1 / (a_x - b_x)` while preserving `a_x`
505
- // 5. Calculate `b_y`
506
- // 6. Calculate `a_y - b_y`, preserving `a_y`
507
- // 7. Calculate `a_y - b_y / (a_x - b_x)`
508
- // 8. Calculate `c_x - a_x`
509
- // 9. Calculate final `c_y`
503
+ // 3. Calculate `[a_y- b_y]`, preserve a[y]
504
+ // 4. Calculate `b_x`
505
+ // 5. Calculate `-b_x`
506
+ // 6. Calculate `1 / (a_x - b_x)` while preserving `a_x`
507
+ // 7. Calculate `(a_y - b_y) / (a_x - b_x)`
508
+ // 8: Read `[c_x]`
509
+ // 9. Calculate `c_x - a_x`
510
+ // 10. Calculate final `c_y`
511
+ // 11. Write c_y to *c_elem
510
512
511
513
// _ *c_end_condition g offset r *c_elem *alphas[r] *a_elem *a_index *b_elem *b_index
512
514
513
- // 1:
515
+ // 1: Read `a_y`
514
516
dup 3
515
517
read_mem { EXTENSION_DEGREE }
516
- swap 7 pop 1
517
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index *b_elem *b_index [a_y]
518
+ swap 7
519
+ pop 1
520
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index *b_elem *b_index [a_y]
518
521
519
- // 2:
520
- dup 9
522
+ // 2: Calculate `a_x`
523
+ dup 11
521
524
dup 6
522
525
read_mem 1
523
526
swap 8
524
527
pop 1
525
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (1<<round) a_index
528
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (1<<round) a_index
526
529
527
- dup 13
530
+ dup 12
528
531
pow
529
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (1<<round) (g^a_index)
532
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (1<<round) (g^a_index)
530
533
531
- dup 12
534
+ dup 11
532
535
mul
533
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (1<<round) (g^a_index * offset)
536
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (1<<round) (g^a_index * offset)
534
537
535
538
pow
536
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (g^a_index * offset)^(1<<round)
537
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] a_x
539
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] (g^a_index * offset)^(1<<round)
540
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] a_x
538
541
539
- // 3:
540
- dup 10
542
+ // 3: Calculate `[a_y- b_y]`, preserve a[y]
541
543
dup 5
544
+ read_mem { EXTENSION_DEGREE }
545
+ swap 9
546
+ pop 1
547
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] a_x [b_y]
548
+
549
+ push -1
550
+ xbmul
551
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] a_x [-b_y]
552
+
553
+ dup 6
554
+ dup 6
555
+ dup 6
556
+ xxadd
557
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index [a_y] a_x [a_y-b_y]
558
+
559
+ // 4: Calculate `b_x`
560
+ dup 15
561
+ dup 15
562
+ dup 9
542
563
read_mem 1
543
- swap 7
564
+ swap 11
544
565
pop 1
545
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x (1<<round) b_index
566
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] (1<<round) g b_index
546
567
547
- dup 14
568
+ swap 1
548
569
pow
549
- dup 13
570
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] (1<<round) (g^b_index)
571
+
572
+ dup 15
550
573
mul
574
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] (1<<round) (g^b_index * offset)
575
+
551
576
pow
552
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x b_x
577
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] (g^b_index * offset)^((1<<round))
578
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] b_x
553
579
580
+ // 5: Calculate `-b_x`
554
581
push -1
555
582
mul
556
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x (-b_x)
583
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] (-b_x)
557
584
558
- // 4:
559
- dup 1
585
+ // 6: Calculate `1 / (a_x - b_x)` while preserving `a_x`
586
+ dup 4
560
587
add
561
588
invert
562
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x (1 / (a_x-b_x))
589
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [a_y-b_y] (1/ (a_x-b_x))
563
590
564
- // 5:
565
- dup 6
566
- read_mem { EXTENSION_DEGREE }
567
- swap 10
568
- pop 1
569
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] a_x (1/(a_x-b_x)) [b_y]
591
+ // 7: Calculate `(a_y - b_y) / (a_x - b_x)`
570
592
571
- // 6:
572
- push -1
573
593
xbmul
574
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] a_x (1/(a_x-b_x)) [-b_y]
575
-
576
- dup 7
577
- dup 7
578
- dup 7
579
- xxadd
580
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] a_x (1/(a_x-b_x)) [a_y-b_y]
581
-
582
- // 7:
583
-
584
- swap 1 swap 2 swap 3
585
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] a_x [a_y-b_y] (1/(a_x-b_x))
586
-
587
- xbmul
588
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] a_x [(a_y-b_y) / (a_x-b_x)]
589
-
590
- swap 1 swap 2 swap 3
591
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] [(a_y-b_y) / (a_x-b_x)] a_x
592
-
593
- push -1
594
- mul
595
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] [(a_y-b_y) / (a_x-b_x)] (-a_x)
594
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [(a_y-b_y)/(a_x-b_x)]
596
595
596
+ // 8: Read `[c_x]`
597
597
dup 11
598
598
read_mem { EXTENSION_DEGREE }
599
599
pop 1
600
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] [(a_y-b_y) / (a_x-b_x)] (-a_x) [c_x]
601
-
602
- swap 1 swap 2 swap 3
603
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] [(a_y-b_y) / (a_x-b_x)] [c_x] (-a_x)
600
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [(a_y-b_y)/(a_x-b_x)] [c_x]
604
601
602
+ // 9: Calculate `c_x - a_x`
603
+ dup 6
604
+ push -1
605
+ mul
605
606
add
606
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [a_y] [(a_y-b_y) / (a_x-b_x)] [c_x -a_x]
607
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [(a_y-b_y)/ (a_x-b_x)] [c_x - a_x]
607
608
609
+ // 10: Calculate final `c_y`
608
610
xxmul
611
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] a_x [(a_y-b_y)/(a_x-b_x) * (c_x -a_x)]
612
+
613
+ swap 1
614
+ swap 2
615
+ swap 3
616
+ pop 1
617
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [a_y] [(a_y-b_y)/(a_x-b_x) * (c_x -a_x)]
618
+
609
619
xxadd
610
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev [c_value]
620
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [(a_y-b_y)/(a_x-b_x) * (c_x -a_x) + a_y]
621
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem *b_index_prev [c_y]
611
622
623
+ // 11. Write c_y to *c_elem
612
624
dup 8
613
625
write_mem { EXTENSION_DEGREE }
614
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev *c_elem_next
615
-
616
626
push { - 2 * EXTENSION_DEGREE as i32 }
617
627
add
618
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev *c_elem_prev
619
-
620
628
swap 6
621
629
pop 1
622
- // _ *c_end_condition g offset (1<<round) *c_elem_prev *alphas[r] *a_elem_prev *a_index_prev *b_elem_prev *b_index_prev
623
630
624
631
recurse
625
632
@@ -779,68 +786,68 @@ impl BasicSnippet for FriSnippet {
779
786
push { -( EXTENSION_DEGREE as i32 - 1 ) }
780
787
add // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition
781
788
782
- dup 8
783
- { & domain_generator} // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g
784
- read_mem 1
785
- pop 1
789
+ dup 12
790
+ push 2
791
+ pow // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round)
786
792
787
793
dup 9
788
- { & domain_offset } // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset
794
+ { & domain_generator } // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g
789
795
read_mem 1
790
796
pop 1
791
797
792
- dup 14 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset r
793
- push 2
794
- pow // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round)
798
+ dup 10
799
+ { & domain_offset} // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset
800
+ read_mem 1
801
+ pop 1
795
802
796
- dup 7 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_elements
797
- dup 9 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_elements *c_indices
798
- read_mem 1 pop 1 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_elements c_indices_len
803
+ dup 7 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_elements
804
+ dup 9 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_elements *c_indices
805
+ read_mem 1 pop 1 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_elements c_indices_len
799
806
800
807
// Write length to *c_elements
801
- dup 0 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_elements c_indices_len c_indices_len
802
- swap 2 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) c_indices_len c_indices_len *c_elements
808
+ dup 0 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_elements c_indices_len c_indices_len
809
+ swap 2 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset c_indices_len c_indices_len *c_elements
803
810
write_mem 1
804
- swap 1 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) (*c_elements + 1) c_indices_len
811
+ swap 1 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset (*c_elements + 1) c_indices_len
805
812
806
813
push -1
807
814
add
808
815
push { EXTENSION_DEGREE }
809
816
mul
810
817
add
811
- // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word
818
+ // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word
812
819
813
820
dup 14
814
- // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *b_indices
821
+ // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *b_indices
815
822
dup 0
816
823
read_mem 1
817
824
pop 1
818
- add // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *b_index_last
825
+ add // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *b_index_last
819
826
820
827
dup 14
821
828
dup 10
822
829
read_mem 1
823
830
pop 1
824
- // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *b_index_last *b_elements c_len
831
+ // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *b_index_last *b_elements c_len
825
832
826
833
push { EXTENSION_DEGREE }
827
834
mul
828
835
add
829
- // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *b_index_last *b_elem_last
836
+ // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *b_index_last *b_elem_last
830
837
831
- dup 9 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *b_index_last *b_elem_last *alphas[r]
838
+ dup 9 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *b_index_last *b_elem_last *alphas[r]
832
839
833
840
swap 2
834
- swap 1 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *alphas[r] *b_index_last *b_elem_last
841
+ swap 1 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *alphas[r] *b_index_last *b_elem_last
835
842
836
843
dup 9
837
- dup 9 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition g offset (1<<round) *c_last_elem_first_word *alphas[r] *b_indices *b_elements *a_elements *a_indices
844
+ dup 9 // _ ... *alphas[r] *a_elements *a_indices *c_elements_end_condition (1<<round) g offset *c_last_elem_first_word *alphas[r] *b_indices *b_elements *a_elements *a_indices
838
845
839
846
swap 2
840
847
swap 1
841
848
swap 3
842
849
843
- // _ *c_end_condition g offset (1<<round) *c_elem *alphas[r] *a_elements *a_indices *b_elements *b_indices
850
+ // _ *c_end_condition (1<<round) g offset *c_elem *alphas[r] *a_elements *a_indices *b_elements *b_indices
844
851
call { compute_c_values_loop}
845
852
846
853
pop 5
@@ -1636,10 +1643,15 @@ mod test {
1636
1643
}
1637
1644
1638
1645
#[ proptest( cases = 3 ) ]
1639
- fn test_shadow ( test_case : TestCase ) {
1646
+ fn test_shadow_prop ( test_case : TestCase ) {
1640
1647
assert_behavioral_equivalence_of_fris ( test_case) ;
1641
1648
}
1642
1649
1650
+ #[ test]
1651
+ fn test_shadow_small ( ) {
1652
+ assert_behavioral_equivalence_of_fris ( TestCase :: small_case ( ) ) ;
1653
+ }
1654
+
1643
1655
#[ test]
1644
1656
fn modifying_any_element_in_vm_proof_iter_of_small_test_case_causes_verification_failure ( ) {
1645
1657
let test_case = TestCase :: small_case ( ) ;
0 commit comments