diff --git a/edwards25519/cmove.go b/edwards25519/cmove.go new file mode 100644 index 0000000..5153f53 --- /dev/null +++ b/edwards25519/cmove.go @@ -0,0 +1,21 @@ +// 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. + +// +build !amd64 + +package edwards25519 + +func FeCMove(f, g *FieldElement, b int32) { + b = -b + f[0] ^= b & (f[0] ^ g[0]) + f[1] ^= b & (f[1] ^ g[1]) + f[2] ^= b & (f[2] ^ g[2]) + f[3] ^= b & (f[3] ^ g[3]) + f[4] ^= b & (f[4] ^ g[4]) + f[5] ^= b & (f[5] ^ g[5]) + f[6] ^= b & (f[6] ^ g[6]) + f[7] ^= b & (f[7] ^ g[7]) + f[8] ^= b & (f[8] ^ g[8]) + f[9] ^= b & (f[9] ^ g[9]) +} diff --git a/edwards25519/cmove_amd64.s b/edwards25519/cmove_amd64.s new file mode 100644 index 0000000..afaae4e --- /dev/null +++ b/edwards25519/cmove_amd64.s @@ -0,0 +1,32 @@ +// 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. + +#include "textflag.h" + +// func FeCMove(f, g *FieldElement, b int32) +TEXT ·FeCMove(SB),NOSPLIT,$0 + MOVQ f+0(FP), AX + MOVQ g+8(FP), BX + MOVL b+16(FP), CX + + MOVQ 0(BX),R11 + MOVQ 8(BX),R12 + MOVQ 16(BX),R13 + MOVQ 24(BX),R14 + MOVQ 32(BX),R15 + + MOVQ $0,DX + CMPQ DX, CX + CMOVQEQ 0(AX), R11 + CMOVQEQ 8(AX), R12 + CMOVQEQ 16(AX),R13 + CMOVQEQ 24(AX),R14 + CMOVQEQ 32(AX),R15 + + MOVQ R11,0(AX) + MOVQ R12,8(AX) + MOVQ R13,16(AX) + MOVQ R14,24(AX) + MOVQ R15,32(AX) + RET diff --git a/edwards25519/cmove_decl.go b/edwards25519/cmove_decl.go new file mode 100644 index 0000000..4e2cd4d --- /dev/null +++ b/edwards25519/cmove_decl.go @@ -0,0 +1,14 @@ +// 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. + +// +build amd64 + +package edwards25519 + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +//go:noescape +func FeCMove(f, g *FieldElement, b int32) diff --git a/edwards25519/edwards25519.go b/edwards25519/edwards25519.go index 9079818..dd4afc2 100644 --- a/edwards25519/edwards25519.go +++ b/edwards25519/edwards25519.go @@ -16,15 +16,30 @@ package edwards25519 // context. type FieldElement [10]int32 -var zero FieldElement - func FeZero(fe *FieldElement) { - copy(fe[:], zero[:]) + fe[0] = 0 + fe[1] = 0 + fe[2] = 0 + fe[3] = 0 + fe[4] = 0 + fe[5] = 0 + fe[6] = 0 + fe[7] = 0 + fe[8] = 0 + fe[9] = 0 } func FeOne(fe *FieldElement) { - FeZero(fe) fe[0] = 1 + fe[1] = 0 + fe[2] = 0 + fe[3] = 0 + fe[4] = 0 + fe[5] = 0 + fe[6] = 0 + fe[7] = 0 + fe[8] = 0 + fe[9] = 0 } func FeAdd(dst, a, b *FieldElement) { @@ -57,24 +72,6 @@ func FeCopy(dst, src *FieldElement) { copy(dst[:], src[:]) } -// Replace (f,g) with (g,g) if b == 1; -// replace (f,g) with (f,g) if b == 0. -// -// Preconditions: b in {0,1}. -func FeCMove(f, g *FieldElement, b int32) { - b = -b - f[0] ^= b & (f[0] ^ g[0]) - f[1] ^= b & (f[1] ^ g[1]) - f[2] ^= b & (f[2] ^ g[2]) - f[3] ^= b & (f[3] ^ g[3]) - f[4] ^= b & (f[4] ^ g[4]) - f[5] ^= b & (f[5] ^ g[5]) - f[6] ^= b & (f[6] ^ g[6]) - f[7] ^= b & (f[7] ^ g[7]) - f[8] ^= b & (f[8] ^ g[8]) - f[9] ^= b & (f[9] ^ g[9]) -} - func load3(in []byte) int64 { var r int64 r = int64(in[0])