[Ecm-commits] r2379 - trunk

cvs commits ecm-commits at lists.gforge.inria.fr
Thu Feb 7 15:08:50 CET 2013


Author: morain
Date: 2013-02-07 15:08:50 +0100 (Thu, 07 Feb 2013)
New Revision: 2379

Log:
Some cleaning + preparing the use of Montgomery curves for D=-4.


Modified:
   trunk/addlaws.c
   trunk/addlaws.h
   trunk/cmecm.c
   trunk/manyecm.c
Modified: trunk/addlaws.c
===================================================================
--- trunk/addlaws.c	2013-02-06 16:05:04 UTC (rev 2378)
+++ trunk/addlaws.c	2013-02-07 14:08:50 UTC (rev 2379)
@@ -1774,3 +1774,96 @@
 #endif
 }
 
+int *
+compute_forbidden_res(int disc)
+{
+    int *t = NULL;
+
+    if(disc == 0)
+	return NULL;
+    if(disc == -3){
+	/* we do not want p = 2 mod 3 */
+	t = (int *)malloc(3 * sizeof(int));
+	t[0] = 3;
+	t[1] = 2;
+	t[2] = -1;
+    }
+    else if(disc == -4){
+	/* we do not want p = 3 mod 4 */
+	t = (int *)malloc(3 * sizeof(int));
+	t[0] = 4;
+	t[1] = 3;
+	t[2] = -1;
+    }
+    else if(disc == -8){
+	/* (-2/p) = -1 <=> p = 5 or 7 mod 8 */
+	t = (int *)malloc(4 * sizeof(int));
+	t[0] = 8;
+	t[1] = 5;
+	t[2] = 7;
+	t[3] = -1;
+    }
+    else if(disc == -7 || disc == -11){
+	/* (-d/p) = (p/d) when d is 3 mod 4 */
+	int x, i, d = -disc;
+
+	/* initialize */
+	t = (int *)malloc(d * sizeof(int));
+	memset(t, 0, d * sizeof(int));
+	/* crude, but sufficient */
+	for(x = 0; x < d; x++)
+	    t[(x*x)%d] = 1;
+	/* x = 0 is always ok */
+	t[0] = d;
+	i = 1;
+	for(x = 1; x < d; x++)
+	    if(t[x] == 0)
+		t[i++] = x;
+	t[i++] = -1;
+#if 0
+	for(x = 0; x < i; x++)
+	    printf(" %d", t[x]);
+	printf("\n");
+#endif
+    }
+    return t;
+}
+
+/* We can probably hack so that s contains the coding of a NAF, containing
+   w, iS, S.
+*/
+int
+compute_s_4_add_sub(mpz_t s, unsigned long B1, int disc)
+{
+    mpz_t t;
+    long tp;
+    short *S;
+    int iS, Slen, w, *forbiddenres = compute_forbidden_res(disc);
+
+    mpz_init(t);
+    tp = cputime();
+    compute_s(t, B1, forbiddenres);
+    free(forbiddenres);
+    printf("# computing prod(p^e <= %lu): %ldms\n", B1, elltime(tp,cputime()));
+#if 0 /* keeping it simple for the time being */
+    mpz_set(s, t);
+#else
+    tp = cputime();
+    w = get_add_sub_w(t);
+    /* Slen = 2 * log_{2^w}(t) = 2*log_2(t)/w = 2 * 64 * size(t)/w */
+    Slen = (2 * GMP_NUMB_BITS * mpz_size(t)) / w;
+    S = (short *)malloc(Slen * sizeof(short));
+    iS = build_add_sub_chain(S, Slen, t, w);
+    printf("# NAF has %d terms (w=%d, Slen=%d): %ldms\n", iS, w, Slen,
+	   elltime(tp,cputime()));
+    if(iS == -1){
+	printf("build_NAF: Slen=%d too small\n", Slen);
+	return 0;
+    }
+    add_sub_pack(s, w, S, iS);
+    free(S);
+#endif
+    mpz_clear(t);
+    return 1;
+}
+

