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: extra25519.go
    path of file: ./repos/bytom/lib/github.com/tendermint/ed25519/extra25519
    
    the code of the file until where you have to start completion: // Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package extra25519

import (
	"crypto/sha512"

	"github.com/tendermint/ed25519/edwards25519"
)

// PrivateKeyToCurve25519 converts an ed25519 private key into a corresponding
// curve25519 private key such that the resulting curve25519 public key will
// equal the result from PublicKeyToCurve25519.
func PrivateKeyToCurve25519(curve25519Private *[32]byte, privateKey *[64]byte) {
	h := sha512.New()
	h.Write(privateKey[:32])
	digest := h.Sum(nil)

	digest[0] &= 248
	digest[31] &= 127
	digest[31] |= 64

	copy(curve25519Private[:], digest)
}

func edwardsToMontgomeryX(outX, y *edwards25519.FieldElement) {
	// We only need the x-coordinate of the curve25519 point, which I'll
	// call u. The isomorphism is u=(y+1)/(1-y), since y=Y/Z, this gives
	// u=(Y+Z)/(Z-Y). We know that Z=1, thus u=(Y+1)/(1-Y).
	var oneMinusY edwards25519.FieldElement
	edwards25519.FeOne(&oneMinusY)
	edwards25519.FeSub(&oneMinusY, &oneMinusY, y)
	edwards25519.FeInvert(&oneMinusY, &oneMinusY)

	edwards25519.FeOne(outX)
	edwards25519.FeAdd(outX, outX, y)

	edwards25519.FeMul(outX, outX, &oneMinusY)
}

// PublicKeyToCurve25519 converts an Ed25519 public key into the curve25519
// public key that would be generated from the same private key.
func PublicKeyToCurve25519(curve25519Public *[32]byte, publicKey *[32]byte) bool {
	var A edwards25519.ExtendedGroupElement
    
func chi(out, z *edwards25519.FieldElement) {
	var t0, t1, t2, t3 edwards25519.FieldElement
	var i int

	edwards25519.FeSquare(&t0, z)     // 2^1
	edwards25519.FeMul(&t1, &t0, z)   // 2^1 + 2^0
	edwards25519.FeSquare(&t0, &t1)   // 2^2 + 2^1
	edwards25519.FeSquare(&t2, &t0)   // 2^3 + 2^2
	edwards25519.FeSquare(&t2, &t2)   // 4,3
	edwards25519.FeMul(&t2, &t2, &t0) // 4,3,2,1
	edwards25519.FeMul(&t1, &t2, z)   // 4..0
	edwards25519.FeSquare(&t2, &t1)   // 5..1
	for i = 1; i < 5; i++ {           // 9,8,7,6,5
		edwards25519.FeSquare(&t2, &t2)
	}
	edwards25519.FeMul(&t1, &t2, &t1) // 9,8,7,6,5,4,3,2,1,0
	edwards25519.FeSquare(&t2, &t1)   // 10..1
	for i = 1; i < 10; i++ {          // 19..10
		edwards25519.FeSquare(&t2, &t2)
	}
	edwards25519.FeMul(&t2, &t2, &t1) // 19..0
	edwards25519.FeSquare(&t3, &t2)   // 20..1
	for i = 1; i < 20; i++ {          // 39..20
		edwards25519.FeSquare(&t3, &t3)
	}
	edwards25519.FeMul(&t2, &t3, &t2) // 39..0
	edwards25519.FeSquare(&t2, &t2)   // 40..1
	for i = 1; i < 10; i++ {          // 49..10
		edwards25519.FeSquare(&t2, &t2)
	}
	edwards25519.FeMul(&t1, &t2, &t1) // 49..0
	edwards25519.FeSquare(&t2, &t1)   // 50..1
	for i = 1; i < 50; i++ {          // 99..50
		edwards25519.FeSquare(&t2, &t2)
	}
	edwards25519.FeMul(&t2, &t2, &t1) // 99..0
	edwards25519.FeSquare(&t3, &t2)   // 100..1
	for i = 1; i < 100; i++ {         // 199..100
		edwards25519.FeSquare(&t3, &t3)
	}
	edwards25519.FeMul(&t2, &t3, &t2) // 199..0
	edwards25519.FeSquare(&t2, &t2)   // 200..1
	for i = 1; i < 50; i++ {          // 249..50
		edwards25519.FeSquare(&t2, &t2)
	}
	edwards25519.FeMul(&t1, &t2, &t1) // 249..0
	edwards25519.FeSquare(&t1, &t1)   // 250..1
	for i = 1; i < 4; i++ {           // 253..4
		edwards25519.FeSquare(&t1, &t1)
	}
	edwards25519.FeMul(out, &t1, &t0) // 253..4,2,1
}