diff --git a/dapps/valuetransfers/packages/address/signaturescheme/bls.go b/dapps/valuetransfers/packages/address/signaturescheme/bls.go index 700eb9e4e05d7e4ae3b8f99b5ad2db0acc7f4645..bcded5295780bfe2c663c20834e110335498ae7e 100644 --- a/dapps/valuetransfers/packages/address/signaturescheme/bls.go +++ b/dapps/valuetransfers/packages/address/signaturescheme/bls.go @@ -95,7 +95,7 @@ func (sigscheme *blsSignatureScheme) Sign(data []byte) Signature { if err != nil { panic(err) } - return newBLSSignature(pubKeyBin, sig) + return NewBLSSignature(pubKeyBin, sig) } func (sigscheme *blsSignatureScheme) String() string { @@ -136,7 +136,7 @@ func BLSSignatureFromBytes(data []byte) (result *BLSSignature, consumedBytes int return } -func newBLSSignature(pubKey, signature []byte) *BLSSignature { +func NewBLSSignature(pubKey, signature []byte) *BLSSignature { var ret BLSSignature ret[0] = address.VersionBLS copy(ret.pubKey(), pubKey) @@ -223,7 +223,7 @@ func AggregateBLSSignatures(sigs ...Signature) (Signature, error) { if err != nil { return nil, err } - return newBLSSignature(pubKeyBin, sigBin), nil + return NewBLSSignature(pubKeyBin, sigBin), nil } // interface contract (allow the compiler to check if the implementation has all of the required methods). diff --git a/dapps/valuetransfers/packages/transaction/transaction.go b/dapps/valuetransfers/packages/transaction/transaction.go index 45d3e620480ba747e9ad1467c70dd513238257cf..87ec0f81a3b61c728a0e1d281d77836a79a4f3d1 100644 --- a/dapps/valuetransfers/packages/transaction/transaction.go +++ b/dapps/valuetransfers/packages/transaction/transaction.go @@ -1,6 +1,7 @@ package transaction import ( + "errors" "fmt" "sync" @@ -279,6 +280,16 @@ func (transaction *Transaction) Sign(signature signaturescheme.SignatureScheme) return transaction } +// PutSignature validates and adds signature to the transaction +func (transaction *Transaction) PutSignature(signature signaturescheme.Signature) error { + if !signature.IsValid(transaction.EssenceBytes()) { + return errors.New("PutSignature: invalid signature") + } + transaction.signatures.Add(signature.Address(), signature) + + return nil +} + // String returns a human readable version of this Transaction (for debug purposes). func (transaction *Transaction) String() string { id := transaction.ID() diff --git a/dapps/valuetransfers/packages/transaction/transaction_test.go b/dapps/valuetransfers/packages/transaction/transaction_test.go index 757a0060ac92821ab1a87b125018f56d55d30ac8..5190fe82e4e5cdfa09caed1143bf8c147c6889d7 100644 --- a/dapps/valuetransfers/packages/transaction/transaction_test.go +++ b/dapps/valuetransfers/packages/transaction/transaction_test.go @@ -124,3 +124,69 @@ func TestMarshalingDataPayload(t *testing.T) { assert.Equal(t, true, bytes.Equal(tx1.ID().Bytes(), tx.ID().Bytes())) } + +func TestPutSignatureValid(t *testing.T) { + sigScheme := signaturescheme.RandBLS() + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte("data payload test") + err := tx.SetDataPayload(dataPayload) + assert.Equal(t, nil, err) + + signature := sigScheme.Sign(tx.EssenceBytes()) + assert.Equal(t, signature.IsValid(tx.EssenceBytes()), true) + + err = tx.PutSignature(signature) + assert.Equal(t, nil, err) + + check := tx.SignaturesValid() + assert.Equal(t, true, check) +} + +func TestPutSignatureInvalid(t *testing.T) { + sigScheme := signaturescheme.RandBLS() + addr := sigScheme.Address() + o1 := NewOutputID(addr, RandomID()) + inputs := NewInputs(o1) + bal := balance.New(balance.ColorIOTA, 1) + outputs := NewOutputs(map[address.Address][]*balance.Balance{addr: {bal}}) + tx := New(inputs, outputs) + + dataPayload := []byte("data payload test") + err := tx.SetDataPayload(dataPayload) + assert.Equal(t, nil, err) + + signatureValid := sigScheme.Sign(tx.EssenceBytes()) + assert.Equal(t, true, signatureValid.IsValid(tx.EssenceBytes())) + + sigBytes := make([]byte, len(signatureValid.Bytes())) + copy(sigBytes, signatureValid.Bytes()) + // inverse last byte --> corrupt the signatureValid + sigBytes[len(sigBytes)-1] = sigBytes[len(sigBytes)-1] ^ sigBytes[len(sigBytes)-1] + + sigCorrupted, consumed, err := signaturescheme.BLSSignatureFromBytes(sigBytes) + + assert.Equal(t, nil, err) + assert.Equal(t, consumed, len(sigBytes)) + assert.Equal(t, false, sigCorrupted.IsValid(tx.EssenceBytes())) + + err = tx.PutSignature(sigCorrupted) + // error expected + assert.Equal(t, true, err != nil) + + // 0 signatures is not valid + assert.Equal(t, true, !tx.SignaturesValid()) + + err = tx.PutSignature(signatureValid) + // no error expected + assert.Equal(t, nil, err) + + // valid signatures expected + assert.Equal(t, true, tx.SignaturesValid()) + +}