// Copyright 2016 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 edwards25519

import 

// This code is a port of the public domain, “ref10” implementation of ed25519
// from SUPERCOP.

// FieldElement represents an element of the field GF(2^255 - 19).  An element
// t, entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
// t[3]+2^102 t[4]+...+2^230 t[9].  Bounds on each t[i] vary depending on
// context.
type FieldElement [10]int32

var zero FieldElement

func ( *FieldElement) {
	copy([:], zero[:])
}

func ( *FieldElement) {
	FeZero()
	[0] = 1
}

func (, ,  *FieldElement) {
	[0] = [0] + [0]
	[1] = [1] + [1]
	[2] = [2] + [2]
	[3] = [3] + [3]
	[4] = [4] + [4]
	[5] = [5] + [5]
	[6] = [6] + [6]
	[7] = [7] + [7]
	[8] = [8] + [8]
	[9] = [9] + [9]
}

func (, ,  *FieldElement) {
	[0] = [0] - [0]
	[1] = [1] - [1]
	[2] = [2] - [2]
	[3] = [3] - [3]
	[4] = [4] - [4]
	[5] = [5] - [5]
	[6] = [6] - [6]
	[7] = [7] - [7]
	[8] = [8] - [8]
	[9] = [9] - [9]
}

func (,  *FieldElement) {
	copy([:], [:])
}

// Replace (f,g) with (g,g) if b == 1;
// replace (f,g) with (f,g) if b == 0.
//
// Preconditions: b in {0,1}.
func (,  *FieldElement,  int32) {
	 = -
	[0] ^=  & ([0] ^ [0])
	[1] ^=  & ([1] ^ [1])
	[2] ^=  & ([2] ^ [2])
	[3] ^=  & ([3] ^ [3])
	[4] ^=  & ([4] ^ [4])
	[5] ^=  & ([5] ^ [5])
	[6] ^=  & ([6] ^ [6])
	[7] ^=  & ([7] ^ [7])
	[8] ^=  & ([8] ^ [8])
	[9] ^=  & ([9] ^ [9])
}

func load3( []byte) int64 {
	var  int64
	 = int64([0])
	 |= int64([1]) << 8
	 |= int64([2]) << 16
	return 
}

func load4( []byte) int64 {
	var  int64
	 = int64([0])
	 |= int64([1]) << 8
	 |= int64([2]) << 16
	 |= int64([3]) << 24
	return 
}

func ( *FieldElement,  *[32]byte) {
	 := load4([:])
	 := load3([4:]) << 6
	 := load3([7:]) << 5
	 := load3([10:]) << 3
	 := load3([13:]) << 2
	 := load4([16:])
	 := load3([20:]) << 7
	 := load3([23:]) << 5
	 := load3([26:]) << 4
	 := (load3([29:]) & 8388607) << 2

	FeCombine(, , , , , , , , , , )
}

// FeToBytes marshals h to s.
// Preconditions:
//   |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
//
// Write p=2^255-19; q=floor(h/p).
// Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
//
// Proof:
//   Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
//   Also have |h-2^230 h9|<2^230 so |19 2^(-255)(h-2^230 h9)|<1/4.
//
//   Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
//   Then 0<y<1.
//
//   Write r=h-pq.
//   Have 0<=r<=p-1=2^255-20.
//   Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
//
//   Write x=r+19(2^-255)r+y.
//   Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
//
//   Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
//   so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
func ( *[32]byte,  *FieldElement) {
	var  [10]int32

	 := (19*[9] + (1 << 24)) >> 25
	 = ([0] + ) >> 26
	 = ([1] + ) >> 25
	 = ([2] + ) >> 26
	 = ([3] + ) >> 25
	 = ([4] + ) >> 26
	 = ([5] + ) >> 25
	 = ([6] + ) >> 26
	 = ([7] + ) >> 25
	 = ([8] + ) >> 26
	 = ([9] + ) >> 25

	// Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20.
	[0] += 19 * 
	// Goal: Output h-2^255 q, which is between 0 and 2^255-20.

	[0] = [0] >> 26
	[1] += [0]
	[0] -= [0] << 26
	[1] = [1] >> 25
	[2] += [1]
	[1] -= [1] << 25
	[2] = [2] >> 26
	[3] += [2]
	[2] -= [2] << 26
	[3] = [3] >> 25
	[4] += [3]
	[3] -= [3] << 25
	[4] = [4] >> 26
	[5] += [4]
	[4] -= [4] << 26
	[5] = [5] >> 25
	[6] += [5]
	[5] -= [5] << 25
	[6] = [6] >> 26
	[7] += [6]
	[6] -= [6] << 26
	[7] = [7] >> 25
	[8] += [7]
	[7] -= [7] << 25
	[8] = [8] >> 26
	[9] += [8]
	[8] -= [8] << 26
	[9] = [9] >> 25
	[9] -= [9] << 25
	// h10 = carry9

	// Goal: Output h[0]+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
	// Have h[0]+...+2^230 h[9] between 0 and 2^255-1;
	// evidently 2^255 h10-2^255 q = 0.
	// Goal: Output h[0]+...+2^230 h[9].

	[0] = byte([0] >> 0)
	[1] = byte([0] >> 8)
	[2] = byte([0] >> 16)
	[3] = byte(([0] >> 24) | ([1] << 2))
	[4] = byte([1] >> 6)
	[5] = byte([1] >> 14)
	[6] = byte(([1] >> 22) | ([2] << 3))
	[7] = byte([2] >> 5)
	[8] = byte([2] >> 13)
	[9] = byte(([2] >> 21) | ([3] << 5))
	[10] = byte([3] >> 3)
	[11] = byte([3] >> 11)
	[12] = byte(([3] >> 19) | ([4] << 6))
	[13] = byte([4] >> 2)
	[14] = byte([4] >> 10)
	[15] = byte([4] >> 18)
	[16] = byte([5] >> 0)
	[17] = byte([5] >> 8)
	[18] = byte([5] >> 16)
	[19] = byte(([5] >> 24) | ([6] << 1))
	[20] = byte([6] >> 7)
	[21] = byte([6] >> 15)
	[22] = byte(([6] >> 23) | ([7] << 3))
	[23] = byte([7] >> 5)
	[24] = byte([7] >> 13)
	[25] = byte(([7] >> 21) | ([8] << 4))
	[26] = byte([8] >> 4)
	[27] = byte([8] >> 12)
	[28] = byte(([8] >> 20) | ([9] << 6))
	[29] = byte([9] >> 2)
	[30] = byte([9] >> 10)
	[31] = byte([9] >> 18)
}

