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 }