You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: optate.go
    path of file: ./repos/awless/vendor/golang.org/x/crypto/bn256
    
    the code of the file until where you have to start completion: // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD
    
func miller(q *twistPoint, p *curvePoint, pool *bnPool) *gfP12 {
	ret := newGFp12(pool)
	ret.SetOne()

	aAffine := newTwistPoint(pool)
	aAffine.Set(q)
	aAffine.MakeAffine(pool)

	bAffine := newCurvePoint(pool)
	bAffine.Set(p)
	bAffine.MakeAffine(pool)

	minusA := newTwistPoint(pool)
	minusA.Negative(aAffine, pool)

	r := newTwistPoint(pool)
	r.Set(aAffine)

	r2 := newGFp2(pool)
	r2.Square(aAffine.y, pool)

	for i := len(sixuPlus2NAF) - 1; i > 0; i-- {
		a, b, c, newR := lineFunctionDouble(r, bAffine, pool)
		if i != len(sixuPlus2NAF)-1 {
			ret.Square(ret, pool)
		}

		mulLine(ret, a, b, c, pool)
		a.Put(pool)
		b.Put(pool)
		c.Put(pool)
		r.Put(pool)
		r = newR

		switch sixuPlus2NAF[i-1] {
		case 1:
			a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2, pool)
		case -1:
			a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2, pool)
		default:
			continue
		}

		mulLine(ret, a, b, c, pool)
		a.Put(pool)
		b.Put(pool)
		c.Put(pool)
		r.Put(pool)
		r = newR
	}

	// In order to calculate Q1 we have to convert q from the sextic twist
	// to the full GF(p^12) group, apply the Frobenius there, and convert
	// back.
	//
	// The twist isomorphism is (x', y') -> (xω², yω³). If we consider just
	// x for a moment, then after applying the Frobenius, we have x̄ω^(2p)
	// where x̄ is the conjugate of x. If we are going to apply the inverse
	// isomorphism we need a value with a single coefficient of ω² so we
	// rewrite this as x̄ω^(2p-2)ω². ξ⁶ = ω and, due to the construction of
	// p, 2p-2 is a multiple of six. Therefore we can rewrite as
	// x̄ξ^((p-1)/3)ω² and applying the inverse isomorphism eliminates the
	// ω².
	//
	// A similar argument can be made for the y value.

	q1 := newTwistPoint(pool)
	q1.x.Conjugate(aAffine.x)
	q1.x.Mul(q1.x, xiToPMinus1Over3, pool)
	q1.y.Conjugate(aAffine.y)
	q1.y.Mul(q1.y, xiToPMinus1Over2, pool)
	q1.z.SetOne()
	q1.t.SetOne()

	// For Q2 we are applying the p² Frobenius. The two conjugations cancel
	// out and we are left only with the factors from the isomorphism. In
	// the case of x, we end up with a pure number which is why
	// xiToPSquaredMinus1Over3 is ∈ GF(p). With y we get a factor of -1. We
	// ignore this to end up with -Q2.

	minusQ2 := newTwistPoint(pool)
	minusQ2.x.MulScalar(aAffine.x, xiToPSquaredMinus1Over3)
	minusQ2.y.Set(aAffine.y)
	minusQ2.z.SetOne()
	minusQ2.t.SetOne()

	r2.Square(q1.y, pool)
	a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2, pool)
	mulLine(ret, a, b, c, pool)
	a.Put(pool)
	b.Put(pool)
	c.Put(pool)
	r.Put(pool)
	r = newR

	r2.Square(minusQ2.y, pool)
	a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2, pool)
	mulLine(ret, a, b, c, pool)
	a.Put(pool)
	b.Put(pool)
	c.Put(pool)
	r.Put(pool)
	r = newR

	aAffine.Put(pool)
	bAffine.Put(pool)
	minusA.Put(pool)
	r.Put(pool)
	r2.Put(pool)

	return ret
}