https://www.thegeeksearch.com/leap-seconds-in-linux/
Linux handles leap seconds by replaying seconds, not smearing them. Because of that, this has a chance to generate existing secrets on such events.
It also generally can't be guaranteed that clocks are atomically advanced. While C# may offer that guarantee, I do know Rust has specific code in its time handler to ensure only fresh values are returned.
Finally, if more than 1000 swaps are made per second, this will also fail.
Solution to all of the above is a global variable which keeps track of the last used time, compared any freshly grabbed time values to it, and if they're older, uses the latest one plus 1 ms. That said, this will break if you reboot, as you'll lose context on how you're operating with future time values. Saving this value to disk and loading it at the start would work. In order to minimize future drift, you can also differentiate each millisecond with an i
value, referring to how many requests were handled for that millisecond. That said, you'll need to save the latest millisecond and the i
.
It should not be feasible to exploit either of these due to how there's no nearby leap second and because the initiator generates the secret, meaning any flood (legit or illegitimate) against your servers of swap requests would only put the requester at risk. You would have to run malicious code to take advantage of this under your current setup. That said, this does potentially break the atomic promise of swaps by using known secrets, so it should be fixed.