Modified: trunk/addlaws.h
===================================================================
--- trunk/addlaws.h	2013-02-06 16:05:04 UTC (rev 2378)
+++ trunk/addlaws.h	2013-02-07 14:08:50 UTC (rev 2379)
@@ -30,6 +30,8 @@
 
 int build_MO_chain(short *S, int Slen, mpz_t e, int w);
 int build_add_sub_chain(short *S, int Slen, mpz_t e, int w);
+int compute_s_4_add_sub(mpz_t s, unsigned long B1, int disc);
+
 int mult_by_3(mpz_t f, mpres_t x, mpres_t y, mpres_t A, mpmod_t n);
 void ec_point_init(ec_point_t P, ec_curve_t E, mpmod_t n);
 void ec_point_clear(ec_point_t P, ATTRIBUTE_UNUSED ec_curve_t E, mpmod_t n);

Modified: trunk/cmecm.c
===================================================================
--- trunk/cmecm.c	2013-02-06 16:05:04 UTC (rev 2378)
+++ trunk/cmecm.c	2013-02-07 14:08:50 UTC (rev 2379)
@@ -116,7 +116,7 @@
 	}
     }
     else if(disc == -4){
-#if 1
+#if 0
 	/* Y^2 = X^3 + 9 * X has rank 1 and a 4-torsion point */
 	/* a generator is (4 : 10 : 1) */
 	imax = (sqroots == NULL ? 1 : 4);
@@ -156,12 +156,34 @@
 	    for(i = 0; i < imax; i++)
 		mpz_init_set(tE[i]->sq[0], sqroots[0]);
 	}
-#else /* one day, use this? */
-	/* => 1/3*y^2 = x^3 + x, gen = (4/3, 10/3) */
-	tE[0]->type = ECM_EC_TYPE_MONTGOMERY;
-	mpres_set_ui(tE[0]->A, 0, n);
-	mod_from_rat_str(f, "4/3", n->orig_modulus);
-	mpres_set_z(tP[0]->x, f, n);
+#else /* Montgomery form curves, we do not need zeta4 */
+	/* Y^2 = X^3+k^2*X -> (1/k)*y^2 = x^3+x, x=X/k, y=Y/k */
+	/* k=3, gen=(4, 10) => 1/3*y^2 = x^3 + x, gen = (4/3, 10/3) */
+	/* {k, num, den} on E.W; divide by k to obtain E.M */
+	long data4[][3] = {{3, 4, 1}, {7, 16, 9}, {10, 5, 1}, {11, 4900, 9},
+			   {14, 2, 1}, {15, 36, 1}, {17, 144, 1},
+			   {19, 722500, 77841}, {23, 7056, 121},
+			   {26, 13, 9}, {31, 1787598400, 32798529},
+			   {35, 225, 4}, {39, 2025, 4},
+			   {0, 0, 0}};
+	for(i = 0; data4[i][0] != 0; i++){
+	    ec_curve_init(tE[i], ECM_EC_TYPE_MONTGOMERY, n);
+	    ec_point_init(tP[i], tE[i], n);
+	    tE[i]->disc = -4;
+	    mpz_init_set_ui(tE[i]->sq[0], 1);
+	    /* compute abscissa of generator in Montgomery form */
+	    mpz_set_ui(tE[i]->A, data4[i][1]);
+	    mpz_set_ui(f, data4[i][2]);
+	    /* do not forget to divide by k */
+	    mpz_mul_ui(f, f, data4[i][0]);
+	    if(mod_from_rat2(tP[i]->x, tE[i]->A, f, n->orig_modulus) == 0){
+		printf("# factor found during Montgomery preparation\n");
+		mpz_set(f, tP[i]->x);
+	    }
+	    mpz_set_ui(tE[i]->A, 0);
+	}
+	printf("# using %d curves in Montgomery form for disc=-4\n", i);
+	*nE = i;
 #endif
     }
     else if(disc == -7){

Modified: trunk/manyecm.c
===================================================================
--- trunk/manyecm.c	2013-02-06 16:05:04 UTC (rev 2378)
+++ trunk/manyecm.c	2013-02-07 14:08:50 UTC (rev 2379)
@@ -158,99 +158,6 @@
     }
 }
 
-int *
-compute_forbidden_res(int disc)
-{
-    int *t = NULL;
-
-    if(disc == 0)
-	return NULL;
-    if(disc == -3){
-	/* we do not want p = 2 mod 3 */
-	t = (int *)malloc(3 * sizeof(int));
-	t[0] = 3;
-	t[1] = 2;
-	t[2] = -1;
-    }
-    else if(disc == -4){
-	/* we do not want p = 3 mod 4 */
-	t = (int *)malloc(3 * sizeof(int));
-	t[0] = 4;
-	t[1] = 3;
-	t[2] = -1;
-    }
-    else if(disc == -8){
-	/* (-2/p) = -1 <=> p = 5 or 7 mod 8 */
-	t = (int *)malloc(4 * sizeof(int));
-	t[0] = 8;
-	t[1] = 5;
-	t[2] = 7;
-	t[3] = -1;
-    }
-    else if(disc == -7 || disc == -11){
-	/* (-d/p) = (p/d) when d is 3 mod 4 */
-	int x, i, d = -disc;
-
-	/* initialize */
-	t = (int *)malloc(d * sizeof(int));
-	memset(t, 0, d * sizeof(int));
-	/* crude, but sufficient */
-	for(x = 0; x < d; x++)
-	    t[(x*x)%d] = 1;
-	/* x = 0 is always ok */
-	t[0] = d;
-	i = 1;
-	for(x = 1; x < d; x++)
-	    if(t[x] == 0)
-		t[i++] = x;
-	t[i++] = -1;
-#if 0
-	for(x = 0; x < i; x++)
-	    printf(" %d", t[x]);
-	printf("\n");
-#endif
-    }
-    return t;
-}
-
-/* We can probably hack so that s contains the coding of a NAF, containing
-   w, iS, S.
-*/
-int
-compute_s_4_add_sub(mpz_t s, unsigned long B1, int disc)
-{
-    mpz_t t;
-    long tp;
-    short *S;
-    int iS, Slen, w, *forbiddenres = compute_forbidden_res(disc);
-
-    mpz_init(t);
-    tp = cputime();
-    compute_s(t, B1, forbiddenres);
-    free(forbiddenres);
-    printf("# computing prod(p^e <= %lu): %ldms\n", B1, elltime(tp,cputime()));
-#if 0 /* keeping it simple for the time being */
-    mpz_set(s, t);
-#else
-    tp = cputime();
-    w = get_add_sub_w(t);
-    /* Slen = 2 * log_{2^w}(t) = 2*log_2(t)/w = 2 * 64 * size(t)/w */
-    Slen = (2 * GMP_NUMB_BITS * mpz_size(t)) / w;
-    S = (short *)malloc(Slen * sizeof(short));
-    iS = build_add_sub_chain(S, Slen, t, w);
-    printf("# NAF has %d terms (w=%d, Slen=%d): %ldms\n", iS, w, Slen,
-	   elltime(tp,cputime()));
-    if(iS == -1){
-	printf("build_NAF: Slen=%d too small\n", Slen);
-	return 0;
-    }
-    add_sub_pack(s, w, S, iS);
-    free(S);
-#endif
-    mpz_clear(t);
-    return 1;
-}
-
 /* TODO: better control of B2 + dichotomy (cf. #B2) */
 int
 one_curve_at_a_time(mpz_t f, char *ok, ec_curve_t *tE, ec_point_t *tP, int nE,




More information about the Ecm-commits mailing list