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.