+/*----- Normal basis ------------------------------------------------------*/
+
+/* --- Field operations --- */
+
+static void fndestroy(field *ff) {
+ fctx_binnorm *f = (fctx_binnorm *)ff; gfreduce_destroy(&f->f.r);
+ gfn_destroy(&f->ntop); gfn_destroy(&f->pton); MP_DROP(f->f.f.q);
+ DESTROY(f);
+}
+
+static int fnsamep(field *ff, field *gg) {
+ fctx_binnorm *f = (fctx_binnorm *)ff, *g = (fctx_binnorm *)gg;
+ return (MP_EQ(f->ntop.r[0], g->ntop.r[0]) && field_stdsamep(ff, gg));
+}
+
+static mp *fnin(field *ff, mp *d, mp *x) {
+ fctx_binnorm *f = (fctx_binnorm *)ff;
+ return (gfn_transform(&f->ntop, d, x));
+}
+
+static mp *fnout(field *ff, mp *d, mp *x) {
+ fctx_binnorm *f = (fctx_binnorm *)ff;
+ return (gfn_transform(&f->pton, d, x));
+}
+
+/* --- Field operations table --- */
+
+static const field_ops fnops = {
+ FTY_BINARY, "binnorm",
+ fndestroy, frand, fnsamep,
+ fnin, fnout,
+ fzerop, field_id, fadd, fadd, fmul, fsqr, finv, freduce, fsqrt,
+ fquadsolve,
+ 0, 0, 0, 0
+};
+
+/* --- @field_binnorm@ --- *
+ *
+ * Arguments: @mp *p@ = the reduction polynomial
+ * @mp *beta@ = representation of normal point
+ *
+ * Returns: A pointer to the field.
+ *
+ * Use: Creates a field structure for a binary field mod @p@ which
+ * uses a normal basis representation externally. Computations
+ * are still done on a polynomial-basis representation.
+ */
+
+field *field_binnorm(mp *p, mp *beta)
+{
+ fctx_binnorm *f = CREATE(fctx_binnorm);
+ f->f.f.ops = &fnops;
+ f->f.f.zero = MP_ZERO;
+ f->f.f.one = MP_ONE;
+ f->f.f.nbits = mp_bits(p) - 1;
+ f->f.f.noctets = (f->f.f.nbits + 7) >> 3;
+ gfreduce_create(&f->f.r, p);
+ f->f.f.m = f->f.r.p;
+ f->f.f.q = mp_lsl(MP_NEW, MP_ONE, f->f.f.nbits);
+ gfn_create(p, beta, &f->ntop, &f->pton);
+ return (&f->f.f);
+}
+