summary refs log tree commit diff
path: root/vendor/filippo.io/edwards25519/tables.go
diff options
context:
space:
mode:
authorEmile <git@emile.space>2024-10-25 15:55:50 +0200
committerEmile <git@emile.space>2024-10-25 15:55:50 +0200
commitc90f36e3dd179d2de96f4f5fe38d8dc9a9de6dfe (patch)
tree89e9afb41c5bf76f48cfb09305a2d3db8d302b06 /vendor/filippo.io/edwards25519/tables.go
parent98bbb0f559a8883bc47bae80607dbe326a448e61 (diff)
vendor HEAD main
Diffstat (limited to 'vendor/filippo.io/edwards25519/tables.go')
-rw-r--r--vendor/filippo.io/edwards25519/tables.go129
1 files changed, 129 insertions, 0 deletions
diff --git a/vendor/filippo.io/edwards25519/tables.go b/vendor/filippo.io/edwards25519/tables.go
new file mode 100644
index 0000000..83234bb
--- /dev/null
+++ b/vendor/filippo.io/edwards25519/tables.go
@@ -0,0 +1,129 @@
+// Copyright (c) 2019 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 (
+	"crypto/subtle"
+)
+
+// A dynamic lookup table for variable-base, constant-time scalar muls.
+type projLookupTable struct {
+	points [8]projCached
+}
+
+// A precomputed lookup table for fixed-base, constant-time scalar muls.
+type affineLookupTable struct {
+	points [8]affineCached
+}
+
+// A dynamic lookup table for variable-base, variable-time scalar muls.
+type nafLookupTable5 struct {
+	points [8]projCached
+}
+
+// A precomputed lookup table for fixed-base, variable-time scalar muls.
+type nafLookupTable8 struct {
+	points [64]affineCached
+}
+
+// Constructors.
+
+// Builds a lookup table at runtime. Fast.
+func (v *projLookupTable) FromP3(q *Point) {
+	// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
+	// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
+	v.points[0].FromP3(q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		// Compute (i+1)*Q as Q + i*Q and convert to a projCached
+		// This is needlessly complicated because the API has explicit
+		// receivers instead of creating stack objects and relying on RVO
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
+	}
+}
+
+// This is not optimised for speed; fixed-base tables should be precomputed.
+func (v *affineLookupTable) FromP3(q *Point) {
+	// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
+	// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
+	v.points[0].FromP3(q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		// Compute (i+1)*Q as Q + i*Q and convert to affineCached
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i])))
+	}
+}
+
+// Builds a lookup table at runtime. Fast.
+func (v *nafLookupTable5) FromP3(q *Point) {
+	// Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q
+	// This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q
+	v.points[0].FromP3(q)
+	q2 := Point{}
+	q2.Add(q, q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 7; i++ {
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(&q2, &v.points[i])))
+	}
+}
+
+// This is not optimised for speed; fixed-base tables should be precomputed.
+func (v *nafLookupTable8) FromP3(q *Point) {
+	v.points[0].FromP3(q)
+	q2 := Point{}
+	q2.Add(q, q)
+	tmpP3 := Point{}
+	tmpP1xP1 := projP1xP1{}
+	for i := 0; i < 63; i++ {
+		v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(&q2, &v.points[i])))
+	}
+}
+
+// Selectors.
+
+// Set dest to x*Q, where -8 <= x <= 8, in constant time.
+func (v *projLookupTable) SelectInto(dest *projCached, x int8) {
+	// Compute xabs = |x|
+	xmask := x >> 7
+	xabs := uint8((x + xmask) ^ xmask)
+
+	dest.Zero()
+	for j := 1; j <= 8; j++ {
+		// Set dest = j*Q if |x| = j
+		cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
+		dest.Select(&v.points[j-1], dest, cond)
+	}
+	// Now dest = |x|*Q, conditionally negate to get x*Q
+	dest.CondNeg(int(xmask & 1))
+}
+
+// Set dest to x*Q, where -8 <= x <= 8, in constant time.
+func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) {
+	// Compute xabs = |x|
+	xmask := x >> 7
+	xabs := uint8((x + xmask) ^ xmask)
+
+	dest.Zero()
+	for j := 1; j <= 8; j++ {
+		// Set dest = j*Q if |x| = j
+		cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
+		dest.Select(&v.points[j-1], dest, cond)
+	}
+	// Now dest = |x|*Q, conditionally negate to get x*Q
+	dest.CondNeg(int(xmask & 1))
+}
+
+// Given odd x with 0 < x < 2^4, return x*Q (in variable time).
+func (v *nafLookupTable5) SelectInto(dest *projCached, x int8) {
+	*dest = v.points[x/2]
+}
+
+// Given odd x with 0 < x < 2^7, return x*Q (in variable time).
+func (v *nafLookupTable8) SelectInto(dest *affineCached, x int8) {
+	*dest = v.points[x/2]
+}