[libmath-prime-util-perl] 14/18: Tweak projective EC point

Partha P. Mukherjee ppm-guest at moszumanska.debian.org
Thu May 21 18:48:04 UTC 2015


This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.26
in repository libmath-prime-util-perl.

commit 34da9f2d7a4c9cf4c601dc75c1e2e3dda21df4f2
Author: Dana Jacobsen <dana at acm.org>
Date:   Fri Apr 19 20:33:51 2013 -0700

    Tweak projective EC point
---
 lib/Math/Prime/Util/ECProjectivePoint.pm | 108 +++++++++++++++----------------
 lib/Math/Prime/Util/PP.pm                |  24 +++----
 2 files changed, 63 insertions(+), 69 deletions(-)

diff --git a/lib/Math/Prime/Util/ECProjectivePoint.pm b/lib/Math/Prime/Util/ECProjectivePoint.pm
index 1d062d8..c83110e 100644
--- a/lib/Math/Prime/Util/ECProjectivePoint.pm
+++ b/lib/Math/Prime/Util/ECProjectivePoint.pm
@@ -17,20 +17,18 @@ BEGIN {
 # in projective coordinates.
 
 sub new {
-  my ($class, $a, $b, $n, $x, $z) = @_;
-  $a = Math::BigInt->new("$a") unless ref($a) eq 'Math::BigInt';
-  $b = Math::BigInt->new("$b") unless ref($b) eq 'Math::BigInt';
+  my ($class, $c, $n, $x, $z) = @_;
+  $c = Math::BigInt->new("$c") unless ref($c) eq 'Math::BigInt';
   $n = Math::BigInt->new("$n") unless ref($n) eq 'Math::BigInt';
   $x = Math::BigInt->new("$x") unless ref($x) eq 'Math::BigInt';
   $z = Math::BigInt->new("$z") unless ref($z) eq 'Math::BigInt';
 
   croak "n must be >= 2" unless $n >= 2;
-  $a->bmod($n);
-  $b->bmod($n);
+  $c->bmod($n);
 
   my $self = {
-    a => $a,
-    b => $b,
+    c => $c,
+    d => ($c + 2) >> 2,
     n => $n,
     x => $x,
     z => $z,
@@ -40,39 +38,39 @@ sub new {
   bless $self, $class;
   return $self;
 }
+ 
+sub _addx {
+  my ($x1, $x2, $xin, $n) = @_;
 
-sub _add {
-  my ($self, $x2, $z2, $x1, $z1, $xin, $n) = @_;
+  my $u = ($x2 - 1) * ($x1 + 1);
+  my $v = ($x2 + 1) * ($x1 - 1);
 
-  my $u = ( ($x2 - $z2) * ($x1 + $z1) ) % $n;
-  my $v = ( ($x2 + $z2) * ($x1 - $z1) ) % $n;
+  my $upv2 = ($u + $v) ** 2;
+  my $umv2 = ($u - $v) ** 2;
 
-  my $puv = $u + $v;
-  my $muv = $u - $v;
-
-  return ( ($puv*$puv) % $n, ($muv*$muv * $xin) % $n );
+  return ( $upv2 % $n, ($umv2*$xin) % $n );
 }
 
 sub _add3 {
-  my ($self, $x1, $z1, $x2, $z2, $xin, $zin, $n) = @_;
+  my ($x1, $z1, $x2, $z2, $xin, $zin, $n) = @_;
 
-  my $u = (($x2 - $z2) * ($x1 + $z1) ) % $n;
-  my $v = (($x2 + $z2) * ($x1 - $z1) ) % $n;
+  my $u = ($x2 - $z2) * ($x1 + $z1);
+  my $v = ($x2 + $z2) * ($x1 - $z1);
 
-  my $upv2 = (($u+$v) * ($u+$v)) % $n;
-  my $umv2 = (($u-$v) * ($u-$v)) % $n;
+  my $upv2 = ($u + $v) ** 2;
+  my $umv2 = ($u - $v) ** 2;
 
   return ( ($upv2*$zin) % $n, ($umv2*$xin) % $n );
 }
 
 sub _double {
-  my ($self, $x, $z, $n) = @_;
+  my ($x, $z, $n, $d) = @_;
 
-  my $u = $x + $z;   $u = ($u * $u) % $n;
-  my $v = $x - $z;   $v = ($v * $v) % $n;
+  my $u = ($x + $z) ** 2;
+  my $v = ($x - $z) ** 2;
   my $w = $u - $v;
-
-  return ( ($u*$v)%$n , ($w*($v+$w*$self->{'b'}))%$n );
+  my $t = $d * $w + $v;
+  return ( ($u * $v) % $n  ,  ($w * $t) % $n );
 }
 
 sub mul {
@@ -80,6 +78,7 @@ sub mul {
   my $x = $self->{'x'};
   my $z = $self->{'z'};
   my $n = $self->{'n'};
+  my $d = $self->{'d'};
 
   my ($x1, $x2, $z1, $z2);
 
@@ -87,28 +86,28 @@ sub mul {
   my $l = -1;
   while ($r != 1) { $r >>= 1; $l++ }
   if ($k & (1 << $l)) {
-    ($x2, $z2) = $self->_double($x, $z, $n);
-    ($x1, $z1) = $self->_add3($x2, $z2, $x, $z, $x, $z, $n);
-    ($x2, $z2) = $self->_double($x2, $z2, $n);
+    ($x2, $z2) = _double($x, $z, $n, $d);
+    ($x1, $z1) = _add3($x2, $z2, $x, $z, $x, $z, $n);
+    ($x2, $z2) = _double($x2, $z2, $n, $d);
   } else {
-    ($x1, $z1) = $self->_double($x, $z, $n);
-    ($x2, $z2) = $self->_add3($x, $z, $x1, $z1, $x, $z, $n);
+    ($x1, $z1) = _double($x, $z, $n, $d);
+    ($x2, $z2) = _add3($x, $z, $x1, $z1, $x, $z, $n);
   }
   $l--;
   while ($l >= 1) {
     if ($k & (1 << $l)) {
-      ($x1, $z1) = $self->_add3($x1, $z1, $x2, $z2, $x, $z, $n);
-      ($x2, $z2) = $self->_double($x2, $z2, $n);
+      ($x1, $z1) = _add3($x1, $z1, $x2, $z2, $x, $z, $n);
+      ($x2, $z2) = _double($x2, $z2, $n, $d);
     } else {
-      ($x2, $z2) = $self->_add3($x2, $z2, $x1, $z1, $x, $z, $n);
-      ($x1, $z1) = $self->_double($x1, $z1, $n);
+      ($x2, $z2) = _add3($x2, $z2, $x1, $z1, $x, $z, $n);
+      ($x1, $z1) = _double($x1, $z1, $n, $d);
     }
     $l--;
   }
   if ($k & 1) {
-    ($x, $z) = $self->_double($x2, $z2, $n);
+    ($x, $z) = _double($x2, $z2, $n, $d);
   } else {
-    ($x, $z) = $self->_add3($x2, $z2, $x1, $z1, $x, $z, $n);
+    ($x, $z) = _add3($x2, $z2, $x1, $z1, $x, $z, $n);
   }
 
   $self->{'x'} = $x;
@@ -121,20 +120,19 @@ sub add {
   croak "add takes a EC point"
     unless ref($other) eq 'Math::Prime::Util::ECProjectivePoint';
   croak "second point is not on the same curve"
-    unless $self->{'a'} == $other->{'a'} &&
-           $self->{'b'} == $other->{'b'} &&
+    unless $self->{'c'} == $other->{'c'} &&
            $self->{'n'} == $other->{'n'};
 
-  ($self->{'x'}, $self->{'z'}) = $self->_add3($self->{'x'}, $self->{'z'},
-                                              $other->{'x'}, $other->{'z'},
-                                              $self->{'x'}, $self->{'z'},
-                                              $self->{'n'});
+  ($self->{'x'}, $self->{'z'}) = _add3($self->{'x'}, $self->{'z'},
+                                       $other->{'x'}, $other->{'z'},
+                                       $self->{'x'}, $self->{'z'},
+                                       $self->{'n'});
   return $self;
 }
 
 sub double {
   my ($self) = @_;
-  ($self->{'x'}, $self->{'z'}) = $self->_double($self->{'x'}, $self->{'z'}, $self->{'n'});
+  ($self->{'x'}, $self->{'z'}) = _double($self->{'x'}, $self->{'z'}, $self->{'n'}, $self->{'d'});
   return $self;
 }
 
@@ -164,8 +162,8 @@ sub normalize {
   return $self;
 }
 
-sub a { return shift->{'a'}; }
-sub b { return shift->{'b'}; }
+sub c { return shift->{'c'}; }
+sub d { return shift->{'d'}; }
 sub n { return shift->{'n'}; }
 sub x { return shift->{'x'}; }
 sub z { return shift->{'z'}; }
@@ -179,7 +177,7 @@ sub is_infinity {
 sub copy {
   my $self = shift;
   return Math::Prime::Util::ECProjectivePoint->new(
-    $self->{'a'}, $self->{'b'}, $self->{'n'}, $self->{'x'}, $self->{'z'});
+    $self->{'c'}, $self->{'n'}, $self->{'x'}, $self->{'z'});
 }
 
 1;
@@ -207,7 +205,7 @@ Version 0.26
 =head1 SYNOPSIS
 
   # Create a point on a curve (a,b,n) with coordinates 0,1
-  my $ECP = Math::Prime::Util::ECProjectivePoint->new($a, $b, $n, 0, 1);
+  my $ECP = Math::Prime::Util::ECProjectivePoint->new($c, $n, 0, 1);
 
   # scalar multiplication by k.
   $ECP->mul($k)
@@ -228,17 +226,19 @@ To write.
 
 =head2 new
 
-  $point = Math::Prime::Util::ECProjectivePoint->new(a, b);
-
-Returns a new curve defined by a and b.
+  $point = Math::Prime::Util::ECProjectivePoint->new(c, n, x, z);
 
-=head2 a
+Returns a new point on the curve defined by the Montgomery parameter c.
 
-=head2 b
+=head2 c
 
 =head2 n
 
-Returns the C<a>, C<b>, or C<n> values that describe the curve.
+Returns the C<c>, C<d>, or C<n> values that describe the curve.
+
+=head2 d
+
+Returns the precalculated value of C<int( (c + 2) / 4 )>.
 
 =head2 x
 
@@ -248,7 +248,7 @@ Returns the C<x> or C<z> values that define the point on the curve.
 
 =head2 f
 
-Returns a possible factor found during EC multiplication.
+Returns a possible factor found after L</normalize>.
 
 =head2 add
 
diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index f8f75a8..34a2ee1 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -1152,7 +1152,7 @@ my @_fsublist = (
   sub { ecm_factor    (shift,    10_000,  50_000, 10) },
   sub { holf_factor   (shift, 256*1024, $_holf_r); $_holf_r += 256*1024; },
   sub { pminus1_factor(shift,20_000_000); },
-  sub { ecm_factor    (shift,   100_000, 400_000, 10) },
+  sub { ecm_factor    (shift,   100_000, 800_000, 10) },
   sub { holf_factor   (shift, 512*1024, $_holf_r); $_holf_r += 512*1024; },
   sub { pbrent_factor (shift, 2048*1024, 13) },
   sub { holf_factor   (shift, 2048*1024, $_holf_r); $_holf_r += 2048*1024; },
@@ -1646,7 +1646,7 @@ sub ecm_factor {
     return @factors;
   }
 
-  $B2 = 1*$B1 unless defined $B2;
+  $B2 = 10*$B1 unless defined $B2;
   my $sqrt_b1 = int(sqrt($B1)+1);
 
   # Affine code.  About 3x slower than the projective, and no stage 2.
@@ -1690,8 +1690,7 @@ sub ecm_factor {
   my $irandf = Math::Prime::Util::_get_rand_func();
 
   foreach my $curve (1 .. $ncurves) {
-    my $sigma;
-    do { $sigma = $irandf->($n-1) } while ($sigma <= 5);
+    my $sigma = $irandf->($n-1-6) + 6;
     my ($u, $v) = ( ($sigma*$sigma - 5) % $n, (4 * $sigma) % $n );
     my ($x, $z) = ( ($u*$u*$u) % $n,  ($v*$v*$v) % $n );
     my $b = (4 * $x * $v) % $n;
@@ -1702,14 +1701,8 @@ sub ecm_factor {
     return _found_factor($f,$n, "ECM B1=$B1 curve $curve", @factors) if $f != 1;
     $u = $b->copy->bmodinv($n);
     $a = (($a*$u) - 2) % $n;
-    $b = $a+2;
-    $b = ( (($b % 2) == 0) ? $b  : $b+$n ) >> 1;
-    $b = ( (($b % 2) == 0) ? $b  : $b+$n ) >> 1;
-    #$u = $z->copy->bmodinv($n);
-    #$x = ($x * $u) % $n;
-    #$z = $n-$n+1;
-
-    my $ECP = Math::Prime::Util::ECProjectivePoint->new($a, $b, $n, $x, $z);
+
+    my $ECP = Math::Prime::Util::ECProjectivePoint->new($a, $n, $x, $z);
     my $fm = $n-$n+1;
     my $i = 15;
 
@@ -1743,14 +1736,15 @@ sub ecm_factor {
         return _found_factor($f, $n, "ECM S2 B1=$B1 curve $curve");
       }
       my $S2x = $S2P->x;
+      my $S2d = $S2P->d;
       my @nqx = ($n-$n, $S2x);
 
       foreach my $i (2 .. 2*$D) {
         my($x2, $z2);
         if ($i % 2) {
-          ($x2, $z2) = $S2P->_add($nqx[($i+1)/2], $one, $nqx[($i-1)/2], $one, $S2x, $n);
+          ($x2, $z2) = Math::Prime::Util::ECProjectivePoint::_addx($nqx[($i-1)/2], $nqx[($i+1)/2], $S2x, $n);
         } else {
-          ($x2, $z2) = $S2P->_double($nqx[$i/2], $one, $n);
+          ($x2, $z2) = Math::Prime::Util::ECProjectivePoint::_double($nqx[$i/2], $one, $n, $S2d);
         }
         $nqx[$i] = $x2;
         #($f, $u, undef) = _extended_gcd($z2, $n);
@@ -1770,7 +1764,7 @@ sub ecm_factor {
       while ($m < ($B2+$D)) {
         if ($m != 1) {
           my $oldx = $S2x;
-          my ($x1, $z1) = $S2P->_add($S2x, $one, $nqx[2*$D], $one, $x, $n);
+          my ($x1, $z1) = Math::Prime::Util::ECProjectivePoint::_addx($nqx[2*$D], $S2x, $x, $n);
           $f = Math::BigInt::bgcd( $z1, $n );
           last if $f != 1;
           $u = $z1->copy->bmodinv($n);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git



More information about the Pkg-perl-cvs-commits mailing list