Store the MasterKey in KeyManager
MODIFY
WalletWasabi/Blockchain/Keys/KeyManager.cs
WalletWasabi/Blockchain/Keys/KeyManager.cs
@@ -141,6 +141,7 @@ public class KeyManager
}
#region Properties
+
[JsonProperty(PropertyName = "EncryptedSecret")]
public BitcoinEncryptedSecretNoEC? EncryptedSecret { get; }
@@ -216,7 +217,7 @@ public class KeyManager
// keys (stored in the `HdPubKeyCache`), minGapLimit, secrets, height, network.
private object CriticalStateLock { get; } = new();
- #endregion
+ #endregion Properties
private HdPubKeyGenerator SegwitExternalKeyGenerator { get; set; }
private HdPubKeyGenerator SegwitInternalKeyGenerator { get; }
@@ -441,15 +442,29 @@ public class KeyManager
return extKeysAndPubs;
}
+ private (int PasswordHash, ExtKey MasterKey)? MasterKeyAndPasswordHash { get; set; }
+
public ExtKey GetMasterExtKey(string password)
{
- password ??= "";
-
if (IsWatchOnly)
{
throw new SecurityException("This is a watchonly wallet.");
}
+ password ??= "";
+
+ var pwHash = password.GetHashCode();
+
+ if (MasterKeyAndPasswordHash is { } hashAndKey)
+ {
+ if (pwHash != hashAndKey.PasswordHash)
+ {
+ throw new SecurityException("Invalid password.");
+ }
+
+ return hashAndKey.MasterKey;
+ }
+
try
{
Key secret = EncryptedSecret.GetKey(password);
@@ -459,6 +474,8 @@ public class KeyManager
MasterFingerprint ??= secret.PubKey.GetHDFingerPrint();
DeriveTaprootExtPubKey(extKey);
+ MasterKeyAndPasswordHash = (pwHash, extKey);
+
return extKey;
}
catch (SecurityException ex)
@@ -697,6 +714,7 @@ public static class KeyPathExtensions
// throw new NotSupportedException("Unknown script type.")
};
}
+
public static class HdPubKeyExtensions
{
public static BitcoinAddress GetAddress(this HdPubKey me, Network network) =>

Store the MasterKey in KeyManager