github.com/klaytn/klaytn@v1.12.1/crypto/bls/bls.go (about) 1 // Copyright 2023 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The klaytn library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package bls 18 19 import ( 20 "crypto/ecdsa" 21 "encoding/hex" 22 "os" 23 "strings" 24 25 "github.com/klaytn/klaytn/crypto" 26 "github.com/klaytn/klaytn/crypto/bls/blst" 27 "github.com/klaytn/klaytn/crypto/bls/types" 28 ) 29 30 type ( 31 SecretKey = types.SecretKey 32 PublicKey = types.PublicKey 33 Signature = types.Signature 34 ) 35 36 // Applications are expected to use below top-level functions, 37 // Do not directly use 'blst' or other underlying implementations. 38 // 39 // Some functions are named after the equivalent functions in prysm Ethereum CL. 40 // (https://github.com/prysmaticlabs/prysm/blob/v4.0.2/crypto/bls/bls.go) 41 // Such naming should provide compatiblity with prysm code snippets, 42 // in case prysm code snippets are integrated to klaytn. 43 // 44 // ikm -> SK: GenerateKey 45 // () -> SK: RandKey 46 // ec -> SK: DeriveFromECDSA 47 // path -> SK: LoadKey 48 // b32 -> SK: SecretKeyFromBytes 49 // b48 -> PK: PublicKeyFromBytes 50 // b96 -> Sig: SignatureFromBytes 51 // 52 // []b48 -> []PK: MultiplePublicKeysFromBytes 53 // []b96 -> []Sig: MultipleSignaturesFromBytes 54 // 55 // []PK -> PK: AggregateMultiplePubkeys 56 // []Sig -> Sig: AggregateSignatures 57 // 58 // []b48 -> PK: AggregatePublicKeys 59 // []b96 -> Sig: AggregateCompressedSignatures 60 // 61 // Sign(SK, msg) -> Sig 62 // VerifySignature(b96, msg, PK) -> ok, err 63 // PopProve(SK) -> Proof 64 // PoPVerify(PK, Proof) -> ok, err 65 66 // GenerateKey generates a BLS secret key from the initial key material (IKM). 67 // It is deterministic process. Same IKM yields the same secret key. 68 func GenerateKey(ikm []byte) (SecretKey, error) { 69 return blst.GenerateKey(ikm) 70 } 71 72 // RandKey generates a random BLS secret key. 73 func RandKey() (SecretKey, error) { 74 return blst.RandKey() 75 } 76 77 // DeriveFromECDSA generates a BLS secret key from the given EC private key. 78 // It is deterministic process. Same EC private key yields the same secret key. 79 func DeriveFromECDSA(priv *ecdsa.PrivateKey) (SecretKey, error) { 80 return GenerateKey(crypto.FromECDSA(priv)) 81 } 82 83 // LoadKey loads a BLS secret key from the given file. 84 func LoadKey(path string) (SecretKey, error) { 85 b, err := os.ReadFile(path) 86 if err != nil { 87 return nil, err 88 } 89 90 content := string(b) 91 content = strings.TrimSpace(content) 92 content = strings.TrimPrefix(content, "0x") 93 b, err = hex.DecodeString(content) 94 if err != nil { 95 return nil, err 96 } 97 98 return SecretKeyFromBytes(b) 99 } 100 101 // SaveKey stores a BLS secret key to the given file. 102 func SaveKey(path string, sk SecretKey) error { 103 b := hex.EncodeToString(sk.Marshal()) 104 return os.WriteFile(path, []byte(b), 0o600) 105 } 106 107 // SecretKeyFromBytes unmarshals and validates a BLS secret key from bytes. 108 func SecretKeyFromBytes(b []byte) (SecretKey, error) { 109 return blst.SecretKeyFromBytes(b) 110 } 111 112 // PublicKeyFromBytes unmarshals and validates a BLS public key from bytes. 113 func PublicKeyFromBytes(b []byte) (PublicKey, error) { 114 return blst.PublicKeyFromBytes(b) 115 } 116 117 // SignatureFromBytes unmarshals and validates a BLS signature from bytes. 118 func SignatureFromBytes(b []byte) (Signature, error) { 119 return blst.SignatureFromBytes(b) 120 } 121 122 // MultiplePublicKeysFromBytes unmarshals and validates multiple BLS public keys 123 // from bytes. Returns an empty slice if an empty slice is given. 124 func MultiplePublicKeysFromBytes(bs [][]byte) ([]PublicKey, error) { 125 return blst.MultiplePublicKeysFromBytes(bs) 126 } 127 128 // MultipleSignaturesFromBytes unmarshals multiple BLS signatures from bytes. 129 // Returns an empty slice if an empty slice is given. 130 func MultipleSignaturesFromBytes(bs [][]byte) ([]Signature, error) { 131 return blst.MultipleSignaturesFromBytes(bs) 132 } 133 134 // AggregateMultiplePubkeys aggregates multiple BLS public keys. 135 // Assumes that all given public keys are previously validated. 136 // Returns error if an empty slice is given. 137 func AggregateMultiplePubkeys(pks []PublicKey) (PublicKey, error) { 138 return blst.AggregatePublicKeys(pks) 139 } 140 141 // AggregateSignatures aggregates multiple BLS signatures. 142 // Assumes that all given signatures are previously validated. 143 // Returns error if an empty slice is given. 144 func AggregateSignatures(sigs []Signature) (Signature, error) { 145 return blst.AggregateSignatures(sigs) 146 } 147 148 // AggregatePublicKeys unmarshals and validates multiple BLS public key from bytes 149 // and then aggregates them. Returns error if an empty slice is given. 150 func AggregatePublicKeys(bs [][]byte) (PublicKey, error) { 151 return blst.AggregatePublicKeysFromBytes(bs) 152 } 153 154 // AggregateCompressedSignatures unmarshals and validates multiple BLS signatures from bytes 155 // and then aggregates them. Returns error if an empty slice is given. 156 func AggregateCompressedSignatures(bs [][]byte) (Signature, error) { 157 return blst.AggregateSignaturesFromBytes(bs) 158 } 159 160 // Sign calculates a signature. 161 func Sign(sk SecretKey, msg []byte) Signature { 162 return blst.Sign(sk, msg) 163 } 164 165 // VerifySignature checks a signature. To perform aggregate verify, supply the 166 // aggregate signature and aggregate public key. 167 func VerifySignature(sig []byte, msg [32]byte, pk PublicKey) (bool, error) { 168 return blst.VerifySignature(sig, msg, pk) 169 } 170 171 // VerifyMultipleSignatures verifies multiple signatures for distinct messages securely. 172 func VerifyMultipleSignatures(sigs [][]byte, msgs [][32]byte, pubKeys []PublicKey) (bool, error) { 173 return blst.VerifyMultipleSignatures(sigs, msgs, pubKeys) 174 } 175 176 // PopProve calculates the proof-of-possession for the secret key, 177 // which is the signature with its public key as message. 178 func PopProve(sk SecretKey) Signature { 179 return blst.PopProve(sk) 180 } 181 182 // PopVerify verifies the proof-of-possession for the public key. 183 func PopVerify(pk PublicKey, sig Signature) bool { 184 return blst.PopVerify(pk, sig) 185 }