func ( *FieldElement) byte {
	var  [32]byte
	FeToBytes(&, )
	return [0] & 1
}

func ( *FieldElement) int32 {
	var  [32]byte
	FeToBytes(&, )
	var  uint8
	for ,  := range  {
		 |= 
	}
	 |=  >> 4
	 |=  >> 2
	 |=  >> 1
	return int32( & 1)
}

// FeNeg sets h = -f
//
// Preconditions:
//    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
//
// Postconditions:
//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
func (,  *FieldElement) {
	[0] = -[0]
	[1] = -[1]
	[2] = -[2]
	[3] = -[3]
	[4] = -[4]
	[5] = -[5]
	[6] = -[6]
	[7] = -[7]
	[8] = -[8]
	[9] = -[9]
}

func ( *FieldElement, , , , , , , , , ,  int64) {
	var , , , , , , , , ,  int64

	/*
	  |h0| <= (1.1*1.1*2^52*(1+19+19+19+19)+1.1*1.1*2^50*(38+38+38+38+38))
	    i.e. |h0| <= 1.2*2^59; narrower ranges for h2, h4, h6, h8
	  |h1| <= (1.1*1.1*2^51*(1+1+19+19+19+19+19+19+19+19))
	    i.e. |h1| <= 1.5*2^58; narrower ranges for h3, h5, h7, h9
	*/

	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	/* |h0| <= 2^25 */
	/* |h4| <= 2^25 */
	/* |h1| <= 1.51*2^58 */
	/* |h5| <= 1.51*2^58 */

	 = ( + (1 << 24)) >> 25
	 += 
	 -=  << 25
	 = ( + (1 << 24)) >> 25
	 += 
	 -=  << 25
	/* |h1| <= 2^24; from now on fits into int32 */
	/* |h5| <= 2^24; from now on fits into int32 */
	/* |h2| <= 1.21*2^59 */
	/* |h6| <= 1.21*2^59 */

	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	/* |h2| <= 2^25; from now on fits into int32 unchanged */
	/* |h6| <= 2^25; from now on fits into int32 unchanged */
	/* |h3| <= 1.51*2^58 */
	/* |h7| <= 1.51*2^58 */

	 = ( + (1 << 24)) >> 25
	 += 
	 -=  << 25
	 = ( + (1 << 24)) >> 25
	 += 
	 -=  << 25
	/* |h3| <= 2^24; from now on fits into int32 unchanged */
	/* |h7| <= 2^24; from now on fits into int32 unchanged */
	/* |h4| <= 1.52*2^33 */
	/* |h8| <= 1.52*2^33 */

	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	/* |h4| <= 2^25; from now on fits into int32 unchanged */
	/* |h8| <= 2^25; from now on fits into int32 unchanged */
	/* |h5| <= 1.01*2^24 */
	/* |h9| <= 1.51*2^58 */

	 = ( + (1 << 24)) >> 25
	 +=  * 19
	 -=  << 25
	/* |h9| <= 2^24; from now on fits into int32 unchanged */
	/* |h0| <= 1.8*2^37 */

	 = ( + (1 << 25)) >> 26
	 += 
	 -=  << 26
	/* |h0| <= 2^25; from now on fits into int32 unchanged */
	/* |h1| <= 1.01*2^24 */

	[0] = int32()
	[1] = int32()
	[2] = int32()
	[3] = int32()
	[4] = int32()
	[5] = int32()
	[6] = int32()
	[7] = int32()
	[8] = int32()
	[9] = int32()
}

// FeMul calculates h = f * g
// Can overlap h with f or g.
//
// Preconditions:
//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
//    |g| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
//
// Postconditions:
//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
//
// Notes on implementation strategy:
//
// Using schoolbook multiplication.
// Karatsuba would save a little in some cost models.
//
// Most multiplications by 2 and 19 are 32-bit precomputations;
// cheaper than 64-bit postcomputations.
//
// There is one remaining multiplication by 19 in the carry chain;
// one *19 precomputation can be merged into this,
// but the resulting data flow is considerably less clean.
//
// There are 12 carries below.
// 10 of them are 2-way parallelizable and vectorizable.
// Can get away with 11 carries, but then data flow is much deeper.
//
// With tighter constraints on inputs, can squeeze carries into int32.
func (, ,  *FieldElement) {
	 := int64([0])
	 := int64([1])
	 := int64([2])
	 := int64([3])
	 := int64([4])
	 := int64([5])
	 := int64([6])
	 := int64([7])
	 := int64([8])
	 := int64([9])

	 := int64(2 * [1])
	 := int64(2 * [3])
	 := int64(2 * [5])
	 := int64(2 * [7])
	 := int64(2 * [9])

	 := int64([0])
	 := int64([1])
	 := int64([2])
	 := int64([3])
	 := int64([4])
	 := int64([5])
	 := int64([6])
	 := int64([7])
	 := int64([8])
	 := int64([9])

	 := int64(19 * [1]) /* 1.4*2^29 */
	 := int64(19 * [2]) /* 1.4*2^30; still ok */
	 := int64(19 * [3])
	 := int64(19 * [4])
	 := int64(19 * [5])
	 := int64(19 * [6])
	 := int64(19 * [7])
	 := int64(19 * [8])
	 := int64(19 * [9])

	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *

	FeCombine(, , , , , , , , , , )
}

