@@ -16,6 +16,7 @@ pub mod stream_pippenger;
1616pub use stream_pippenger:: * ;
1717
1818use super :: ScalarMul ;
19+ use ark_ff:: biginteger:: { U128OrI128 , U64OrI64 } ;
1920
2021#[ cfg( all(
2122 target_has_atomic = "8" ,
@@ -644,6 +645,106 @@ pub fn msm_u128<V: VariableBaseMSM>(
644645 . sum ( )
645646}
646647
648+ /// MSM over mixed-signed 64-bit integers using the small-scalar engine.
649+ pub fn msm_u64_or_i64 < V : VariableBaseMSM > (
650+ mut bases : & [ V :: MulBase ] ,
651+ mut scalars : & [ U64OrI64 ] ,
652+ serial : bool ,
653+ ) -> V {
654+ // Partition by sign for better locality; build magnitudes as u64.
655+ let ( negative_bases, non_negative_bases) : ( Vec < V :: MulBase > , Vec < V :: MulBase > ) =
656+ bases
657+ . iter ( )
658+ . enumerate ( )
659+ . partition_map ( |( i, b) | if scalars[ i] . is_negative ( ) {
660+ Either :: Left ( b)
661+ } else {
662+ Either :: Right ( b)
663+ } ) ;
664+ let ( negative_scalars, non_negative_scalars) : ( Vec < u64 > , Vec < u64 > ) = scalars
665+ . iter ( )
666+ . partition_map ( |s| match * s {
667+ U64OrI64 :: Unsigned ( u) => Either :: Right ( u) ,
668+ U64OrI64 :: Signed ( v) => {
669+ if v < 0 {
670+ Either :: Left ( v. unsigned_abs ( ) )
671+ } else {
672+ Either :: Right ( v as u64 )
673+ }
674+ }
675+ } ) ;
676+
677+ if serial {
678+ return msm_serial :: < V , _ > ( & non_negative_bases, & non_negative_scalars)
679+ - msm_serial :: < V , _ > ( & negative_bases, & negative_scalars) ;
680+ } else {
681+ let chunk_size = match preamble ( & mut bases, & mut scalars, serial) {
682+ Some ( chunk_size) => chunk_size,
683+ None => return V :: zero ( ) ,
684+ } ;
685+
686+ let non_negative_msm: V = cfg_chunks ! ( non_negative_bases, chunk_size)
687+ . zip ( cfg_chunks ! ( non_negative_scalars, chunk_size) )
688+ . map ( |( b, s) | msm_serial :: < V , _ > ( b, s) )
689+ . sum ( ) ;
690+ let negative_msm: V = cfg_chunks ! ( negative_bases, chunk_size)
691+ . zip ( cfg_chunks ! ( negative_scalars, chunk_size) )
692+ . map ( |( b, s) | msm_serial :: < V , _ > ( b, s) )
693+ . sum ( ) ;
694+ non_negative_msm - negative_msm
695+ }
696+ }
697+
698+ /// MSM over mixed-signed 128-bit integers.
699+ pub fn msm_u128_or_i128 < V : VariableBaseMSM > (
700+ mut bases : & [ V :: MulBase ] ,
701+ mut scalars : & [ U128OrI128 ] ,
702+ serial : bool ,
703+ ) -> V {
704+ // u128 path with sign partitioning.
705+ let ( negative_bases, non_negative_bases) : ( Vec < V :: MulBase > , Vec < V :: MulBase > ) = bases
706+ . iter ( )
707+ . enumerate ( )
708+ . partition_map ( |( i, b) | if match scalars[ i] { U128OrI128 :: Signed ( v) if v < 0 => true , _ => false } {
709+ Either :: Left ( b)
710+ } else {
711+ Either :: Right ( b)
712+ } ) ;
713+ let ( negative_scalars, non_negative_scalars) : ( Vec < u128 > , Vec < u128 > ) = scalars
714+ . iter ( )
715+ . partition_map ( |s| match * s {
716+ U128OrI128 :: Unsigned ( u) => Either :: Right ( u) ,
717+ U128OrI128 :: Signed ( v) => {
718+ let abs = v. unsigned_abs ( ) ;
719+ if v < 0 {
720+ Either :: Left ( abs)
721+ } else {
722+ Either :: Right ( abs)
723+ }
724+ }
725+ } ) ;
726+
727+ if serial {
728+ msm_serial :: < V , _ > ( & non_negative_bases, & non_negative_scalars)
729+ - msm_serial :: < V , _ > ( & negative_bases, & negative_scalars)
730+ } else {
731+ let chunk_size = match preamble ( & mut bases, & mut scalars, serial) {
732+ Some ( chunk_size) => chunk_size,
733+ None => return V :: zero ( ) ,
734+ } ;
735+
736+ let non_negative_msm: V = cfg_chunks ! ( non_negative_bases, chunk_size)
737+ . zip ( cfg_chunks ! ( non_negative_scalars, chunk_size) )
738+ . map ( |( b, s) | msm_serial :: < V , _ > ( b, s) )
739+ . sum ( ) ;
740+ let negative_msm: V = cfg_chunks ! ( negative_bases, chunk_size)
741+ . zip ( cfg_chunks ! ( negative_scalars, chunk_size) )
742+ . map ( |( b, s) | msm_serial :: < V , _ > ( b, s) )
743+ . sum ( ) ;
744+ non_negative_msm - negative_msm
745+ }
746+ }
747+
647748// Compute msm using windowed non-adjacent form
648749fn msm_bigint_wnaf_parallel < V : VariableBaseMSM > (
649750 bases : & [ V :: MulBase ] ,
0 commit comments