+ field *f = c->f;
+ mp *y, *u, *v;
+
+ if (F_ZEROP(f, x))
+ y = F_SQRT(f, MP_NEW, c->b);
+ else {
+ u = F_SQR(f, MP_NEW, x); /* %$x^2$% */
+ y = F_MUL(f, MP_NEW, u, c->a); /* %$a x^2$% */
+ y = F_ADD(f, y, y, c->b); /* %$a x^2 + b$% */
+ v = F_MUL(f, MP_NEW, u, x); /* %$x^3$% */
+ y = F_ADD(f, y, y, v); /* %$A = x^3 + a x^2 + b$% */
+ if (!F_ZEROP(f, y)) {
+ u = F_INV(f, u, u); /* %$x^{-2}$% */
+ v = F_MUL(f, v, u, y); /* %$B = A x^{-2} = x + a + b x^{-2}$% */
+ y = F_QUADSOLVE(f, y, v); /* %$z^2 + z = B$% */
+ if (y) y = F_MUL(f, y, y, x); /* %$y = z x$% */
+ }
+ MP_DROP(u);
+ MP_DROP(v);
+ }
+ if (!y) return (0);
+ EC_DESTROY(d);
+ d->x = MP_COPY(x);
+ d->y = y;
+ d->z = MP_COPY(f->one);
+ return (d);