func feSquare( *FieldElement) (, , , , , , , , ,  int64) {
	 := int64([0])
	 := int64([1])
	 := int64([2])
	 := int64([3])
	 := int64([4])
	 := int64([5])
	 := int64([6])
	 := int64([7])
	 := int64([8])
	 := int64([9])
	 := int64(2 * [0])
	 := int64(2 * [1])
	 := int64(2 * [2])
	 := int64(2 * [3])
	 := int64(2 * [4])
	 := int64(2 * [5])
	 := int64(2 * [6])
	 := int64(2 * [7])
	 := 38 *  // 1.31*2^30
	 := 19 *  // 1.31*2^30
	 := 38 *  // 1.31*2^30
	 := 19 *  // 1.31*2^30
	 := 38 *  // 1.31*2^30

	 = * + * + * + * + * + *
	 = * + * + * + * + *
	 = * + * + * + * + * + *
	 = * + * + * + * + *
	 = * + * + * + * + * + *
	 = * + * + * + * + *
	 = * + * + * + * + * + *
	 = * + * + * + * + *
	 = * + * + * + * + * + *
	 = * + * + * + * + *

	return
}

// FeSquare calculates h = f*f. Can overlap h with f.
//
// Preconditions:
//    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
//
// Postconditions:
//    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
func (,  *FieldElement) {
	, , , , , , , , ,  := feSquare()
	FeCombine(, , , , , , , , , , )
}

// FeSquare2 sets h = 2 * f * f
//
// Can overlap h with f.
//
// Preconditions:
//    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
//
// Postconditions:
//    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
// See fe_mul.c for discussion of implementation strategy.
func (,  *FieldElement) {
	, , , , , , , , ,  := feSquare()

	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 
	 += 

	FeCombine(, , , , , , , , , , )
}

func (,  *FieldElement) {
	var , , ,  FieldElement
	var  int

	FeSquare(&, )        // 2^1
	FeSquare(&, &)      // 2^2
	for  = 1;  < 2; ++ { // 2^3
		FeSquare(&, &)
	}
	FeMul(&, , &)      // 2^3 + 2^0
	FeMul(&, &, &)    // 2^3 + 2^1 + 2^0
	FeSquare(&, &)      // 2^4 + 2^2 + 2^1
	FeMul(&, &, &)    // 2^4 + 2^3 + 2^2 + 2^1 + 2^0
	FeSquare(&, &)      // 5,4,3,2,1
	for  = 1;  < 5; ++ { // 9,8,7,6,5
		FeSquare(&, &)
	}
	FeMul(&, &, &)     // 9,8,7,6,5,4,3,2,1,0
	FeSquare(&, &)       // 10..1
	for  = 1;  < 10; ++ { // 19..10
		FeSquare(&, &)
	}
	FeMul(&, &, &)     // 19..0
	FeSquare(&, &)       // 20..1
	for  = 1;  < 20; ++ { // 39..20
		FeSquare(&, &)
	}
	FeMul(&, &, &)     // 39..0
	FeSquare(&, &)       // 40..1
	for  = 1;  < 10; ++ { // 49..10
		FeSquare(&, &)
	}
	FeMul(&, &, &)     // 49..0
	FeSquare(&, &)       // 50..1
	for  = 1;  < 50; ++ { // 99..50
		FeSquare(&, &)
	}
	FeMul(&, &, &)      // 99..0
	FeSquare(&, &)        // 100..1
	for  = 1;  < 100; ++ { // 199..100
		FeSquare(&, &)
	}
	FeMul(&, &, &)     // 199..0
	FeSquare(&, &)       // 200..1
	for  = 1;  < 50; ++ { // 249..50
		FeSquare(&, &)
	}
	FeMul(&, &, &)    // 249..0
	FeSquare(&, &)      // 250..1
	for  = 1;  < 5; ++ { // 254..5
		FeSquare(&, &)
	}
	FeMul(, &, &) // 254..5,3,1,0
}

func fePow22523(,  *FieldElement) {
	var , ,  FieldElement
	var  int

	FeSquare(&, )
	for  = 1;  < 1; ++ {
		FeSquare(&, &)
	}
	FeSquare(&, &)
	for  = 1;  < 2; ++ {
		FeSquare(&, &)
	}
	FeMul(&, , &)
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 1; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 5; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 10; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 20; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 10; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 50; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 100; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 50; ++ {
		FeSquare(&, &)
	}
	FeMul(&, &, &)
	FeSquare(&, &)
	for  = 1;  < 2; ++ {
		FeSquare(&, &)
	}
	FeMul(, &, )
}

// Group elements are members of the elliptic curve -x^2 + y^2 = 1 + d * x^2 *
// y^2 where d = -121665/121666.
//
// Several representations are used:
//   ProjectiveGroupElement: (X:Y:Z) satisfying x=X/Z, y=Y/Z
//   ExtendedGroupElement: (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
//   CompletedGroupElement: ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
//   PreComputedGroupElement: (y+x,y-x,2dxy)

type ProjectiveGroupElement struct {
	X, Y, Z FieldElement
}

type ExtendedGroupElement struct {
	X, Y, Z, T FieldElement
}

type CompletedGroupElement struct {
	X, Y, Z, T FieldElement
}

type PreComputedGroupElement struct {
	yPlusX, yMinusX, xy2d FieldElement
}

type CachedGroupElement struct {
	yPlusX, yMinusX, Z, T2d FieldElement
}

func ( *ProjectiveGroupElement) () {
	FeZero(&.X)
	FeOne(&.Y)
	FeOne(&.Z)
}

