HSMs Synchronization
In Secubit’s architecture, multiple HSMs may be deployed across different secure facilities or datacenters. These HSMs must always agree on the current Merkle root to guarantee consistency of wallet data and policies. The synchronization process ensures that updates are cryptographically validated before any root change is applied, preventing unauthorized modifications or state divergence.
The protocol works as follows:
-
HMAC Generation
Each HSM derives a synchronization proof by concatenating the old root hash with the new root hash and computing an HMAC-SHA256 over this data using a shared sync key. The sync key is provisioned securely into all HSMs during initialization and never leaves hardware. -
Cross-Validation
When an update is proposed, HSM 1 generates a sync object containing the old root hash, the new root hash, and its HMAC. This object is sent to HSM 2, which recomputes the HMAC locally and checks for equality. If the HMACs differ, the update is rejected. -
Current State Check
In addition to HMAC validation, HSM 2 checks whether the provided old root hash matches its currently stored root hash. This prevents replay attacks or desynchronization if one HSM has already advanced. -
Update Process
Only if both checks succeed—the HMAC matches and the current root matches the expected old root—does HSM 2 accept the update and replace its root hash with the new root hash. If either validation fails, the update is discarded.
flowchart
subgraph HSM1["HSM 1"]
RH_OLD1("old_root_hash")
RH_NEW1("new_root_hash")
SK1("🔑 sync_key")
RH_OLD1 --> C1
RH_NEW1 --> C1
C1(["concat"])
C1 --> H1
SK1 --> H1
H1(["hmac256"])
H1 --> HMAC1
HMAC1("hmac")
end
subgraph SO["sync_object"]
RH_OLD_SO("old_root_hash")
RH_NEW_SO("new_root_hash")
HMAC_SO("hmac")
end
style SO fill:none
RH_OLD1 --> RH_OLD_SO
RH_NEW1 --> RH_NEW_SO
HMAC1 --> HMAC_SO
subgraph HSM2["HSM 2"]
RH_OLD_SO --> C2
RH_NEW_SO --> C2
C2(["concat"])
SK2("🔑 sync_key")
C2 --> H2
SK2 --> H2
H2(["hmac256"])
H2 --> HMAC2
HMAC2("hmac")
HMAC2 --> EH2
HMAC_SO --> EH2
EH2{"equal?"}
RH2("root_hash")
RH_OLD_SO --> ER2
RH2 --> ER2
ER2{"equal?"}
ER2 --> U2
EH2 --> U2
U2[["update root_hash to new_root_hash"]]
end
Security Guarantees
-
Data integrity
Every update binds both the old root hash and the new root hash into the HMAC, ensuring that no forged or altered update can be applied undetected. -
Replay resistance
The HSM validates that the provided old root hash matches its current state, preventing an attacker from replaying a previously valid synchronization object. -
Shared secret protection
The synchronization key used for HMAC is provisioned securely inside each HSM and never leaves the hardware boundary, making it impossible to forge updates from outside. -
Consistency across HSMs
Updates are accepted only when both the HMAC check and the root equality check succeed, guaranteeing that all HSMs converge on the same new root hash.