github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/encodable/keys.go (about)

     1  package encodable
     2  
     3  import (
     4  	"encoding/hex"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/ethereum/go-ethereum/rlp"
    10  	"github.com/fxamacker/cbor/v2"
    11  	"github.com/vmihailenco/msgpack"
    12  
    13  	"github.com/onflow/crypto"
    14  )
    15  
    16  // ConsensusVoteSigLen is the length of a consensus vote as well as aggregated consensus votes.
    17  const ConsensusVoteSigLen = uint(crypto.SignatureLenBLSBLS12381)
    18  
    19  // RandomBeaconSigLen is the length of a random beacon signature share as well as the random beacon resonstructed signature.
    20  const RandomBeaconSigLen = uint(crypto.SignatureLenBLSBLS12381)
    21  
    22  func toHex(bs []byte) string {
    23  	return fmt.Sprintf("%x", bs)
    24  }
    25  
    26  func fromJSONHex(b []byte) ([]byte, error) {
    27  	var x string
    28  	if err := json.Unmarshal(b, &x); err != nil {
    29  		return nil, fmt.Errorf("could not unmarshal the key: %w", err)
    30  	}
    31  	return hex.DecodeString(x)
    32  }
    33  
    34  func fromMsgPackHex(b []byte) ([]byte, error) {
    35  	var x string
    36  	if err := msgpack.Unmarshal(b, &x); err != nil {
    37  		return nil, fmt.Errorf("could not unmarshal the key: %w", err)
    38  	}
    39  	return hex.DecodeString(x)
    40  }
    41  
    42  func fromCBORPackHex(b []byte) ([]byte, error) {
    43  	var x string
    44  	if err := cbor.Unmarshal(b, &x); err != nil {
    45  		return nil, fmt.Errorf("could not unmarshal the key: %w", err)
    46  	}
    47  	return hex.DecodeString(x)
    48  }
    49  
    50  // NetworkPubKey wraps a public key and allows it to be JSON encoded and decoded. It is not defined in the
    51  // crypto package since the crypto package should not know about the different key types.
    52  type NetworkPubKey struct {
    53  	crypto.PublicKey
    54  }
    55  
    56  func (pub NetworkPubKey) MarshalJSON() ([]byte, error) {
    57  	if pub.PublicKey == nil {
    58  		return json.Marshal(nil)
    59  	}
    60  	return json.Marshal(toHex(pub.Encode()))
    61  }
    62  
    63  func (pub *NetworkPubKey) UnmarshalJSON(b []byte) error {
    64  	bz, err := fromJSONHex(b)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	if len(bz) == 0 {
    70  		return nil
    71  	}
    72  
    73  	pub.PublicKey, err = crypto.DecodePublicKey(crypto.ECDSAP256, bz)
    74  	return err
    75  }
    76  
    77  // NetworkPrivKey wraps a private key and allows it to be JSON encoded and decoded. It is not defined in the
    78  // crypto package since the crypto package should not know about the different key types. More importantly, private
    79  // keys should not be automatically encodable/serializable to prevent accidental secret sharing. The bootstrapping
    80  // package is an exception, since it generates private keys that need to be serialized.
    81  type NetworkPrivKey struct {
    82  	crypto.PrivateKey
    83  }
    84  
    85  func (priv NetworkPrivKey) MarshalJSON() ([]byte, error) {
    86  	if priv.PrivateKey == nil {
    87  		return json.Marshal(nil)
    88  	}
    89  	return json.Marshal(toHex(priv.Encode()))
    90  }
    91  
    92  func (priv *NetworkPrivKey) UnmarshalJSON(b []byte) error {
    93  	bz, err := fromJSONHex(b)
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	if len(bz) == 0 {
    99  		return nil
   100  	}
   101  	priv.PrivateKey, err = crypto.DecodePrivateKey(crypto.ECDSAP256, bz)
   102  	return err
   103  }
   104  
   105  // StakingPubKey wraps a public key and allows it to be JSON encoded and decoded. It is not defined in the
   106  // crypto package since the crypto package should not know about the different key types.
   107  type StakingPubKey struct {
   108  	crypto.PublicKey
   109  }
   110  
   111  func (pub StakingPubKey) MarshalJSON() ([]byte, error) {
   112  	if pub.PublicKey == nil {
   113  		return json.Marshal(nil)
   114  	}
   115  	return json.Marshal(toHex(pub.Encode()))
   116  }
   117  
   118  func (pub *StakingPubKey) UnmarshalJSON(b []byte) error {
   119  	bz, err := fromJSONHex(b)
   120  	if err != nil {
   121  		return err
   122  	}
   123  
   124  	if len(bz) == 0 {
   125  		return nil
   126  	}
   127  	pub.PublicKey, err = crypto.DecodePublicKey(crypto.BLSBLS12381, bz)
   128  	return err
   129  }
   130  
   131  // StakingPrivKey wraps a private key and allows it to be JSON encoded and decoded. It is not defined in the
   132  // crypto package since the crypto package should not know about the different key types. More importantly, private
   133  // keys should not be automatically encodable/serializable to prevent accidental secret sharing. The bootstrapping
   134  // package is an exception, since it generates private keys that need to be serialized.
   135  type StakingPrivKey struct {
   136  	crypto.PrivateKey
   137  }
   138  
   139  func (priv StakingPrivKey) MarshalJSON() ([]byte, error) {
   140  	if priv.PrivateKey == nil {
   141  		return json.Marshal(nil)
   142  	}
   143  	return json.Marshal(toHex(priv.Encode()))
   144  }
   145  
   146  func (priv *StakingPrivKey) UnmarshalJSON(b []byte) error {
   147  	bz, err := fromJSONHex(b)
   148  	if err != nil {
   149  		return err
   150  	}
   151  
   152  	if len(bz) == 0 {
   153  		return nil
   154  	}
   155  	priv.PrivateKey, err = crypto.DecodePrivateKey(crypto.BLSBLS12381, bz)
   156  	return err
   157  }
   158  
   159  // RandomBeaconPubKey wraps a public key and allows it to be JSON encoded and decoded. It is not defined in the
   160  // crypto package since the crypto package should not know about the different key types.
   161  type RandomBeaconPubKey struct {
   162  	crypto.PublicKey
   163  }
   164  
   165  func WrapRandomBeaconPubKeys(keys []crypto.PublicKey) []RandomBeaconPubKey {
   166  	encodables := make([]RandomBeaconPubKey, len(keys))
   167  	for i := range keys {
   168  		encodables[i] = RandomBeaconPubKey{PublicKey: keys[i]}
   169  	}
   170  	return encodables
   171  }
   172  
   173  func (pub RandomBeaconPubKey) MarshalJSON() ([]byte, error) {
   174  	if pub.PublicKey == nil {
   175  		return json.Marshal(nil)
   176  	}
   177  	return json.Marshal(toHex(pub.Encode()))
   178  }
   179  
   180  func (pub *RandomBeaconPubKey) UnmarshalJSON(b []byte) error {
   181  	bz, err := fromJSONHex(b)
   182  	if err != nil {
   183  		return err
   184  	}
   185  
   186  	if len(bz) == 0 {
   187  		return nil
   188  	}
   189  	pub.PublicKey, err = crypto.DecodePublicKey(crypto.BLSBLS12381, bz)
   190  	return err
   191  }
   192  
   193  func (pub RandomBeaconPubKey) MarshalCBOR() ([]byte, error) {
   194  	if pub.PublicKey == nil {
   195  		return cbor.Marshal(nil)
   196  	}
   197  	return cbor.Marshal(toHex(pub.Encode()))
   198  }
   199  
   200  func (pub *RandomBeaconPubKey) UnmarshalCBOR(b []byte) error {
   201  	bz, err := fromCBORPackHex(b)
   202  	if err != nil {
   203  		return err
   204  	}
   205  
   206  	if len(bz) == 0 {
   207  		return nil
   208  	}
   209  	pub.PublicKey, err = crypto.DecodePublicKey(crypto.BLSBLS12381, bz)
   210  	return err
   211  }
   212  
   213  func (pub RandomBeaconPubKey) MarshalMsgpack() ([]byte, error) {
   214  	if pub.PublicKey == nil {
   215  		return nil, fmt.Errorf("empty public key")
   216  	}
   217  	return msgpack.Marshal(toHex(pub.PublicKey.Encode()))
   218  }
   219  
   220  func (pub *RandomBeaconPubKey) UnmarshalMsgpack(b []byte) error {
   221  	bz, err := fromMsgPackHex(b)
   222  	if err != nil {
   223  		return err
   224  	}
   225  
   226  	pub.PublicKey, err = crypto.DecodePublicKey(crypto.BLSBLS12381, bz)
   227  	return err
   228  }
   229  
   230  func (pub *RandomBeaconPubKey) EncodeRLP(w io.Writer) error {
   231  	return rlp.Encode(w, pub.PublicKey.Encode())
   232  }
   233  
   234  // RandomBeaconPrivKey wraps a private key and allows it to be JSON encoded and decoded. It is not defined in
   235  // the crypto package since the crypto package should not know about the different key types. More importantly, private
   236  // keys should not be automatically encodable/serializable to prevent accidental secret sharing. The bootstrapping
   237  // package is an exception, since it generates private keys that need to be serialized.
   238  type RandomBeaconPrivKey struct {
   239  	crypto.PrivateKey
   240  }
   241  
   242  func (priv RandomBeaconPrivKey) MarshalJSON() ([]byte, error) {
   243  	if priv.PrivateKey == nil {
   244  		return json.Marshal(nil)
   245  	}
   246  	return json.Marshal(toHex(priv.Encode()))
   247  }
   248  
   249  func (priv *RandomBeaconPrivKey) UnmarshalJSON(b []byte) error {
   250  	bz, err := fromJSONHex(b)
   251  	if err != nil {
   252  		return err
   253  	}
   254  
   255  	if len(bz) == 0 {
   256  		return nil
   257  	}
   258  	priv.PrivateKey, err = crypto.DecodePrivateKey(crypto.BLSBLS12381, bz)
   259  	return err
   260  }
   261  
   262  func (priv RandomBeaconPrivKey) MarshalMsgpack() ([]byte, error) {
   263  	if priv.PrivateKey == nil {
   264  		return nil, fmt.Errorf("empty private key")
   265  	}
   266  	return msgpack.Marshal(toHex(priv.PrivateKey.Encode()))
   267  }
   268  
   269  func (priv *RandomBeaconPrivKey) UnmarshalMsgpack(b []byte) error {
   270  	bz, err := fromMsgPackHex(b)
   271  	if err != nil {
   272  		return err
   273  	}
   274  
   275  	priv.PrivateKey, err = crypto.DecodePrivateKey(crypto.BLSBLS12381, bz)
   276  	return err
   277  }
   278  
   279  // MachineAccountPrivKey wraps a private key and allows it to be JSON encoded and decoded. It is not defined in the
   280  // crypto package since the crypto package should not know about the different key types. More importantly, private
   281  // keys should not be automatically encodable/serializable to prevent accidental secret sharing. The bootstrapping
   282  // package is an exception, since it generates private keys that need to be serialized.
   283  type MachineAccountPrivKey struct {
   284  	crypto.PrivateKey
   285  }
   286  
   287  func (priv MachineAccountPrivKey) MarshalJSON() ([]byte, error) {
   288  	if priv.PrivateKey == nil {
   289  		return json.Marshal(nil)
   290  	}
   291  	return json.Marshal(toHex(priv.Encode()))
   292  }
   293  
   294  func (priv *MachineAccountPrivKey) UnmarshalJSON(b []byte) error {
   295  	bz, err := fromJSONHex(b)
   296  	if err != nil {
   297  		return err
   298  	}
   299  
   300  	if len(bz) == 0 {
   301  		return nil
   302  	}
   303  	priv.PrivateKey, err = crypto.DecodePrivateKey(crypto.ECDSAP256, bz)
   304  	return err
   305  }