diff --git a/bridge/cmd/guardiand/bridge.go b/bridge/cmd/guardiand/bridge.go index c10823251..11c648319 100644 --- a/bridge/cmd/guardiand/bridge.go +++ b/bridge/cmd/guardiand/bridge.go @@ -311,7 +311,7 @@ func runBridge(cmd *cobra.Command, args []string) { logger.Fatal("failed to generate devnet guardian key", zap.Error(err)) } - err = writeGuardianKey(gk, "auto-generated deterministic devnet key", *bridgeKeyPath) + err = writeGuardianKey(gk, "auto-generated deterministic devnet key", *bridgeKeyPath, true) if err != nil { logger.Fatal("failed to write devnet guardian key", zap.Error(err)) } diff --git a/bridge/cmd/guardiand/bridgekey.go b/bridge/cmd/guardiand/bridgekey.go index 5fe6d517d..6bdc865b7 100644 --- a/bridge/cmd/guardiand/bridgekey.go +++ b/bridge/cmd/guardiand/bridgekey.go @@ -46,7 +46,7 @@ func runKeygen(cmd *cobra.Command, args []string) { log.Fatalf("failed to generate key: %v", err) } - err = writeGuardianKey(gk, *keyDescription, args[0]) + err = writeGuardianKey(gk, *keyDescription, args[0], false) if err != nil { log.Fatalf("failed to write key: %v", err) } @@ -79,6 +79,10 @@ func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) { return nil, fmt.Errorf("failed to deserialize protobuf: %w", err) } + if !*unsafeDevMode && m.UnsafeDeterministicKey { + return nil, errors.New("refusing to use deterministic key in production") + } + gk, err := ethcrypto.ToECDSA(m.Data) if err != nil { return nil, fmt.Errorf("failed to deserialize raw key data: %w", err) @@ -88,13 +92,14 @@ func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) { } // writeGuardianKey serializes a guardian key and writes it to disk. -func writeGuardianKey(key *ecdsa.PrivateKey, description string, filename string) error { +func writeGuardianKey(key *ecdsa.PrivateKey, description string, filename string, unsafe bool) error { if _, err := os.Stat(filename); !os.IsNotExist(err) { return errors.New("refusing to override existing key") } m := &nodev1.GuardianKey{ - Data: ethcrypto.FromECDSA(key), + Data: ethcrypto.FromECDSA(key), + UnsafeDeterministicKey: unsafe, } // The private key is a really long-lived piece of data, and we really want to use the stable binary diff --git a/proto/node/v1/node.proto b/proto/node/v1/node.proto index d5a3d8084..278a7e79e 100644 --- a/proto/node/v1/node.proto +++ b/proto/node/v1/node.proto @@ -66,6 +66,8 @@ message GuardianSetUpdate { message GuardianKey { // data is the binary representation of the secp256k1 private key. bytes data = 1; + // Whether this key is deterministically generated and unsuitable for production mode. + bool unsafeDeterministicKey = 2; } // ContractUpgrade represents a Wormhole contract update to be submitted to and signed by the node.