== On Indexed Loads and Stores

The RISC-V architecture is a pure load-and-store achitecture. The perform
a an _indexed_ load or store, the index must generally be scaled and added
to a base pointer, and only then a separate load operation can be performed.

**Try to avoid table lookups with secret-derived indexes.**
One prominent use of indexed loads in cryptography is to implement S-Boxes
found in various secret-key algorithms. Secret-dependant loads (table lookups)
are problematic in cryptography because of their high potential for cache
timing attacks. We hope that our instruction extensions remove this problem
for AES and other relevant cryptographic algorithms; they often allow
lookup-free implementation without resorting to "bit slicing" the entire
algorithm.

**In RISC-V pointers are generally used for loop control.**
For (arithmetic) loops the lack of indexing becomes less of a problem when
one understands that RISC-V also makes no distinction between index and
address registers and hence one can use pointers as indexes and loop
counters. This is a transformation that a compiler usually does
automatically; when your code is iterating through some vector `v[i]`
with `i=0..n` there is no trace of an "index" in the compiled code.
A single register is both a pointer and index and iterates through
`*v++` until it reaches a pre-computed v + n point.

**Offset loads and stores are "free".**
All loads and stores in RISC-V have a 12-bit signed byte offset built into
the instruction word itself. The offset loads and stores allow an
implementor to often easily unroll a few steps to reduce the relative
time spent on loop control and to potentially parallelize the operation
in superscalar architectures without relying on branch prediction.

