bridge/class-master/depend/pari/src/basemath/ellsea.c
/*Finds the kernel polynomial h, dividing the ell-division polynomial from the
  isogenous curve Eb and trace term pp1. Uses CCR algorithm and returns h.
  Return NULL if E and Eb are *not* isogenous. */
Finds the kernel polynomial h, dividing the ell-division polynomial from the
isogenous curve Eb and trace term pp1. Uses CCR algorithm and returns h.
Return NULL if E and Eb are *not* isogenous.
Finds the kernel polynomial h dividing the ell - division polynomial from the isogenous curve Eb and trace term pp1 . Uses CCR algorithm and returns h . Return NULL if E and Eb are * not * isogenous .
static GEN
find_kernel(GEN a4, GEN a6, ulong ell, GEN a4t, GEN a6t, GEN pp1, GEN T, GEN p, GEN pp, long e)
{
  const long ext = 2;
  pari_sp ltop = avma, btop;
  GEN P, v, tlist, h;
  long i, j, k;
  long deg = (ell - 1)/2, dim = 2 + deg + ext;
  GEN psi2 = Fq_elldivpol2(a4, a6, T, p);
  GEN Dpsi2 = Fq_elldivpol2d(a4, T, p);
  GEN C  = find_coeff(a4, a6, T, p, dim, pp, e);
  GEN Ct = find_coeff(a4t, a6t, T, p, dim, pp, e);
  GEN V = cgetg(dim+1, t_VEC);
  for (k = 1; k <= dim; k++)
  {
    long v = mael(C,2,k);
    GEN z = gmul(gsub(gmael(Ct,1,k), gmael(C,1,k)), shifti(mpfact(2*k), -1));
    if (signe(z) && Zq_pval(z, pp) < v) return NULL;
    gel(V, k) = Zq_divexact(z, powiu(pp, v));
  }
  btop = avma;
  v = zerovec(dim);
  gel(v, 1) = utoi(deg);
  gel(v, 2) = pp1;
  P = pol_x(0);
  for (k = 3; k <= dim; k++)
  {
    GEN s, r = FqX_Fq_mul(Dpsi2, gel(P, 3), T, p);
    for (j = 4; j < lg(P); j++)
    {
      long o = j - 2;
      GEN D = FqX_add(RgX_shift_shallow(Dpsi2, 1), FqX_mulu(psi2, o-1, T, p), T, p);
      GEN E = FqX_Fq_mul(D, Fq_mulu(gel(P, j), o, T, p), T, p);
      r = FqX_add(r, RgX_shift_shallow(E, o-2), T, p);
    }
    P = r;
    s = Fq_mul(gel(P, 2), gel(v, 1), T, p);
    for (j = 3; j < lg(P)-1; j++)
      s = Fq_add(s, Fq_mul(gel(P, j), gel(v, j-1), T, p), T, p);
    gel(v, k) = Zq_Z_div_safe(Fq_sub(gel(V, k-2), s, T, p), gel(P, j), T, p, pp, e);
    if (gc_needed(btop, 1))
    {
      if(DEBUGMEM>1) pari_warn(warnmem,"find_kernel");
      gerepileall(btop, 2, &v, &P);
    }
  }
  tlist = cgetg(dim, t_VEC);
  gel(tlist, dim-1) = gen_1;
  for (k = 1; k <= dim-2; k++)
  {
    pari_sp btop = avma;
    GEN s = gel(v, k+1);
    for (i = 1; i < k; i++)
      s = Fq_add(s, Fq_mul(gel(tlist, dim-i-1), gel(v, k-i+1), T, p), T, p);
    gel(tlist, dim-k-1) = gerepileupto(btop, Zq_Z_div_safe(s, stoi(-k), T, p, pp, e));
  }
  for (i = 1; i <= ext; i++)
    if (signe(Fq_red(gel(tlist, i),T, pp))) { avma = ltop; return NULL; }
  h = FqX_red(RgV_to_RgX(vecslice(tlist, ext+1, dim-1), 0),T,p);
  return signe(Fq_elldivpolmod(a4, a6, ell, h, T, pp)) ? NULL: h;
}
static GEN find_kernel ( GEN a4 , GEN a6 , ulong ell , GEN a4t , GEN a6t , GEN pp1 , GEN T , GEN p , GEN pp , long e ) { const long ext = 2 ; pari_sp ltop = avma , btop ; GEN P , v , tlist , h ; long i , j , k ; long deg = ( ell - 1 ) / 2 , dim = 2 + deg + ext ; GEN psi2 = Fq_elldivpol2 ( a4 , a6 , T , p ) ; GEN Dpsi2 = Fq_elldivpol2d ( a4 , T , p ) ; GEN C = find_coeff ( a4 , a6 , T , p , dim , pp , e ) ; GEN Ct = find_coeff ( a4t , a6t , T , p , dim , pp , e ) ; GEN V = cgetg ( dim + 1 , t_VEC ) ; for ( k = 1 ; k <= dim ; k ++ ) { long v = mael ( C , 2 , k ) ; GEN z = gmul ( gsub ( gmael ( Ct , 1 , k ) , gmael ( C , 1 , k ) ) , shifti ( mpfact ( 2 * k ) , -1 ) ) ; if ( signe ( z ) && Zq_pval ( z , pp ) < v ) return NULL ; gel ( V , k ) = Zq_divexact ( z , powiu ( pp , v ) ) ; } btop = avma ; v = zerovec ( dim ) ; gel ( v , 1 ) = utoi ( deg ) ; gel ( v , 2 ) = pp1 ; P = pol_x ( 0 ) ; for ( k = 3 ; k <= dim ; k ++ ) { GEN s , r = FqX_Fq_mul ( Dpsi2 , gel ( P , 3 ) , T , p ) ; for ( j = 4 ; j < lg ( P ) ; j ++ ) { long o = j - 2 ; GEN D = FqX_add ( RgX_shift_shallow ( Dpsi2 , 1 ) , FqX_mulu ( psi2 , o - 1 , T , p ) , T , p ) ; GEN E = FqX_Fq_mul ( D , Fq_mulu ( gel ( P , j ) , o , T , p ) , T , p ) ; r = FqX_add ( r , RgX_shift_shallow ( E , o - 2 ) , T , p ) ; } P = r ; s = Fq_mul ( gel ( P , 2 ) , gel ( v , 1 ) , T , p ) ; for ( j = 3 ; j < lg ( P ) - 1 ; j ++ ) s = Fq_add ( s , Fq_mul ( gel ( P , j ) , gel ( v , j - 1 ) , T , p ) , T , p ) ; gel ( v , k ) = Zq_Z_div_safe ( Fq_sub ( gel ( V , k - 2 ) , s , T , p ) , gel ( P , j ) , T , p , pp , e ) ; if ( gc_needed ( btop , 1 ) ) { if ( DEBUGMEM > 1 ) pari_warn ( warnmem , " " ) ; gerepileall ( btop , 2 , & v , & P ) ; } } tlist = cgetg ( dim , t_VEC ) ; gel ( tlist , dim - 1 ) = gen_1 ; for ( k = 1 ; k <= dim - 2 ; k ++ ) { pari_sp btop = avma ; GEN s = gel ( v , k + 1 ) ; for ( i = 1 ; i < k ; i ++ ) s = Fq_add ( s , Fq_mul ( gel ( tlist , dim - i - 1 ) , gel ( v , k - i + 1 ) , T , p ) , T , p ) ; gel ( tlist , dim - k - 1 ) = gerepileupto ( btop , Zq_Z_div_safe ( s , stoi ( - k ) , T , p , pp , e ) ) ; } for ( i = 1 ; i <= ext ; i ++ ) if ( signe ( Fq_red ( gel ( tlist , i ) , T , pp ) ) ) { avma = ltop ; return NULL ; } h = FqX_red ( RgV_to_RgX ( vecslice ( tlist , ext + 1 , dim - 1 ) , 0 ) , T , p ) ; return signe ( Fq_elldivpolmod ( a4 , a6 , ell , h , T , pp ) ) ? NULL : h ; }
Finds the kernel polynomial h, dividing the ell-division polynomial from the
isogenous curve Eb and trace term pp1.
Finds the kernel polynomial h dividing the ell - division polynomial from the isogenous curve Eb and trace term pp1 .