@@ -233,6 +233,15 @@ inline AffinePoint<Curve> to_affine(const ProjPoint<Curve>& p) noexcept
233233 return {p.x * zz_inv, p.y * zzz_inv};
234234}
235235
236+ template <typename Curve>
237+ inline AffinePoint<Curve> to_affine (const ProjPoint<Curve>& p, const auto & z_inv) noexcept
238+ {
239+ // This works correctly for the point at infinity (z == 0) because then z_inv == 0.
240+ const auto zz_inv = z_inv * z_inv;
241+ const auto zzz_inv = zz_inv * z_inv;
242+ return {p.x * zz_inv, p.y * zzz_inv};
243+ }
244+
236245// / Elliptic curve point addition in affine coordinates.
237246// /
238247// / Computes P ⊕ Q for two points in affine coordinates on the elliptic curve.
@@ -588,23 +597,77 @@ inline ProjPoint<Curve> shamir_multiply(const typename Curve::uint_type& u1,
588597
589598 const auto jp1p2p3p4 = add (jp1p2, jp3p4);
590599
600+
601+ const auto & z_12 = jp1p2.z ;
602+ const auto & z_13 = jp1p3.z ;
603+ const auto & z_14 = jp1p4.z ;
604+ const auto & z_23 = jp2p3.z ;
605+ const auto & z_24 = jp2p4.z ;
606+ const auto & z_34 = jp3p4.z ;
607+ const auto & z_123 = jp1p2p3.z ;
608+ const auto & z_124 = jp1p2p4.z ;
609+ const auto & z_134 = jp1p3p4.z ;
610+ const auto & z_234 = jp2p3p4.z ;
611+ const auto & z_1234 = jp1p2p3p4.z ;
612+
613+ const auto z_12_13 = z_12 * z_13;
614+ const auto z_12_13_14 = z_12_13 * z_14;
615+ const auto z_12_13_14_23 = z_12_13_14 * z_23;
616+ const auto z_12_13_14_23_24 = z_12_13_14_23 * z_24;
617+ const auto z_12_13_14_23_24_34 = z_12_13_14_23_24 * z_34;
618+ const auto z_12_13_14_23_24_34_123 = z_12_13_14_23_24_34 * z_123;
619+ const auto z_12_13_14_23_24_34_123_124 = z_12_13_14_23_24_34_123 * z_124;
620+ const auto z_12_13_14_23_24_34_123_124_134 = z_12_13_14_23_24_34_123_124 * z_134;
621+ const auto z_12_13_14_23_24_34_123_124_134_234 = z_12_13_14_23_24_34_123_124_134 * z_234;
622+ const auto z_12_13_14_23_24_34_123_124_134_234_1234 =
623+ z_12_13_14_23_24_34_123_124_134_234 * z_1234;
624+
625+ const auto i_12_13_14_23_24_34_123_124_134_234_1234 =
626+ 1 / z_12_13_14_23_24_34_123_124_134_234_1234;
627+ const auto i_1234 =
628+ i_12_13_14_23_24_34_123_124_134_234_1234 * z_12_13_14_23_24_34_123_124_134_234;
629+ const auto i_12_13_14_23_24_34_123_124_134_234 =
630+ i_12_13_14_23_24_34_123_124_134_234_1234 * z_1234;
631+ const auto i_234 = i_12_13_14_23_24_34_123_124_134_234 * z_12_13_14_23_24_34_123_124_134;
632+ const auto i_12_13_14_23_24_34_123_124_134 = i_12_13_14_23_24_34_123_124_134_234 * z_234;
633+ const auto i_134 = i_12_13_14_23_24_34_123_124_134 * z_12_13_14_23_24_34_123_124;
634+ const auto i_12_13_14_23_24_34_123_124 = i_12_13_14_23_24_34_123_124_134 * z_134;
635+ const auto i_124 = i_12_13_14_23_24_34_123_124 * z_12_13_14_23_24_34_123;
636+ const auto i_12_13_14_23_24_34_123 = i_12_13_14_23_24_34_123_124 * z_124;
637+ const auto i_123 = i_12_13_14_23_24_34_123 * z_12_13_14_23_24_34;
638+ const auto i_12_13_14_23_24_34 = i_12_13_14_23_24_34_123 * z_123;
639+ const auto i_34 = i_12_13_14_23_24_34 * z_12_13_14_23_24;
640+ const auto i_12_13_14_23_24 = i_12_13_14_23_24_34 * z_34;
641+ const auto i_24 = i_12_13_14_23_24 * z_12_13_14_23;
642+ const auto i_12_13_14_23 = i_12_13_14_23_24 * z_24;
643+ const auto i_23 = i_12_13_14_23 * z_12_13_14;
644+ const auto i_12_13_14 = i_12_13_14_23 * z_23;
645+ const auto i_14 = i_12_13_14 * z_12_13;
646+ const auto i_12_13 = i_12_13_14 * z_14;
647+ const auto i_13 = i_12_13 * z_12;
648+ const auto i_12 = i_12_13 * z_13;
649+
650+
651+ // auto inv = 1 / jp1p2.z;
652+ // const auto p1p2 = to_affine(jp1p2, inv);
653+
591654 const AffinePoint<Curve> points[]{
592655 AffinePoint<Curve>{},
593- p1, // 0001
594- p2, // 0010
595- to_affine (jp1p2), // 0011
596- p3, // 0100
597- to_affine (jp1p3), // 0101
598- to_affine (jp2p3), // 0110
599- to_affine (jp1p2p3), // 0111
600- p4, // 1000
601- to_affine (jp1p4), // 1001
602- to_affine (jp2p4), // 1010
603- to_affine (jp1p2p4), // 1011
604- to_affine (jp3p4), // 1100
605- to_affine (jp1p3p4), // 1101
606- to_affine (jp2p3p4), // 1110
607- to_affine (jp1p2p3p4), // 1111
656+ p1, // 0001
657+ p2, // 0010
658+ to_affine (jp1p2, i_12), // 0011
659+ p3, // 0100
660+ to_affine (jp1p3, i_13), // 0101
661+ to_affine (jp2p3, i_23), // 0110
662+ to_affine (jp1p2p3, i_123), // 0111
663+ p4, // 1000
664+ to_affine (jp1p4, i_14), // 1001
665+ to_affine (jp2p4, i_24), // 1010
666+ to_affine (jp1p2p4, i_124), // 1011
667+ to_affine (jp3p4, i_34), // 1100
668+ to_affine (jp1p3p4, i_134), // 1101
669+ to_affine (jp2p3p4, i_234), // 1110
670+ to_affine (jp1p2p3p4, i_1234 ), // 1111
608671 };
609672
610673 for (auto i = bit_width; i != 0 ; --i)
0 commit comments