|
1 | 1 | use ark_ff::prelude::*; |
| 2 | +use ark_ff::biginteger::{S128, S64}; |
2 | 3 | use ark_std::{ |
3 | 4 | borrow::Borrow, |
4 | 5 | cfg_chunks, cfg_into_iter, cfg_iter, |
@@ -626,6 +627,102 @@ pub fn msm_i128<V: VariableBaseMSM>( |
626 | 627 | } |
627 | 628 | } |
628 | 629 |
|
| 630 | +pub fn msm_s64<V: VariableBaseMSM>( |
| 631 | + mut bases: &[V::MulBase], |
| 632 | + mut scalars: &[S64], |
| 633 | + serial: bool, |
| 634 | +) -> V { |
| 635 | + let (negative_bases, non_negative_bases): (Vec<V::MulBase>, Vec<V::MulBase>) = |
| 636 | + bases.iter().enumerate().partition_map(|(i, b)| { |
| 637 | + if !scalars[i].sign() { |
| 638 | + Either::Left(b) |
| 639 | + } else { |
| 640 | + Either::Right(b) |
| 641 | + } |
| 642 | + }); |
| 643 | + let (negative_scalars, non_negative_scalars): (Vec<u64>, Vec<u64>) = scalars |
| 644 | + .iter() |
| 645 | + .partition_map(|s| { |
| 646 | + let mag = s.magnitude_as_u64(); |
| 647 | + if !s.sign() { |
| 648 | + Either::Left(mag) |
| 649 | + } else { |
| 650 | + Either::Right(mag) |
| 651 | + } |
| 652 | + }); |
| 653 | + if serial { |
| 654 | + return msm_serial::<V, _>(&non_negative_bases, &non_negative_scalars) |
| 655 | + - msm_serial::<V, _>(&negative_bases, &negative_scalars); |
| 656 | + } else { |
| 657 | + let chunk_size = match preamble(&mut bases, &mut scalars, serial) { |
| 658 | + Some(chunk_size) => chunk_size, |
| 659 | + None => return V::zero(), |
| 660 | + }; |
| 661 | + |
| 662 | + let non_negative_msm: V = cfg_chunks!(non_negative_bases, chunk_size) |
| 663 | + .zip(cfg_chunks!(non_negative_scalars, chunk_size)) |
| 664 | + .map(|(non_negative_bases, non_negative_scalars)| { |
| 665 | + msm_serial::<V, _>(non_negative_bases, non_negative_scalars) |
| 666 | + }) |
| 667 | + .sum(); |
| 668 | + let negative_msm: V = cfg_chunks!(negative_bases, chunk_size) |
| 669 | + .zip(cfg_chunks!(negative_scalars, chunk_size)) |
| 670 | + .map(|(negative_bases, negative_scalars)| { |
| 671 | + msm_serial::<V, _>(negative_bases, negative_scalars) |
| 672 | + }) |
| 673 | + .sum(); |
| 674 | + non_negative_msm - negative_msm |
| 675 | + } |
| 676 | +} |
| 677 | + |
| 678 | +pub fn msm_s128<V: VariableBaseMSM>( |
| 679 | + mut bases: &[V::MulBase], |
| 680 | + mut scalars: &[S128], |
| 681 | + serial: bool, |
| 682 | +) -> V { |
| 683 | + let (negative_bases, non_negative_bases): (Vec<V::MulBase>, Vec<V::MulBase>) = |
| 684 | + bases.iter().enumerate().partition_map(|(i, b)| { |
| 685 | + if !scalars[i].sign() { |
| 686 | + Either::Left(b) |
| 687 | + } else { |
| 688 | + Either::Right(b) |
| 689 | + } |
| 690 | + }); |
| 691 | + let (negative_scalars, non_negative_scalars): (Vec<u128>, Vec<u128>) = scalars |
| 692 | + .iter() |
| 693 | + .partition_map(|s| { |
| 694 | + let mag = s.magnitude_as_u128(); |
| 695 | + if !s.sign() { |
| 696 | + Either::Left(mag) |
| 697 | + } else { |
| 698 | + Either::Right(mag) |
| 699 | + } |
| 700 | + }); |
| 701 | + if serial { |
| 702 | + return msm_serial::<V, _>(&non_negative_bases, &non_negative_scalars) |
| 703 | + - msm_serial::<V, _>(&negative_bases, &negative_scalars); |
| 704 | + } else { |
| 705 | + let chunk_size = match preamble(&mut bases, &mut scalars, serial) { |
| 706 | + Some(chunk_size) => chunk_size, |
| 707 | + None => return V::zero(), |
| 708 | + }; |
| 709 | + |
| 710 | + let non_negative_msm: V = cfg_chunks!(non_negative_bases, chunk_size) |
| 711 | + .zip(cfg_chunks!(non_negative_scalars, chunk_size)) |
| 712 | + .map(|(non_negative_bases, non_negative_scalars)| { |
| 713 | + msm_serial::<V, _>(non_negative_bases, non_negative_scalars) |
| 714 | + }) |
| 715 | + .sum(); |
| 716 | + let negative_msm: V = cfg_chunks!(negative_bases, chunk_size) |
| 717 | + .zip(cfg_chunks!(negative_scalars, chunk_size)) |
| 718 | + .map(|(negative_bases, negative_scalars)| { |
| 719 | + msm_serial::<V, _>(negative_bases, negative_scalars) |
| 720 | + }) |
| 721 | + .sum(); |
| 722 | + non_negative_msm - negative_msm |
| 723 | + } |
| 724 | +} |
| 725 | + |
629 | 726 | pub fn msm_u128<V: VariableBaseMSM>( |
630 | 727 | mut bases: &[V::MulBase], |
631 | 728 | mut scalars: &[u128], |
|
0 commit comments