func ( *ProjectiveGroupElement) ( *CompletedGroupElement) {
	var  FieldElement

	FeSquare(&.X, &.X)
	FeSquare(&.Z, &.Y)
	FeSquare2(&.T, &.Z)
	FeAdd(&.Y, &.X, &.Y)
	FeSquare(&, &.Y)
	FeAdd(&.Y, &.Z, &.X)
	FeSub(&.Z, &.Z, &.X)
	FeSub(&.X, &, &.Y)
	FeSub(&.T, &.T, &.Z)
}

func ( *ProjectiveGroupElement) ( *[32]byte) {
	var , ,  FieldElement

	FeInvert(&, &.Z)
	FeMul(&, &.X, &)
	FeMul(&, &.Y, &)
	FeToBytes(, &)
	[31] ^= FeIsNegative(&) << 7
}

func ( *ExtendedGroupElement) () {
	FeZero(&.X)
	FeOne(&.Y)
	FeOne(&.Z)
	FeZero(&.T)
}

func ( *ExtendedGroupElement) ( *CompletedGroupElement) {
	var  ProjectiveGroupElement
	.ToProjective(&)
	.Double()
}

func ( *ExtendedGroupElement) ( *CachedGroupElement) {
	FeAdd(&.yPlusX, &.Y, &.X)
	FeSub(&.yMinusX, &.Y, &.X)
	FeCopy(&.Z, &.Z)
	FeMul(&.T2d, &.T, &d2)
}

func ( *ExtendedGroupElement) ( *ProjectiveGroupElement) {
	FeCopy(&.X, &.X)
	FeCopy(&.Y, &.Y)
	FeCopy(&.Z, &.Z)
}

func ( *ExtendedGroupElement) ( *[32]byte) {
	var , ,  FieldElement

	FeInvert(&, &.Z)
	FeMul(&, &.X, &)
	FeMul(&, &.Y, &)
	FeToBytes(, &)
	[31] ^= FeIsNegative(&) << 7
}

func ( *ExtendedGroupElement) ( *[32]byte) bool {
	var , , , ,  FieldElement

	FeFromBytes(&.Y, )
	FeOne(&.Z)
	FeSquare(&, &.Y)
	FeMul(&, &, &d)
	FeSub(&, &, &.Z) // u = y^2-1
	FeAdd(&, &, &.Z) // v = dy^2+1

	FeSquare(&, &)
	FeMul(&, &, &) // v3 = v^3
	FeSquare(&.X, &)
	FeMul(&.X, &.X, &)
	FeMul(&.X, &.X, &) // x = uv^7

	fePow22523(&.X, &.X) // x = (uv^7)^((q-5)/8)
	FeMul(&.X, &.X, &)
	FeMul(&.X, &.X, &) // x = uv^3(uv^7)^((q-5)/8)

	var ,  [32]byte

	FeSquare(&, &.X)
	FeMul(&, &, &)
	FeSub(&, &, &) // vx^2-u
	if FeIsNonZero(&) == 1 {
		FeAdd(&, &, &) // vx^2+u
		if FeIsNonZero(&) == 1 {
			return false
		}
		FeMul(&.X, &.X, &SqrtM1)

		FeToBytes(&, &.X)
		for ,  := range  {
			[31-] = 
		}
	}

	if FeIsNegative(&.X) != ([31] >> 7) {
		FeNeg(&.X, &.X)
	}

	FeMul(&.T, &.X, &.Y)
	return true
}

func ( *CompletedGroupElement) ( *ProjectiveGroupElement) {
	FeMul(&.X, &.X, &.T)
	FeMul(&.Y, &.Y, &.Z)
	FeMul(&.Z, &.Z, &.T)
}

func ( *CompletedGroupElement) ( *ExtendedGroupElement) {
	FeMul(&.X, &.X, &.T)
	FeMul(&.Y, &.Y, &.Z)
	FeMul(&.Z, &.Z, &.T)
	FeMul(&.T, &.X, &.Y)
}

func ( *PreComputedGroupElement) () {
	FeOne(&.yPlusX)
	FeOne(&.yMinusX)
	FeZero(&.xy2d)
}

func geAdd( *CompletedGroupElement,  *ExtendedGroupElement,  *CachedGroupElement) {
	var  FieldElement

	FeAdd(&.X, &.Y, &.X)
	FeSub(&.Y, &.Y, &.X)
	FeMul(&.Z, &.X, &.yPlusX)
	FeMul(&.Y, &.Y, &.yMinusX)
	FeMul(&.T, &.T2d, &.T)
	FeMul(&.X, &.Z, &.Z)
	FeAdd(&, &.X, &.X)
	FeSub(&.X, &.Z, &.Y)
	FeAdd(&.Y, &.Z, &.Y)
	FeAdd(&.Z, &, &.T)
	FeSub(&.T, &, &.T)
}

func geSub( *CompletedGroupElement,  *ExtendedGroupElement,  *CachedGroupElement) {
	var  FieldElement

	FeAdd(&.X, &.Y, &.X)
	FeSub(&.Y, &.Y, &.X)
	FeMul(&.Z, &.X, &.yMinusX)
	FeMul(&.Y, &.Y, &.yPlusX)
	FeMul(&.T, &.T2d, &.T)
	FeMul(&.X, &.Z, &.Z)
	FeAdd(&, &.X, &.X)
	FeSub(&.X, &.Z, &.Y)
	FeAdd(&.Y, &.Z, &.Y)
	FeSub(&.Z, &, &.T)
	FeAdd(&.T, &, &.T)
}

func geMixedAdd( *CompletedGroupElement,  *ExtendedGroupElement,  *PreComputedGroupElement) {
	var  FieldElement

	FeAdd(&.X, &.Y, &.X)
	FeSub(&.Y, &.Y, &.X)
	FeMul(&.Z, &.X, &.yPlusX)
	FeMul(&.Y, &.Y, &.yMinusX)
	FeMul(&.T, &.xy2d, &.T)
	FeAdd(&, &.Z, &.Z)
	FeSub(&.X, &.Z, &.Y)
	FeAdd(&.Y, &.Z, &.Y)
	FeAdd(&.Z, &, &.T)
	FeSub(&.T, &, &.T)
}

