Optimization of exponentiation
There are two points where you can improve the performance. This is more related to the algorithm itself, but I guess the answer fits better here than in crypto.SE...


When computing m and u, you are using mod(r) and divide(r). But since r is a power of 2, these are just a bitwise and (with r - 1) and a right shift (by n.bitLength()), which should be much faster. It also helps reducing t modulo r (also using and) before multiplying by nPrime.
Montgomery works better at the word level. If n has w words, then your code takes 2 * (w^2) word multiplications when computing m and u, but could take w^2 + w when using word-level Montgomery. So if you really need speed, you'll need to use an array of integers instead of BigInteger.