www.pudn.com > calc.rar > cubicr.c
/* cubicr.c */ #include#include #include "integer.h" #include "fun.h" void ADD_CUBICR(MPR *X1, MPR *Y1, MPR *X2, MPR *Y2, MPR **Xptr, MPR **Yptr, MPR *A1, MPR *A2, MPR *A3, MPR *A4, MPR *A6) /* * (*Xptr,*Yptr) is the sum of the two points (X1,Y1) and (X2,Y2) on the * elliptic curve y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6. * See D. Husemoller, Elliptic curves, page 25. */ { MPR *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5,*Tmp6,*Tmp7,*M; if (X1 == NULL && X2 != NULL) { *Xptr = COPYR(X2); *Yptr = COPYR(Y2); return; } if (X2 == NULL && X1 != NULL) { *Xptr = COPYR(X1); *Yptr = COPYR(Y1); return; } if (X2 == NULL && X1 == NULL) { *Xptr = (MPR *)NULL; *Yptr = (MPR *)NULL; return; } if (EQUALR(X1, X2)) { if (!EQUALR(Y1, Y2)) { *Xptr = (MPR *)NULL; *Yptr = (MPR *)NULL; return; } Tmp2 = ADDR(Y1, Y1); Tmp3 = MULTABCR(A3, A1, X1); Tmp7 = ADDR(Tmp3, Tmp2); FREEMPR(Tmp2); FREEMPR(Tmp3); if (EQZEROR(Tmp7)) { *Xptr = (MPR *)NULL; *Yptr = (MPR *)NULL; FREEMPR(Tmp7); return; } else { Tmp1 = BUILDMPR(); Tmp1->N = CHANGE(2); Tmp1->D = ONEI(); Tmp2 = ADDR(X1, A2); Tmp3 = MULTR(Tmp1, Tmp2); FREEMPR(Tmp1); FREEMPR(Tmp2); Tmp4 = ADDR(X1, Tmp3); FREEMPR(Tmp3); Tmp5 = MULTR(X1, Tmp4); FREEMPR(Tmp4); Tmp = Tmp5; Tmp5 = ADDR(Tmp5, A4); FREEMPR(Tmp); Tmp6 = MULTR(A1, Y1); Tmp = SUBR(Tmp5, Tmp6); FREEMPR(Tmp5); FREEMPR(Tmp6); M = RATIOR(Tmp, Tmp7); FREEMPR(Tmp); FREEMPR(Tmp7); } } else { Tmp1 = SUBR(X1, X2); Tmp2 = SUBR(Y1, Y2); M = RATIOR(Tmp2, Tmp1); FREEMPR(Tmp1); FREEMPR(Tmp2); } Tmp1 = ADDR(M, A1); Tmp = Tmp1; Tmp1 = MULTR(Tmp1, M); FREEMPR(Tmp); Tmp2 = ADDR(X1, X2); Tmp = Tmp2; Tmp2 = ADDR(Tmp2, A2); FREEMPR(Tmp); Tmp = Tmp2; Tmp2 = MINUSR(Tmp2); FREEMPR(Tmp); *Xptr = ADDR(Tmp1, Tmp2); FREEMPR(Tmp1); FREEMPR(Tmp2); Tmp1 = SUBR(X1, *Xptr); Tmp = Tmp1; Tmp1 = MULTR(M, Tmp1); FREEMPR(Tmp); Tmp2 = MULTABCR(A3, A1, *Xptr); Tmp = Tmp2; Tmp2 = ADDR(Y1, Tmp2); FREEMPR(Tmp); Tmp = Tmp2; Tmp2 = MINUSR(Tmp2); FREEMPR(Tmp); *Yptr = ADDR(Tmp1, Tmp2); FREEMPR(Tmp1); FREEMPR(Tmp2); FREEMPR(M); return; } void ADD_CUBICRX() /* * Front end for ADD_CUBICR(). */ { MPR *X1, *X2, *X3, *Y1, *Y2, *Y3, *A1, *A2, *A3, *A4, *A6; MPR *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5; MPR *TWO, *THREE, *FOUR, *NINE, *DELTA, *B2, *B4, *B6, *B8; unsigned int u; printf("Calculating the elliptic curve sum of (X1,Y1) and (X2,Y2)\n"); printf("for the nonsingular elliptic curve y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6.\n"); printf("Enter A1: "); A1 = INPUTR(&u); printf("Enter A2: "); A2 = INPUTR(&u); printf("Enter A3: "); A3 = INPUTR(&u); printf("Enter A4: "); A4 = INPUTR(&u); printf("Enter A6: "); A6 = INPUTR(&u); TWO = BUILDMPR(); TWO->N = CHANGE(2); TWO->D = ONEI(); THREE = BUILDMPR(); THREE->N = CHANGE(3); THREE->D = ONEI(); FOUR = MULTR(TWO, TWO); NINE = MULTR(THREE, THREE); Tmp = MULTR(FOUR, A2); B2 = MULTABCR(Tmp, A1, A1); FREEMPR(Tmp); Tmp = MULTR(TWO, A4); B4 = MULTABCR(Tmp, A1, A3); FREEMPR(Tmp); Tmp = MULTR(FOUR, A6); B6 = MULTABCR(Tmp, A3, A3); FREEMPR(Tmp); Tmp1 = MULTR(B2, B6); Tmp2 = MULTR(B4, B4); Tmp3 = SUBR(Tmp1, Tmp2); B8 = RATIOR(Tmp3, FOUR); FREEMPR(Tmp1); FREEMPR(Tmp2); FREEMPR(Tmp3); /* Finally DELTA = -B2^2*B8 -8*B4^3 - 27*B6^2 + 9*B2*B4*B6. */ Tmp1 = MULTR3(B2, B2, B8); Tmp2 = MULTR(TWO, B4); Tmp3 = MULTR3(Tmp2, Tmp2, Tmp2); Tmp = Tmp3; Tmp3 = ADDR(Tmp1, Tmp3); FREEMPR(Tmp); FREEMPR(Tmp1); FREEMPR(Tmp2); Tmp2 = MULTR(B2, B4); Tmp4 = MULTR(THREE, B6); Tmp5 = SUBR(Tmp2, Tmp4); FREEMPR(Tmp2); FREEMPR(Tmp4); Tmp2 = MULTR3(NINE, B6, Tmp5); DELTA = SUBR(Tmp2, Tmp3); printf("DELTA = "); PRINTR(DELTA); printf("\n"); FREEMPR(Tmp2); FREEMPR(Tmp3); FREEMPR(Tmp5); FREEMPR(TWO); FREEMPR(THREE); FREEMPR(FOUR); FREEMPR(NINE); FREEMPR(B2); FREEMPR(B4); FREEMPR(B6); FREEMPR(B8); if (EQZEROR(DELTA)) { fprintf(stderr, "Discriminant is zero.\n"); exit (1); } FREEMPR(DELTA); while (GetYN()) { printf("Enter X1: "); X1 = INPUTR(&u); printf("Enter Y1: "); Y1 = INPUTR(&u); printf("Enter X2: "); X2 = INPUTR(&u); printf("Enter Y2: "); Y2 = INPUTR(&u); ADD_CUBICR(X1, Y1, X2, Y2, &X3, &Y3, A1, A2, A3, A4, A6); if (X3) { printf("(X3, Y3) = ("); PRINTR(X3); printf(", "); PRINTR(Y3); printf(")\n"); FREEMPR(X3); FREEMPR(Y3); } else printf("(X3, Y3) = IDENTITY\n"); FREEMPR(X1); FREEMPR(Y1); FREEMPR(X2); FREEMPR(Y2); } FREEMPR(A1); FREEMPR(A2); FREEMPR(A3); FREEMPR(A4); FREEMPR(A6); return; } void POWER_CUBICR(MPR *X1, MPR *Y1, MPR **Xptr, MPR **Yptr, MPR *A1, MPR *A2, MPR *A3, MPR *A4, MPR *A6, unsigned int n) /* * (*Xptr, *Yptr)= n(X1, Y1), where 0 <= n < R0 * R0 and (X1, Y1) is on the * elliptic curve y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6. * See D. Husemoller, Elliptic curves, page 25. */ { MPR *BXtmp, *CXtmp, *BYtmp, *CYtmp; *Xptr = (MPR *)NULL; *Yptr = (MPR *)NULL; if (n == 0) { printf(" about to return\n"); return; } BXtmp = COPYR(X1); BYtmp = COPYR(Y1); while (1) { if (n & 1) { CXtmp = *Xptr; CYtmp = *Yptr; ADD_CUBICR(BXtmp, BYtmp, CXtmp, CYtmp, Xptr, Yptr, A1, A2, A3, A4, A6); FREEMPR(CXtmp); FREEMPR(CYtmp); if (n == 1) { FREEMPR(BXtmp); FREEMPR(BYtmp); return; } } CXtmp = BXtmp; CYtmp = BYtmp; ADD_CUBICR(CXtmp, CYtmp, CXtmp, CYtmp, &BXtmp, &BYtmp, A1, A2, A3, A4, A6); FREEMPR(CXtmp); FREEMPR(CYtmp); n = n >> 1; } } void POWER_CUBICRX() /* * Front end for POWER_CUBICR(). */ { MPR *X1, *X2, *Y1, *Y2, *A1, *A2, *A3, *A4, *A6; MPR *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5; MPR *TWO, *THREE, *FOUR, *NINE, *DELTA, *B2, *B4, *B6, *B8; unsigned int u, n; printf("Calculating n(X1,Y1) for the nonsingular elliptic curve \n"); printf("y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6.\n"); printf("Enter A1: "); A1 = INPUTR(&u); printf("Enter A2: "); A2 = INPUTR(&u); printf("Enter A3: "); A3 = INPUTR(&u); printf("Enter A4: "); A4 = INPUTR(&u); printf("Enter A6: "); A6 = INPUTR(&u); TWO = BUILDMPR(); TWO->N = CHANGE(2); TWO->D = ONEI(); THREE = BUILDMPR(); THREE->N = CHANGE(3); THREE->D = ONEI(); FOUR = MULTR(TWO, TWO); NINE = MULTR(THREE, THREE); Tmp = MULTR(FOUR, A2); B2 = MULTABCR(Tmp, A1, A1); FREEMPR(Tmp); Tmp = MULTR(TWO, A4); B4 = MULTABCR(Tmp, A1, A3); FREEMPR(Tmp); Tmp = MULTR(FOUR, A6); B6 = MULTABCR(Tmp, A3, A3); FREEMPR(Tmp); Tmp1 = MULTR(B2, B6); Tmp2 = MULTR(B4, B4); Tmp3 = SUBR(Tmp1, Tmp2); B8 = RATIOR(Tmp3, FOUR); FREEMPR(Tmp1); FREEMPR(Tmp2); FREEMPR(Tmp3); /* Finally DELTA = -B2^2*B8 -8*B4^3 - 27*B6^2 + 9*B2*B4*B6. */ Tmp1 = MULTR3(B2, B2, B8); Tmp2 = MULTR(TWO, B4); Tmp3 = MULTR3(Tmp2, Tmp2, Tmp2); Tmp = Tmp3; Tmp3 = ADDR(Tmp1, Tmp3); FREEMPR(Tmp); FREEMPR(Tmp1); FREEMPR(Tmp2); Tmp2 = MULTR(B2, B4); Tmp4 = MULTR(THREE, B6); Tmp5 = SUBR(Tmp2, Tmp4); FREEMPR(Tmp2); FREEMPR(Tmp4); Tmp2 = MULTR3(NINE, B6, Tmp5); DELTA = SUBR(Tmp2, Tmp3); printf("DELTA = "); PRINTR(DELTA); printf("\n"); FREEMPR(Tmp2); FREEMPR(Tmp3); FREEMPR(Tmp5); FREEMPR(TWO); FREEMPR(THREE); FREEMPR(FOUR); FREEMPR(NINE); FREEMPR(B2); FREEMPR(B4); FREEMPR(B6); FREEMPR(B8); if (EQZEROR(DELTA)) { fprintf(stderr, "Discriminant is zero.\n"); exit (1); } FREEMPR(DELTA); while (GetYN()) { printf("Enter X1: "); X1 = INPUTR(&u); printf("Enter Y1: "); Y1 = INPUTR(&u); printf("Enter n: "); scanf("%u", &n); printf("n = %u\n", n); POWER_CUBICR(X1, Y1, &X2, &Y2, A1, A2, A3, A4, A6, n); if (X2) { printf("(X2, Y2) = ("); PRINTR(X2); printf(", "); PRINTR(Y2); printf(")\n"); FREEMPR(X2); FREEMPR(Y2); } else printf("(X2, Y2) = IDENTITY\n"); FREEMPR(X1); FREEMPR(Y1); } FREEMPR(A1); FREEMPR(A2); FREEMPR(A3); FREEMPR(A4); FREEMPR(A6); return; } MPR *MULTR3(MPR *A, MPR *B, MPR *C) /* Returns A * B * C. */ { MPR *Tmp1, *Tmp2; Tmp1 = MULTR(A, B); Tmp2 = MULTR(Tmp1, C); FREEMPR(Tmp1); return (Tmp2); } MPR *MULTABCR(MPR *A, MPR *B, MPR *C) /* Returns A + B * C. */ { MPR *Temp1, *Temp2; Temp1 = MULTR(B,C); Temp2 = ADDR(A, Temp1); FREEMPR(Temp1); return (Temp2); } void ADD_CUBICM(MPI *X1, MPI *Y1, MPI *X2, MPI *Y2, MPI **Xptr, MPI **Yptr, MPI *A1, MPI *A2, MPI *A3, MPI *A4, MPI *A6, MPI *MODULUS) /* * (*Xptr,*Yptr) is the sum of the two points (X1,Y1) and (X2,Y2) on the * elliptic curve y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6 mod p=MODULUS. * See D. Husemoller, Elliptic curves, page 25. */ { MPI *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5,*Tmp6,*Tmp7,*M; if (X1 == NULL && X2 != NULL) { *Xptr = COPYI(X2); *Yptr = COPYI(Y2); return; } if (X2 == NULL && X1 != NULL) { *Xptr = COPYI(X1); *Yptr = COPYI(Y1); return; } if (X2 == NULL && X1 == NULL) { *Xptr = (MPI *)NULL; *Yptr = (MPI *)NULL; return; } if (EQUALI(X1, X2)) { if (!EQUALI(Y1, Y2)) { *Xptr = (MPI *)NULL; *Yptr = (MPI *)NULL; return; } Tmp2 = ADDM(Y1, Y1, MODULUS); Tmp3 = MULTABCM(A3, A1, X1, MODULUS); Tmp7 = ADDM(Tmp3, Tmp2, MODULUS); FREEMPI(Tmp2); FREEMPI(Tmp3); if (EQZEROI(Tmp7)) { *Xptr = (MPI *)NULL; *Yptr = (MPI *)NULL; FREEMPI(Tmp7); return; } else { Tmp1 = CHANGE(2); Tmp2 = ADDM(X1, A2, MODULUS); Tmp3 = MULTM(Tmp1, Tmp2, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); Tmp4 = ADDM(X1, Tmp3, MODULUS); FREEMPI(Tmp3); Tmp5 = MULTM(X1, Tmp4, MODULUS); FREEMPI(Tmp4); Tmp = Tmp5; Tmp5 = ADDM(Tmp5, A4, MODULUS); FREEMPI(Tmp); Tmp6 = MULTM(A1, Y1, MODULUS); Tmp = SUBM(Tmp5, Tmp6, MODULUS); FREEMPI(Tmp5); FREEMPI(Tmp6); M = DIVM(Tmp, Tmp7, MODULUS); FREEMPI(Tmp); FREEMPI(Tmp7); } } else { Tmp1 = SUBM(X1, X2, MODULUS); Tmp2 = SUBM(Y1, Y2, MODULUS); M = DIVM(Tmp2, Tmp1, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); } Tmp1 = ADDM(M, A1, MODULUS); Tmp = Tmp1; Tmp1 = MULTM(Tmp1, M, MODULUS); FREEMPI(Tmp); Tmp2 = ADDM(X1, X2, MODULUS); Tmp = Tmp2; Tmp2 = ADDM(Tmp2, A2, MODULUS); FREEMPI(Tmp); Tmp = Tmp2; Tmp2 = MINUSM(Tmp2, MODULUS); FREEMPI(Tmp); *Xptr = ADDM(Tmp1, Tmp2, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); Tmp1 = SUBM(X1, *Xptr, MODULUS); Tmp = Tmp1; Tmp1 = MULTM(M, Tmp1, MODULUS); FREEMPI(Tmp); Tmp2 = MULTABCM(A3, A1, *Xptr, MODULUS); Tmp = Tmp2; Tmp2 = ADDM(Y1, Tmp2, MODULUS); FREEMPI(Tmp); Tmp = Tmp2; Tmp2 = MINUSM(Tmp2, MODULUS); FREEMPI(Tmp); *Yptr = ADDM(Tmp1, Tmp2, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); FREEMPI(M); return; } void ADD_CUBICMX() /* * Front end for ADD_CUBICM(). */ { MPI *X1, *X2, *X3, *Y1, *Y2, *Y3, *A1, *A2, *A3, *A4, *A6; MPI *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5, *MODULUS; MPI *TWO, *THREE, *FOUR, *NINE, *DELTA, *B2, *B4, *B6, *B8; unsigned int u; printf("Calculating the elliptic curve sum of (X1,Y1) and (X2,Y2)\n"); printf("mod MODULUS\n"); printf("for the nonsingular elliptic curve y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6.\n"); printf("Enter A1: "); A1 = INPUTI(&u); printf("Enter A2: "); A2 = INPUTI(&u); printf("Enter A3: "); A3 = INPUTI(&u); printf("Enter A4: "); A4 = INPUTI(&u); printf("Enter A6: "); A6 = INPUTI(&u); printf("Enter MODULUS: "); MODULUS = INPUTI(&u); TWO = CHANGE(2); THREE = CHANGE(3); FOUR = MULTM(TWO, TWO, MODULUS); NINE = MULTM(THREE, THREE, MODULUS); Tmp = MULTM(FOUR, A2, MODULUS); B2 = MULTABCM(Tmp, A1, A1, MODULUS); FREEMPI(Tmp); Tmp = MULTM(TWO, A4, MODULUS); B4 = MULTABCM(Tmp, A1, A3, MODULUS); FREEMPI(Tmp); Tmp = MULTM(FOUR, A6, MODULUS); B6 = MULTABCM(Tmp, A3, A3, MODULUS); FREEMPI(Tmp); Tmp1 = MULTM(B2, B6, MODULUS); Tmp2 = MULTM(B4, B4, MODULUS); Tmp3 = SUBM(Tmp1, Tmp2, MODULUS); B8 = DIVM(Tmp3, FOUR, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); FREEMPI(Tmp3); /* Finally DELTA = -B2^2*B8 -8*B4^3 - 27*B6^2 + 9*B2*B4*B6. */ Tmp1 = MULTM3(B2, B2, B8, MODULUS); Tmp2 = MULTM(TWO, B4, MODULUS); Tmp3 = MULTM3(Tmp2, Tmp2, Tmp2, MODULUS); Tmp = Tmp3; Tmp3 = ADDM(Tmp1, Tmp3, MODULUS); FREEMPI(Tmp); FREEMPI(Tmp1); FREEMPI(Tmp2); Tmp2 = MULTM(B2, B4, MODULUS); Tmp4 = MULTM(THREE, B6, MODULUS); Tmp5 = SUBM(Tmp2, Tmp4, MODULUS); FREEMPI(Tmp2); FREEMPI(Tmp4); Tmp2 = MULTM3(NINE, B6, Tmp5, MODULUS); DELTA = SUBM(Tmp2, Tmp3, MODULUS); printf("DELTA = "); PRINTI(DELTA); printf("\n"); FREEMPI(Tmp2); FREEMPI(Tmp3); FREEMPI(Tmp5); FREEMPI(TWO); FREEMPI(THREE); FREEMPI(FOUR); FREEMPI(NINE); FREEMPI(B2); FREEMPI(B4); FREEMPI(B6); FREEMPI(B8); if (EQZEROI(DELTA)) { fprintf(stderr, "Discriminant is zero.\n"); exit (1); } FREEMPI(DELTA); while (GetYN()) { printf("Enter X1: "); X1 = INPUTI(&u); printf("Enter Y1: "); Y1 = INPUTI(&u); printf("Enter X2: "); X2 = INPUTI(&u); printf("Enter Y2: "); Y2 = INPUTI(&u); ADD_CUBICM(X1, Y1, X2, Y2, &X3, &Y3, A1, A2, A3, A4, A6, MODULUS); if (X3) { printf("(X3, Y3) = ("); PRINTI(X3); printf(", "); PRINTI(Y3); printf(")\n"); FREEMPI(X3); FREEMPI(Y3); } else printf("(X3, Y3) = IDENTITY\n"); FREEMPI(X1); FREEMPI(Y1); FREEMPI(X2); FREEMPI(Y2); } FREEMPI(A1); FREEMPI(A2); FREEMPI(A3); FREEMPI(A4); FREEMPI(A6); return; } void POWER_CUBICM(MPI *X1, MPI *Y1, MPI **Xptr, MPI **Yptr, MPI *A1, MPI *A2, MPI *A3, MPI *A4, MPI *A6, unsigned int n, MPI *MODULUS) /* * (*Xptr, *Yptr)= n(X1, Y1), where 0 <= n < R0 * R0 and (X1, Y1) is on the * elliptic curve y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6 mod MODULUS. * See D. Husemoller, Elliptic curves, page 25. */ { MPI *BXtmp, *CXtmp, *BYtmp, *CYtmp; *Xptr = (MPI *)NULL; *Yptr = (MPI *)NULL; if (n == 0) { printf(" about to return\n"); return; } BXtmp = COPYI(X1); BYtmp = COPYI(Y1); while (1) { if (n & 1) { CXtmp = *Xptr; CYtmp = *Yptr; ADD_CUBICM(BXtmp, BYtmp, CXtmp, CYtmp, Xptr, Yptr, A1, A2, A3, A4, A6, MODULUS); FREEMPI(CXtmp); FREEMPI(CYtmp); if (n == 1) { FREEMPI(BXtmp); FREEMPI(BYtmp); return; } } CXtmp = BXtmp; CYtmp = BYtmp; ADD_CUBICM(CXtmp, CYtmp, CXtmp, CYtmp, &BXtmp, &BYtmp, A1, A2, A3, A4, A6, MODULUS); FREEMPI(CXtmp); FREEMPI(CYtmp); n = n >> 1; } } void POWER_CUBICMX() /* * Front end for POWER_CUBICM(). */ { MPI *X1, *X2, *Y1, *Y2, *A1, *A2, *A3, *A4, *A6; MPI *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5, *MODULUS; MPI *TWO, *THREE, *FOUR, *NINE, *DELTA, *B2, *B4, *B6, *B8; unsigned int u, n; printf("Calculating n(X1,Y1) for the nonsingular elliptic curve \n"); printf("y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6 mod MODULUS.\n"); printf("Enter A1: "); A1 = INPUTI(&u); printf("Enter A2: "); A2 = INPUTI(&u); printf("Enter A3: "); A3 = INPUTI(&u); printf("Enter A4: "); A4 = INPUTI(&u); printf("Enter A6: "); A6 = INPUTI(&u); printf("Enter MODULUS: "); MODULUS = INPUTI(&u); TWO = CHANGE(2); THREE = CHANGE(3); FOUR = MULTM(TWO, TWO, MODULUS); NINE = MULTM(THREE, THREE, MODULUS); Tmp = MULTM(FOUR, A2, MODULUS); B2 = MULTABCM(Tmp, A1, A1, MODULUS); FREEMPI(Tmp); Tmp = MULTM(TWO, A4, MODULUS); B4 = MULTABCM(Tmp, A1, A3, MODULUS); FREEMPI(Tmp); Tmp = MULTM(FOUR, A6, MODULUS); B6 = MULTABCM(Tmp, A3, A3, MODULUS); FREEMPI(Tmp); Tmp1 = MULTM(B2, B6, MODULUS); Tmp2 = MULTM(B4, B4, MODULUS); Tmp3 = SUBM(Tmp1, Tmp2, MODULUS); B8 = DIVM(Tmp3, FOUR, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); FREEMPI(Tmp3); /* Finally DELTA = -B2^2*B8 -8*B4^3 - 27*B6^2 + 9*B2*B4*B6. */ Tmp1 = MULTM3(B2, B2, B8, MODULUS); Tmp2 = MULTM(TWO, B4, MODULUS); Tmp3 = MULTM3(Tmp2, Tmp2, Tmp2, MODULUS); Tmp = Tmp3; Tmp3 = ADDM(Tmp1, Tmp3, MODULUS); FREEMPI(Tmp); FREEMPI(Tmp1); FREEMPI(Tmp2); Tmp2 = MULTM(B2, B4, MODULUS); Tmp4 = MULTM(THREE, B6, MODULUS); Tmp5 = SUBM(Tmp2, Tmp4, MODULUS); FREEMPI(Tmp2); FREEMPI(Tmp4); Tmp2 = MULTM3(NINE, B6, Tmp5, MODULUS); DELTA = SUBM(Tmp2, Tmp3, MODULUS); printf("DELTA = "); PRINTI(DELTA); printf("\n"); FREEMPI(Tmp2); FREEMPI(Tmp3); FREEMPI(Tmp5); FREEMPI(TWO); FREEMPI(THREE); FREEMPI(FOUR); FREEMPI(NINE); FREEMPI(B2); FREEMPI(B4); FREEMPI(B6); FREEMPI(B8); if (EQZEROI(DELTA)) { fprintf(stderr, "Discriminant is zero.\n"); exit (1); } FREEMPI(DELTA); while (GetYN()) { printf("Enter X1: "); X1 = INPUTI(&u); printf("Enter Y1: "); Y1 = INPUTI(&u); printf("Enter n: "); scanf("%u", &n); printf("n = %u\n", n); POWER_CUBICM(X1, Y1, &X2, &Y2, A1, A2, A3, A4, A6, n, MODULUS); if (X2) { printf("(X2, Y2) = ("); PRINTI(X2); printf(", "); PRINTI(Y2); printf(")\n"); FREEMPI(X2); FREEMPI(Y2); } else printf("(X2, Y2) = IDENTITY\n"); FREEMPI(X1); FREEMPI(Y1); } FREEMPI(A1); FREEMPI(A2); FREEMPI(A3); FREEMPI(A4); FREEMPI(A6); FREEMPI(MODULUS); return; } MPI *MULTABCM(MPI *A, MPI *B, MPI *C, MPI *M) /* Returns A + B * C. */ { MPI *Temp1, *Temp2; Temp1 = MULTM(B,C, M); Temp2 = ADDM(A, Temp1, M); FREEMPI(Temp1); return (Temp2); } MPI *MULTM3(MPI *A, MPI *B, MPI *C, MPI *M) /* Returns A * B * C mod M. */ { MPI *Tmp1, *Tmp2; Tmp1 = MULTM(A, B, M); Tmp2 = MULTM(Tmp1, C, M); FREEMPI(Tmp1); return (Tmp2); } unsigned int ORDER_CUBICM(MPI *X1, MPI *Y1, MPI *A1, MPI *A2, MPI *A3, MPI *A4, MPI *A6, MPI *MODULUS) /* Returns order of (X1,Y1) on the elliptic curve * y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6 mod MODULUS. */ { unsigned int k; MPI *X2, *Y2, *X3, *Y3; k = 1; if (X1 == NULL) return 1; else X2= COPYI(X1); Y2= COPYI(Y1); while (1){ ADD_CUBICM(X1, Y1, X2, Y2, &X3, &Y3, A1, A2, A3, A4, A6, MODULUS); FREEMPI(X2); FREEMPI(Y2); k++; if (X3 == NULL) break; else { X2 = X3; Y2 = Y3; } } return (k); } /*unsigned int ORDER_CUBICM(MPI *X1, MPI *Y1, MPI *A1, MPI *A2, MPI *A3, MPI *A4, MPI *A6, MPI *MODULUS)*/ /* Returns order of (X1,Y1) on the elliptic curve * y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6 mod MODULUS. */ /*{ unsigned int k; MPI *X2, *Y2; k = 1; if (X1 == NULL) return 1; while (1){ POWER_CUBICM(X1, Y1, &X2, &Y2, A1, A2, A3, A4, A6, k, MODULUS); if (X2 == NULL) break; else { FREEMPI(X2); FREEMPI(Y2); k++; } } return (k); } */ void ORDER_CUBICMX() /* * Front end for ORDER_CUBICM(). */ { MPI *X1, *Y1, *A1, *A2, *A3, *A4, *A6; MPI *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5, *MODULUS; MPI *TWO, *THREE, *FOUR, *NINE, *DELTA, *B2, *B4, *B6, *B8; unsigned int k, u; printf("Calculating o(X1,Y1) for the nonsingular elliptic curve \n"); printf("y^2+A1*xy+A3*y=X^3+A2*X^2+A4*x+A6 modulo a prime.\n"); printf("Enter A1: "); A1 = INPUTI(&u); printf("Enter A2: "); A2 = INPUTI(&u); printf("Enter A3: "); A3 = INPUTI(&u); printf("Enter A4: "); A4 = INPUTI(&u); printf("Enter A6: "); A6 = INPUTI(&u); printf("Enter MODULUS: "); MODULUS = INPUTI(&u); TWO = CHANGE(2); THREE = CHANGE(3); FOUR = MULTM(TWO, TWO, MODULUS); NINE = MULTM(THREE, THREE, MODULUS); Tmp = MULTM(FOUR, A2, MODULUS); B2 = MULTABCM(Tmp, A1, A1, MODULUS); FREEMPI(Tmp); Tmp = MULTM(TWO, A4, MODULUS); B4 = MULTABCM(Tmp, A1, A3, MODULUS); FREEMPI(Tmp); Tmp = MULTM(FOUR, A6, MODULUS); B6 = MULTABCM(Tmp, A3, A3, MODULUS); FREEMPI(Tmp); Tmp1 = MULTM(B2, B6, MODULUS); Tmp2 = MULTM(B4, B4, MODULUS); Tmp3 = SUBM(Tmp1, Tmp2, MODULUS); B8 = DIVM(Tmp3, FOUR, MODULUS); FREEMPI(Tmp1); FREEMPI(Tmp2); FREEMPI(Tmp3); /* Finally DELTA = -B2^2*B8 -8*B4^3 - 27*B6^2 + 9*B2*B4*B6. */ Tmp1 = MULTM3(B2, B2, B8, MODULUS); Tmp2 = MULTM(TWO, B4, MODULUS); Tmp3 = MULTM3(Tmp2, Tmp2, Tmp2, MODULUS); Tmp = Tmp3; Tmp3 = ADDM(Tmp1, Tmp3, MODULUS); FREEMPI(Tmp); FREEMPI(Tmp1); FREEMPI(Tmp2); Tmp2 = MULTM(B2, B4, MODULUS); Tmp4 = MULTM(THREE, B6, MODULUS); Tmp5 = SUBM(Tmp2, Tmp4, MODULUS); FREEMPI(Tmp2); FREEMPI(Tmp4); Tmp2 = MULTM3(NINE, B6, Tmp5, MODULUS); DELTA = SUBM(Tmp2, Tmp3, MODULUS); printf("DELTA = "); PRINTI(DELTA); printf("\n"); FREEMPI(Tmp2); FREEMPI(Tmp3); FREEMPI(Tmp5); FREEMPI(TWO); FREEMPI(THREE); FREEMPI(FOUR); FREEMPI(NINE); FREEMPI(B2); FREEMPI(B4); FREEMPI(B6); FREEMPI(B8); if (EQZEROI(DELTA)) { fprintf(stderr, "Discriminant is zero.\n"); exit (1); } FREEMPI(DELTA); while (GetYN()) { printf("Enter X1: "); X1 = INPUTI(&u); printf("Enter Y1: "); Y1 = INPUTI(&u); k=ORDER_CUBICM(X1, Y1, A1, A2, A3, A4, A6, MODULUS); printf("Order of ("); PRINTI(X1); printf(","); PRINTI(Y1); printf(") on the curve\n"); printf("y^2"); if (A1->S) { printf("+"); if (!EQONEI(A1)) PRINTI(A1); printf("xy"); } if (A3->S) { printf("+"); if (!EQONEI(A3)) PRINTI(A3); printf("y"); } printf("=x^3"); if (A2->S > 0) { printf("+"); if (!EQONEI(A2)) PRINTI(A2); printf("x^2"); } if (A4->S > 0) { printf("+"); if (!EQONEI(A4)) PRINTI(A4); printf("x"); } if (A6->S > 0) { printf("+"); PRINTI(A6); } printf(" mod "); PRINTI(MODULUS); printf("\n"); printf(" is %u\n ", k); FREEMPI(X1); FREEMPI(Y1); } FREEMPI(A1); FREEMPI(A2); FREEMPI(A3); FREEMPI(A4); FREEMPI(A6); FREEMPI(MODULUS); return; } unsigned int ORDER_CUBICR(MPR *X1, MPR *Y1, MPR *A1, MPR *A2, MPR *A3, MPR *A4, MPR *A6) /* Returns order of (X1,Y1) on the elliptic curve * y^2+A1*x*y+A3*y=X^3+A2*X^2+A4*x+A6. Uses fact that |tor(E)|<= 12. */ { unsigned int k; MPR *X2, *Y2; k = 1; if (X1 == NULL) return 1; while (k <= 12){ POWER_CUBICR(X1, Y1, &X2, &Y2, A1, A2, A3, A4, A6, k); if (X2 == NULL) break; else { FREEMPR(X2); FREEMPR(Y2); k++; } } if (k == 13) return (0); else return (k); } void ORDER_CUBICRX() /* * Front end for ORDER_CUBICR(). */ { MPR *X1, *Y1, *A1, *A2, *A3, *A4, *A6; MPR *Tmp, *Tmp1,*Tmp2,*Tmp3,*Tmp4,*Tmp5; MPR *TWO, *THREE, *FOUR, *NINE, *DELTA, *B2, *B4, *B6, *B8; unsigned int k, u; printf("Calculating o(X1,Y1) for the nonsingular elliptic curve \n"); printf("y^2+A1*xy+A3y=X^3+A2*X^2+A4*x+A6.\n"); printf("Enter A1: "); A1 = INPUTR(&u); printf("Enter A2: "); A2 = INPUTR(&u); printf("Enter A3: "); A3 = INPUTR(&u); printf("Enter A4: "); A4 = INPUTR(&u); printf("Enter A6: "); A6 = INPUTR(&u); TWO = BUILDMPR(); TWO->N = CHANGE(2); TWO->D = ONEI(); THREE = BUILDMPR(); THREE->N = CHANGE(3); THREE->D = ONEI(); FOUR = MULTR(TWO, TWO); NINE = MULTR(THREE, THREE); Tmp = MULTR(FOUR, A2); B2 = MULTABCR(Tmp, A1, A1); FREEMPR(Tmp); Tmp = MULTR(TWO, A4); B4 = MULTABCR(Tmp, A1, A3); FREEMPR(Tmp); Tmp = MULTR(FOUR, A6); B6 = MULTABCR(Tmp, A3, A3); FREEMPR(Tmp); Tmp1 = MULTR(B2, B6); Tmp2 = MULTR(B4, B4); Tmp3 = SUBR(Tmp1, Tmp2); B8 = RATIOR(Tmp3, FOUR); FREEMPR(Tmp1); FREEMPR(Tmp2); FREEMPR(Tmp3); /* Finally DELTA = -B2^2*B8 -8*B4^3 - 27*B6^2 + 9*B2*B4*B6. */ Tmp1 = MULTR3(B2, B2, B8); Tmp2 = MULTR(TWO, B4); Tmp3 = MULTR3(Tmp2, Tmp2, Tmp2); Tmp = Tmp3; Tmp3 = ADDR(Tmp1, Tmp3); FREEMPR(Tmp); FREEMPR(Tmp1); FREEMPR(Tmp2); Tmp2 = MULTR(B2, B4); Tmp4 = MULTR(THREE, B6); Tmp5 = SUBR(Tmp2, Tmp4); FREEMPR(Tmp2); FREEMPR(Tmp4); Tmp2 = MULTR3(NINE, B6, Tmp5); DELTA = SUBR(Tmp2, Tmp3); printf("DELTA = "); PRINTR(DELTA); printf("\n"); FREEMPR(Tmp2); FREEMPR(Tmp3); FREEMPR(Tmp5); FREEMPR(TWO); FREEMPR(THREE); FREEMPR(FOUR); FREEMPR(NINE); FREEMPR(B2); FREEMPR(B4); FREEMPR(B6); FREEMPR(B8); if (EQZEROR(DELTA)) { fprintf(stderr, "Discriminant is zero.\n"); exit (1); } FREEMPR(DELTA); while (GetYN()) { printf("Enter X1: "); X1 = INPUTR(&u); printf("Enter Y1: "); Y1 = INPUTR(&u); k=ORDER_CUBICR(X1, Y1, A1, A2, A3, A4, A6); printf("Order of ("); PRINTR(X1); printf(","); PRINTR(Y1); printf(") on the curve\n"); printf("y^2"); if ((A1->N)->S > 0) { printf("+"); if (!EQONER(A1)) PRINTR(A1); printf("xy"); } else if ((A1->N)->S < 0) { if (!EQMINUSONER(A1)) PRINTR(A1); else printf("-"); printf("xy"); } if ((A3->N)->S > 0) { printf("+"); if (!EQONER(A3)) PRINTR(A3); printf("y"); } else if ((A3->N)->S < 0) { if (!EQMINUSONER(A3)) PRINTR(A3); else printf("-"); printf("y"); } printf("=x^3"); if ((A2->N)->S > 0) { printf("+"); if (!EQONER(A2)) PRINTR(A2); printf("x^2"); } else if ((A2->N)->S < 0) { if (!EQMINUSONER(A2)) PRINTR(A2); else printf("-"); printf("x^2"); } if ((A4->N)->S > 0) { printf("+"); if (!EQONER(A4)) PRINTR(A4); printf("x"); } else if ((A4->N)->S < 0) { if (!EQMINUSONER(A4)) PRINTR(A4); else printf("-"); printf("x"); } if ((A6->N)->S > 0) { printf("+"); PRINTR(A6); } else if ((A6->N)->S < 0) PRINTR(A6); printf("\n"); if (k) printf(" is %u\n ", k); else printf(" is infinite\n "); FREEMPR(X1); FREEMPR(Y1); } FREEMPR(A1); FREEMPR(A2); FREEMPR(A3); FREEMPR(A4); FREEMPR(A6); return; }