diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 3336be456f..e3687968a5 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -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] diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go index a45885c948..5ff473f624 100644 --- a/accounts/abi/argument.go +++ b/accounts/abi/argument.go @@ -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() diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 56bf28530d..1b5c71701c 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -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 diff --git a/cicd/devnet/start.sh b/cicd/devnet/start.sh index bd13986d32..8899d16fa2 100755 --- a/cicd/devnet/start.sh +++ b/cicd/devnet/start.sh @@ -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" diff --git a/cicd/mainnet/start.sh b/cicd/mainnet/start.sh index f6d2938a99..c9512a804c 100755 --- a/cicd/mainnet/start.sh +++ b/cicd/mainnet/start.sh @@ -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" diff --git a/cicd/testnet/start.sh b/cicd/testnet/start.sh index 392b55cfb0..6050ac990c 100755 --- a/cicd/testnet/start.sh +++ b/cicd/testnet/start.sh @@ -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" diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index 26cadc3555..7a213f5b65 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -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, diff --git a/consensus/XDPoS/engines/engine_v2/mining.go b/consensus/XDPoS/engines/engine_v2/mining.go index 69c861acc7..550dd0831d 100644 --- a/consensus/XDPoS/engines/engine_v2/mining.go +++ b/consensus/XDPoS/engines/engine_v2/mining.go @@ -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 } diff --git a/consensus/XDPoS/engines/engine_v2/utils.go b/consensus/XDPoS/engines/engine_v2/utils.go index e54b2b59b0..b15e2917ee 100644 --- a/consensus/XDPoS/engines/engine_v2/utils.go +++ b/consensus/XDPoS/engines/engine_v2/utils.go @@ -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 } diff --git a/core/vm/privacy/bulletproof.go b/core/vm/privacy/bulletproof.go index fab0d5fc7a..f620d230b2 100644 --- a/core/vm/privacy/bulletproof.go +++ b/core/vm/privacy/bulletproof.go @@ -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 } diff --git a/core/vm/privacy/ringct.go b/core/vm/privacy/ringct.go index cc5c70d6bc..93c97c56ce 100644 --- a/core/vm/privacy/ringct.go +++ b/core/vm/privacy/ringct.go @@ -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++ { diff --git a/core/vm/privacy/ringct_test.go b/core/vm/privacy/ringct_test.go index 0c6733b6db..3e5b771c0b 100644 --- a/core/vm/privacy/ringct_test.go +++ b/core/vm/privacy/ringct_test.go @@ -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") +} diff --git a/crypto/secp256k1/LICENSE b/crypto/secp256k1/LICENSE new file mode 100644 index 0000000000..f9090e1423 --- /dev/null +++ b/crypto/secp256k1/LICENSE @@ -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. diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index ecf7a238f0..9b26ab2928 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -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 } diff --git a/crypto/secp256k1/dummy.go b/crypto/secp256k1/dummy.go new file mode 100644 index 0000000000..65a75080f6 --- /dev/null +++ b/crypto/secp256k1/dummy.go @@ -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" +) diff --git a/crypto/secp256k1/ext.h b/crypto/secp256k1/ext.h index 9b043c724e..e422fe4b49 100644 --- a/crypto/secp256k1/ext.h +++ b/crypto/secp256k1/ext.h @@ -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 . +// 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() { diff --git a/crypto/secp256k1/libsecp256k1/contrib/dummy.go b/crypto/secp256k1/libsecp256k1/contrib/dummy.go new file mode 100644 index 0000000000..2c946210c5 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/contrib/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/dummy.go b/crypto/secp256k1/libsecp256k1/dummy.go new file mode 100644 index 0000000000..04bbe3d76e --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/include/dummy.go b/crypto/secp256k1/libsecp256k1/include/dummy.go new file mode 100644 index 0000000000..64c71b8451 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/include/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s b/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s index 5df561f2fc..5a9cc3ffcf 100644 --- a/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s +++ b/crypto/secp256k1/libsecp256k1/src/asm/field_10x26_arm.s @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/src/dummy.go b/crypto/secp256k1/libsecp256k1/src/dummy.go new file mode 100644 index 0000000000..2df270adc3 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/src/modules/dummy.go b/crypto/secp256k1/libsecp256k1/src/modules/dummy.go new file mode 100644 index 0000000000..99c538db51 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go new file mode 100644 index 0000000000..48c2e0aa54 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/ecdh/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/src/modules/recovery/dummy.go b/crypto/secp256k1/libsecp256k1/src/modules/recovery/dummy.go new file mode 100644 index 0000000000..8efbd7abe7 --- /dev/null +++ b/crypto/secp256k1/libsecp256k1/src/modules/recovery/dummy.go @@ -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 diff --git a/crypto/secp256k1/libsecp256k1/src/num.h b/crypto/secp256k1/libsecp256k1/src/num.h index 7bb9c5be8c..eff842200f 100644 --- a/crypto/secp256k1/libsecp256k1/src/num.h +++ b/crypto/secp256k1/libsecp256k1/src/num.h @@ -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. */ diff --git a/crypto/secp256k1/libsecp256k1/src/secp256k1.c b/crypto/secp256k1/libsecp256k1/src/secp256k1.c index fb8b882faa..7d637bfad1 100755 --- a/crypto/secp256k1/libsecp256k1/src/secp256k1.c +++ b/crypto/secp256k1/libsecp256k1/src/secp256k1.c @@ -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(); } diff --git a/crypto/secp256k1/panic_cb.go b/crypto/secp256k1/panic_cb.go index e0e9034ee0..a30b04f51b 100644 --- a/crypto/secp256k1/panic_cb.go +++ b/crypto/secp256k1/panic_cb.go @@ -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 . +// 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 diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go new file mode 100644 index 0000000000..8afa9d023b --- /dev/null +++ b/crypto/secp256k1/scalar_mult_cgo.go @@ -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 +} diff --git a/crypto/secp256k1/scalar_mult_nocgo.go b/crypto/secp256k1/scalar_mult_nocgo.go new file mode 100644 index 0000000000..22f53ac6ae --- /dev/null +++ b/crypto/secp256k1/scalar_mult_nocgo.go @@ -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") +} diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index eefbb99ee4..61abc1eaf0 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -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 . +// 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. diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index f8902607b9..74408d06d2 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -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 . +// 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() diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index dc67bea846..08d7410171 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -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, diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 16a87c9810..3b4ff04122 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -106,7 +106,7 @@ var Flags = []cli.Flag{ //blockprofilerateFlag, cpuprofileFlag, //traceFlag, - periodicProfilingFlag, + //periodicProfilingFlag, debugDataDirFlag, } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 57627d6669..242584e863 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -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 diff --git a/params/config.go b/params/config.go index 337dae4a04..86864d9f8b 100644 --- a/params/config.go +++ b/params/config.go @@ -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] } diff --git a/params/version.go b/params/version.go index 6bb11eab6f..ea91eea3d5 100644 --- a/params/version.go +++ b/params/version.go @@ -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 )