func geMixedSub( *CompletedGroupElement,  *ExtendedGroupElement,  *PreComputedGroupElement) {
	var  FieldElement

	FeAdd(&.X, &.Y, &.X)
	FeSub(&.Y, &.Y, &.X)
	FeMul(&.Z, &.X, &.yMinusX)
	FeMul(&.Y, &.Y, &.yPlusX)
	FeMul(&.T, &.xy2d, &.T)
	FeAdd(&, &.Z, &.Z)
	FeSub(&.X, &.Z, &.Y)
	FeAdd(&.Y, &.Z, &.Y)
	FeSub(&.Z, &, &.T)
	FeAdd(&.T, &, &.T)
}

func slide( *[256]int8,  *[32]byte) {
	for  := range  {
		[] = int8(1 & ([>>3] >> uint(&7)))
	}

	for  := range  {
		if [] != 0 {
			for  := 1;  <= 6 && + < 256; ++ {
				if [+] != 0 {
					if []+([+]<<uint()) <= 15 {
						[] += [+] << uint()
						[+] = 0
					} else if []-([+]<<uint()) >= -15 {
						[] -= [+] << uint()
						for  :=  + ;  < 256; ++ {
							if [] == 0 {
								[] = 1
								break
							}
							[] = 0
						}
					} else {
						break
					}
				}
			}
		}
	}
}

// GeDoubleScalarMultVartime sets r = a*A + b*B
// where a = a[0]+256*a[1]+...+256^31 a[31].
// and b = b[0]+256*b[1]+...+256^31 b[31].
// B is the Ed25519 base point (x,4/5) with x positive.
func ( *ProjectiveGroupElement,  *[32]byte,  *ExtendedGroupElement,  *[32]byte) {
	var ,  [256]int8
	var  [8]CachedGroupElement // A,3A,5A,7A,9A,11A,13A,15A
	var  CompletedGroupElement
	var ,  ExtendedGroupElement
	var  int

	slide(&, )
	slide(&, )

	.ToCached(&[0])
	.Double(&)
	.ToExtended(&)

	for  := 0;  < 7; ++ {
		geAdd(&, &, &[])
		.ToExtended(&)
		.ToCached(&[+1])
	}

	.Zero()

	for  = 255;  >= 0; -- {
		if [] != 0 || [] != 0 {
			break
		}
	}

	for ;  >= 0; -- {
		.Double(&)

		if [] > 0 {
			.ToExtended(&)
			geAdd(&, &, &[[]/2])
		} else if [] < 0 {
			.ToExtended(&)
			geSub(&, &, &[(-[])/2])
		}

		if [] > 0 {
			.ToExtended(&)
			geMixedAdd(&, &, &bi[[]/2])
		} else if [] < 0 {
			.ToExtended(&)
			geMixedSub(&, &, &bi[(-[])/2])
		}

		.ToProjective()
	}
}

// equal returns 1 if b == c and 0 otherwise, assuming that b and c are
// non-negative.
func equal(,  int32) int32 {
	 := uint32( ^ )
	--
	return int32( >> 31)
}

// negative returns 1 if b < 0 and 0 otherwise.
func negative( int32) int32 {
	return ( >> 31) & 1
}

func (,  *PreComputedGroupElement,  int32) {
	FeCMove(&.yPlusX, &.yPlusX, )
	FeCMove(&.yMinusX, &.yMinusX, )
	FeCMove(&.xy2d, &.xy2d, )
}

func selectPoint( *PreComputedGroupElement,  int32,  int32) {
	var  PreComputedGroupElement
	 := negative()
	 :=  - (((-) & ) << 1)

	.Zero()
	for  := int32(0);  < 8; ++ {
		PreComputedGroupElementCMove(, &base[][], equal(, +1))
	}
	FeCopy(&.yPlusX, &.yMinusX)
	FeCopy(&.yMinusX, &.yPlusX)
	FeNeg(&.xy2d, &.xy2d)
	PreComputedGroupElementCMove(, &, )
}

// GeScalarMultBase computes h = a*B, where
//   a = a[0]+256*a[1]+...+256^31 a[31]
//   B is the Ed25519 base point (x,4/5) with x positive.
//
// Preconditions:
//   a[31] <= 127
func ( *ExtendedGroupElement,  *[32]byte) {
	var  [64]int8

	for ,  := range  {
		[2*] = int8( & 15)
		[2*+1] = int8(( >> 4) & 15)
	}

	// each e[i] is between 0 and 15 and e[63] is between 0 and 7.

	 := int8(0)
	for  := 0;  < 63; ++ {
		[] += 
		 = ([] + 8) >> 4
		[] -=  << 4
	}
	[63] += 
	// each e[i] is between -8 and 8.

	.Zero()
	var  PreComputedGroupElement
	var  CompletedGroupElement
	for  := int32(1);  < 64;  += 2 {
		selectPoint(&, /2, int32([]))
		geMixedAdd(&, , &)
		.ToExtended()
	}

	var  ProjectiveGroupElement

	.Double(&)
	.ToProjective(&)
	.Double(&)
	.ToProjective(&)
	.Double(&)
	.ToProjective(&)
	.Double(&)
	.ToExtended()

	for  := int32(0);  < 64;  += 2 {
		selectPoint(&, /2, int32([]))
		geMixedAdd(&, , &)
		.ToExtended()
	}
}

// The scalars are GF(2^252 + 27742317777372353535851937790883648493).

// Input:
//   a[0]+256*a[1]+...+256^31*a[31] = a
//   b[0]+256*b[1]+...+256^31*b[31] = b
//   c[0]+256*c[1]+...+256^31*c[31] = c
//
// Output:
//   s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l
//   where l = 2^252 + 27742317777372353535851937790883648493.
func (, , ,  *[32]byte) {
	 := 2097151 & load3([:])
	 := 2097151 & (load4([2:]) >> 5)
	 := 2097151 & (load3([5:]) >> 2)
	 := 2097151 & (load4([7:]) >> 7)
	 := 2097151 & (load4([10:]) >> 4)
	 := 2097151 & (load3([13:]) >> 1)
	 := 2097151 & (load4([15:]) >> 6)
	 := 2097151 & (load3([18:]) >> 3)
	 := 2097151 & load3([21:])
	 := 2097151 & (load4([23:]) >> 5)
	 := 2097151 & (load3([26:]) >> 2)
	 := (load4([28:]) >> 7)
	 := 2097151 & load3([:])
	 := 2097151 & (load4([2:]) >> 5)
	 := 2097151 & (load3([5:]) >> 2)
	 := 2097151 & (load4([7:]) >> 7)
	 := 2097151 & (load4([10:]) >> 4)
	 := 2097151 & (load3([13:]) >> 1)
	 := 2097151 & (load4([15:]) >> 6)
	 := 2097151 & (load3([18:]) >> 3)
	 := 2097151 & load3([21:])
	 := 2097151 & (load4([23:]) >> 5)
	 := 2097151 & (load3([26:]) >> 2)
	 := (load4([28:]) >> 7)
	 := 2097151 & load3([:])
	 := 2097151 & (load4([2:]) >> 5)
	 := 2097151 & (load3([5:]) >> 2)
	 := 2097151 & (load4([7:]) >> 7)
	 := 2097151 & (load4([10:]) >> 4)
	 := 2097151 & (load3([13:]) >> 1)
	 := 2097151 & (load4([15:]) >> 6)
	 := 2097151 & (load3([18:]) >> 3)
	 := 2097151 & load3([21:])
	 := 2097151 & (load4([23:]) >> 5)
	 := 2097151 & (load3([26:]) >> 2)
	 := (load4([28:]) >> 7)
	var  [23]int64

	 :=  + *
	 :=  + * + *
	 :=  + * + * + *
	 :=  + * + * + * + *
	 :=  + * + * + * + * + *
	 :=  + * + * + * + * + * + *
	 :=  + * + * + * + * + * + * + *
	 :=  + * + * + * + * + * + * + * + *
	 :=  + * + * + * + * + * + * + * + * + *
	 :=  + * + * + * + * + * + * + * + * + * + *
	 :=  + * + * + * + * + * + * + * + * + * + * + *
	 :=  + * + * + * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + * + *
	 := * + * + * + * + * + * + *
	 := * + * + * + * + * + *
	 := * + * + * + * + *
	 := * + * + * + *
	 := * + * + *
	 := * + *
	 :=  * 
	 := int64(0)

	[0] = ( + (1 << 20)) >> 21
	 += [0]
	 -= [0] << 21
	[2] = ( + (1 << 20)) >> 21
	 += [2]
	 -= [2] << 21
	[4] = ( + (1 << 20)) >> 21
	 += [4]
	 -= [4] << 21
	[6] = ( + (1 << 20)) >> 21
	 += [6]
	 -= [6] << 21
	[8] = ( + (1 << 20)) >> 21
	 += [8]
	 -= [8] << 21
	[10] = ( + (1 << 20)) >> 21
	 += [10]
	 -= [10] << 21
	[12] = ( + (1 << 20)) >> 21
	 += [12]
	 -= [12] << 21
	[14] = ( + (1 << 20)) >> 21
	 += [14]
	 -= [14] << 21
	[16] = ( + (1 << 20)) >> 21
	 += [16]
	 -= [16] << 21
	[18] = ( + (1 << 20)) >> 21
	 += [18]
	 -= [18] << 21
	[20] = ( + (1 << 20)) >> 21
	 += [20]
	 -= [20] << 21
	[22] = ( + (1 << 20)) >> 21
	 += [22]
	 -= [22] << 21

	[1] = ( + (1 << 20)) >> 21
	 += [1]
	 -= [1] << 21
	[3] = ( + (1 << 20)) >> 21
	 += [3]
	 -= [3] << 21
	[5] = ( + (1 << 20)) >> 21
	 += [5]
	 -= [5] << 21
	[7] = ( + (1 << 20)) >> 21
	 += [7]
	 -= [7] << 21
	[9] = ( + (1 << 20)) >> 21
	 += [9]
	 -= [9] << 21
	[11] = ( + (1 << 20)) >> 21
	 += [11]
	 -= [11] << 21
	[13] = ( + (1 << 20)) >> 21
	 += [13]
	 -= [13] << 21
	[15] = ( + (1 << 20)) >> 21
	 += [15]
	 -= [15] << 21
	[17] = ( + (1 << 20)) >> 21
	 += [17]
	 -= [17] << 21
	[19] = ( + (1 << 20)) >> 21
	 += [19]
	 -= [19] << 21
	[21] = ( + (1 << 20)) >> 21
	 += [21]
	 -= [21] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[6] = ( + (1 << 20)) >> 21
	 += [6]
	 -= [6] << 21
	[8] = ( + (1 << 20)) >> 21
	 += [8]
	 -= [8] << 21
	[10] = ( + (1 << 20)) >> 21
	 += [10]
	 -= [10] << 21
	[12] = ( + (1 << 20)) >> 21
	 += [12]
	 -= [12] << 21
	[14] = ( + (1 << 20)) >> 21
	 += [14]
	 -= [14] << 21
	[16] = ( + (1 << 20)) >> 21
	 += [16]
	 -= [16] << 21

	[7] = ( + (1 << 20)) >> 21
	 += [7]
	 -= [7] << 21
	[9] = ( + (1 << 20)) >> 21
	 += [9]
	 -= [9] << 21
	[11] = ( + (1 << 20)) >> 21
	 += [11]
	 -= [11] << 21
	[13] = ( + (1 << 20)) >> 21
	 += [13]
	 -= [13] << 21
	[15] = ( + (1 << 20)) >> 21
	 += [15]
	 -= [15] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[0] = ( + (1 << 20)) >> 21
	 += [0]
	 -= [0] << 21
	[2] = ( + (1 << 20)) >> 21
	 += [2]
	 -= [2] << 21
	[4] = ( + (1 << 20)) >> 21
	 += [4]
	 -= [4] << 21
	[6] = ( + (1 << 20)) >> 21
	 += [6]
	 -= [6] << 21
	[8] = ( + (1 << 20)) >> 21
	 += [8]
	 -= [8] << 21
	[10] = ( + (1 << 20)) >> 21
	 += [10]
	 -= [10] << 21

	[1] = ( + (1 << 20)) >> 21
	 += [1]
	 -= [1] << 21
	[3] = ( + (1 << 20)) >> 21
	 += [3]
	 -= [3] << 21
	[5] = ( + (1 << 20)) >> 21
	 += [5]
	 -= [5] << 21
	[7] = ( + (1 << 20)) >> 21
	 += [7]
	 -= [7] << 21
	[9] = ( + (1 << 20)) >> 21
	 += [9]
	 -= [9] << 21
	[11] = ( + (1 << 20)) >> 21
	 += [11]
	 -= [11] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[0] =  >> 21
	 += [0]
	 -= [0] << 21
	[1] =  >> 21
	 += [1]
	 -= [1] << 21
	[2] =  >> 21
	 += [2]
	 -= [2] << 21
	[3] =  >> 21
	 += [3]
	 -= [3] << 21
	[4] =  >> 21
	 += [4]
	 -= [4] << 21
	[5] =  >> 21
	 += [5]
	 -= [5] << 21
	[6] =  >> 21
	 += [6]
	 -= [6] << 21
	[7] =  >> 21
	 += [7]
	 -= [7] << 21
	[8] =  >> 21
	 += [8]
	 -= [8] << 21
	[9] =  >> 21
	 += [9]
	 -= [9] << 21
	[10] =  >> 21
	 += [10]
	 -= [10] << 21
	[11] =  >> 21
	 += [11]
	 -= [11] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[0] =  >> 21
	 += [0]
	 -= [0] << 21
	[1] =  >> 21
	 += [1]
	 -= [1] << 21
	[2] =  >> 21
	 += [2]
	 -= [2] << 21
	[3] =  >> 21
	 += [3]
	 -= [3] << 21
	[4] =  >> 21
	 += [4]
	 -= [4] << 21
	[5] =  >> 21
	 += [5]
	 -= [5] << 21
	[6] =  >> 21
	 += [6]
	 -= [6] << 21
	[7] =  >> 21
	 += [7]
	 -= [7] << 21
	[8] =  >> 21
	 += [8]
	 -= [8] << 21
	[9] =  >> 21
	 += [9]
	 -= [9] << 21
	[10] =  >> 21
	 += [10]
	 -= [10] << 21

	[0] = byte( >> 0)
	[1] = byte( >> 8)
	[2] = byte(( >> 16) | ( << 5))
	[3] = byte( >> 3)
	[4] = byte( >> 11)
	[5] = byte(( >> 19) | ( << 2))
	[6] = byte( >> 6)
	[7] = byte(( >> 14) | ( << 7))
	[8] = byte( >> 1)
	[9] = byte( >> 9)
	[10] = byte(( >> 17) | ( << 4))
	[11] = byte( >> 4)
	[12] = byte( >> 12)
	[13] = byte(( >> 20) | ( << 1))
	[14] = byte( >> 7)
	[15] = byte(( >> 15) | ( << 6))
	[16] = byte( >> 2)
	[17] = byte( >> 10)
	[18] = byte(( >> 18) | ( << 3))
	[19] = byte( >> 5)
	[20] = byte( >> 13)
	[21] = byte( >> 0)
	[22] = byte( >> 8)
	[23] = byte(( >> 16) | ( << 5))
	[24] = byte( >> 3)
	[25] = byte( >> 11)
	[26] = byte(( >> 19) | ( << 2))
	[27] = byte( >> 6)
	[28] = byte(( >> 14) | ( << 7))
	[29] = byte( >> 1)
	[30] = byte( >> 9)
	[31] = byte( >> 17)
}

// Input:
//   s[0]+256*s[1]+...+256^63*s[63] = s
//
// Output:
//   s[0]+256*s[1]+...+256^31*s[31] = s mod l
//   where l = 2^252 + 27742317777372353535851937790883648493.
func ( *[32]byte,  *[64]byte) {
	 := 2097151 & load3([:])
	 := 2097151 & (load4([2:]) >> 5)
	 := 2097151 & (load3([5:]) >> 2)
	 := 2097151 & (load4([7:]) >> 7)
	 := 2097151 & (load4([10:]) >> 4)
	 := 2097151 & (load3([13:]) >> 1)
	 := 2097151 & (load4([15:]) >> 6)
	 := 2097151 & (load3([18:]) >> 3)
	 := 2097151 & load3([21:])
	 := 2097151 & (load4([23:]) >> 5)
	 := 2097151 & (load3([26:]) >> 2)
	 := 2097151 & (load4([28:]) >> 7)
	 := 2097151 & (load4([31:]) >> 4)
	 := 2097151 & (load3([34:]) >> 1)
	 := 2097151 & (load4([36:]) >> 6)
	 := 2097151 & (load3([39:]) >> 3)
	 := 2097151 & load3([42:])
	 := 2097151 & (load4([44:]) >> 5)
	 := 2097151 & (load3([47:]) >> 2)
	 := 2097151 & (load4([49:]) >> 7)
	 := 2097151 & (load4([52:]) >> 4)
	 := 2097151 & (load3([55:]) >> 1)
	 := 2097151 & (load4([57:]) >> 6)
	 := (load4([60:]) >> 3)

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	var  [17]int64

	[6] = ( + (1 << 20)) >> 21
	 += [6]
	 -= [6] << 21
	[8] = ( + (1 << 20)) >> 21
	 += [8]
	 -= [8] << 21
	[10] = ( + (1 << 20)) >> 21
	 += [10]
	 -= [10] << 21
	[12] = ( + (1 << 20)) >> 21
	 += [12]
	 -= [12] << 21
	[14] = ( + (1 << 20)) >> 21
	 += [14]
	 -= [14] << 21
	[16] = ( + (1 << 20)) >> 21
	 += [16]
	 -= [16] << 21

	[7] = ( + (1 << 20)) >> 21
	 += [7]
	 -= [7] << 21
	[9] = ( + (1 << 20)) >> 21
	 += [9]
	 -= [9] << 21
	[11] = ( + (1 << 20)) >> 21
	 += [11]
	 -= [11] << 21
	[13] = ( + (1 << 20)) >> 21
	 += [13]
	 -= [13] << 21
	[15] = ( + (1 << 20)) >> 21
	 += [15]
	 -= [15] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[0] = ( + (1 << 20)) >> 21
	 += [0]
	 -= [0] << 21
	[2] = ( + (1 << 20)) >> 21
	 += [2]
	 -= [2] << 21
	[4] = ( + (1 << 20)) >> 21
	 += [4]
	 -= [4] << 21
	[6] = ( + (1 << 20)) >> 21
	 += [6]
	 -= [6] << 21
	[8] = ( + (1 << 20)) >> 21
	 += [8]
	 -= [8] << 21
	[10] = ( + (1 << 20)) >> 21
	 += [10]
	 -= [10] << 21

	[1] = ( + (1 << 20)) >> 21
	 += [1]
	 -= [1] << 21
	[3] = ( + (1 << 20)) >> 21
	 += [3]
	 -= [3] << 21
	[5] = ( + (1 << 20)) >> 21
	 += [5]
	 -= [5] << 21
	[7] = ( + (1 << 20)) >> 21
	 += [7]
	 -= [7] << 21
	[9] = ( + (1 << 20)) >> 21
	 += [9]
	 -= [9] << 21
	[11] = ( + (1 << 20)) >> 21
	 += [11]
	 -= [11] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[0] =  >> 21
	 += [0]
	 -= [0] << 21
	[1] =  >> 21
	 += [1]
	 -= [1] << 21
	[2] =  >> 21
	 += [2]
	 -= [2] << 21
	[3] =  >> 21
	 += [3]
	 -= [3] << 21
	[4] =  >> 21
	 += [4]
	 -= [4] << 21
	[5] =  >> 21
	 += [5]
	 -= [5] << 21
	[6] =  >> 21
	 += [6]
	 -= [6] << 21
	[7] =  >> 21
	 += [7]
	 -= [7] << 21
	[8] =  >> 21
	 += [8]
	 -= [8] << 21
	[9] =  >> 21
	 += [9]
	 -= [9] << 21
	[10] =  >> 21
	 += [10]
	 -= [10] << 21
	[11] =  >> 21
	 += [11]
	 -= [11] << 21

	 +=  * 666643
	 +=  * 470296
	 +=  * 654183
	 -=  * 997805
	 +=  * 136657
	 -=  * 683901
	 = 0

	[0] =  >> 21
	 += [0]
	 -= [0] << 21
	[1] =  >> 21
	 += [1]
	 -= [1] << 21
	[2] =  >> 21
	 += [2]
	 -= [2] << 21
	[3] =  >> 21
	 += [3]
	 -= [3] << 21
	[4] =  >> 21
	 += [4]
	 -= [4] << 21
	[5] =  >> 21
	 += [5]
	 -= [5] << 21
	[6] =  >> 21
	 += [6]
	 -= [6] << 21
	[7] =  >> 21
	 += [7]
	 -= [7] << 21
	[8] =  >> 21
	 += [8]
	 -= [8] << 21
	[9] =  >> 21
	 += [9]
	 -= [9] << 21
	[10] =  >> 21
	 += [10]
	 -= [10] << 21

	[0] = byte( >> 0)
	[1] = byte( >> 8)
	[2] = byte(( >> 16) | ( << 5))
	[3] = byte( >> 3)
	[4] = byte( >> 11)
	[5] = byte(( >> 19) | ( << 2))
	[6] = byte( >> 6)
	[7] = byte(( >> 14) | ( << 7))
	[8] = byte( >> 1)
	[9] = byte( >> 9)
	[10] = byte(( >> 17) | ( << 4))
	[11] = byte( >> 4)
	[12] = byte( >> 12)
	[13] = byte(( >> 20) | ( << 1))
	[14] = byte( >> 7)
	[15] = byte(( >> 15) | ( << 6))
	[16] = byte( >> 2)
	[17] = byte( >> 10)
	[18] = byte(( >> 18) | ( << 3))
	[19] = byte( >> 5)
	[20] = byte( >> 13)
	[21] = byte( >> 0)
	[22] = byte( >> 8)
	[23] = byte(( >> 16) | ( << 5))
	[24] = byte( >> 3)
	[25] = byte( >> 11)
	[26] = byte(( >> 19) | ( << 2))
	[27] = byte( >> 6)
	[28] = byte(( >> 14) | ( << 7))
	[29] = byte( >> 1)
	[30] = byte( >> 9)
	[31] = byte( >> 17)
}

// order is the order of Curve25519 in little-endian form.
var order = [4]uint64{0x5812631a5cf5d3ed, 0x14def9dea2f79cd6, 0, 0x1000000000000000}

// ScMinimal returns true if the given scalar is less than the order of the
// curve.
func ( *[32]byte) bool {
	for  := 3; ; -- {
		 := binary.LittleEndian.Uint64([*8:])
		if  > order[] {
			return false
		} else if  < order[] {
			break
		} else if  == 0 {
			return false
		}
	}

	return true
}