@@ -174,20 +174,42 @@ def __init__(self, curve, x, y, z, order=None, generator=False):
174
174
self .__y = y
175
175
self .__z = z
176
176
self .__order = order
177
+ self .__generator = generator
177
178
self .__precompute = []
178
- if generator :
179
- assert order
180
- i = 1
181
- order *= 2
182
- doubler = PointJacobi (curve , x , y , z , order )
183
- order *= 2
184
- self .__precompute .append ((doubler .x (), doubler .y ()))
185
-
186
- while i < order :
187
- i *= 2
188
- doubler = doubler .double ().scale ()
179
+
180
+ def _maybe_precompute (self ):
181
+ if self .__generator :
182
+ # since we lack promotion of read-locks to write-locks, we do a
183
+ # "acquire-read-lock check, acquire-write-lock plus recheck" cycle
184
+ try :
185
+ self ._scale_lock .reader_acquire ()
186
+ if self .__precompute :
187
+ return
188
+ finally :
189
+ self ._scale_lock .reader_release ()
190
+
191
+ try :
192
+ self ._scale_lock .writer_acquire ()
193
+ if self .__precompute :
194
+ return
195
+ order = self .__order
196
+ assert order
197
+ i = 1
198
+ order *= 2
199
+ doubler = PointJacobi (
200
+ self .__curve , self .__x , self .__y , self .__z , order
201
+ )
202
+ order *= 2
189
203
self .__precompute .append ((doubler .x (), doubler .y ()))
190
204
205
+ while i < order :
206
+ i *= 2
207
+ doubler = doubler .double ().scale ()
208
+ self .__precompute .append ((doubler .x (), doubler .y ()))
209
+
210
+ finally :
211
+ self ._scale_lock .writer_release ()
212
+
191
213
def __getstate__ (self ):
192
214
try :
193
215
self ._scale_lock .reader_acquire ()
@@ -574,6 +596,7 @@ def __mul__(self, other):
574
596
if self .__order :
575
597
# order*2 as a protection for Minerva
576
598
other = other % (self .__order * 2 )
599
+ self ._maybe_precompute ()
577
600
if self .__precompute :
578
601
return self ._mul_precompute (other )
579
602
@@ -621,6 +644,8 @@ def mul_add(self, self_mul, other, other_mul):
621
644
other = PointJacobi .from_affine (other )
622
645
# when the points have precomputed answers, then multiplying them alone
623
646
# is faster (as it uses NAF)
647
+ self ._maybe_precompute ()
648
+ other ._maybe_precompute ()
624
649
if self .__precompute and other .__precompute :
625
650
return self * self_mul + other * other_mul
626
651
0 commit comments