@@ -484,6 +484,71 @@ inline ProjPoint<Curve> shamir_multiply(const typename Curve::uint_type& u,
484484 return r;
485485}
486486
487+ template <typename Curve>
488+ inline ProjPoint<Curve> shamir_multiply (const typename Curve::uint_type& u1,
489+ const AffinePoint<Curve>& p1, const typename Curve::uint_type& u2, const AffinePoint<Curve>& p2,
490+ const typename Curve::uint_type& u3, const AffinePoint<Curve>& p3,
491+ const typename Curve::uint_type& u4, const AffinePoint<Curve>& p4)
492+ {
493+ ProjPoint<Curve> r;
494+
495+ const auto w = u1 | u2 | u3 | u4;
496+ const auto bit_width = sizeof (w) * 8 - intx::clz (w);
497+ if (bit_width == 0 )
498+ return r;
499+
500+ const auto p1p2 = add (p1, p2);
501+ const auto p1p3 = add (p1, p3);
502+ const auto p1p4 = add (p1, p4);
503+ const auto p2p3 = add (p2, p3);
504+ const auto p2p4 = add (p2, p4);
505+ const auto p3p4 = add (p3, p4);
506+
507+ const auto p1p2p3 = add (p1p2, p3);
508+ const auto p1p2p4 = add (p1p2, p4);
509+
510+ const auto p1p3p4 = add (p1p3, p4);
511+
512+ const auto p2p3p4 = add (p2p3, p4);
513+
514+ const auto p1p2p3p4 = add (p1p2, p3p4);
515+
516+ const AffinePoint<Curve>* const points[]{
517+ nullptr ,
518+ &p1, // 0001
519+ &p2, // 0010
520+ &p1p2, // 0011
521+ &p3, // 0100
522+ &p1p3, // 0101
523+ &p2p3, // 0110
524+ &p1p2p3, // 0111
525+ &p4, // 1000
526+ &p1p4, // 1001
527+ &p2p4, // 1010
528+ &p1p2p4, // 1011
529+ &p3p4, // 1100
530+ &p1p3p4, // 1101
531+ &p2p3p4, // 1110
532+ &p1p2p3p4, // 1111
533+ };
534+
535+ for (auto i = bit_width; i != 0 ; --i)
536+ {
537+ r = dbl (r);
538+
539+ const auto u1_bit = bit_test (u1, i - 1 );
540+ const auto u2_bit = bit_test (u2, i - 1 );
541+ const auto u3_bit = bit_test (u3, i - 1 );
542+ const auto u4_bit = bit_test (u4, i - 1 );
543+ const auto idx = u1_bit | (u2_bit << 1 ) | (u3_bit << 2 ) | (u4_bit << 3 );
544+ if (idx == 0 )
545+ continue ;
546+ r = add (r, *points[idx]);
547+ }
548+
549+ return r;
550+ }
551+
487552// Decomposes scalar k into k₁ and k₂ such that k₁ + k₂λ ≡ k mod n
488553// Returns ((is_negative, k1), (is_negative, k2))
489554template <typename ConfigT, typename UIntT>
0 commit comments