mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-21 22:24:32 +00:00
Merge pull request #428 from XinFinOrg/dev-upgrade
Dev upgrade and bump version to 2.0.2
This commit is contained in:
commit
1720858916
36 changed files with 604 additions and 194 deletions
|
|
@ -148,7 +148,6 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
|
|||
return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
|
||||
}
|
||||
|
||||
|
||||
// revertSelector is a special function selector for revert reason unpacking.
|
||||
var revertSelector = crypto.Keccak256([]byte("Error(string)"))[:4]
|
||||
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ func capitalise(input string) string {
|
|||
return strings.ToUpper(input[:1]) + input[1:]
|
||||
}
|
||||
|
||||
//unpackStruct extracts each argument into its corresponding struct field
|
||||
// unpackStruct extracts each argument into its corresponding struct field
|
||||
func unpackStruct(value, reflectValue reflect.Value, arg Argument) error {
|
||||
name := capitalise(arg.Name)
|
||||
typ := value.Type()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/event"
|
||||
)
|
||||
|
||||
var (
|
||||
errNoEventSignature = errors.New("no event signature")
|
||||
)
|
||||
|
||||
// SignerFn is a signer function callback when a contract requires a method to
|
||||
// sign the transaction before submission.
|
||||
type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error)
|
||||
|
|
@ -326,6 +330,13 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter
|
|||
|
||||
// UnpackLog unpacks a retrieved log into the provided output structure.
|
||||
func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error {
|
||||
// Anonymous events are not supported.
|
||||
if len(log.Topics) == 0 {
|
||||
return errNoEventSignature
|
||||
}
|
||||
if log.Topics[0] != c.abi.Events[event].Id() {
|
||||
return fmt.Errorf("event signature mismatch")
|
||||
}
|
||||
if len(log.Data) > 0 {
|
||||
if err := c.abi.Unpack(out, event, log.Data); err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -1,28 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Update AWS Max Health can resolve below issue, and it's already addressed
|
||||
# echo "Preparing to start the XDC chain, it's likely to take up to 1 minute"
|
||||
# Sleep for > 30 as we need to wait for the ECS tasks container being killed by fargate. Otherwise it will ended up with two same nodes running on a single /work/xdcchain directory
|
||||
# sleep 60
|
||||
|
||||
if [ ! -d /work/xdcchain/XDC/chaindata ]
|
||||
then
|
||||
# Randomly select a key from environment variable, seperated by ','
|
||||
if test -z "$PRIVATE_KEYS"
|
||||
if test -z "$PRIVATE_KEY"
|
||||
then
|
||||
echo "PRIVATE_KEYS environment variable has not been set. You need to pass at least one PK, or you can pass multiple PK seperated by ',', we will randomly choose one for you"
|
||||
echo "PRIVATE_KEY environment variable has not been set."
|
||||
exit 1
|
||||
fi
|
||||
IFS=', ' read -r -a private_keys <<< "$PRIVATE_KEYS"
|
||||
private_key=${private_keys[ $RANDOM % ${#private_keys[@]} ]}
|
||||
|
||||
echo "${private_key}" >> /tmp/key
|
||||
echo "Creating a new wallet"
|
||||
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}')
|
||||
echo $PRIVATE_KEY >> /tmp/key
|
||||
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -v FS="({|})" '{print $2}')
|
||||
XDC --datadir /work/xdcchain init /work/genesis.json
|
||||
else
|
||||
echo "Wallet already exist, re-use the same one"
|
||||
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}')
|
||||
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -v FS="({|})" '{print $2}')
|
||||
fi
|
||||
|
||||
input="/work/bootnodes.list"
|
||||
|
|
|
|||
|
|
@ -1,23 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ ! -d /work/xdcchain/XDC/chaindata ]
|
||||
then
|
||||
# Randomly select a key from environment variable, seperated by ','
|
||||
if test -z "$PRIVATE_KEYS"
|
||||
if test -z "$PRIVATE_KEY"
|
||||
then
|
||||
echo "PRIVATE_KEYS environment variable has not been set. You need to pass at least one PK, or you can pass multiple PK seperated by ',', we will randomly choose one for you"
|
||||
echo "PRIVATE_KEY environment variable has not been set."
|
||||
exit 1
|
||||
fi
|
||||
IFS=', ' read -r -a private_keys <<< "$PRIVATE_KEYS"
|
||||
private_key=${private_keys[ $RANDOM % ${#private_keys[@]} ]}
|
||||
|
||||
echo "${private_key}" >> /tmp/key
|
||||
echo "Creating a new wallet"
|
||||
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}')
|
||||
echo $PRIVATE_KEY >> /tmp/key
|
||||
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -v FS="({|})" '{print $2}')
|
||||
XDC --datadir /work/xdcchain init /work/genesis.json
|
||||
else
|
||||
echo "Wallet already exist, re-use the same one"
|
||||
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}')
|
||||
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -v FS="({|})" '{print $2}')
|
||||
fi
|
||||
|
||||
input="/work/bootnodes.list"
|
||||
|
|
|
|||
|
|
@ -2,22 +2,16 @@
|
|||
|
||||
if [ ! -d /work/xdcchain/XDC/chaindata ]
|
||||
then
|
||||
# Randomly select a key from environment variable, seperated by ','
|
||||
if test -z "$PRIVATE_KEYS"
|
||||
if test -z "$PRIVATE_KEY"
|
||||
then
|
||||
echo "PRIVATE_KEYS environment variable has not been set. You need to pass at least one PK, or you can pass multiple PK seperated by ',', we will randomly choose one for you"
|
||||
echo "PRIVATE_KEY environment variable has not been set."
|
||||
exit 1
|
||||
fi
|
||||
IFS=', ' read -r -a private_keys <<< "$PRIVATE_KEYS"
|
||||
private_key=${private_keys[ $RANDOM % ${#private_keys[@]} ]}
|
||||
|
||||
echo "${private_key}" >> /tmp/key
|
||||
echo "Creating a new wallet"
|
||||
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -F '[{}]' '{print $2}')
|
||||
echo $PRIVATE_KEY >> /tmp/key
|
||||
wallet=$(XDC account import --password .pwd --datadir /work/xdcchain /tmp/key | awk -v FS="({|})" '{print $2}')
|
||||
XDC --datadir /work/xdcchain init /work/genesis.json
|
||||
else
|
||||
echo "Wallet already exist, re-use the same one"
|
||||
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -F '[{}]' '{print $2}')
|
||||
wallet=$(XDC account list --datadir /work/xdcchain | head -n 1 | awk -v FS="({|})" '{print $2}')
|
||||
fi
|
||||
|
||||
input="/work/bootnodes.list"
|
||||
|
|
|
|||
|
|
@ -451,6 +451,9 @@ func (x *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (
|
|||
switch x.config.BlockConsensusVersion(header.Number, header.Extra, ExtraFieldCheck) {
|
||||
case params.ConsensusEngineVersion2:
|
||||
sp, err := x.EngineV2.GetSnapshot(chain, header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &utils.PublicApiSnapshot{
|
||||
Number: sp.Number,
|
||||
Hash: sp.Hash,
|
||||
|
|
@ -458,6 +461,9 @@ func (x *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (
|
|||
}, err
|
||||
default: // Default "v1"
|
||||
sp, err := x.EngineV1.GetSnapshot(chain, header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Convert to a standard PublicApiSnapshot type, otherwise it's a breaking change to API
|
||||
return &utils.PublicApiSnapshot{
|
||||
Number: sp.Number,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func (x *XDPoS_v2) yourturn(chain consensus.ChainReader, round types.Round, pare
|
|||
|
||||
curIndex := utils.Position(masterNodes, signer)
|
||||
if curIndex == -1 {
|
||||
log.Warn("[yourturn] I am not in masternodes list", "Hash", parent.Hash().Hex(), "signer", signer.Hex())
|
||||
log.Debug("[yourturn] I am not in masternodes list", "Hash", parent.Hash().Hex(), "signer", signer.Hex())
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -161,6 +161,9 @@ func (x *XDPoS_v2) GetRoundNumber(header *types.Header) (types.Round, error) {
|
|||
|
||||
func (x *XDPoS_v2) GetSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
|
||||
snap, err := x.getSnapshot(chain, header.Number.Uint64(), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return snap.NextEpochMasterNodes, err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -830,7 +830,7 @@ func (ipp *InnerProdArg) Deserialize(proof []byte, numChallenges int) error {
|
|||
if len(proof) <= (offset + 32*numChallenges) {
|
||||
return errors.New("input data too short")
|
||||
}
|
||||
for i := 0; i < int(numChallenges); i++ {
|
||||
for i := 0; i < numChallenges; i++ {
|
||||
ipp.Challenges = append(ipp.Challenges, new(big.Int).SetBytes(proof[offset:offset+32]))
|
||||
offset += 32
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
)
|
||||
|
||||
|
|
@ -259,6 +261,10 @@ func Deserialize(r []byte) (*RingSignature, error) {
|
|||
|
||||
sig.SerializedRing = r
|
||||
|
||||
if !Verify(sig, false) {
|
||||
return nil, errors.New("failed to deserialize, invalid ring signature")
|
||||
}
|
||||
|
||||
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++ {
|
||||
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.Size = ringsize
|
||||
sig.NumRing = numRing
|
||||
|
|
@ -447,6 +454,9 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS
|
|||
// calculate L[j][idx] = s[j][idx]*G + c[idx]*Ring[j][idx]
|
||||
px, py := curve.ScalarMult(rings[j][idx].X, rings[j][idx].Y, PadTo32Bytes(C[idx].Bytes())) // px, py = c_i*P_i
|
||||
sx, sy := curve.ScalarBaseMult(PadTo32Bytes(S[j][idx].Bytes())) // sx, sy = s[n-1]*G
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return nil, errors.New("Could not create ring signature")
|
||||
}
|
||||
l_x, l_y := curve.Add(sx, sy, px, py)
|
||||
L[j][idx] = &ecdsa.PublicKey{curve, l_x, l_y}
|
||||
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
|
||||
|
|
@ -456,6 +466,9 @@ func Sign(m [32]byte, rings []Ring, privkeys []*ecdsa.PrivateKey, s int) (*RingS
|
|||
px, py = curve.ScalarMult(images[j].X, images[j].Y, C[idx].Bytes()) // px, py = c_i*I
|
||||
hx, hy := HashPoint(rings[j][idx])
|
||||
sx, sy = curve.ScalarMult(hx, hy, S[j][idx].Bytes()) // sx, sy = s[n-1]*H_p(P_i)
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return nil, errors.New("Could not create ring signature")
|
||||
}
|
||||
r_x, r_y := curve.Add(sx, sy, px, py)
|
||||
R[j][idx] = &ecdsa.PublicKey{curve, r_x, r_y}
|
||||
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
|
||||
|
|
@ -504,18 +517,41 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
|
|||
S := sig.S
|
||||
C := make([]*big.Int, ringsize+1)
|
||||
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
|
||||
|
||||
//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])
|
||||
// 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()))
|
||||
for j := 0; j < ringsize; j++ {
|
||||
var l []byte
|
||||
for i := 0; i < numRing; i++ {
|
||||
// Validate S[i][j] and C[j]
|
||||
if !isValidScalar(S[i][j], curve) || !isValidScalar(C[j], curve) {
|
||||
return false // Or handle the error as required
|
||||
}
|
||||
|
||||
// calculate L[i][j] = s[i][j]*G + c[j]*Ring[i][j]
|
||||
px, py := curve.ScalarMult(rings[i][j].X, rings[i][j].Y, C[j].Bytes()) // px, py = c_i*P_i
|
||||
sx, sy := curve.ScalarBaseMult(S[i][j].Bytes()) // sx, sy = s[i]*G
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return false
|
||||
}
|
||||
l_x, l_y := curve.Add(sx, sy, px, py)
|
||||
lT := append(PadTo32Bytes(l_x.Bytes()), PadTo32Bytes(l_y.Bytes())...)
|
||||
//log.Info("L[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(lT))
|
||||
|
|
@ -524,9 +560,17 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
|
|||
// calculate R_i = s[i][j]*H_p(Ring[i][j]) + c[j]*I[j]
|
||||
px, py = curve.ScalarMult(image[i].X, image[i].Y, C[j].Bytes()) // px, py = c[i]*I
|
||||
hx, hy := HashPoint(rings[i][j])
|
||||
|
||||
// Validate S[i][j], hx, and hy
|
||||
if !isValidScalar(S[i][j], curve) || !isValidScalar(hx, curve) || !isValidScalar(hy, curve) {
|
||||
return false // Or handle the error as required
|
||||
}
|
||||
//log.Info("H[i][j]", "i", i, "j", j, "x.input", common.Bytes2Hex(rings[i][j].X.Bytes()), "y.input", common.Bytes2Hex(rings[i][j].Y.Bytes()))
|
||||
//log.Info("H[i][j]", "i", i, "j", j, "x", common.Bytes2Hex(hx.Bytes()), "y", common.Bytes2Hex(hy.Bytes()))
|
||||
sx, sy = curve.ScalarMult(hx, hy, S[i][j].Bytes()) // sx, sy = s[i]*H_p(P[i])
|
||||
if px == nil || py == nil || sx == nil || sy == nil {
|
||||
return false
|
||||
}
|
||||
r_x, r_y := curve.Add(sx, sy, px, py)
|
||||
rT := append(PadTo32Bytes(r_x.Bytes()), PadTo32Bytes(r_y.Bytes())...)
|
||||
//log.Info("R[i][j]", "i", i, "j", j, "L", common.Bytes2Hex(rT))
|
||||
|
|
@ -549,6 +593,10 @@ func Verify(sig *RingSignature, verifyMes bool) bool {
|
|||
return bytes.Equal(sig.C.Bytes(), C[ringsize].Bytes())
|
||||
}
|
||||
|
||||
func isValidScalar(scalar *big.Int, curve elliptic.Curve) bool {
|
||||
return scalar.Sign() >= 0 && scalar.Cmp(curve.Params().N) < 0
|
||||
}
|
||||
|
||||
func Link(sig_a *RingSignature, sig_b *RingSignature) bool {
|
||||
for i := 0; i < len(sig_a.I); i++ {
|
||||
for j := 0; j < len(sig_b.I); j++ {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@ import (
|
|||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto/secp256k1"
|
||||
)
|
||||
|
||||
func TestSign(t *testing.T) {
|
||||
|
|
@ -83,6 +87,62 @@ func TestDeserialize(t *testing.T) {
|
|||
_, err = Deserialize(sig)
|
||||
assert.EqualError(t, err, "incorrect ring size, len r: 3804, sig.NumRing: 5 sig.Size: 56759212534490939")
|
||||
}
|
||||
|
||||
func TestVerify1(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 7
|
||||
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
if err != nil {
|
||||
t.Error("fail to generate rings")
|
||||
}
|
||||
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("fail to create ring signature")
|
||||
}
|
||||
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("fail to serialize input ring signature")
|
||||
}
|
||||
|
||||
deserializedSig, err := Deserialize(sig)
|
||||
if err != nil {
|
||||
t.Error("fail to deserialize ring signature")
|
||||
}
|
||||
|
||||
assert.True(t, Verify(deserializedSig, false), "Verify should return true")
|
||||
}
|
||||
|
||||
func TestDeserialize2(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 7
|
||||
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
if err != nil {
|
||||
t.Error("fail to generate rings")
|
||||
}
|
||||
|
||||
ringSignature, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
t.Error("fail to create ring signature")
|
||||
}
|
||||
|
||||
// change one sig to the scalar field
|
||||
ringSignature.S[0][0] = curve.Params().N
|
||||
|
||||
sig, err := ringSignature.Serialize()
|
||||
if err != nil {
|
||||
t.Error("fail to serialize input ring signature")
|
||||
}
|
||||
|
||||
_, err = Deserialize(sig)
|
||||
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
|
||||
}
|
||||
|
||||
func TestPadTo32Bytes(t *testing.T) {
|
||||
arr := [44]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
|
||||
|
||||
|
|
@ -127,3 +187,138 @@ func TestPadTo32Bytes(t *testing.T) {
|
|||
assert.True(t, bytes.Equal(PadTo32Bytes(arr[10:40]), arr[8:40]), "Test PadTo32Bytes shorter than 32 bytes #9")
|
||||
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) {
|
||||
curve := crypto.S256().(*secp256k1.BitCurve)
|
||||
|
||||
x, y := curve.ScalarBaseMult(curve.Params().N.Bytes())
|
||||
if x == nil && y == nil {
|
||||
fmt.Println("Scalar multiplication with base point returns nil when scalar is the scalar field")
|
||||
}
|
||||
|
||||
x2, y2 := curve.ScalarMult(new(big.Int).SetUint64(uint64(100)), new(big.Int).SetUint64(uint64(2)), curve.Params().N.Bytes())
|
||||
if x2 == nil && y2 == nil {
|
||||
fmt.Println("Scalar multiplication with a point (not necessarily on curve) returns nil when scalar is the scalar field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilPointerDereferencePanic(t *testing.T) {
|
||||
numRing := 5
|
||||
ringSize := 10
|
||||
s := 7
|
||||
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
|
||||
|
||||
ringSig, err := Sign(m, rings, privkeys, s)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to set up")
|
||||
}
|
||||
|
||||
ringSig.S[0][0] = curve.Params().N // change one sig to the scalar field
|
||||
|
||||
sig, err := ringSig.Serialize()
|
||||
if err != nil {
|
||||
t.Error("Failed to Serialize input Ring signature")
|
||||
}
|
||||
|
||||
_ , err = Deserialize(sig)
|
||||
// Should failed to verify Ring signature as the signature is invalid
|
||||
assert.EqualError(t, err, "failed to deserialize, invalid ring signature")
|
||||
}
|
||||
|
|
|
|||
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 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
|
||||
// modification, are permitted provided that the following conditions are
|
||||
|
|
@ -34,16 +35,28 @@ package secp256k1
|
|||
import (
|
||||
"crypto/elliptic"
|
||||
"math/big"
|
||||
"unsafe"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||
)
|
||||
|
||||
/*
|
||||
#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"
|
||||
const (
|
||||
// number of bits in a big.Word
|
||||
wordBits = 32 << (uint64(^big.Word(0)) >> 63)
|
||||
// number of bytes in a big.Word
|
||||
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
|
||||
// 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 {
|
||||
// y² = x³ + b
|
||||
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
|
||||
}
|
||||
|
||||
//TODO: double check if the function is okay
|
||||
// affineFromJacobian reverses the Jacobian transform. See the comment at the
|
||||
// top of the file.
|
||||
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)
|
||||
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)
|
||||
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))
|
||||
}
|
||||
|
||||
|
|
@ -222,40 +245,6 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int,
|
|||
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
|
||||
// an integer in big-endian form.
|
||||
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
|
||||
ret := make([]byte, 1+2*byteLen)
|
||||
ret[0] = 4 // uncompressed point flag
|
||||
math.ReadBits(x, ret[1:1+byteLen])
|
||||
math.ReadBits(y, ret[1+byteLen:])
|
||||
readBits(x, ret[1:1+byteLen])
|
||||
readBits(y, ret[1+byteLen:])
|
||||
return ret
|
||||
}
|
||||
|
||||
|
|
@ -293,12 +282,12 @@ var theCurve = new(BitCurve)
|
|||
func init() {
|
||||
// See SEC 2 section 2.7.1
|
||||
// curve parameters taken from:
|
||||
// http://www.secg.org/collateral/sec2_final.pdf
|
||||
theCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
|
||||
theCurve.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
|
||||
theCurve.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16)
|
||||
theCurve.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16)
|
||||
theCurve.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16)
|
||||
// http://www.secg.org/sec2-v2.pdf
|
||||
theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0)
|
||||
theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0)
|
||||
theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0)
|
||||
theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0)
|
||||
theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0)
|
||||
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
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// 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/>.
|
||||
// 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.
|
||||
|
||||
// secp256k1_context_create_sign_verify creates a context for signing and signature verification.
|
||||
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
|
||||
'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 24, 1 @ Tag_ABI_align_needed = 8-byte
|
||||
.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
|
||||
.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. */
|
||||
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);
|
||||
|
||||
/** Check whether a number is zero. */
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
} while(0)
|
||||
|
||||
static void default_illegal_callback_fn(const char* str, void* data) {
|
||||
(void)data;
|
||||
fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str);
|
||||
abort();
|
||||
}
|
||||
|
|
@ -37,7 +36,6 @@ static const secp256k1_callback default_illegal_callback = {
|
|||
};
|
||||
|
||||
static void default_error_callback_fn(const char* str, void* data) {
|
||||
(void)data;
|
||||
fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str);
|
||||
abort();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,9 @@
|
|||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// 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/>.
|
||||
// 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
|
||||
|
||||
|
|
|
|||
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
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// 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/>.
|
||||
// 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 wraps the bitcoin secp256k1 C library.
|
||||
package secp256k1
|
||||
|
|
@ -20,12 +11,24 @@ package secp256k1
|
|||
/*
|
||||
#cgo CFLAGS: -I./libsecp256k1
|
||||
#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_FIELD_10X26
|
||||
#define USE_FIELD_INV_BUILTIN
|
||||
#define USE_SCALAR_8X32
|
||||
#define USE_SCALAR_INV_BUILTIN
|
||||
#define NDEBUG
|
||||
#include "./libsecp256k1/src/secp256k1.c"
|
||||
#include "./libsecp256k1/src/modules/recovery/main_impl.h"
|
||||
#include "ext.h"
|
||||
|
|
@ -98,7 +101,7 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) {
|
|||
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.
|
||||
// sig must be a 65-byte compact ECDSA signature containing the
|
||||
// recovery id as the last element.
|
||||
|
|
|
|||
|
|
@ -1,18 +1,9 @@
|
|||
// Copyright 2015 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// 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/>.
|
||||
// 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
|
||||
|
||||
|
|
@ -22,10 +13,8 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto/randentropy"
|
||||
)
|
||||
|
||||
const TestCount = 1000
|
||||
|
|
@ -36,11 +25,24 @@ func generateKeyPair() (pubkey, privkey []byte) {
|
|||
panic(err)
|
||||
}
|
||||
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 {
|
||||
sig := randentropy.GetEntropyCSPRNG(65)
|
||||
sig := csprngEntropy(65)
|
||||
sig[32] &= 0x70
|
||||
sig[64] %= 4
|
||||
return sig
|
||||
|
|
@ -49,7 +51,7 @@ func randSig() []byte {
|
|||
// tests for malleability
|
||||
// highest bit of signature ECDSA s value must be 0, in the 33th byte
|
||||
func compactSigCheck(t *testing.T, sig []byte) {
|
||||
var b int = int(sig[32])
|
||||
var b = int(sig[32])
|
||||
if b < 0 {
|
||||
t.Errorf("highest bit is negative: %d", b)
|
||||
}
|
||||
|
|
@ -63,7 +65,7 @@ func compactSigCheck(t *testing.T, sig []byte) {
|
|||
|
||||
func TestSignatureValidity(t *testing.T) {
|
||||
pubkey, seckey := generateKeyPair()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
sig, err := Sign(msg, seckey)
|
||||
if err != nil {
|
||||
t.Errorf("signature error: %s", err)
|
||||
|
|
@ -86,7 +88,7 @@ func TestSignatureValidity(t *testing.T) {
|
|||
|
||||
func TestInvalidRecoveryID(t *testing.T) {
|
||||
_, seckey := generateKeyPair()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
sig, _ := Sign(msg, seckey)
|
||||
sig[64] = 99
|
||||
_, err := RecoverPubkey(msg, sig)
|
||||
|
|
@ -97,7 +99,7 @@ func TestInvalidRecoveryID(t *testing.T) {
|
|||
|
||||
func TestSignAndRecover(t *testing.T) {
|
||||
pubkey1, seckey := generateKeyPair()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
sig, err := Sign(msg, seckey)
|
||||
if err != nil {
|
||||
t.Errorf("signature error: %s", err)
|
||||
|
|
@ -148,7 +150,7 @@ func TestRandomMessagesWithRandomKeys(t *testing.T) {
|
|||
func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)) {
|
||||
for i := 0; i < TestCount; i++ {
|
||||
pubkey1, seckey := keys()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
sig, err := Sign(msg, seckey)
|
||||
if err != nil {
|
||||
t.Fatalf("signature error: %s", err)
|
||||
|
|
@ -176,7 +178,7 @@ func signAndRecoverWithRandomMessages(t *testing.T, keys func() ([]byte, []byte)
|
|||
|
||||
func TestRecoveryOfRandomSignature(t *testing.T) {
|
||||
pubkey1, _ := generateKeyPair()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
|
||||
for i := 0; i < TestCount; i++ {
|
||||
// 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) {
|
||||
pubkey1, seckey := generateKeyPair()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
sig, _ := Sign(msg, seckey)
|
||||
|
||||
for i := 0; i < TestCount; i++ {
|
||||
msg = randentropy.GetEntropyCSPRNG(32)
|
||||
msg = csprngEntropy(32)
|
||||
pubkey2, _ := RecoverPubkey(msg, sig)
|
||||
// recovery can sometimes work, but if so should always give wrong pubkey
|
||||
if bytes.Equal(pubkey1, pubkey2) {
|
||||
|
|
@ -219,7 +221,7 @@ func TestRecoverSanity(t *testing.T) {
|
|||
|
||||
func BenchmarkSign(b *testing.B) {
|
||||
_, seckey := generateKeyPair()
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
|
@ -228,7 +230,7 @@ func BenchmarkSign(b *testing.B) {
|
|||
}
|
||||
|
||||
func BenchmarkRecover(b *testing.B) {
|
||||
msg := randentropy.GetEntropyCSPRNG(32)
|
||||
msg := csprngEntropy(32)
|
||||
_, seckey := generateKeyPair()
|
||||
sig, _ := Sign(msg, seckey)
|
||||
b.ResetTimer()
|
||||
|
|
|
|||
|
|
@ -94,13 +94,14 @@ type Service struct {
|
|||
// websocket.
|
||||
//
|
||||
// From Gorilla websocket docs:
|
||||
// Connections support one concurrent reader and one concurrent writer.
|
||||
// Applications are responsible for ensuring that no more than one goroutine calls the write methods
|
||||
// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel
|
||||
// concurrently and that no more than one goroutine calls the read methods
|
||||
// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler
|
||||
// concurrently.
|
||||
// The Close and WriteControl methods can be called concurrently with all other methods.
|
||||
//
|
||||
// Connections support one concurrent reader and one concurrent writer.
|
||||
// Applications are responsible for ensuring that no more than one goroutine calls the write methods
|
||||
// - NextWriter, SetWriteDeadline, WriteMessage, WriteJSON, EnableWriteCompression, SetCompressionLevel
|
||||
// concurrently and that no more than one goroutine calls the read methods
|
||||
// - NextReader, SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler
|
||||
// concurrently.
|
||||
// The Close and WriteControl methods can be called concurrently with all other methods.
|
||||
type connWrapper struct {
|
||||
conn *websocket.Conn
|
||||
|
||||
|
|
@ -674,7 +675,10 @@ func (s *Service) assembleBlockStats(block *types.Block) *blockStats {
|
|||
txs = []txStats{}
|
||||
}
|
||||
// Assemble and return the block stats
|
||||
author, _ := s.engine.Author(header)
|
||||
author, err := s.engine.Author(header)
|
||||
if err != nil {
|
||||
log.Error("Failed to retrieve block author", "err", err, "number", header.Number, "hash", header.Hash())
|
||||
}
|
||||
|
||||
return &blockStats{
|
||||
Number: header.Number,
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ var Flags = []cli.Flag{
|
|||
//blockprofilerateFlag,
|
||||
cpuprofileFlag,
|
||||
//traceFlag,
|
||||
periodicProfilingFlag,
|
||||
//periodicProfilingFlag,
|
||||
debugDataDirFlag,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1251,7 +1251,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, bl
|
|||
|
||||
res, _, failed, err, vmErr := s.doCall(ctx, args, rpc.LatestBlockNumber, vm.Config{}, 0)
|
||||
if err != nil {
|
||||
if errors.Is(err, core.ErrIntrinsicGas) {
|
||||
if errors.Is(err, vm.ErrOutOfGas) || errors.Is(err, core.ErrIntrinsicGas) {
|
||||
return false, nil, nil, nil // Special case, raise gas limit
|
||||
}
|
||||
return false, nil, err, nil // Bail out
|
||||
|
|
@ -1262,6 +1262,25 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, bl
|
|||
|
||||
return true, nil, nil, nil
|
||||
}
|
||||
|
||||
// If the transaction is a plain value transfer, short circuit estimation and
|
||||
// directly try 21000. Returning 21000 without any execution is dangerous as
|
||||
// some tx field combos might bump the price up even for plain transfers (e.g.
|
||||
// unused access list items). Ever so slightly wasteful, but safer overall.
|
||||
if len(args.Data) == 0 && args.To != nil {
|
||||
statedb, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
|
||||
if statedb == nil || err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if statedb.GetCodeSize(*args.To) == 0 {
|
||||
ok, _, err, _ := executable(params.TxGas)
|
||||
if ok && err == nil {
|
||||
return hexutil.Uint64(params.TxGas), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the binary search and hone in on an executable gas limit
|
||||
for lo+1 < hi {
|
||||
mid := (hi + lo) / 2
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ func (v *V2) UpdateConfig(round uint64) {
|
|||
}
|
||||
}
|
||||
// update to current config
|
||||
log.Warn("[updateV2Config] Update config", "index", index, "round", round, "SwitchRound", v.AllConfigs[index].SwitchRound)
|
||||
log.Info("[updateV2Config] Update config", "index", index, "round", round, "SwitchRound", v.AllConfigs[index].SwitchRound)
|
||||
v.CurrentConfig = v.AllConfigs[index]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import (
|
|||
const (
|
||||
VersionMajor = 2 // Major version component of the current release
|
||||
VersionMinor = 0 // Minor version component of the current release
|
||||
VersionPatch = 1 // Patch version component of the current release
|
||||
VersionPatch = 2 // Patch version component of the current release
|
||||
VersionMeta = "beta1" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue