(Note that I'm a defender, not an attacker. I'm usually confronted with descriptions of successful attacks, and tasked to defend against them. Professionals can surely mount attacks far more efficiently than my limited understanding.)
Is there a program that I can run alongside mine that can gather side-channel information?
The most common kind of practical side-channel attacks on a PC-type system is cache timing attacks. The cache is shared between all programs, so if an attacker can run code on the same machine, they can observe when the attacker's program's code or data gets evicted from the cache, which happens when the victim is filling the same cache line. This allows the attacker to make a log of when your program accesses memory and at what address.
The achievable resolution for timing depends heavily on the system and the attacker power. For example, when the normal operating system wants to attack an SGX enclave, the state of the art is a resolution of a single instruction. (I don't remember seeing a similar productized software for Arm TrustZone but it's likely just as feasible.) When an unprivileged Linux or Windows process is attacking another, the possible resolution is likely much worse.
Often the first step in mounting a cache timing attack is to read the memory accesses over many traces (thousands, millions… as much as practical), and do some data mining on the results, looking for correlations between the traces and the values (public inputs and public outputs). That part can be mostly automated. Then there's a phase of interpretation of the results, to go from “these bits look interesting” to ”you can reconstruct the secret form these bits“. That part typically requires a good understanding of how the algorithm is implemented.
If the first part exhibits correlations, even if you don't understand the math well enough to conduct an attack, be very worried.
the sequence of operations depends on r so as to obfuscate n to side-channel attacks
Making the sequence of operations depend on a random factor is not necessarily sufficient to protect against side-channel attacks. For a start, keep in mind that the blinding itself might have side-channel attacks. If the attacker can read r in a single trace, you've lost.
The only reliable way to protect against timing side channels is to operate in constant time. That mainly means, for a typical PC-like architecture:
- The timing and location at which your program accesses memory does not depend on any secret. Otherwise the secret leaks through cache timing attacks. This means, for example, not accessing an array (or list or other data structure) at a secret index.
- No conditionals depend on secret data, even if the branches themselves have the same timing and memory access pattern. Conditional branching itself leaks through the branch predictor.
(This is not an exhaustive list, but it's the two things for which attacks from an unprivileged process work reasonably well and don't depend on fine details of the processor architecture.)
I'm writing a higher-order function in Haskell
Haskell is not a good language for protecting against timing attacks. Haskell is a very high-level language and you have no control over when your compiler runs your code. Haskell is in fact especially bad in this aspect among high-level languages — it's the same phenomenon that makes predicting the performance of a program hard.
To resist against timing attacks, you need precise control over your program's timing. That's hard enough to achieve even in C, a low-level language but one where the compiler can still optimize in undesired ways sometimes. The ideal language from this point of view is assembly, but of course assembly has major downsides (portability, and difficulty to write a correct program).
Write your constant-time cryptographic primitives in Rust or, if you're more adventurous, F*. Use Haskell for the high-level logic built on top of those constant-time primitives.