bridge/class-master/depend/pari/src/basemath/elliptic.c
/* E an ell, x a scalar */
E an ell, x a scalar
E an ell x a scalar
static GEN
ellordinate_i(GEN E, GEN x, long prec)
{
  pari_sp av = avma;
  GEN a, b, D, d, y, p, nf = NULL;
  if (ell_get_type(E) == t_ELL_NF)
  {
    nf = ellnf_get_nf(E);
    x = nftoalg(nf,x);
  }
  a = ec_f_evalx(E,x);
  b = ec_h_evalx(E,x);
  D = gadd(gsqr(b), gmul2n(a,2));
  if (gequal0(D)) {
    if (ell_get_type(E) == t_ELL_Fq && absequaliu(ellff_get_p(E),2))
      retmkvec( FF_sqrt(a) );
    b = gneg_i(b); y = cgetg(2,t_VEC);
    gel(y,1) = gmul2n(b,-1);
    return gerepileupto(av,y);
  }
  switch(ell_get_type(E))
  {
    case t_ELL_Fp: 
      p = ellff_get_p(E);
      D = gel(D,2);
      if (kronecker(D, p) < 0) { avma = av; return cgetg(1,t_VEC); }
      d = Fp_sqrt(D, p);
      break;
    case t_ELL_Fq:
      if (absequaliu(ellff_get_p(E),2))
      {
        GEN F = FFX_roots(mkpoln(3, gen_1, b, a), D);
        if (lg(F) == 1) { avma = av; return cgetg(1,t_VEC); }
        return gerepileupto(av, F);
      }
      if (!FF_issquareall(D,&d)) { avma = av; return cgetg(1,t_VEC); }
      break;
    case t_ELL_Q:
      if (typ(x) == t_COMPLEX) { d = gsqrt(D, prec); break; }
      if (!issquareall(D,&d)) { avma = av; return cgetg(1,t_VEC); }
      break;
    case t_ELL_NF:
    {
      GEN T = mkpoln(3, gen_1, gen_0, gneg(D));
      setvarn(T, fetch_var_higher());
      d = nfroots(nf, T);
      delete_var();
      if (lg(d) == 1) { avma = av; return cgetg(1, t_VEC); }
      d = gel(d,1);
      break;
    }
    case t_ELL_Qp:
      p = ellQp_get_p(E);
      D = cvtop(D, p, ellQp_get_prec(E));
      if (!issquare(D)) { avma = av; return cgetg(1,t_VEC); }
      d = Qp_sqrt(D);
      break;
    default:
      d = gsqrt(D,prec);
  }
  a = gsub(d,b); y = cgetg(3,t_VEC);
  gel(y,1) = gmul2n(a, -1);
  gel(y,2) = gsub(gel(y,1),d);
  return gerepileupto(av,y);
}
static GEN ellordinate_i ( GEN E , GEN x , long prec ) { pari_sp av = avma ; GEN a , b , D , d , y , p , nf = NULL ; if ( ell_get_type ( E ) == t_ELL_NF ) { nf = ellnf_get_nf ( E ) ; x = nftoalg ( nf , x ) ; } a = ec_f_evalx ( E , x ) ; b = ec_h_evalx ( E , x ) ; D = gadd ( gsqr ( b ) , gmul2n ( a , 2 ) ) ; if ( gequal0 ( D ) ) { if ( ell_get_type ( E ) == t_ELL_Fq && absequaliu ( ellff_get_p ( E ) , 2 ) ) retmkvec ( FF_sqrt ( a ) ) ; b = gneg_i ( b ) ; y = cgetg ( 2 , t_VEC ) ; gel ( y , 1 ) = gmul2n ( b , -1 ) ; return gerepileupto ( av , y ) ; } switch ( ell_get_type ( E ) ) { case t_ELL_Fp : p = ellff_get_p ( E ) ; D = gel ( D , 2 ) ; if ( kronecker ( D , p ) < 0 ) { avma = av ; return cgetg ( 1 , t_VEC ) ; } d = Fp_sqrt ( D , p ) ; break ; case t_ELL_Fq : if ( absequaliu ( ellff_get_p ( E ) , 2 ) ) { GEN F = FFX_roots ( mkpoln ( 3 , gen_1 , b , a ) , D ) ; if ( lg ( F ) == 1 ) { avma = av ; return cgetg ( 1 , t_VEC ) ; } return gerepileupto ( av , F ) ; } if ( ! FF_issquareall ( D , & d ) ) { avma = av ; return cgetg ( 1 , t_VEC ) ; } break ; case t_ELL_Q : if ( typ ( x ) == t_COMPLEX ) { d = gsqrt ( D , prec ) ; break ; } if ( ! issquareall ( D , & d ) ) { avma = av ; return cgetg ( 1 , t_VEC ) ; } break ; case t_ELL_NF : { GEN T = mkpoln ( 3 , gen_1 , gen_0 , gneg ( D ) ) ; setvarn ( T , fetch_var_higher ( ) ) ; d = nfroots ( nf , T ) ; delete_var ( ) ; if ( lg ( d ) == 1 ) { avma = av ; return cgetg ( 1 , t_VEC ) ; } d = gel ( d , 1 ) ; break ; } case t_ELL_Qp : p = ellQp_get_p ( E ) ; D = cvtop ( D , p , ellQp_get_prec ( E ) ) ; if ( ! issquare ( D ) ) { avma = av ; return cgetg ( 1 , t_VEC ) ; } d = Qp_sqrt ( D ) ; break ; default : d = gsqrt ( D , prec ) ; } a = gsub ( d , b ) ; y = cgetg ( 3 , t_VEC ) ; gel ( y , 1 ) = gmul2n ( a , -1 ) ; gel ( y , 2 ) = gsub ( gel ( y , 1 ) , d ) ; return gerepileupto ( av , y ) ; }
E an ell, x a scalar
E an ell x a scalar
/* solve y*(y+b) = a */ /* D != 0 */ /* imply p!=2 */