-
Notifications
You must be signed in to change notification settings - Fork 70
Initial constant-time stack-allocated Bernstein-Yang #632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Aside from a similar change to the |
fd95714 to
e277688
Compare
The previous implementation runs in variable-time with respect to `g`. However in the event both inputs are secret a fully constant-time implementation is required. This implements the method described in section 11 of https://eprint.iacr.org/2019/266.pdf and more specifically this Python code from Figure 11.1: from divsteps2 import divsteps2 def iterations(d): return (49*d+80)//17 if d<46 else (49*d+57)//17 def gcd2(f,g): assert f & 1 d = max(f.nbits(),g.nbits()) m = iterations(d) delta, fm, gm, P = divsteps2 (m,m+d,1,f,g) return abs(fm) def recip2(f,g): assert f & 1 d = max(f.nbits(),g.nbits()) m = iterations(d) precomp = Integers(f)((f+1)/2)^(m−1) delta, fm, gm, P = divsteps2(m,m+1,1,f,g) V = sign(fm)*ZZ(P[0][1]*2^(m-1)) return ZZ(V*precomp) Instead of bounding the loop on `g` reaching zero, this instead computes a fixed number of iterations relative to the highest bit of either `f` or `g` after which the algorithm will converge, then runs for that number of iterations instead. This results in about a 22X performance impact: Bernstein-Yang invert, U256 time: [36.934 µs 37.151 µs 37.391 µs] change: [+2256.7% +2267.7% +2278.4%] (p = 0.00 < 0.05) Performance has regressed. The previous implementation which is variable-time with respect to `g` is preserved as well, for now as `gcd_vartime`, but it would also be nice to add an `inv_mod_vartime` as well.
e277688 to
51cd353
Compare
|
Note: there's an alternative strategy for computing the upper bounds here which we should investigate https://github.com/sipa/safegcd-bounds |
|
I wonder if an implementation of |
|
I should probably add benchmarks for |
|
Added some benchmarks in f2a5aed. For reference: @fjarri I guess the idea would be to use |
|
That's true, but an implementation vartime in both arguments is useful too, so I wonder if removing the restriction on the first argument leads to a noticeable performance gain. |
|
@fjarri I guess we could potentially have all three options, but I'm not sure about naming. One question I'd have is what is the use case for a fully variable time GCD in cryptographic algorithms. |
|
I tried out a Euclidean algorithm implementation with |
The previous implementation runs in variable-time with respect to `g`. However in the event both inputs are secret a fully constant-time implementation is required. This implements Bernstein-Yang in constant-time with respect to both parameters by computing a worst case number of iterations for the algorithm to converge, partially sharing the implementation with #632.
The previous implementation runs in variable-time with respect to `g`. However in the event both inputs are secret a fully constant-time implementation is required. This implements Bernstein-Yang in constant-time with respect to both parameters by computing a worst case number of iterations for the algorithm to converge, partially sharing the implementation with #632.
The previous implementation runs in variable-time with respect to `g`. However in the event both inputs are secret a fully constant-time implementation is required. This implements Bernstein-Yang in constant-time with respect to both parameters by computing a worst case number of iterations for the algorithm to converge, partially sharing the implementation with #632.
The previous implementation runs in variable-time with respect to
g. However in the event both inputs are secret a fully constant-time implementation is required.This implements the method described in section 11 of https://eprint.iacr.org/2019/266.pdf and more specifically this Python code from Figure 11.1:
Instead of bounding the loop on
greaching zero, this instead computes a fixed number of iterations relative to the highest bit of eitherforgafter which the algorithm will converge, then runs for that number of iterations instead.This results in about a 22X performance impact:
The previous implementation which is variable-time with respect to
gis preserved as well, for now asgcd_vartime, but it would also be nice to add aninv_mod_vartimeas well.