@@ -82,15 +82,18 @@ public static uint ModOddInverse(uint[] m, uint[] x, uint[] z)
82
82
Debug . Assert ( - 1 == signF | 0 == signF ) ;
83
83
84
84
CNegate30 ( len30 , signF , F ) ;
85
- CNegate30 ( len30 , signF , D ) ;
86
85
87
- Decode30 ( bits , D , 0 , z , 0 ) ;
88
-
89
- int signD = D [ len30 - 1 ] >> 31 ;
86
+ int signD = CNegate30 ( len30 , signF , D ) ;
90
87
Debug . Assert ( - 1 == signD | 0 == signD ) ;
91
88
92
- signD += ( int ) Nat . CAdd ( len32 , signD , z , m , z ) ;
93
- Debug . Assert ( 0 == signD & 0 != Nat . LessThan ( len32 , z , m ) ) ;
89
+ // TODO 'D' should already be in [P, -P), but absent a proof we support [-2P, 2P)
90
+ signD = CSub30 ( len30 , ~ signD , D , M ) ;
91
+ signD = CAdd30 ( len30 , signD , D , M ) ;
92
+ signD = CAdd30 ( len30 , signD , D , M ) ;
93
+ Debug . Assert ( 0 == signD ) ;
94
+
95
+ Decode30 ( bits , D , 0 , z , 0 ) ;
96
+ Debug . Assert ( 0 != Nat . LessThan ( len32 , z , m ) ) ;
94
97
95
98
return ( uint ) ( EqualTo ( len30 , F , 1 ) & EqualToZero ( len30 , G ) ) ;
96
99
}
@@ -162,16 +165,26 @@ public static bool ModOddInverseVar(uint[] m, uint[] x, uint[] z)
162
165
if ( ! IsOne ( lenFG , F ) )
163
166
return false ;
164
167
165
- Decode30 ( bits , D , 0 , z , 0 ) ;
166
-
167
168
int signD = D [ lenDE - 1 ] >> 31 ;
168
169
Debug . Assert ( - 1 == signD | 0 == signD ) ;
169
170
171
+ // TODO 'D' should already be in [P, -P), but absent a proof we support [-2P, 2P)
172
+ if ( signD < 0 )
173
+ {
174
+ signD = Add30 ( len30 , D , M ) ;
175
+ }
176
+ else
177
+ {
178
+ signD = Sub30 ( len30 , D , M ) ;
179
+ }
170
180
if ( signD < 0 )
171
181
{
172
- signD += ( int ) Nat . AddTo ( len32 , m , z ) ;
182
+ signD = Add30 ( len30 , D , M ) ;
173
183
}
174
- Debug . Assert ( 0 == signD && ! Nat . Gte ( len32 , z , m ) ) ;
184
+ Debug . Assert ( 0 == signD ) ;
185
+
186
+ Decode30 ( bits , D , 0 , z , 0 ) ;
187
+ Debug . Assert ( ! Nat . Gte ( len32 , z , m ) ) ;
175
188
176
189
return true ;
177
190
}
@@ -200,22 +213,71 @@ public static uint[] Random(uint[] p)
200
213
return s ;
201
214
}
202
215
203
- private static void CNegate30 ( int len , int cond , int [ ] D )
216
+ private static int Add30 ( int len30 , int [ ] D , int [ ] M )
204
217
{
205
- Debug . Assert ( len > 0 ) ;
206
- Debug . Assert ( D . Length >= len ) ;
218
+ Debug . Assert ( len30 > 0 ) ;
219
+ Debug . Assert ( D . Length >= len30 ) ;
220
+ Debug . Assert ( M . Length >= len30 ) ;
207
221
208
- int last = len - 1 ;
209
- long cd = 0L ;
222
+ int c = 0 , last = len30 - 1 ;
223
+ for ( int i = 0 ; i < last ; ++ i )
224
+ {
225
+ c += D [ i ] + M [ i ] ;
226
+ D [ i ] = c & M30 ; c >>= 30 ;
227
+ }
228
+ c += D [ last ] + M [ last ] ;
229
+ D [ last ] = c ; c >>= 30 ;
230
+ return c ;
231
+ }
210
232
233
+ private static int CAdd30 ( int len30 , int cond , int [ ] D , int [ ] M )
234
+ {
235
+ Debug . Assert ( len30 > 0 ) ;
236
+ Debug . Assert ( D . Length >= len30 ) ;
237
+ Debug . Assert ( M . Length >= len30 ) ;
238
+
239
+ int c = 0 , last = len30 - 1 ;
211
240
for ( int i = 0 ; i < last ; ++ i )
212
241
{
213
- cd += ( D [ i ] ^ cond ) - cond ;
214
- D [ i ] = ( int ) cd & M30 ; cd >>= 30 ;
242
+ c += D [ i ] + ( M [ i ] & cond ) ;
243
+ D [ i ] = c & M30 ; c >>= 30 ;
215
244
}
245
+ c += D [ last ] + ( M [ last ] & cond ) ;
246
+ D [ last ] = c ; c >>= 30 ;
247
+ return c ;
248
+ }
249
+
250
+ private static int CNegate30 ( int len30 , int cond , int [ ] D )
251
+ {
252
+ Debug . Assert ( len30 > 0 ) ;
253
+ Debug . Assert ( D . Length >= len30 ) ;
216
254
217
- cd += ( D [ last ] ^ cond ) - cond ;
218
- D [ last ] = ( int ) cd ;
255
+ int c = 0 , last = len30 - 1 ;
256
+ for ( int i = 0 ; i < last ; ++ i )
257
+ {
258
+ c += ( D [ i ] ^ cond ) - cond ;
259
+ D [ i ] = c & M30 ; c >>= 30 ;
260
+ }
261
+ c += ( D [ last ] ^ cond ) - cond ;
262
+ D [ last ] = c ; c >>= 30 ;
263
+ return c ;
264
+ }
265
+
266
+ private static int CSub30 ( int len30 , int cond , int [ ] D , int [ ] M )
267
+ {
268
+ Debug . Assert ( len30 > 0 ) ;
269
+ Debug . Assert ( D . Length >= len30 ) ;
270
+ Debug . Assert ( M . Length >= len30 ) ;
271
+
272
+ int c = 0 , last = len30 - 1 ;
273
+ for ( int i = 0 ; i < last ; ++ i )
274
+ {
275
+ c += D [ i ] - ( M [ i ] & cond ) ;
276
+ D [ i ] = c & M30 ; c >>= 30 ;
277
+ }
278
+ c += D [ last ] - ( M [ last ] & cond ) ;
279
+ D [ last ] = c ; c >>= 30 ;
280
+ return c ;
219
281
}
220
282
221
283
private static void Decode30 ( int bits , int [ ] x , int xOff , uint [ ] z , int zOff )
@@ -424,30 +486,63 @@ private static bool IsZero(int len, int[] x)
424
486
return true ;
425
487
}
426
488
427
- private static void Negate30 ( int len , int [ ] D )
428
- {
429
- Debug . Assert ( len > 0 ) ;
430
- Debug . Assert ( D . Length >= len ) ;
489
+ // private static void Negate30(int len, int[] D)
490
+ // {
491
+ // Debug.Assert(len > 0);
492
+ // Debug.Assert(D.Length >= len);
431
493
432
- int last = len - 1 ;
433
- long cd = 0L ;
494
+ // int last = len - 1;
495
+ // long cd = 0L;
434
496
497
+ // for (int i = 0; i < last; ++i)
498
+ // {
499
+ // cd -= D[i];
500
+ // D[i] = (int)cd & M30; cd >>= 30;
501
+ // }
502
+
503
+ // cd -= D[last];
504
+ // D[last] = (int)cd;
505
+ //}
506
+
507
+ private static int Negate30 ( int len30 , int [ ] D )
508
+ {
509
+ Debug . Assert ( len30 > 0 ) ;
510
+ Debug . Assert ( D . Length >= len30 ) ;
511
+
512
+ int c = 0 , last = len30 - 1 ;
435
513
for ( int i = 0 ; i < last ; ++ i )
436
514
{
437
- cd -= D [ i ] ;
438
- D [ i ] = ( int ) cd & M30 ; cd >>= 30 ;
515
+ c -= D [ i ] ;
516
+ D [ i ] = c & M30 ; c >>= 30 ;
439
517
}
518
+ c -= D [ last ] ;
519
+ D [ last ] = c ; c >>= 30 ;
520
+ return c ;
521
+ }
440
522
441
- cd -= D [ last ] ;
442
- D [ last ] = ( int ) cd ;
523
+ private static int Sub30 ( int len30 , int [ ] D , int [ ] M )
524
+ {
525
+ Debug . Assert ( len30 > 0 ) ;
526
+ Debug . Assert ( D . Length >= len30 ) ;
527
+ Debug . Assert ( M . Length >= len30 ) ;
528
+
529
+ int c = 0 , last = len30 - 1 ;
530
+ for ( int i = 0 ; i < last ; ++ i )
531
+ {
532
+ c += D [ i ] - M [ i ] ;
533
+ D [ i ] = c & M30 ; c >>= 30 ;
534
+ }
535
+ c += D [ last ] - M [ last ] ;
536
+ D [ last ] = c ; c >>= 30 ;
537
+ return c ;
443
538
}
444
539
445
- private static void UpdateDE30 ( int len , int [ ] D , int [ ] E , int [ ] t , int m0Inv30x4 , int [ ] M )
540
+ private static void UpdateDE30 ( int len30 , int [ ] D , int [ ] E , int [ ] t , int m0Inv30x4 , int [ ] M )
446
541
{
447
- Debug . Assert ( len > 0 ) ;
448
- Debug . Assert ( D . Length >= len ) ;
449
- Debug . Assert ( E . Length >= len ) ;
450
- Debug . Assert ( M . Length >= len ) ;
542
+ Debug . Assert ( len30 > 0 ) ;
543
+ Debug . Assert ( D . Length >= len30 ) ;
544
+ Debug . Assert ( E . Length >= len30 ) ;
545
+ Debug . Assert ( M . Length >= len30 ) ;
451
546
Debug . Assert ( m0Inv30x4 * M [ 0 ] == - 1 << 2 ) ;
452
547
453
548
int u = t [ 0 ] , v = t [ 1 ] , q = t [ 2 ] , r = t [ 3 ] ;
@@ -472,7 +567,7 @@ private static void UpdateDE30(int len, int[] D, int[] E, int[] t, int m0Inv30x4
472
567
cd >>= 30 ;
473
568
ce >>= 30 ;
474
569
475
- for ( i = 1 ; i < len ; ++ i )
570
+ for ( i = 1 ; i < len30 ; ++ i )
476
571
{
477
572
di = D [ i ] ;
478
573
ei = E [ i ] ;
@@ -487,15 +582,15 @@ private static void UpdateDE30(int len, int[] D, int[] E, int[] t, int m0Inv30x4
487
582
E [ i - 1 ] = ( int ) ce & M30 ; ce >>= 30 ;
488
583
}
489
584
490
- D [ len - 1 ] = ( int ) cd ;
491
- E [ len - 1 ] = ( int ) ce ;
585
+ D [ len30 - 1 ] = ( int ) cd ;
586
+ E [ len30 - 1 ] = ( int ) ce ;
492
587
}
493
588
494
- private static void UpdateFG30 ( int len , int [ ] F , int [ ] G , int [ ] t )
589
+ private static void UpdateFG30 ( int len30 , int [ ] F , int [ ] G , int [ ] t )
495
590
{
496
- Debug . Assert ( len > 0 ) ;
497
- Debug . Assert ( F . Length >= len ) ;
498
- Debug . Assert ( G . Length >= len ) ;
591
+ Debug . Assert ( len30 > 0 ) ;
592
+ Debug . Assert ( F . Length >= len30 ) ;
593
+ Debug . Assert ( G . Length >= len30 ) ;
499
594
500
595
int u = t [ 0 ] , v = t [ 1 ] , q = t [ 2 ] , r = t [ 3 ] ;
501
596
int fi , gi , i ;
@@ -513,7 +608,7 @@ private static void UpdateFG30(int len, int[] F, int[] G, int[] t)
513
608
cf >>= 30 ;
514
609
cg >>= 30 ;
515
610
516
- for ( i = 1 ; i < len ; ++ i )
611
+ for ( i = 1 ; i < len30 ; ++ i )
517
612
{
518
613
fi = F [ i ] ;
519
614
gi = G [ i ] ;
@@ -525,8 +620,8 @@ private static void UpdateFG30(int len, int[] F, int[] G, int[] t)
525
620
G [ i - 1 ] = ( int ) cg & M30 ; cg >>= 30 ;
526
621
}
527
622
528
- F [ len - 1 ] = ( int ) cf ;
529
- G [ len - 1 ] = ( int ) cg ;
623
+ F [ len30 - 1 ] = ( int ) cf ;
624
+ G [ len30 - 1 ] = ( int ) cg ;
530
625
}
531
626
}
532
627
}
0 commit comments