github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/crypto/bls/bls.go (about)

     1  package blscrypto
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/ecdsa"
     6  	"encoding/hex"
     7  	"errors"
     8  	"fmt"
     9  	"math/big"
    10  
    11  	"github.com/celo-org/bls-zexe/go"
    12  	"github.com/ethereum/go-ethereum/crypto"
    13  )
    14  
    15  const (
    16  	PUBLICKEYBYTES = bls.PUBLICKEYBYTES
    17  	SIGNATUREBYTES = bls.SIGNATUREBYTES
    18  )
    19  
    20  type SerializedPublicKey [PUBLICKEYBYTES]byte
    21  type SerializedSignature [SIGNATUREBYTES]byte
    22  
    23  func ECDSAToBLS(privateKeyECDSA *ecdsa.PrivateKey) ([]byte, error) {
    24  	for i := 0; i < 256; i++ {
    25  		modulus := big.NewInt(0)
    26  		modulus, ok := modulus.SetString(bls.MODULUS377, 10)
    27  		if !ok {
    28  			return nil, errors.New("can't parse modulus")
    29  		}
    30  		privateKeyECDSABytes := crypto.FromECDSA(privateKeyECDSA)
    31  
    32  		keyBytes := []byte("ecdsatobls")
    33  		keyBytes = append(keyBytes, uint8(i))
    34  		keyBytes = append(keyBytes, privateKeyECDSABytes...)
    35  
    36  		privateKeyBLSBytes := crypto.Keccak256(keyBytes)
    37  		privateKeyBLSBytes[0] &= bls.MODULUSMASK
    38  		privateKeyBLSBig := big.NewInt(0)
    39  		privateKeyBLSBig.SetBytes(privateKeyBLSBytes)
    40  		if privateKeyBLSBig.Cmp(modulus) >= 0 {
    41  			continue
    42  		}
    43  
    44  		privateKeyBytes := privateKeyBLSBig.Bytes()
    45  		for len(privateKeyBytes) < len(privateKeyBLSBytes) {
    46  			privateKeyBytes = append([]byte{0x00}, privateKeyBytes...)
    47  		}
    48  		if !bytes.Equal(privateKeyBLSBytes, privateKeyBytes) {
    49  			return nil, fmt.Errorf("private key bytes should have been the same: %s, %s", hex.EncodeToString(privateKeyBLSBytes), hex.EncodeToString(privateKeyBytes))
    50  		}
    51  		// reverse order, as the BLS library expects little endian
    52  		for i := len(privateKeyBytes)/2 - 1; i >= 0; i-- {
    53  			opp := len(privateKeyBytes) - 1 - i
    54  			privateKeyBytes[i], privateKeyBytes[opp] = privateKeyBytes[opp], privateKeyBytes[i]
    55  		}
    56  
    57  		privateKeyBLS, err := bls.DeserializePrivateKey(privateKeyBytes)
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  		defer privateKeyBLS.Destroy()
    62  		privateKeyBLSBytesFromLib, err := privateKeyBLS.Serialize()
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  		if !bytes.Equal(privateKeyBytes, privateKeyBLSBytesFromLib) {
    67  			return nil, errors.New("private key bytes from library should have been the same")
    68  		}
    69  
    70  		return privateKeyBLSBytesFromLib, nil
    71  	}
    72  
    73  	return nil, errors.New("couldn't derive a BLS key from an ECDSA key")
    74  }
    75  
    76  func PrivateToPublic(privateKeyBytes []byte) (SerializedPublicKey, error) {
    77  	privateKey, err := bls.DeserializePrivateKey(privateKeyBytes)
    78  	if err != nil {
    79  		return SerializedPublicKey{}, err
    80  	}
    81  	defer privateKey.Destroy()
    82  
    83  	publicKey, err := privateKey.ToPublic()
    84  	if err != nil {
    85  		return SerializedPublicKey{}, err
    86  	}
    87  	defer publicKey.Destroy()
    88  
    89  	pubKeyBytes, err := publicKey.Serialize()
    90  	if err != nil {
    91  		return SerializedPublicKey{}, err
    92  	}
    93  
    94  	pubKeyBytesFixed := SerializedPublicKey{}
    95  	copy(pubKeyBytesFixed[:], pubKeyBytes)
    96  
    97  	return pubKeyBytesFixed, nil
    98  }
    99  
   100  func VerifyAggregatedSignature(publicKeys []SerializedPublicKey, message []byte, extraData []byte, signature []byte, shouldUseCompositeHasher bool) error {
   101  	publicKeyObjs := []*bls.PublicKey{}
   102  	for _, publicKey := range publicKeys {
   103  		publicKeyObj, err := bls.DeserializePublicKey(publicKey[:])
   104  		if err != nil {
   105  			return err
   106  		}
   107  		defer publicKeyObj.Destroy()
   108  		publicKeyObjs = append(publicKeyObjs, publicKeyObj)
   109  	}
   110  	apk, err := bls.AggregatePublicKeys(publicKeyObjs)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	defer apk.Destroy()
   115  
   116  	signatureObj, err := bls.DeserializeSignature(signature)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	defer signatureObj.Destroy()
   121  
   122  	err = apk.VerifySignature(message, extraData, signatureObj, shouldUseCompositeHasher)
   123  	return err
   124  }
   125  
   126  func AggregateSignatures(signatures [][]byte) ([]byte, error) {
   127  	signatureObjs := []*bls.Signature{}
   128  	for _, signature := range signatures {
   129  		signatureObj, err := bls.DeserializeSignature(signature)
   130  		if err != nil {
   131  			return nil, err
   132  		}
   133  		defer signatureObj.Destroy()
   134  		signatureObjs = append(signatureObjs, signatureObj)
   135  	}
   136  
   137  	asig, err := bls.AggregateSignatures(signatureObjs)
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  	defer asig.Destroy()
   142  
   143  	asigBytes, err := asig.Serialize()
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	return asigBytes, nil
   149  }
   150  
   151  func VerifySignature(publicKey SerializedPublicKey, message []byte, extraData []byte, signature []byte, shouldUseCompositeHasher bool) error {
   152  	publicKeyObj, err := bls.DeserializePublicKey(publicKey[:])
   153  	if err != nil {
   154  		return err
   155  	}
   156  	defer publicKeyObj.Destroy()
   157  
   158  	signatureObj, err := bls.DeserializeSignature(signature)
   159  	if err != nil {
   160  		return err
   161  	}
   162  	defer signatureObj.Destroy()
   163  
   164  	err = publicKeyObj.VerifySignature(message, extraData, signatureObj, shouldUseCompositeHasher)
   165  	return err
   166  }
   167  
   168  func EncodeEpochSnarkData(newValSet []SerializedPublicKey, maximumNonSignersPlusOne uint32, epochIndex uint16) ([]byte, error) {
   169  	pubKeys := []*bls.PublicKey{}
   170  	for _, pubKey := range newValSet {
   171  		publicKeyObj, err := bls.DeserializePublicKey(pubKey[:])
   172  		if err != nil {
   173  			return nil, err
   174  		}
   175  		defer publicKeyObj.Destroy()
   176  
   177  		pubKeys = append(pubKeys, publicKeyObj)
   178  	}
   179  	apk, err := bls.AggregatePublicKeys(pubKeys)
   180  	if err != nil {
   181  		return nil, err
   182  	}
   183  	defer apk.Destroy()
   184  
   185  	return bls.EncodeEpochToBytes(epochIndex, maximumNonSignersPlusOne, apk, pubKeys)
   186  }
   187  
   188  func SerializedSignatureFromBytes(serializedSignature []byte) (SerializedSignature, error) {
   189  	if len(serializedSignature) != SIGNATUREBYTES {
   190  		return SerializedSignature{}, fmt.Errorf("wrong length for serialized signature: expected %d, got %d", SIGNATUREBYTES, len(serializedSignature))
   191  	}
   192  	signatureBytesFixed := SerializedSignature{}
   193  	copy(signatureBytesFixed[:], serializedSignature)
   194  	return signatureBytesFixed, nil
   195  }