0

Say I have a field $\mathbb{F}_q$ for prime modulus $q$, and I have a function random() that yields a uniformly random element of $\mathbb{F}_q$ in constant time.

How would you efficiently build a function random_non_zero() that yields a uniformly random element of $\mathbb{F}_q^* = \mathbb{F}_q - \{0\}$ in constant time? If needed, we can employ additional functions / relations / restrictions (e.g., uniformly random bit generation, access to a mod q function, etc...).

To the best of my knowledge:

  • Reject sampling is not constant-time.
  • A straightforward method is to sample a big enough number, reduce it mod {q-1}, then add 1. However, most field implementations in the wild only provide efficient mod q operations.

Can we sample non-zero values without computing mod q-1?

ibarrond
  • 101
  • 3

1 Answers1

2

If $q=2$ then return $1$. Otherwise it's impossible, because in constant time you can only call random() a fixed number of times, say $N$, producing a uniform distribution over $q^N$ results, and returning $q-1$ different values amounts to binning those results, but $q-1$ doesn't divide $q^N$, so the distribution of return values will necessarily be nonuniform.

You talk about "a big enough number", so it seems you're willing to accept less than perfect uniformity. In that case, you can do this:

repeat N times:
    k ← random()
    if k ≠ 0:
        return k
return 1

That will return $1$ and any other value in the ratio $1{+}\frac{q^N-1}{q-1} : \frac{q^N-1}{q-1}$, so adjust $N$ until that's sufficiently close to $1:1$.

If it needs to be constant-time in the cryptographic sense, not merely the computer-science sense, then you can do it this way:

k ← 1
repeat N times:
    k ← random() or k
return k

where or is the operation found in some languages that returns its left argument if it's nonzero and its right argument otherwise. It's easy enough to implement that in constant time with bit-twiddling.

benrg
  • 891
  • 5
  • 9