static GEN F2xq_elltrace_Harley(GEN a6, GEN T2) { pari_sp ltop = avma; pari_timer ti; GEN T, sqx; GEN x, x2, t; long n = F2x_degree(T2), N = ((n + 1)>>1) + 2; long ispcyc; if (n==1) return gen_m1; if (n==2) return F2x_degree(a6) ? gen_1 : stoi(-3); if (n==3) return F2x_degree(a6) ? (F2xq_trace(a6,T2) ? stoi(-3): gen_1) : stoi(5); timer_start(&ti); sqx = mkvec2(F2xq_sqrt(polx_F2x(T2[1]),T2), T2); if (DEBUGLEVEL>1) timer_printf(&ti,"Sqrtx"); ispcyc = zx_is_pcyc(F2x_to_Flx(T2)); T = ispcyc? F2x_to_ZX(T2): F2x_canonlift(T2, N-2); if (DEBUGLEVEL>1) timer_printf(&ti,"Teich"); T = FpX_get_red(T, int2n(N)); if (DEBUGLEVEL>1) timer_printf(&ti,"Barrett"); x = solve_AGM_eqn(F2x_to_ZX(a6), N-2, T, sqx); if (DEBUGLEVEL>1) timer_printf(&ti,"Lift"); x2 = ZX_Z_add_shallow(ZX_shifti(x,2), gen_1); t = (ispcyc? Z2XQ_invnorm_pcyc: Z2XQ_invnorm)(x2, T, N); if (DEBUGLEVEL>1) timer_printf(&ti,"Norm"); if (cmpii(sqri(t), int2n(n + 2)) > 0) t = subii(t, int2n(N)); return gerepileuptoint(ltop, t); }
/* Finds a random non-singular point on E */ GEN random_F2xqE(GEN a, GEN a6, GEN T) { pari_sp ltop = avma; GEN x, y, rhs, u; do { avma= ltop; x = random_F2x(F2x_degree(T),T[1]); if (typ(a) == t_VECSMALL) { GEN a2 = a, x2; if (!lgpol(x)) { avma=ltop; retmkvec2(pol0_Flx(T[1]), F2xq_sqrt(a6,T)); } u = x; x2 = F2xq_sqr(x, T); rhs = F2x_add(F2xq_mul(x2,F2x_add(x,a2),T),a6); rhs = F2xq_div(rhs,x2,T); } else { GEN a3 = gel(a,1), a4 = gel(a,2), a3i = gel(a,3), u2i; u = a3; u2i = F2xq_sqr(a3i,T); rhs = F2x_add(F2xq_mul(x,F2x_add(F2xq_sqr(x,T),a4),T),a6); rhs = F2xq_mul(rhs,u2i,T); } } while (F2xq_trace(rhs,T)); y = F2xq_mul(F2xq_Artin_Schreier(rhs, T), u, T); return gerepilecopy(ltop, mkvec2(x, y)); }
static GEN _can_invd(void *E, GEN V, GEN v, GEN q, long M) { GEN F; (void)E; (void)q; F = mkvec2(ZX_shifti(gel(v,2),1), ZX_shifti(RgX_shift_shallow(gel(v,3),1),1)); return gen_Z2X_Dixon(F, V, M, NULL, _can_lin, _can_lins, _can_invls); }
static GEN F2xqE_neg_i(GEN P, GEN a) { GEN LHS; if (ell_is_inf(P)) return P; LHS = typ(a)==t_VECSMALL ? gel(P,1): gel(a,1); return mkvec2(gel(P,1), F2x_add(LHS, gel(P,2))); }
GEN F2xqE_neg(GEN P, GEN a, GEN T) { GEN LHS; (void) T; if (ell_is_inf(P)) return ellinf(); LHS = typ(a)==t_VECSMALL ? gel(P,1): gel(a,1); return mkvec2(gcopy(gel(P,1)), F2x_add(LHS, gel(P,2))); }
GEN nfrootsall_and_pr(GEN nf, GEN pol) { GEN J1,J2, pr, T; pari_sp av = avma; GEN z = gerepileupto(av, nfsqff(checknf(nf), pol, 2)); if (lg(z) == 1) return NULL; (void)nf_pick_prime(1, nf, unifpol(nf, pol, t_COL), 2, &J1, &J2, &pr, &T); return mkvec2(z, pr); }
GEN shallowconcat(GEN x, GEN y) { long tx=typ(x),ty=typ(y),lx=lg(x),ly=lg(y),i; GEN z,p1; if (tx==t_STR || ty==t_STR) return strconcat(x,y); if (tx==t_LIST || ty==t_LIST) return listconcat(x,y); if (tx==t_MAT && lx==1) { if (ty!=t_VEC) return gtomat(y); if (ly==1) return cgetg(1, t_MAT); err_cat(x,y); } if (ty==t_MAT && ly==1) { if (tx!=t_VEC) return gtomat(x); if (lx==1) return cgetg(1, t_MAT); err_cat(x,y); } if (tx == ty) { if (tx == t_MAT) { if (lgcols(x) != lgcols(y)) err_cat(x,y); } else if (!is_matvec_t(tx) && tx != t_VECSMALL) return mkvec2(x, y); z=cgetg(lx+ly-1,tx); for (i=1; i<lx; i++) z[i] = x[i]; for (i=1; i<ly; i++) z[lx+i-1]= y[i]; return z; } if (! is_matvec_t(tx)) { if (! is_matvec_t(ty)) return mkvec2(x, y); z=cgetg(ly+1,ty); if (ty != t_MAT) p1 = x; else { if (lgcols(y)!=2) err_cat(x,y); p1 = mkcol(x); } for (i=2; i<=ly; i++) z[i] = y[i-1]; gel(z, 1) = p1; return z; } if (! is_matvec_t(ty)) { z=cgetg(lx+1,tx); if (tx != t_MAT) p1 = y; else { if (lgcols(x)!=2) err_cat(x,y); p1 = mkcol(y); } for (i=1; i<lx; i++) z[i]=x[i]; gel(z, lx) = p1; return z; } switch(tx) { case t_VEC: switch(ty) { case t_COL: if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1),y); if (ly>=3) break; return (ly==1)? x: shallowconcat(x,gel(y,1)); case t_MAT: z=cgetg(ly,t_MAT); if (lx != ly) break; for (i=1; i<ly; i++) gel(z,i) = shallowconcat(gel(x,i),gel(y,i)); return z; } break; case t_COL: switch(ty) { case t_VEC: if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1), y); if (ly>=3) break; return (ly==1)? x: shallowconcat(x, gel(y,1)); case t_MAT: if (lx != lgcols(y)) break; z=cgetg(ly+1,t_MAT); gel(z,1) = x; for (i=2; i<=ly; i++) gel(z,i) = gel(y,i-1); return z; } break; case t_MAT: switch(ty) { case t_VEC: z=cgetg(lx, t_MAT); if (ly != lx) break; for (i=1; i<lx; i++) gel(z,i) = shallowconcat(gel(x,i), gel(y,i)); return z; case t_COL: if (ly != lgcols(x)) break; z=cgetg(lx+1,t_MAT); gel(z,lx) = y; for (i=1; i<lx; i++) z[i]=x[i]; return z; } break; } err_cat(x,y); return NULL; /* not reached */ }
static GEN bnflog_i(GEN bnf, GEN ell) { long prec0, prec; GEN nf, US, vdegS, S, T, M, CLp, CLt, Ftilde, vtG, ellk; GEN D, Ap, cycAp, bnfS; long i, j, lS, lvAp; checkbnf(bnf); nf = checknf(bnf); S = idealprimedec(nf, ell); bnfS = bnfsunit0(bnf, S, nf_GENMAT, LOWDEFAULTPREC); /* S-units */ US = leafcopy(gel(bnfS,1)); prec0 = maxss(30, vtilde_prec(nf, US, ell)); US = shallowconcat(bnf_get_fu(bnf), US); settyp(US, t_COL); T = padicfact(nf, S, prec0); lS = lg(S); Ftilde = cgetg(lS, t_VECSMALL); for (j = 1; j < lS; j++) Ftilde[j] = ftilde(nf, gel(S,j), gel(T,j)); CLp = CL_prime(bnf, ell, S); cycAp = gel(CLp,1); Ap = gel(CLp,2); for(;;) { CLt = CL_tilde(nf, US, ell, T, Ftilde, &vtG, prec0); if (CLt) break; prec0 <<= 1; T = padicfact(nf, S, prec0); } prec = ellexpo(cycAp, ell) + ellexpo(CLt,ell) + 1; if (prec == 1) return mkvec3(cgetg(1,t_VEC), cgetg(1,t_VEC), cgetg(1,t_VEC)); vdegS = get_vdegS(Ftilde, ell, prec0); ellk = powiu(ell, prec); lvAp = lg(Ap); if (lvAp > 1) { GEN Kcyc = bnf_get_cyc(bnf); GEN C = zeromatcopy(lvAp-1, lS-1); GEN Rell = gel(CLp,3), Uell = gel(CLp,4), ordS = gel(CLp,5); for (i = 1; i < lvAp; i++) { GEN a, b, bi, A = gel(Ap,i), d = gel(cycAp,i); bi = isprincipal(bnf, A); a = vecmodii(ZC_Z_mul(bi,d), Kcyc); /* a in subgroup generated by S = Rell; hence b integral */ b = hnf_invimage(Rell, a); b = vecmodii(ZM_ZC_mul(Uell, ZC_neg(b)), ordS); A = mkvec2(A, cgetg(1,t_MAT)); A = idealpowred(nf, A, d); /* find a principal representative of A_i^cycA_i up to elements of S */ a = isprincipalfact(bnf,gel(A,1),S,b,nf_GENMAT|nf_FORCE); if (!gequal0(gel(a,1))) pari_err_BUG("bnflog"); a = famat_mul_shallow(gel(A,2), gel(a,2)); /* principal part */ if (lg(a) == 1) continue; for (j = 1; j < lS; j++) gcoeff(C,i,j) = vtilde(nf, a, gel(T,j), gel(vdegS,j), ell, prec0); } C = gmod(gneg(C),ellk); C = shallowtrans(C); M = mkmat2(mkcol2(diagonal_shallow(cycAp), C), mkcol2(gen_0, vtG)); M = shallowmatconcat(M); /* relation matrix */ } else M = vtG; M = ZM_hnfmodid(M, ellk); D = matsnf0(M, 4); if (lg(D) == 1 || !dvdii(gel(D,1), ellk)) pari_err_BUG("bnflog [missing Z_l component]"); D = vecslice(D,2,lg(D)-1); return mkvec3(D, CLt, ellsylow(cycAp, ell)); }
/* g = polynomial, h = embedding. Return [[g,h]] */ static GEN _subfield(GEN g, GEN h) { return mkvec(mkvec2(g,h)); }