Levels. Just a math transformation of color. Let c be the color of a pixel. c[i] be the corresponding normalized components of the color vector. Then levels will just return a new color using a linear transformation of the form a*c[i] + q to simplify, where a and q are parameters chosen remap values in the desired range.
One interesting difference that I'm finding as I am playing with this is that the levels effect seems to nicely interpolate between the values you keyframed (as if sliding the slider from one value to the next) whereas the curves effect seems to just 'fade' between the two values. The result is completely different when animated.