From 0b1549518e988c5a56e1292a1ad607d9d73747bf Mon Sep 17 00:00:00 2001
From: lunfardo314 <evaldas.drasutis@iota.org>
Date: Thu, 26 Mar 2020 13:15:38 +0200
Subject: [PATCH] added BLS signatures and addresses + tests

---
 .../address/signaturescheme/bls.go            | 25 ++++++++++++++++---
 .../valuetransfer/transaction/signatures.go   | 17 ++++++++++++-
 .../transaction/signatures_test.go            |  8 +++---
 3 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/packages/binary/valuetransfer/address/signaturescheme/bls.go b/packages/binary/valuetransfer/address/signaturescheme/bls.go
index b20d3273..5f77819e 100644
--- a/packages/binary/valuetransfer/address/signaturescheme/bls.go
+++ b/packages/binary/valuetransfer/address/signaturescheme/bls.go
@@ -23,9 +23,10 @@ import (
 var suite = bn256.NewSuite()
 
 const (
-	BLS_SIGNATURE_SIZE   = 64
-	BLS_PUBLIC_KEY_SIZE  = 128
-	BLS_PRIVATE_KEY_SIZE = 32
+	BLS_SIGNATURE_SIZE      = 64
+	BLS_PUBLIC_KEY_SIZE     = 128
+	BLS_PRIVATE_KEY_SIZE    = 32
+	BLS_FULL_SIGNATURE_SIZE = 1 + BLS_PUBLIC_KEY_SIZE + BLS_SIGNATURE_SIZE
 )
 
 // ---------------- implements SignatureScheme interface
@@ -110,7 +111,23 @@ var _ SignatureScheme = &blsSignatureScheme{}
 
 // ---------------- implements Signature interface
 
-type blsSignature [1 + BLS_PUBLIC_KEY_SIZE + BLS_SIGNATURE_SIZE]byte
+type blsSignature [BLS_FULL_SIGNATURE_SIZE]byte
+
+func BLSSignatureFromBytes(data []byte) (result *blsSignature, err error, consumedBytes int) {
+	consumedBytes = 0
+	err = nil
+	if len(data) < BLS_FULL_SIGNATURE_SIZE {
+		err = fmt.Errorf("marshalled BLS signature size must be %d", BLS_FULL_SIGNATURE_SIZE)
+		return
+	}
+	if data[0] != address.VERSION_BLS {
+		err = fmt.Errorf("wrong version byte, expected %d", address.VERSION_BLS)
+	}
+	result = &blsSignature{}
+	copy(result[:BLS_FULL_SIGNATURE_SIZE], data)
+	consumedBytes = BLS_FULL_SIGNATURE_SIZE
+	return
+}
 
 func newBLSSignature(pubKey, signature []byte) *blsSignature {
 	var ret blsSignature
diff --git a/packages/binary/valuetransfer/transaction/signatures.go b/packages/binary/valuetransfer/transaction/signatures.go
index ca2faf3f..843389e3 100644
--- a/packages/binary/valuetransfer/transaction/signatures.go
+++ b/packages/binary/valuetransfer/transaction/signatures.go
@@ -44,7 +44,9 @@ func SignaturesFromBytes(bytes []byte, optionalTargetObject ...*Signatures) (res
 	}
 
 	// 0 byte encodes the end of the signatures
+	var typeCastedSignature signaturescheme.Signature
 	for versionByte != 0 {
+		typeCastedSignature = nil
 		// perform signature scheme specific decoding
 		switch versionByte {
 		case address.VERSION_ED25519:
@@ -55,8 +57,21 @@ func SignaturesFromBytes(bytes []byte, optionalTargetObject ...*Signatures) (res
 
 				return
 			}
-			typeCastedSignature := signature.(signaturescheme.Signature)
+			typeCastedSignature = signature.(signaturescheme.Signature)
 
+		case address.VERSION_BLS:
+			marshalUtil.ReadSeek(-1)
+			signature, signatureErr := marshalUtil.Parse(func(data []byte) (interface{}, error, int) { return signaturescheme.BLSSignatureFromBytes(data) })
+			if signatureErr != nil {
+				err = signatureErr
+
+				return
+			}
+			typeCastedSignature = signature.(signaturescheme.Signature)
+		default:
+			// unknown signature type...
+		}
+		if typeCastedSignature != nil {
 			result.orderedMap.Set(typeCastedSignature.Address(), typeCastedSignature)
 		}
 
diff --git a/packages/binary/valuetransfer/transaction/signatures_test.go b/packages/binary/valuetransfer/transaction/signatures_test.go
index 88589852..a27426c1 100644
--- a/packages/binary/valuetransfer/transaction/signatures_test.go
+++ b/packages/binary/valuetransfer/transaction/signatures_test.go
@@ -15,16 +15,18 @@ func TestSignatures(t *testing.T) {
 
 	address1SigScheme := signaturescheme.ED25519(ed25119.GenerateKeyPair())
 	address2SigScheme := signaturescheme.ED25519(ed25119.GenerateKeyPair())
+	address3SigScheme := signaturescheme.RandBLS()
 
 	signatures := NewSignatures()
 	signatures.Add(address1SigScheme.Address(), address1SigScheme.Sign(dataToSign))
 	signatures.Add(address2SigScheme.Address(), address2SigScheme.Sign(dataToSign))
+	signatures.Add(address3SigScheme.Address(), address3SigScheme.Sign(dataToSign))
 
-	assert.Equal(t, 2, signatures.Size())
+	assert.Equal(t, 3, signatures.Size())
 
 	signatures.Add(address1SigScheme.Address(), address1SigScheme.Sign(dataToSign))
 
-	assert.Equal(t, 2, signatures.Size())
+	assert.Equal(t, 3, signatures.Size())
 
 	signatures.ForEach(func(address address.Address, signature signaturescheme.Signature) bool {
 		assert.Equal(t, true, signature.IsValid(dataToSign))
@@ -39,7 +41,7 @@ func TestSignatures(t *testing.T) {
 		return
 	}
 
-	assert.Equal(t, 2, clonedSignatures.Size())
+	assert.Equal(t, 3, clonedSignatures.Size())
 
 	clonedSignatures.ForEach(func(address address.Address, signature signaturescheme.Signature) bool {
 		assert.Equal(t, true, signature.IsValid(dataToSign))
-- 
GitLab