summaryrefslogtreecommitdiff
path: root/cli/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go
diff options
context:
space:
mode:
Diffstat (limited to 'cli/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go')
-rw-r--r--cli/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go196
1 files changed, 196 insertions, 0 deletions
diff --git a/cli/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go b/cli/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go
new file mode 100644
index 0000000..fa613de
--- /dev/null
+++ b/cli/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go
@@ -0,0 +1,196 @@
+// Copyright (c) 2014-2015 The btcsuite developers
+// Copyright (c) 2015-2021 The Decred developers
+// Use of this source code is governed by an ISC
+// license that can be found in the LICENSE file.
+
+// This file is ignored during the regular build due to the following build tag.
+// This build tag is set during go generate.
+//go:build gensecp256k1
+// +build gensecp256k1
+
+package secp256k1
+
+// References:
+// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
+
+import (
+ "encoding/binary"
+ "math/big"
+)
+
+// compressedBytePoints are dummy points used so the code which generates the
+// real values can compile.
+var compressedBytePoints = ""
+
+// SerializedBytePoints returns a serialized byte slice which contains all of
+// the possible points per 8-bit window. This is used to when generating
+// compressedbytepoints.go.
+func SerializedBytePoints() []byte {
+ // Calculate G^(2^i) for i in 0..255. These are used to avoid recomputing
+ // them for each digit of the 8-bit windows.
+ doublingPoints := make([]JacobianPoint, curveParams.BitSize)
+ var q JacobianPoint
+ bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &q)
+ for i := 0; i < curveParams.BitSize; i++ {
+ // Q = 2*Q.
+ doublingPoints[i] = q
+ DoubleNonConst(&q, &q)
+ }
+
+ // Separate the bits into byte-sized windows.
+ curveByteSize := curveParams.BitSize / 8
+ serialized := make([]byte, curveByteSize*256*2*10*4)
+ offset := 0
+ for byteNum := 0; byteNum < curveByteSize; byteNum++ {
+ // Grab the 8 bits that make up this byte from doubling points.
+ startingBit := 8 * (curveByteSize - byteNum - 1)
+ windowPoints := doublingPoints[startingBit : startingBit+8]
+
+ // Compute all points in this window, convert them to affine, and
+ // serialize them.
+ for i := 0; i < 256; i++ {
+ var point JacobianPoint
+ for bit := 0; bit < 8; bit++ {
+ if i>>uint(bit)&1 == 1 {
+ AddNonConst(&point, &windowPoints[bit], &point)
+ }
+ }
+ point.ToAffine()
+
+ for i := 0; i < len(point.X.n); i++ {
+ binary.LittleEndian.PutUint32(serialized[offset:], point.X.n[i])
+ offset += 4
+ }
+ for i := 0; i < len(point.Y.n); i++ {
+ binary.LittleEndian.PutUint32(serialized[offset:], point.Y.n[i])
+ offset += 4
+ }
+ }
+ }
+
+ return serialized
+}
+
+// sqrt returns the square root of the provided big integer using Newton's
+// method. It's only compiled and used during generation of pre-computed
+// values, so speed is not a huge concern.
+func sqrt(n *big.Int) *big.Int {
+ // Initial guess = 2^(log_2(n)/2)
+ guess := big.NewInt(2)
+ guess.Exp(guess, big.NewInt(int64(n.BitLen()/2)), nil)
+
+ // Now refine using Newton's method.
+ big2 := big.NewInt(2)
+ prevGuess := big.NewInt(0)
+ for {
+ prevGuess.Set(guess)
+ guess.Add(guess, new(big.Int).Div(n, guess))
+ guess.Div(guess, big2)
+ if guess.Cmp(prevGuess) == 0 {
+ break
+ }
+ }
+ return guess
+}
+
+// EndomorphismVectors runs the first 3 steps of algorithm 3.74 from [GECC] to
+// generate the linearly independent vectors needed to generate a balanced
+// length-two representation of a multiplier such that k = k1 + k2λ (mod N) and
+// returns them. Since the values will always be the same given the fact that N
+// and λ are fixed, the final results can be accelerated by storing the
+// precomputed values.
+func EndomorphismVectors() (a1, b1, a2, b2 *big.Int) {
+ bigMinus1 := big.NewInt(-1)
+
+ // This section uses an extended Euclidean algorithm to generate a
+ // sequence of equations:
+ // s[i] * N + t[i] * λ = r[i]
+
+ nSqrt := sqrt(curveParams.N)
+ u, v := new(big.Int).Set(curveParams.N), new(big.Int).Set(endomorphismLambda)
+ x1, y1 := big.NewInt(1), big.NewInt(0)
+ x2, y2 := big.NewInt(0), big.NewInt(1)
+ q, r := new(big.Int), new(big.Int)
+ qu, qx1, qy1 := new(big.Int), new(big.Int), new(big.Int)
+ s, t := new(big.Int), new(big.Int)
+ ri, ti := new(big.Int), new(big.Int)
+ a1, b1, a2, b2 = new(big.Int), new(big.Int), new(big.Int), new(big.Int)
+ found, oneMore := false, false
+ for u.Sign() != 0 {
+ // q = v/u
+ q.Div(v, u)
+
+ // r = v - q*u
+ qu.Mul(q, u)
+ r.Sub(v, qu)
+
+ // s = x2 - q*x1
+ qx1.Mul(q, x1)
+ s.Sub(x2, qx1)
+
+ // t = y2 - q*y1
+ qy1.Mul(q, y1)
+ t.Sub(y2, qy1)
+
+ // v = u, u = r, x2 = x1, x1 = s, y2 = y1, y1 = t
+ v.Set(u)
+ u.Set(r)
+ x2.Set(x1)
+ x1.Set(s)
+ y2.Set(y1)
+ y1.Set(t)
+
+ // As soon as the remainder is less than the sqrt of n, the
+ // values of a1 and b1 are known.
+ if !found && r.Cmp(nSqrt) < 0 {
+ // When this condition executes ri and ti represent the
+ // r[i] and t[i] values such that i is the greatest
+ // index for which r >= sqrt(n). Meanwhile, the current
+ // r and t values are r[i+1] and t[i+1], respectively.
+
+ // a1 = r[i+1], b1 = -t[i+1]
+ a1.Set(r)
+ b1.Mul(t, bigMinus1)
+ found = true
+ oneMore = true
+
+ // Skip to the next iteration so ri and ti are not
+ // modified.
+ continue
+
+ } else if oneMore {
+ // When this condition executes ri and ti still
+ // represent the r[i] and t[i] values while the current
+ // r and t are r[i+2] and t[i+2], respectively.
+
+ // sum1 = r[i]^2 + t[i]^2
+ rSquared := new(big.Int).Mul(ri, ri)
+ tSquared := new(big.Int).Mul(ti, ti)
+ sum1 := new(big.Int).Add(rSquared, tSquared)
+
+ // sum2 = r[i+2]^2 + t[i+2]^2
+ r2Squared := new(big.Int).Mul(r, r)
+ t2Squared := new(big.Int).Mul(t, t)
+ sum2 := new(big.Int).Add(r2Squared, t2Squared)
+
+ // if (r[i]^2 + t[i]^2) <= (r[i+2]^2 + t[i+2]^2)
+ if sum1.Cmp(sum2) <= 0 {
+ // a2 = r[i], b2 = -t[i]
+ a2.Set(ri)
+ b2.Mul(ti, bigMinus1)
+ } else {
+ // a2 = r[i+2], b2 = -t[i+2]
+ a2.Set(r)
+ b2.Mul(t, bigMinus1)
+ }
+
+ // All done.
+ break
+ }
+
+ ri.Set(r)
+ ti.Set(t)
+ }
+
+ return a1, b1, a2, b2
+}