mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 19:00:46 +00:00
RIN-08 RIN-10 RIN-11 Fix curve issues (#425)
* update secp256k1 library from go-eth code * cast deprecated functions to use new BitCurve type * add IsOnCurve checks and tests * add test outcome check
This commit is contained in:
parent
7c6a81af5b
commit
30581274a1
21 changed files with 410 additions and 138 deletions
|
|
@ -13,6 +13,8 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -259,6 +261,10 @@ func Deserialize(r []byte) (*RingSignature, error) {
|
||||||
|
|
||||||
sig.SerializedRing = r
|
sig.SerializedRing = r
|
||||||
|
|
||||||
|
if !Verify(sig, false) {
|
||||||
|
return nil, errors.New("failed to deserialize, invalid ring signature")
|
||||||
|
}
|
||||||
|
|
||||||
return sig, nil
|
return sig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -357,7 +363,8 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS
|
||||||
for i := 0; i < numRing; i++ {
|
for i := 0; i < numRing; i++ {
|
||||||
pubkeys[i] = &privkeys[i].PublicKey
|
pubkeys[i] = &privkeys[i].PublicKey
|
||||||
}
|
}
|
||||||
curve := pubkeys[0].Curve
|
//cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated
|
||||||
|
curve := pubkeys[0].Curve.(*secp256k1.BitCurve)
|
||||||
sig := new(RingSignature)
|
sig := new(RingSignature)
|
||||||
sig.Size = ringsize
|
sig.Size = ringsize
|
||||||
sig.NumRing = numRing
|
sig.NumRing = numRing
|
||||||
|
|
@ -504,9 +511,24 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
|
||||||
S := sig.S
|
S := sig.S
|
||||||
C := make([]*big.Int, ringsize+1)
|
C := make([]*big.Int, ringsize+1)
|
||||||
C[0] = sig.C
|
C[0] = sig.C
|
||||||
curve := sig.Curve
|
//cast to BitCurve used in go-eth since elliptic.Curve.Add() and elliptic.Curve.ScalarMult() is deprecated
|
||||||
|
curve := sig.Curve.(*secp256k1.BitCurve)
|
||||||
image := sig.I
|
image := sig.I
|
||||||
|
|
||||||
|
//check on curve
|
||||||
|
for i := 0; i < numRing; i++ {
|
||||||
|
onCurve := curve.IsOnCurve(image[i].X, image[i].Y)
|
||||||
|
if !onCurve {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for j := 0; j < ringsize; j++ {
|
||||||
|
onCurve := curve.IsOnCurve(rings[i][j].X, rings[i][j].Y)
|
||||||
|
if !onCurve {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calculate c[i+1] = H(m, s[i]*G + c[i]*P[i])
|
// calculate c[i+1] = H(m, s[i]*G + c[i]*P[i])
|
||||||
// and c[0] = H)(m, s[n-1]*G + c[n-1]*P[n-1]) where n is the ring size
|
// and c[0] = H)(m, s[n-1]*G + c[n-1]*P[n-1]) where n is the ring size
|
||||||
//log.Info("C", "0", common.Bytes2Hex(C[0].Bytes()))
|
//log.Info("C", "0", common.Bytes2Hex(C[0].Bytes()))
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import (
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSign(t *testing.T) {
|
func TestSign(t *testing.T) {
|
||||||
|
|
@ -130,6 +132,104 @@ func TestPadTo32Bytes(t *testing.T) {
|
||||||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:41]), arr[9:41]), "Test PadTo32Bytes shorter than 32 bytes #10")
|
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:41]), arr[9:41]), "Test PadTo32Bytes shorter than 32 bytes #10")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCurveAddNegative(t *testing.T) {
|
||||||
|
curve := crypto.S256().(*secp256k1.BitCurve)
|
||||||
|
|
||||||
|
x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(2)).Bytes())
|
||||||
|
fmt.Printf("Point(%x, %x)\n", x1, y1)
|
||||||
|
|
||||||
|
x2 := x1
|
||||||
|
y2 := new(big.Int).Neg(y1) // negative of point (x1,y1)
|
||||||
|
|
||||||
|
x3, y3 := curve.Add(x1, y1, x2, y2)
|
||||||
|
fmt.Printf("Output is Point(%x, %x)\n", x3, y3)
|
||||||
|
|
||||||
|
x0 := new(big.Int).SetUint64(uint64(0))
|
||||||
|
y0 := new(big.Int).SetUint64(uint64(0)) // infinity
|
||||||
|
|
||||||
|
if (x3.Cmp(x0) == 0) && (y3.Cmp(y0) == 0) {
|
||||||
|
// fmt.Printf("Correct, add negative of self should yield (0,0)")
|
||||||
|
} else {
|
||||||
|
t.Error("Incorrect, add negative of self did not yield (0,0)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCurveAddZero(t *testing.T) {
|
||||||
|
// curve := crypto.S256()
|
||||||
|
curve := crypto.S256().(*secp256k1.BitCurve)
|
||||||
|
|
||||||
|
x1, y1 := curve.ScalarBaseMult(new(big.Int).SetUint64(uint64(1)).Bytes())
|
||||||
|
fmt.Printf("Point(%x, %x)\n", x1, y1)
|
||||||
|
|
||||||
|
x0 := new(big.Int).SetUint64(uint64(0))
|
||||||
|
y0 := new(big.Int).SetUint64(uint64(0)) // infinity
|
||||||
|
fmt.Printf("Is point (%d,%d) on the curve: %t \n", x0, y0, curve.IsOnCurve(x0, y0))
|
||||||
|
|
||||||
|
x2, y2 := curve.Add(x1, y1, x0, y0)
|
||||||
|
fmt.Printf("Output is Point(%x, %x)\n", x2, y2)
|
||||||
|
|
||||||
|
if (x1.Cmp(x2) == 0) && (y1.Cmp(y2) == 0) {
|
||||||
|
// fmt.Printf("Correct, Point on curve is the same after Zero addition\n")
|
||||||
|
} else {
|
||||||
|
t.Error("Incorrect, Point on curve changed after Zero addition\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOnCurveVerify(t *testing.T) {
|
||||||
|
numRing := 5
|
||||||
|
ringSize := 10
|
||||||
|
s := 5
|
||||||
|
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||||
|
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Failed to create Ring signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
valid := Verify(ringSignature, false)
|
||||||
|
if !valid {
|
||||||
|
t.Error("Incorrect, unmodified ringSignature should be valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
ringsModified := ringSignature.Ring
|
||||||
|
ringsModified[0][0].X = big.NewInt(1)
|
||||||
|
ringsModified[0][0].Y = big.NewInt(1)
|
||||||
|
valid = Verify(ringSignature, false)
|
||||||
|
if valid {
|
||||||
|
t.Error("Incorrect, modified ringSignature should be invalid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOnCurveDeserialize(t *testing.T) {
|
||||||
|
numRing := 5
|
||||||
|
ringSize := 10
|
||||||
|
s := 5
|
||||||
|
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||||
|
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Failed to create Ring signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := ringSignature.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Failed to Serialize input Ring signature")
|
||||||
|
}
|
||||||
|
_, err = Deserialize(sig)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Failed to Deserialize")
|
||||||
|
}
|
||||||
|
|
||||||
|
ringsModified := ringSignature.Ring
|
||||||
|
ringsModified[0][0].X = big.NewInt(1)
|
||||||
|
ringsModified[0][0].Y = big.NewInt(1)
|
||||||
|
|
||||||
|
sig, err = ringSignature.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("Failed to Serialize input Ring signature")
|
||||||
|
}
|
||||||
|
_, err = Deserialize(sig)
|
||||||
|
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
|
||||||
|
}
|
||||||
|
|
||||||
func TestCurveScalarMult(t *testing.T) {
|
func TestCurveScalarMult(t *testing.T) {
|
||||||
curve := crypto.S256()
|
curve := crypto.S256()
|
||||||
|
|
||||||
|
|
|
||||||
31
crypto/secp256k1/LICENSE
Normal file
31
crypto/secp256k1/LICENSE
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
Copyright (c) 2010 The Go Authors. All rights reserved.
|
||||||
|
Copyright (c) 2011 ThePiachu. All rights reserved.
|
||||||
|
Copyright (c) 2015 Jeffrey Wilcke. All rights reserved.
|
||||||
|
Copyright (c) 2015 Felix Lange. All rights reserved.
|
||||||
|
Copyright (c) 2015 Gustav Simonsson. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of the copyright holder. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
// Copyright 2011 ThePiachu. All rights reserved.
|
// Copyright 2011 ThePiachu. All rights reserved.
|
||||||
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -34,16 +35,28 @@ package secp256k1
|
||||||
import (
|
import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"math/big"
|
"math/big"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
const (
|
||||||
#include "libsecp256k1/include/secp256k1.h"
|
// number of bits in a big.Word
|
||||||
extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
|
wordBits = 32 << (uint64(^big.Word(0)) >> 63)
|
||||||
*/
|
// number of bytes in a big.Word
|
||||||
import "C"
|
wordBytes = wordBits / 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// readBits encodes the absolute value of bigint as big-endian bytes. Callers
|
||||||
|
// must ensure that buf has enough space. If buf is too short the result will
|
||||||
|
// be incomplete.
|
||||||
|
func readBits(bigint *big.Int, buf []byte) {
|
||||||
|
i := len(buf)
|
||||||
|
for _, d := range bigint.Bits() {
|
||||||
|
for j := 0; j < wordBytes && i > 0; j++ {
|
||||||
|
i--
|
||||||
|
buf[i] = byte(d)
|
||||||
|
d >>= 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This code is from https://github.com/ThePiachu/GoBit and implements
|
// This code is from https://github.com/ThePiachu/GoBit and implements
|
||||||
// several Koblitz elliptic curves over prime fields.
|
// several Koblitz elliptic curves over prime fields.
|
||||||
|
|
@ -77,7 +90,7 @@ func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsOnBitCurve returns true if the given (x,y) lies on the BitCurve.
|
// IsOnCurve returns true if the given (x,y) lies on the BitCurve.
|
||||||
func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
|
func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
|
||||||
// y² = x³ + b
|
// y² = x³ + b
|
||||||
y2 := new(big.Int).Mul(y, y) //y²
|
y2 := new(big.Int).Mul(y, y) //y²
|
||||||
|
|
@ -92,7 +105,6 @@ func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
|
||||||
return x3.Cmp(y2) == 0
|
return x3.Cmp(y2) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: double check if the function is okay
|
|
||||||
// affineFromJacobian reverses the Jacobian transform. See the comment at the
|
// affineFromJacobian reverses the Jacobian transform. See the comment at the
|
||||||
// top of the file.
|
// top of the file.
|
||||||
func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
|
func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
|
||||||
|
|
@ -113,7 +125,18 @@ func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.
|
||||||
|
|
||||||
// Add returns the sum of (x1,y1) and (x2,y2)
|
// Add returns the sum of (x1,y1) and (x2,y2)
|
||||||
func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
|
func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
|
||||||
|
// If one point is at infinity, return the other point.
|
||||||
|
// Adding the point at infinity to any point will preserve the other point.
|
||||||
|
if x1.Sign() == 0 && y1.Sign() == 0 {
|
||||||
|
return x2, y2
|
||||||
|
}
|
||||||
|
if x2.Sign() == 0 && y2.Sign() == 0 {
|
||||||
|
return x1, y1
|
||||||
|
}
|
||||||
z := new(big.Int).SetInt64(1)
|
z := new(big.Int).SetInt64(1)
|
||||||
|
if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 {
|
||||||
|
return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z))
|
||||||
|
}
|
||||||
return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
|
return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,40 +245,6 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int,
|
||||||
return x3, y3, z3
|
return x3, y3, z3
|
||||||
}
|
}
|
||||||
|
|
||||||
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
|
|
||||||
// Ensure scalar is exactly 32 bytes. We pad always, even if
|
|
||||||
// scalar is 32 bytes long, to avoid a timing side channel.
|
|
||||||
if len(scalar) > 32 {
|
|
||||||
panic("can't handle scalars > 256 bits")
|
|
||||||
}
|
|
||||||
// NOTE: potential timing issue
|
|
||||||
padded := make([]byte, 32)
|
|
||||||
copy(padded[32-len(scalar):], scalar)
|
|
||||||
scalar = padded
|
|
||||||
|
|
||||||
// Do the multiplication in C, updating point.
|
|
||||||
point := make([]byte, 64)
|
|
||||||
math.ReadBits(Bx, point[:32])
|
|
||||||
math.ReadBits(By, point[32:])
|
|
||||||
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
|
|
||||||
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
|
|
||||||
res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
|
|
||||||
|
|
||||||
// Unpack the result and clear temporaries.
|
|
||||||
x := new(big.Int).SetBytes(point[:32])
|
|
||||||
y := new(big.Int).SetBytes(point[32:])
|
|
||||||
for i := range point {
|
|
||||||
point[i] = 0
|
|
||||||
}
|
|
||||||
for i := range padded {
|
|
||||||
scalar[i] = 0
|
|
||||||
}
|
|
||||||
if res != 1 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return x, y
|
|
||||||
}
|
|
||||||
|
|
||||||
// ScalarBaseMult returns k*G, where G is the base point of the group and k is
|
// ScalarBaseMult returns k*G, where G is the base point of the group and k is
|
||||||
// an integer in big-endian form.
|
// an integer in big-endian form.
|
||||||
func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
|
func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
|
||||||
|
|
@ -268,8 +257,8 @@ func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
|
||||||
byteLen := (BitCurve.BitSize + 7) >> 3
|
byteLen := (BitCurve.BitSize + 7) >> 3
|
||||||
ret := make([]byte, 1+2*byteLen)
|
ret := make([]byte, 1+2*byteLen)
|
||||||
ret[0] = 4 // uncompressed point flag
|
ret[0] = 4 // uncompressed point flag
|
||||||
math.ReadBits(x, ret[1:1+byteLen])
|
readBits(x, ret[1:1+byteLen])
|
||||||
math.ReadBits(y, ret[1+byteLen:])
|
readBits(y, ret[1+byteLen:])
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,12 +282,12 @@ var theCurve = new(BitCurve)
|
||||||
func init() {
|
func init() {
|
||||||
// See SEC 2 section 2.7.1
|
// See SEC 2 section 2.7.1
|
||||||
// curve parameters taken from:
|
// curve parameters taken from:
|
||||||
// http://www.secg.org/collateral/sec2_final.pdf
|
// http://www.secg.org/sec2-v2.pdf
|
||||||
theCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
|
theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0)
|
||||||
theCurve.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
|
theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0)
|
||||||
theCurve.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
|
theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0)
|
||||||
theCurve.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
|
theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0)
|
||||||
theCurve.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
|
theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0)
|
||||||
theCurve.BitSize = 256
|
theCurve.BitSize = 256
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
21
crypto/secp256k1/dummy.go
Normal file
21
crypto/secp256k1/dummy.go
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// This file is part of a workaround for `go mod vendor` which won't vendor
|
||||||
|
// C files if there's no Go file in the same directory.
|
||||||
|
// This would prevent the crypto/secp256k1/libsecp256k1/include/secp256k1.h file to be vendored.
|
||||||
|
//
|
||||||
|
// This Go file imports the c directory where there is another dummy.go file which
|
||||||
|
// is the second part of this workaround.
|
||||||
|
//
|
||||||
|
// These two files combined make it so `go mod vendor` behaves correctly.
|
||||||
|
//
|
||||||
|
// See this issue for reference: https://github.com/golang/go/issues/26366
|
||||||
|
|
||||||
|
package secp256k1
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/include"
|
||||||
|
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src"
|
||||||
|
_ "github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1/src/modules/recovery"
|
||||||
|
)
|
||||||
|
|
@ -1,18 +1,6 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
// This file is part of the go-ethereum library.
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
//
|
// the LICENSE file.
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// secp256k1_context_create_sign_verify creates a context for signing and signature verification.
|
// secp256k1_context_create_sign_verify creates a context for signing and signature verification.
|
||||||
static secp256k1_context* secp256k1_context_create_sign_verify() {
|
static secp256k1_context* secp256k1_context_create_sign_verify() {
|
||||||
|
|
|
||||||
8
crypto/secp256k1/libsecp256k1/contrib/dummy.go
Normal file
8
crypto/secp256k1/libsecp256k1/contrib/dummy.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package contrib
|
||||||
8
crypto/secp256k1/libsecp256k1/dummy.go
Normal file
8
crypto/secp256k1/libsecp256k1/dummy.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package libsecp256k1
|
||||||
8
crypto/secp256k1/libsecp256k1/include/dummy.go
Normal file
8
crypto/secp256k1/libsecp256k1/include/dummy.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package include
|
||||||
|
|
@ -11,7 +11,7 @@ Note:
|
||||||
|
|
||||||
- To avoid unnecessary loads and make use of available registers, two
|
- To avoid unnecessary loads and make use of available registers, two
|
||||||
'passes' have every time been interleaved, with the odd passes accumulating c' and d'
|
'passes' have every time been interleaved, with the odd passes accumulating c' and d'
|
||||||
which will be added to c and d respectively in the the even passes
|
which will be added to c and d respectively in the even passes
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ Note:
|
||||||
.eabi_attribute 10, 0 @ Tag_FP_arch = none
|
.eabi_attribute 10, 0 @ Tag_FP_arch = none
|
||||||
.eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte
|
.eabi_attribute 24, 1 @ Tag_ABI_align_needed = 8-byte
|
||||||
.eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP
|
.eabi_attribute 25, 1 @ Tag_ABI_align_preserved = 8-byte, except leaf SP
|
||||||
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Agressive Speed
|
.eabi_attribute 30, 2 @ Tag_ABI_optimization_goals = Aggressive Speed
|
||||||
.eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6
|
.eabi_attribute 34, 1 @ Tag_CPU_unaligned_access = v6
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
|
||||||
8
crypto/secp256k1/libsecp256k1/src/dummy.go
Normal file
8
crypto/secp256k1/libsecp256k1/src/dummy.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package src
|
||||||
8
crypto/secp256k1/libsecp256k1/src/modules/dummy.go
Normal file
8
crypto/secp256k1/libsecp256k1/src/modules/dummy.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package module
|
||||||
8
crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go
Normal file
8
crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package ecdh
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
//go:build dummy
|
||||||
|
// +build dummy
|
||||||
|
|
||||||
|
// Package c contains only a C file.
|
||||||
|
//
|
||||||
|
// This Go file is part of a workaround for `go mod vendor`.
|
||||||
|
// Please see the file crypto/secp256k1/dummy.go for more information.
|
||||||
|
package recovery
|
||||||
|
|
@ -54,7 +54,7 @@ static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const se
|
||||||
even if r was negative. */
|
even if r was negative. */
|
||||||
static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m);
|
static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m);
|
||||||
|
|
||||||
/** Right-shift the passed number by bits bits. */
|
/** Right-shift the passed number by bits. */
|
||||||
static void secp256k1_num_shift(secp256k1_num *r, int bits);
|
static void secp256k1_num_shift(secp256k1_num *r, int bits);
|
||||||
|
|
||||||
/** Check whether a number is zero. */
|
/** Check whether a number is zero. */
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
static void default_illegal_callback_fn(const char* str, void* data) {
|
static void default_illegal_callback_fn(const char* str, void* data) {
|
||||||
(void)data;
|
|
||||||
fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str);
|
fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
@ -37,7 +36,6 @@ static const secp256k1_callback default_illegal_callback = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void default_error_callback_fn(const char* str, void* data) {
|
static void default_error_callback_fn(const char* str, void* data) {
|
||||||
(void)data;
|
|
||||||
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
|
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,9 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
// This file is part of the go-ethereum library.
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
//
|
// the LICENSE file.
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
//go:build !gofuzz && cgo
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// +build !gofuzz,cgo
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package secp256k1
|
package secp256k1
|
||||||
|
|
||||||
|
|
|
||||||
57
crypto/secp256k1/scalar_mult_cgo.go
Normal file
57
crypto/secp256k1/scalar_mult_cgo.go
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !gofuzz && cgo
|
||||||
|
// +build !gofuzz,cgo
|
||||||
|
|
||||||
|
package secp256k1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
#include "libsecp256k1/include/secp256k1.h"
|
||||||
|
|
||||||
|
extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar);
|
||||||
|
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
|
||||||
|
// Ensure scalar is exactly 32 bytes. We pad always, even if
|
||||||
|
// scalar is 32 bytes long, to avoid a timing side channel.
|
||||||
|
if len(scalar) > 32 {
|
||||||
|
panic("can't handle scalars > 256 bits")
|
||||||
|
}
|
||||||
|
// NOTE: potential timing issue
|
||||||
|
padded := make([]byte, 32)
|
||||||
|
copy(padded[32-len(scalar):], scalar)
|
||||||
|
scalar = padded
|
||||||
|
|
||||||
|
// Do the multiplication in C, updating point.
|
||||||
|
point := make([]byte, 64)
|
||||||
|
readBits(Bx, point[:32])
|
||||||
|
readBits(By, point[32:])
|
||||||
|
|
||||||
|
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
|
||||||
|
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
|
||||||
|
res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
|
||||||
|
|
||||||
|
// Unpack the result and clear temporaries.
|
||||||
|
x := new(big.Int).SetBytes(point[:32])
|
||||||
|
y := new(big.Int).SetBytes(point[32:])
|
||||||
|
for i := range point {
|
||||||
|
point[i] = 0
|
||||||
|
}
|
||||||
|
for i := range padded {
|
||||||
|
scalar[i] = 0
|
||||||
|
}
|
||||||
|
if res != 1 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return x, y
|
||||||
|
}
|
||||||
14
crypto/secp256k1/scalar_mult_nocgo.go
Normal file
14
crypto/secp256k1/scalar_mult_nocgo.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
|
||||||
|
//go:build gofuzz || !cgo
|
||||||
|
// +build gofuzz !cgo
|
||||||
|
|
||||||
|
package secp256k1
|
||||||
|
|
||||||
|
import "math/big"
|
||||||
|
|
||||||
|
func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
|
||||||
|
panic("ScalarMult is not available when secp256k1 is built without cgo")
|
||||||
|
}
|
||||||
|
|
@ -1,18 +1,9 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
// This file is part of the go-ethereum library.
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
//
|
// the LICENSE file.
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
//go:build !gofuzz && cgo
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// +build !gofuzz,cgo
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// Package secp256k1 wraps the bitcoin secp256k1 C library.
|
// Package secp256k1 wraps the bitcoin secp256k1 C library.
|
||||||
package secp256k1
|
package secp256k1
|
||||||
|
|
@ -20,12 +11,24 @@ package secp256k1
|
||||||
/*
|
/*
|
||||||
#cgo CFLAGS: -I./libsecp256k1
|
#cgo CFLAGS: -I./libsecp256k1
|
||||||
#cgo CFLAGS: -I./libsecp256k1/src/
|
#cgo CFLAGS: -I./libsecp256k1/src/
|
||||||
|
|
||||||
|
#ifdef __SIZEOF_INT128__
|
||||||
|
# define HAVE___INT128
|
||||||
|
# define USE_FIELD_5X52
|
||||||
|
# define USE_SCALAR_4X64
|
||||||
|
#else
|
||||||
|
# define USE_FIELD_10X26
|
||||||
|
# define USE_SCALAR_8X32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
# define NDEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define USE_ENDOMORPHISM
|
||||||
#define USE_NUM_NONE
|
#define USE_NUM_NONE
|
||||||
#define USE_FIELD_10X26
|
|
||||||
#define USE_FIELD_INV_BUILTIN
|
#define USE_FIELD_INV_BUILTIN
|
||||||
#define USE_SCALAR_8X32
|
|
||||||
#define USE_SCALAR_INV_BUILTIN
|
#define USE_SCALAR_INV_BUILTIN
|
||||||
#define NDEBUG
|
|
||||||
#include "./libsecp256k1/src/secp256k1.c"
|
#include "./libsecp256k1/src/secp256k1.c"
|
||||||
#include "./libsecp256k1/src/modules/recovery/main_impl.h"
|
#include "./libsecp256k1/src/modules/recovery/main_impl.h"
|
||||||
#include "ext.h"
|
#include "ext.h"
|
||||||
|
|
@ -98,7 +101,7 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) {
|
||||||
return sig, nil
|
return sig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoverPubkey returns the the public key of the signer.
|
// RecoverPubkey returns the public key of the signer.
|
||||||
// msg must be the 32-byte hash of the message to be signed.
|
// msg must be the 32-byte hash of the message to be signed.
|
||||||
// sig must be a 65-byte compact ECDSA signature containing the
|
// sig must be a 65-byte compact ECDSA signature containing the
|
||||||
// recovery id as the last element.
|
// recovery id as the last element.
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,9 @@
|
||||||
// Copyright 2015 The go-ethereum Authors
|
// Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved.
|
||||||
// This file is part of the go-ethereum library.
|
// Use of this source code is governed by a BSD-style license that can be found in
|
||||||
//
|
// the LICENSE file.
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
//go:build !gofuzz && cgo
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
// +build !gofuzz,cgo
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package secp256k1
|
package secp256k1
|
||||||
|
|
||||||
|
|
@ -22,10 +13,8 @@ import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto/randentropy"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const TestCount = 1000
|
const TestCount = 1000
|
||||||
|
|
@ -36,11 +25,24 @@ func generateKeyPair() (pubkey, privkey []byte) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
pubkey = elliptic.Marshal(S256(), key.X, key.Y)
|
pubkey = elliptic.Marshal(S256(), key.X, key.Y)
|
||||||
return pubkey, math.PaddedBigBytes(key.D, 32)
|
|
||||||
|
privkey = make([]byte, 32)
|
||||||
|
blob := key.D.Bytes()
|
||||||
|
copy(privkey[32-len(blob):], blob)
|
||||||
|
|
||||||
|
return pubkey, privkey
|
||||||
|
}
|
||||||
|
|
||||||
|
func csprngEntropy(n int) []byte {
|
||||||
|
buf := make([]byte, n)
|
||||||
|
if _, err := io.ReadFull(rand.Reader, buf); err != nil {
|
||||||
|
panic("reading from crypto/rand failed: " + err.Error())
|
||||||
|
}
|
||||||
|
return buf
|
||||||
}
|
}
|
||||||
|
|
||||||
func randSig() []byte {
|
func randSig() []byte {
|
||||||
sig := randentropy.GetEntropyCSPRNG(65)
|
sig := csprngEntropy(65)
|
||||||
sig[32] &= 0x70
|
sig[32] &= 0x70
|
||||||
sig[64] %= 4
|
sig[64] %= 4
|
||||||
return sig
|
return sig
|
||||||
|
|
@ -49,7 +51,7 @@ func randSig() []byte {
|
||||||
// tests for malleability
|
// tests for malleability
|
||||||
// highest bit of signature ECDSA s value must be 0, in the 33th byte
|
// highest bit of signature ECDSA s value must be 0, in the 33th byte
|
||||||
func compactSigCheck(t *testing.T, sig []byte) {
|
func compactSigCheck(t *testing.T, sig []byte) {
|
||||||
var b int = int(sig[32])
|
var b = int(sig[32])
|
||||||
if b < 0 {
|
if b < 0 {
|
||||||
t.Errorf("highest bit is negative: %d", b)
|
t.Errorf("highest bit is negative: %d", b)
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +65,7 @@ func compactSigCheck(t *testing.T, sig []byte) {
|
||||||
|
|
||||||
func TestSignatureValidity(t *testing.T) {
|
func TestSignatureValidity(t *testing.T) {
|
||||||
pubkey, seckey := generateKeyPair()
|
pubkey, seckey := generateKeyPair()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
sig, err := Sign(msg, seckey)
|
sig, err := Sign(msg, seckey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("signature error: %s", err)
|
t.Errorf("signature error: %s", err)
|
||||||
|
|
@ -86,7 +88,7 @@ func TestSignatureValidity(t *testing.T) {
|
||||||
|
|
||||||
func TestInvalidRecoveryID(t *testing.T) {
|
func TestInvalidRecoveryID(t *testing.T) {
|
||||||
_, seckey := generateKeyPair()
|
_, seckey := generateKeyPair()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
sig, _ := Sign(msg, seckey)
|
sig, _ := Sign(msg, seckey)
|
||||||
sig[64] = 99
|
sig[64] = 99
|
||||||
_, err := RecoverPubkey(msg, sig)
|
_, err := RecoverPubkey(msg, sig)
|
||||||
|
|
@ -97,7 +99,7 @@ func TestInvalidRecoveryID(t *testing.T) {
|
||||||
|
|
||||||
func TestSignAndRecover(t *testing.T) {
|
func TestSignAndRecover(t *testing.T) {
|
||||||
pubkey1, seckey := generateKeyPair()
|
pubkey1, seckey := generateKeyPair()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
sig, err := Sign(msg, seckey)
|
sig, err := Sign(msg, seckey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("signature error: %s", err)
|
t.Errorf("signature error: %s", err)
|
||||||
|
|
@ -148,7 +150,7 @@ func TestRandomMessagesWithRandomKeys(t *testing.T) {
|
||||||
func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) {
|
func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) {
|
||||||
for i := 0; i < TestCount; i++ {
|
for i := 0; i < TestCount; i++ {
|
||||||
pubkey1, seckey := keys()
|
pubkey1, seckey := keys()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
sig, err := Sign(msg, seckey)
|
sig, err := Sign(msg, seckey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("signature error: %s", err)
|
t.Fatalf("signature error: %s", err)
|
||||||
|
|
@ -176,7 +178,7 @@ func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)
|
||||||
|
|
||||||
func TestRecoveryOfRandomSignature(t *testing.T) {
|
func TestRecoveryOfRandomSignature(t *testing.T) {
|
||||||
pubkey1, _ := generateKeyPair()
|
pubkey1, _ := generateKeyPair()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
|
|
||||||
for i := 0; i < TestCount; i++ {
|
for i := 0; i < TestCount; i++ {
|
||||||
// recovery can sometimes work, but if so should always give wrong pubkey
|
// recovery can sometimes work, but if so should always give wrong pubkey
|
||||||
|
|
@ -189,11 +191,11 @@ func TestRecoveryOfRandomSignature(t *testing.T) {
|
||||||
|
|
||||||
func TestRandomMessagesAgainstValidSig(t *testing.T) {
|
func TestRandomMessagesAgainstValidSig(t *testing.T) {
|
||||||
pubkey1, seckey := generateKeyPair()
|
pubkey1, seckey := generateKeyPair()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
sig, _ := Sign(msg, seckey)
|
sig, _ := Sign(msg, seckey)
|
||||||
|
|
||||||
for i := 0; i < TestCount; i++ {
|
for i := 0; i < TestCount; i++ {
|
||||||
msg = randentropy.GetEntropyCSPRNG(32)
|
msg = csprngEntropy(32)
|
||||||
pubkey2, _ := RecoverPubkey(msg, sig)
|
pubkey2, _ := RecoverPubkey(msg, sig)
|
||||||
// recovery can sometimes work, but if so should always give wrong pubkey
|
// recovery can sometimes work, but if so should always give wrong pubkey
|
||||||
if bytes.Equal(pubkey1, pubkey2) {
|
if bytes.Equal(pubkey1, pubkey2) {
|
||||||
|
|
@ -219,7 +221,7 @@ func TestRecoverSanity(t *testing.T) {
|
||||||
|
|
||||||
func BenchmarkSign(b *testing.B) {
|
func BenchmarkSign(b *testing.B) {
|
||||||
_, seckey := generateKeyPair()
|
_, seckey := generateKeyPair()
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
|
@ -228,7 +230,7 @@ func BenchmarkSign(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkRecover(b *testing.B) {
|
func BenchmarkRecover(b *testing.B) {
|
||||||
msg := randentropy.GetEntropyCSPRNG(32)
|
msg := csprngEntropy(32)
|
||||||
_, seckey := generateKeyPair()
|
_, seckey := generateKeyPair()
|
||||||
sig, _ := Sign(msg, seckey)
|
sig, _ := Sign(msg, seckey)
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue