Cache lib/interval's small bit-masks
diff --git a/lib/interval/interval.go b/lib/interval/interval.go
index 45f556c..9293423 100644
--- a/lib/interval/interval.go
+++ b/lib/interval/interval.go
@@ -42,15 +42,33 @@
 	one = big.NewInt(1)
 )
 
+var smallBitMasks = [...]*big.Int{
+	big.NewInt(0x00),
+	big.NewInt(0x01),
+	big.NewInt(0x03),
+	big.NewInt(0x07),
+	big.NewInt(0x0F),
+	big.NewInt(0x1F),
+	big.NewInt(0x3F),
+	big.NewInt(0x7F),
+	big.NewInt(0xFF),
+}
+
 // bitMask returns ((1<<n) - 1), where n is the largest of n0 and n1.
 func bitMask(n0 int, n1 int) *big.Int {
 	n := n0
 	if n < n1 {
 		n = n1
 	}
-	if n > (1 << 30) {
+	if n < 0 {
+		panic("unreachable")
+	} else if n > (1 << 30) {
 		panic("interval: input is too large")
 	}
+
+	if n < len(smallBitMasks) {
+		return smallBitMasks[n]
+	}
 	z := big.NewInt(1)
 	z = z.Lsh(z, uint(n))
 	z = z.Sub(z, one)