Consistency and general cleanup in btcec.
This commit contains various modifications for code and comment consistency in the btcec package: - Call out references at the top and reference them by their identifier in the other comments - Remove a TODO that no longer applies - Add comments to the fields in the KoblitzCurve struct and reorder them slightly - Make comments wrap to 80 - Cleanup code that was far exceeding col 80 (only function declarations typically do this) - Extend block comments to use as much of the 80 cols as available - Add a bit more explanation in a couple of places - Update copyright year on secp256k1.go - Fix a couple of typos in the comments
This commit is contained in:
parent
4b84bd52dd
commit
2713c8528d
3 changed files with 109 additions and 88 deletions
191
btcec/btcec.go
191
btcec/btcec.go
|
@ -9,6 +9,8 @@ package btcec
|
||||||
// References:
|
// References:
|
||||||
// [SECG]: Recommended Elliptic Curve Domain Parameters
|
// [SECG]: Recommended Elliptic Curve Domain Parameters
|
||||||
// http://www.secg.org/sec2-v2.pdf
|
// http://www.secg.org/sec2-v2.pdf
|
||||||
|
//
|
||||||
|
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
|
||||||
|
|
||||||
// This package operates, internally, on Jacobian coordinates. For a given
|
// This package operates, internally, on Jacobian coordinates. For a given
|
||||||
// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
|
// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
|
||||||
|
@ -23,9 +25,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO: examine if we need to care about EC optimization as descibed here
|
|
||||||
// https://bitcointalk.org/index.php?topic=155054.0;all
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// fieldOne is simply the integer 1 in field representation. It is
|
// fieldOne is simply the integer 1 in field representation. It is
|
||||||
// used to avoid needing to create it multiple times during the internal
|
// used to avoid needing to create it multiple times during the internal
|
||||||
|
@ -40,21 +39,29 @@ type KoblitzCurve struct {
|
||||||
q *big.Int
|
q *big.Int
|
||||||
H int // cofactor of the curve.
|
H int // cofactor of the curve.
|
||||||
|
|
||||||
// The next 6 values are used specifically for endomorphism optimizations
|
// byteSize is simply the bit size / 8 and is provided for convenience
|
||||||
// in ScalarMult.
|
// since it is calculated repeatedly.
|
||||||
|
byteSize int
|
||||||
|
|
||||||
// lambda should fulfill lambda^3 = 1 mod N where N is the order of G
|
// bytePoints
|
||||||
lambda *big.Int
|
|
||||||
// beta should fulfill beta^3 = 1 mod P where P is the prime field of the curve
|
|
||||||
beta *fieldVal
|
|
||||||
// a1, b1, a2 and b2 are explained in detail in Guide To Elliptical Curve
|
|
||||||
// Cryptography (Hankerson, Menezes, Vanstone) in Algorithm 3.74
|
|
||||||
a1 *big.Int
|
|
||||||
b1 *big.Int
|
|
||||||
a2 *big.Int
|
|
||||||
b2 *big.Int
|
|
||||||
byteSize int
|
|
||||||
bytePoints *[32][256][3]fieldVal
|
bytePoints *[32][256][3]fieldVal
|
||||||
|
|
||||||
|
// The next 6 values are used specifically for endomorphism
|
||||||
|
// optimizations in ScalarMult.
|
||||||
|
|
||||||
|
// lambda must fulfill lambda^3 = 1 mod N where N is the order of G.
|
||||||
|
lambda *big.Int
|
||||||
|
|
||||||
|
// beta must fulfill beta^3 = 1 mod P where P is the prime field of the
|
||||||
|
// curve.
|
||||||
|
beta *fieldVal
|
||||||
|
|
||||||
|
// See the EndomorphismVectors in gensecp256k1.go to see how these are
|
||||||
|
// derived.
|
||||||
|
a1 *big.Int
|
||||||
|
b1 *big.Int
|
||||||
|
a2 *big.Int
|
||||||
|
b2 *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Params returns the parameters for the curve.
|
// Params returns the parameters for the curve.
|
||||||
|
@ -609,20 +616,23 @@ func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
|
||||||
return curve.fieldJacobianToBigAffine(fx3, fy3, fz3)
|
return curve.fieldJacobianToBigAffine(fx3, fy3, fz3)
|
||||||
}
|
}
|
||||||
|
|
||||||
// splitK returns a balanced length-two representation of k and their
|
// splitK returns a balanced length-two representation of k and their signs.
|
||||||
// signs.
|
// This is algorithm 3.74 from [GECC].
|
||||||
// This is algorithm 3.74 from Guide to Elliptical Curve Cryptography (ref above)
|
//
|
||||||
// One thing of note about this algorithm is that no matter what c1 and c2 are,
|
// One thing of note about this algorithm is that no matter what c1 and c2 are,
|
||||||
// the final equation of k = k1 + k2 * lambda (mod n) will hold. This is provable
|
// the final equation of k = k1 + k2 * lambda (mod n) will hold. This is
|
||||||
// mathematically due to how a1/b1/a2/b2 are computed.
|
// provable mathematically due to how a1/b1/a2/b2 are computed.
|
||||||
|
//
|
||||||
// c1 and c2 are chosen to minimize the max(k1,k2).
|
// c1 and c2 are chosen to minimize the max(k1,k2).
|
||||||
func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
|
func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
|
||||||
|
|
||||||
// All math here is done with big.Int, which is slow.
|
// All math here is done with big.Int, which is slow.
|
||||||
// At some point, it might be useful to write something similar to fieldVal
|
// At some point, it might be useful to write something similar to
|
||||||
// but for N instead of P as the prime field if this ends up being a
|
// fieldVal but for N instead of P as the prime field if this ends up
|
||||||
// bottleneck.
|
// being a bottleneck.
|
||||||
bigIntK, c1, c2, tmp1, tmp2, k1, k2 := new(big.Int), new(big.Int), new(big.Int), new(big.Int), new(big.Int), new(big.Int), new(big.Int)
|
bigIntK := new(big.Int)
|
||||||
|
c1, c2 := new(big.Int), new(big.Int)
|
||||||
|
tmp1, tmp2 := new(big.Int), new(big.Int)
|
||||||
|
k1, k2 := new(big.Int), new(big.Int)
|
||||||
|
|
||||||
bigIntK.SetBytes(k)
|
bigIntK.SetBytes(k)
|
||||||
// c1 = round(b2 * k / n) from step 4.
|
// c1 = round(b2 * k / n) from step 4.
|
||||||
|
@ -649,15 +659,14 @@ func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
|
||||||
return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign()
|
return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign()
|
||||||
}
|
}
|
||||||
|
|
||||||
// moduloReduce reduces k from more than 32 bytes to 32 bytes and under.
|
// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This
|
||||||
// This is done by doing a simple modulo curve.N. We can do this since
|
// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and
|
||||||
// G^N = 1 and thus any other valid point on the elliptical curve has the
|
// thus any other valid point on the elliptic curve has the same order.
|
||||||
// same order.
|
|
||||||
func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
|
func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
|
||||||
// Since the order of G is curve.N, we can use a much smaller number
|
// Since the order of G is curve.N, we can use a much smaller number
|
||||||
// by doing modulo curve.N
|
// by doing modulo curve.N
|
||||||
if len(k) > curve.byteSize {
|
if len(k) > curve.byteSize {
|
||||||
// reduce k by performing modulo curve.N
|
// Reduce k by performing modulo curve.N.
|
||||||
tmpK := new(big.Int).SetBytes(k)
|
tmpK := new(big.Int).SetBytes(k)
|
||||||
tmpK.Mod(tmpK, curve.N)
|
tmpK.Mod(tmpK, curve.N)
|
||||||
return tmpK.Bytes()
|
return tmpK.Bytes()
|
||||||
|
@ -666,24 +675,24 @@ func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
// NAF takes a positive integer k and returns the Non-Adjacent Form (NAF)
|
// NAF takes a positive integer k and returns the Non-Adjacent Form (NAF) as two
|
||||||
// as two byte slices. The first is where 1's should be. The second is where
|
// byte slices. The first is where 1s will be. The second is where -1s will
|
||||||
// -1's should be.
|
// be. NAF is convenient in that on average, only 1/3rd of its values are
|
||||||
// NAF is also convenient in that on average, only 1/3rd of its values are
|
// non-zero. This is algorithm 3.30 from [GECC].
|
||||||
// non-zero.
|
//
|
||||||
// The algorithm here is from Guide to Elliptical Cryptography 3.30 (ref above)
|
|
||||||
// Essentially, this makes it possible to minimize the number of operations
|
// Essentially, this makes it possible to minimize the number of operations
|
||||||
// since the resulting ints returned will be at least 50% 0's.
|
// since the resulting ints returned will be at least 50% 0s.
|
||||||
func NAF(k []byte) ([]byte, []byte) {
|
func NAF(k []byte) ([]byte, []byte) {
|
||||||
|
|
||||||
// The essence of this algorithm is that whenever we have consecutive 1s
|
// The essence of this algorithm is that whenever we have consecutive 1s
|
||||||
// in the binary, we want to put a -1 in the lowest bit and get a bunch of
|
// in the binary, we want to put a -1 in the lowest bit and get a bunch
|
||||||
// 0s up to the highest bit of consecutive 1s. This is due to this identity:
|
// of 0s up to the highest bit of consecutive 1s. This is due to this
|
||||||
|
// identity:
|
||||||
// 2^n + 2^(n-1) + 2^(n-2) + ... + 2^(n-k) = 2^(n+1) - 2^(n-k)
|
// 2^n + 2^(n-1) + 2^(n-2) + ... + 2^(n-k) = 2^(n+1) - 2^(n-k)
|
||||||
// The algorithm thus may need to go 1 more bit than the length of the bits
|
//
|
||||||
// we actually have, hence bits being 1 bit longer than was necessary.
|
// The algorithm thus may need to go 1 more bit than the length of the
|
||||||
// Since we need to know whether adding will cause a carry, we go from
|
// bits we actually have, hence bits being 1 bit longer than was
|
||||||
// right-to-left in this addition.
|
// necessary. Since we need to know whether adding will cause a carry,
|
||||||
|
// we go from right-to-left in this addition.
|
||||||
var carry, curIsOne, nextIsOne bool
|
var carry, curIsOne, nextIsOne bool
|
||||||
// these default to zero
|
// these default to zero
|
||||||
retPos := make([]byte, len(k)+1)
|
retPos := make([]byte, len(k)+1)
|
||||||
|
@ -703,28 +712,33 @@ func NAF(k []byte) ([]byte, []byte) {
|
||||||
}
|
}
|
||||||
if carry {
|
if carry {
|
||||||
if curIsOne {
|
if curIsOne {
|
||||||
// This bit is 1, so we continue to carry and
|
// This bit is 1, so continue to carry
|
||||||
// don't need to do anything
|
// and don't need to do anything.
|
||||||
} else {
|
} else {
|
||||||
// We've hit a 0 after some number of 1s.
|
// We've hit a 0 after some number of
|
||||||
|
// 1s.
|
||||||
if nextIsOne {
|
if nextIsOne {
|
||||||
// We start carrying again since we're starting
|
// Start carrying again since
|
||||||
// a new sequence of 1s.
|
// a new sequence of 1s is
|
||||||
|
// starting.
|
||||||
retNeg[i+1] += 1 << j
|
retNeg[i+1] += 1 << j
|
||||||
} else {
|
} else {
|
||||||
// We stop carrying since 1s have stopped.
|
// Stop carrying since 1s have
|
||||||
|
// stopped.
|
||||||
carry = false
|
carry = false
|
||||||
retPos[i+1] += 1 << j
|
retPos[i+1] += 1 << j
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if curIsOne {
|
} else if curIsOne {
|
||||||
if nextIsOne {
|
if nextIsOne {
|
||||||
// if this is the start of at least 2 consecutive 1's
|
// If this is the start of at least 2
|
||||||
// we want to set the current one to -1 and start carrying
|
// consecutive 1s, set the current one
|
||||||
|
// to -1 and start carrying.
|
||||||
retNeg[i+1] += 1 << j
|
retNeg[i+1] += 1 << j
|
||||||
carry = true
|
carry = true
|
||||||
} else {
|
} else {
|
||||||
// this is a singleton, not consecutive 1's.
|
// This is a singleton, not consecutive
|
||||||
|
// 1s.
|
||||||
retPos[i+1] += 1 << j
|
retPos[i+1] += 1 << j
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -744,27 +758,31 @@ func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big
|
||||||
// Point Q = ∞ (point at infinity).
|
// Point Q = ∞ (point at infinity).
|
||||||
qx, qy, qz := new(fieldVal), new(fieldVal), new(fieldVal)
|
qx, qy, qz := new(fieldVal), new(fieldVal), new(fieldVal)
|
||||||
|
|
||||||
// decompose K into k1 and k2 in order to halve the number of EC ops
|
// Decompose K into k1 and k2 in order to halve the number of EC ops.
|
||||||
// see Algorithm 3.74 in Guide to Elliptical Curve Cryptography by
|
// See Algorithm 3.74 in [GECC].
|
||||||
// Hankerson, et al.
|
|
||||||
k1, k2, signK1, signK2 := curve.splitK(curve.moduloReduce(k))
|
k1, k2, signK1, signK2 := curve.splitK(curve.moduloReduce(k))
|
||||||
|
|
||||||
// The main equation here to remember is
|
// The main equation here to remember is:
|
||||||
// k * P = k1 * P + k2 * ϕ(P)
|
// k * P = k1 * P + k2 * ϕ(P)
|
||||||
|
//
|
||||||
// P1 below is P in the equation, P2 below is ϕ(P) in the equation
|
// P1 below is P in the equation, P2 below is ϕ(P) in the equation
|
||||||
p1x, p1y := curve.bigAffineToField(Bx, By)
|
p1x, p1y := curve.bigAffineToField(Bx, By)
|
||||||
// For NAF, we need the negative point
|
|
||||||
p1yNeg := new(fieldVal).NegateVal(p1y, 1)
|
p1yNeg := new(fieldVal).NegateVal(p1y, 1)
|
||||||
p1z := new(fieldVal).SetInt(1)
|
p1z := new(fieldVal).SetInt(1)
|
||||||
// Note ϕ(x,y) = (βx,y), the Jacobian z coordinate is 1, so this math
|
|
||||||
|
// NOTE: ϕ(x,y) = (βx,y). The Jacobian z coordinate is 1, so this math
|
||||||
// goes through.
|
// goes through.
|
||||||
p2x := new(fieldVal).Mul2(p1x, curve.beta)
|
p2x := new(fieldVal).Mul2(p1x, curve.beta)
|
||||||
p2y := new(fieldVal).Set(p1y)
|
p2y := new(fieldVal).Set(p1y)
|
||||||
// For NAF, we need the negative point
|
|
||||||
p2yNeg := new(fieldVal).NegateVal(p2y, 1)
|
p2yNeg := new(fieldVal).NegateVal(p2y, 1)
|
||||||
p2z := new(fieldVal).SetInt(1)
|
p2z := new(fieldVal).SetInt(1)
|
||||||
|
|
||||||
// If k1 or k2 are negative, we flip the positive/negative values
|
// Flip the positive and negative values of the points as needed
|
||||||
|
// depending on the signs of k1 and k2. As mentioned in the equation
|
||||||
|
// above, each of k1 and k2 are multiplied by the respective point.
|
||||||
|
// Since -k * P is the same thing as k * -P, and the group law for
|
||||||
|
// elliptic curves states that P(x, y) = -P(x, -y), it's faster and
|
||||||
|
// simplifies the code to just make the point negative.
|
||||||
if signK1 == -1 {
|
if signK1 == -1 {
|
||||||
p1y, p1yNeg = p1yNeg, p1y
|
p1y, p1yNeg = p1yNeg, p1y
|
||||||
}
|
}
|
||||||
|
@ -772,9 +790,10 @@ func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big
|
||||||
p2y, p2yNeg = p2yNeg, p2y
|
p2y, p2yNeg = p2yNeg, p2y
|
||||||
}
|
}
|
||||||
|
|
||||||
// NAF versions of k1 and k2 should have a lot more zeros
|
// NAF versions of k1 and k2 should have a lot more zeros.
|
||||||
// the Pos version of the bytes contain the +1's and the Neg versions
|
//
|
||||||
// contain the -1's
|
// The Pos version of the bytes contain the +1s and the Neg versions
|
||||||
|
// contain the -1s.
|
||||||
k1PosNAF, k1NegNAF := NAF(k1)
|
k1PosNAF, k1NegNAF := NAF(k1)
|
||||||
k2PosNAF, k2NegNAF := NAF(k2)
|
k2PosNAF, k2NegNAF := NAF(k2)
|
||||||
k1Len := len(k1PosNAF)
|
k1Len := len(k1PosNAF)
|
||||||
|
@ -785,14 +804,13 @@ func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big
|
||||||
m = k2Len
|
m = k2Len
|
||||||
}
|
}
|
||||||
|
|
||||||
// We add left-to-right using the NAF optimization. This is using
|
// Add left-to-right using the NAF optimization. See algorithm 3.77
|
||||||
// algorithm 3.77 from Guide to Elliptical Curve Cryptography.
|
// from [GECC]. This should be faster overall since there will be a lot
|
||||||
// This should be faster overall since there will be a lot more instances
|
// more instances of 0, hence reducing the number of Jacobian additions
|
||||||
// of 0, hence reducing the number of Jacobian additions at the cost
|
// at the cost of 1 possible extra doubling.
|
||||||
// of 1 possible extra doubling.
|
|
||||||
var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte
|
var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte
|
||||||
for i := 0; i < m; i++ {
|
for i := 0; i < m; i++ {
|
||||||
// Since we're going left-to-right, we need to pad the front with 0's
|
// Since we're going left-to-right, pad the front with 0s.
|
||||||
if i < m-k1Len {
|
if i < m-k1Len {
|
||||||
k1BytePos = 0
|
k1BytePos = 0
|
||||||
k1ByteNeg = 0
|
k1ByteNeg = 0
|
||||||
|
@ -813,15 +831,19 @@ func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big
|
||||||
curve.doubleJacobian(qx, qy, qz, qx, qy, qz)
|
curve.doubleJacobian(qx, qy, qz, qx, qy, qz)
|
||||||
|
|
||||||
if k1BytePos&0x80 == 0x80 {
|
if k1BytePos&0x80 == 0x80 {
|
||||||
curve.addJacobian(qx, qy, qz, p1x, p1y, p1z, qx, qy, qz)
|
curve.addJacobian(qx, qy, qz, p1x, p1y, p1z,
|
||||||
|
qx, qy, qz)
|
||||||
} else if k1ByteNeg&0x80 == 0x80 {
|
} else if k1ByteNeg&0x80 == 0x80 {
|
||||||
curve.addJacobian(qx, qy, qz, p1x, p1yNeg, p1z, qx, qy, qz)
|
curve.addJacobian(qx, qy, qz, p1x, p1yNeg, p1z,
|
||||||
|
qx, qy, qz)
|
||||||
}
|
}
|
||||||
|
|
||||||
if k2BytePos&0x80 == 0x80 {
|
if k2BytePos&0x80 == 0x80 {
|
||||||
curve.addJacobian(qx, qy, qz, p2x, p2y, p2z, qx, qy, qz)
|
curve.addJacobian(qx, qy, qz, p2x, p2y, p2z,
|
||||||
|
qx, qy, qz)
|
||||||
} else if k2ByteNeg&0x80 == 0x80 {
|
} else if k2ByteNeg&0x80 == 0x80 {
|
||||||
curve.addJacobian(qx, qy, qz, p2x, p2yNeg, p2z, qx, qy, qz)
|
curve.addJacobian(qx, qy, qz, p2x, p2yNeg, p2z,
|
||||||
|
qx, qy, qz)
|
||||||
}
|
}
|
||||||
k1BytePos <<= 1
|
k1BytePos <<= 1
|
||||||
k1ByteNeg <<= 1
|
k1ByteNeg <<= 1
|
||||||
|
@ -850,8 +872,8 @@ func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
|
||||||
// Each "digit" in the 8-bit window can be looked up using bytePoints
|
// Each "digit" in the 8-bit window can be looked up using bytePoints
|
||||||
// and added together.
|
// and added together.
|
||||||
for i, byteVal := range newK {
|
for i, byteVal := range newK {
|
||||||
point := curve.bytePoints[diff+i][byteVal]
|
p := curve.bytePoints[diff+i][byteVal]
|
||||||
curve.addJacobian(qx, qy, qz, &point[0], &point[1], &point[2], qx, qy, qz)
|
curve.addJacobian(qx, qy, qz, &p[0], &p[1], &p[2], qx, qy, qz)
|
||||||
}
|
}
|
||||||
return curve.fieldJacobianToBigAffine(qx, qy, qz)
|
return curve.fieldJacobianToBigAffine(qx, qy, qz)
|
||||||
}
|
}
|
||||||
|
@ -894,6 +916,9 @@ func initS256() {
|
||||||
secp256k1.q = new(big.Int).Div(new(big.Int).Add(secp256k1.P,
|
secp256k1.q = new(big.Int).Div(new(big.Int).Add(secp256k1.P,
|
||||||
big.NewInt(1)), big.NewInt(4))
|
big.NewInt(1)), big.NewInt(4))
|
||||||
|
|
||||||
|
// Provided for convenience since this gets computed repeatedly.
|
||||||
|
secp256k1.byteSize = secp256k1.BitSize / 8
|
||||||
|
|
||||||
// Deserialize and set the pre-computed table used to accelerate scalar
|
// Deserialize and set the pre-computed table used to accelerate scalar
|
||||||
// base multiplication. This is hard-coded data, so any errors are
|
// base multiplication. This is hard-coded data, so any errors are
|
||||||
// panics because it means something is wrong in the source code.
|
// panics because it means something is wrong in the source code.
|
||||||
|
@ -904,8 +929,9 @@ func initS256() {
|
||||||
// Next 6 constants are from Hal Finney's bitcointalk.org post:
|
// Next 6 constants are from Hal Finney's bitcointalk.org post:
|
||||||
// https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565
|
// https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565
|
||||||
// May he rest in peace.
|
// May he rest in peace.
|
||||||
// These have been independently verified by Dave Collins using
|
//
|
||||||
// an ecc math script.
|
// They have also been independently derived from the code in the
|
||||||
|
// EndomorphismVectors function in gensecp256k1.go.
|
||||||
secp256k1.lambda = fromHex("5363AD4CC05C30E0A5261C028812645A122E22EA20816678DF02967C1B23BD72")
|
secp256k1.lambda = fromHex("5363AD4CC05C30E0A5261C028812645A122E22EA20816678DF02967C1B23BD72")
|
||||||
secp256k1.beta = new(fieldVal).SetHex("7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE")
|
secp256k1.beta = new(fieldVal).SetHex("7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE")
|
||||||
secp256k1.a1 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
secp256k1.a1 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
||||||
|
@ -913,13 +939,8 @@ func initS256() {
|
||||||
secp256k1.a2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
|
secp256k1.a2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
|
||||||
secp256k1.b2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
secp256k1.b2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
|
||||||
|
|
||||||
// for convenience this gets computed repeatedly
|
|
||||||
secp256k1.byteSize = secp256k1.BitSize / 8
|
|
||||||
|
|
||||||
// Alternatively, we can use the parameters below, however, they seem
|
// Alternatively, we can use the parameters below, however, they seem
|
||||||
// to be about 8% slower.
|
// to be about 8% slower.
|
||||||
// λ = AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE
|
|
||||||
// β = 851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40
|
|
||||||
// secp256k1.lambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE")
|
// secp256k1.lambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE")
|
||||||
// secp256k1.beta = new(fieldVal).SetHex("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40")
|
// secp256k1.beta = new(fieldVal).SetHex("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40")
|
||||||
// secp256k1.a1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3")
|
// secp256k1.a1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3")
|
||||||
|
|
|
@ -641,7 +641,7 @@ func (f *fieldVal) MulInt(val uint) *fieldVal {
|
||||||
// Mul multiplies the passed value to the existing field value and stores the
|
// Mul multiplies the passed value to the existing field value and stores the
|
||||||
// result in f. Note that this function can overflow if multiplying any
|
// result in f. Note that this function can overflow if multiplying any
|
||||||
// of the individual words exceeds a max uint32. In practice, this means the
|
// of the individual words exceeds a max uint32. In practice, this means the
|
||||||
// magnitude of either value invovled in the multiplication must be a max of
|
// magnitude of either value involved in the multiplication must be a max of
|
||||||
// 8.
|
// 8.
|
||||||
//
|
//
|
||||||
// The field value is returned to support chaining. This enables syntax like:
|
// The field value is returned to support chaining. This enables syntax like:
|
||||||
|
@ -653,7 +653,7 @@ func (f *fieldVal) Mul(val *fieldVal) *fieldVal {
|
||||||
// Mul2 multiplies the passed two field values together and stores the result
|
// Mul2 multiplies the passed two field values together and stores the result
|
||||||
// result in f. Note that this function can overflow if multiplying any of
|
// result in f. Note that this function can overflow if multiplying any of
|
||||||
// the individual words exceeds a max uint32. In practice, this means the
|
// the individual words exceeds a max uint32. In practice, this means the
|
||||||
// magnitude of either value invovled in the multiplication must be a max of
|
// magnitude of either value involved in the multiplication must be a max of
|
||||||
// 8.
|
// 8.
|
||||||
//
|
//
|
||||||
// The field value is returned to support chaining. This enables syntax like:
|
// The field value is returned to support chaining. This enables syntax like:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) 2014 Conformal Systems LLC.
|
// Copyright (c) 2015 Conformal Systems LLC.
|
||||||
// Use of this source code is governed by an ISC
|
// Use of this source code is governed by an ISC
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue