@morbidCode My comment about correctness is conditioned upon being able to separate out the next and prev like using my let (or something similar in idea). Without being able to separate out the two, your test isn't quite correct.
@morbidCode Cool, I'm glad to be of help! Especially with regard to the redundancy. I'm surprised about not being able to use let (it's a very basic Scheme construct!) but it's what it is. :-)
As for ^, you can check for that by checking the value (remainder (square (modexp base (/ exp 2) m)) m) against 1. You may need to stash the value using a let for later use.
2. (remainder (expmod ... m) m) is completely redundant since the return value of the (expmod ... m) is already supposed to be clipped to mod m (if not, then your expmod has a bug), so the remainder does nothing useful.
@morbidCode (expmod base (/ exp 2) m) is the recursive case. You then square the result to get what you need, then you mod m so you can compare the result to 1.
@morbidCode Clamping x to mod m means (modulo x m), so that the result is always between 0 and m-1. The return value of expmod should, by contract, always be clamped to mod m, so the remainder call in your (remainder (expmod (square base) (/ exp 2) m) m) is redundant.
@morbidCode "You should, however, clamp the result of square to mod m" means use (expmod (remainder (square base) m) (/ exp 2) m) instead. Or, as in my version, (remainder (square (expmod base (/ exp 2) m)) m). Notice how, in both cases, the shape of the expression is (remainder (square ...)), not(remainder (expmod ...)).
@quartata Just writing to let you know I haven't forgotten your program! I have some comments to write on it, but I'm busy preparing for a lightning talk I'm giving tomorrow, so I'll try to do it after this weekend. :-)