ReactOS 0.4.17-dev-1005-g171e1de
fdef_int.c
Go to the documentation of this file.
1//
2// fdef_int.c INT functions for default number format
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7#include "precomp.h"
8
9//
10// Default big-number format:
11// INT objects are stored in two parts:
12// a SYMCRYPT_FDEF_INT structure
13// an array of UINT32; the # elements in the array is a multiple of SYMCRYPT_FDEF_DIGIT_SIZE/4.
14//
15// The pointer passed points to the start of the UINT32 array, just after the SYMCRYPT_FDEF_INT structure.
16//
17// The generic implementation accesses the digits as an array of UINT32, but on 64-bit CPUs
18// the code can also view it as an array of UINT64.
19//
20
27 UINT32 nDigits )
28{
29 UINT32 i;
30 UINT64 t;
31
32 t = 0;
33 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
34 {
35 t = t + pSrc1[i] + pSrc2[i];
36 pDst[i] = (UINT32) t;
37 t >>= 32;
38 }
39
40 return (UINT32) t;
41}
42
49 UINT32 nDigits )
50{
51#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_ARM
52 return SymCryptFdefRawAddAsm( pSrc1, pSrc2, pDst, nDigits );
53#else
54 return SymCryptFdefRawAddC( pSrc1, pSrc2, pDst, nDigits );
55#endif
56}
57
58
63 UINT32 Src2,
65 UINT32 nDigits )
66{
67 UINT32 i;
68 UINT64 t;
69
70 t = Src2;
71 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
72 {
73 t = t + Src1[i];
74 Dst[i] = (UINT32) t;
75 t >>= 32;
76 }
77
78 return (UINT32) t;
79}
80
84 _In_ PCSYMCRYPT_INT piSrc1,
85 UINT32 u32Src2,
86 _Out_ PSYMCRYPT_INT piDst )
87{
88 SYMCRYPT_CHECK_MAGIC( piSrc1 );
89 SYMCRYPT_CHECK_MAGIC( piDst );
90
91 SYMCRYPT_ASSERT( piSrc1->nDigits == piDst->nDigits );
92
93 return SymCryptFdefRawAddUint32( SYMCRYPT_FDEF_INT_PUINT32( piSrc1 ), u32Src2, SYMCRYPT_FDEF_INT_PUINT32( piDst ), piDst->nDigits );
94}
95
99 _In_ PCSYMCRYPT_INT piSrc1,
100 _In_ PCSYMCRYPT_INT piSrc2,
101 _Out_ PSYMCRYPT_INT piDst )
102{
103 SYMCRYPT_ASSERT( piSrc1->nDigits == piSrc2->nDigits && piSrc2->nDigits == piDst->nDigits );
104
108 piDst->nDigits );
109}
110
111UINT32
114 _In_ PCSYMCRYPT_INT piSrc1,
115 _In_ PCSYMCRYPT_INT piSrc2,
116 _Out_ PSYMCRYPT_INT piDst )
117{
118 UINT32 nS1 = piSrc1->nDigits;
119 UINT32 nS2 = piSrc2->nDigits;
120 UINT32 nD = piDst->nDigits;
121 UINT32 c;
122 UINT32 nW;
123
124 SYMCRYPT_ASSERT( nD >= nS1 && nD >= nS2 );
125
126 if( nS1 < nS2 )
127 {
130 nW = nS2;
131 } else {
132 // nS2 < nS1
135 nW = nS1;
136 }
137
138 if( nW < nD )
139 {
142 c = 0;
143 }
144
145 return c;
146}
147
148UINT32
154 UINT32 nDigits )
155{
156 UINT32 i;
157 UINT64 t;
158 UINT32 c;
159
160 c = 0;
161 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
162 {
163 // c == 1 for carry, 0 for no carry
164 t = (UINT64) pSrc1[i] - pSrc2[i] - c;
165 pDst[i] = (UINT32) t;
166 c = (UINT32)(t >> 32) & 1;
167 }
168
169 return c;
170}
171
172UINT32
178 UINT32 nDigits )
179{
180#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_ARM
181 return SymCryptFdefRawSubAsm( pSrc1, pSrc2, pDst, nDigits );
182#else
183 return SymCryptFdefRawSubC( pSrc1, pSrc2, pDst, nDigits );
184#endif
185}
186
187
188UINT32
192 UINT32 Src2,
194 UINT32 nDigits )
195{
196 UINT32 i;
197 UINT64 t;
198 UINT32 c;
199
200 c = Src2;
201 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
202 {
203 t = (UINT64)pSrc1[i] - c;
204 pDst[i] = (UINT32) t;
205 c = (UINT32)(t >> 32) & 1;
206 }
207
208 return c;
209}
210
211UINT32
215 UINT32 carryIn,
217 UINT32 nDigits )
218{
219 UINT32 i;
220 UINT64 t;
221 UINT32 c;
222
223 c = carryIn;
224 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
225 {
226 t = (UINT64)0 - pSrc1[i] - c;
227 pDst[i] = (UINT32) t;
228 c = (UINT32)(t >> 32) & 1;
229 }
230
231 return c;
232}
233
234UINT32
237 _In_ PCSYMCRYPT_INT piSrc1,
238 UINT32 u32Src2,
239 _Out_ PSYMCRYPT_INT piDst )
240{
241 SYMCRYPT_ASSERT( piSrc1->nDigits == piDst->nDigits );
242
243 return SymCryptFdefRawSubUint32( SYMCRYPT_FDEF_INT_PUINT32( piSrc1 ), u32Src2, SYMCRYPT_FDEF_INT_PUINT32( piDst ), piDst->nDigits );
244}
245
246UINT32
249 _In_ PCSYMCRYPT_INT piSrc1,
250 _In_ PCSYMCRYPT_INT piSrc2,
251 _Out_ PSYMCRYPT_INT piDst )
252{
253 SYMCRYPT_ASSERT( piSrc1->nDigits == piSrc2->nDigits && piSrc1->nDigits == piDst->nDigits );
254
255 return SymCryptFdefRawSub( SYMCRYPT_FDEF_INT_PUINT32( piSrc1 ), SYMCRYPT_FDEF_INT_PUINT32( piSrc2 ), SYMCRYPT_FDEF_INT_PUINT32( piDst ), piDst->nDigits );
256}
257
258UINT32
261 _In_ PCSYMCRYPT_INT piSrc1,
262 _In_ PCSYMCRYPT_INT piSrc2,
263 _Out_ PSYMCRYPT_INT piDst )
264{
265 UINT32 nS1 = piSrc1->nDigits;
266 UINT32 nS2 = piSrc2->nDigits;
267 UINT32 nD = piDst->nDigits;
268 UINT32 c;
269 UINT32 n;
270
271 SYMCRYPT_ASSERT( nD >= nS1 && nD >= nS2 );
272
273 if( nS1 < nS2 )
274 {
278 } else {
279 // nS2 < nS1
283 }
284
285 //
286 // Set the rest of the result to 0s or 1s
287 //
288 while( n < nD * SYMCRYPT_FDEF_DIGIT_NUINT32 )
289 {
290 SYMCRYPT_FDEF_INT_PUINT32( piDst )[n++] = 0 - c;
291 }
292
293 return c;
294}
295
296UINT32
301 UINT32 nDigits )
302{
303 UINT32 i;
304 UINT64 t;
305 UINT32 c;
306
307 // We just do a subtraction without writing and return the carry
308 c = 0;
309 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
310 {
311 // c == 1 for carry, 0 for no carry
312 t = (UINT64) pSrc1[i] - pSrc2[i] - c;
313 c = (UINT32)(t >> 32) & 1;
314 }
315
316 // All booleans are returned as masks
317 return 0 - c;
318}
319
320UINT32
325 UINT32 nDigits )
326{
327#if 0 & SYMCRYPT_CPU_AMD64
328// return SymCryptFdefRawIsLessThanAsm( pSrc1, pSrc2, nDigits );
329#else
330 return SymCryptFdefRawIsLessThanC( pSrc1, pSrc2, nDigits );
331#endif
332}
333
334UINT32
338 UINT32 nDigits )
339{
340 UINT32 i;
341 UINT32 c;
342
343 c = 0;
344 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
345 {
346 c |= pSrc1[i];
347 }
348
349 // All booleans are returned as masks
350 return SYMCRYPT_MASK32_ZERO( c );
351}
352
353UINT32
357 UINT32 nDigits )
358{
359#if 0 & SYMCRYPT_CPU_AMD64
360// return SymCryptFdefRawIsZeroAsm( pSrc1, nDigits );
361#else
362 return SymCryptFdefRawIsZeroC( pSrc1, nDigits );
363#endif
364}
365
366UINT32
369 _In_ PCSYMCRYPT_INT piSrc1,
370 _In_ PCSYMCRYPT_INT piSrc2 )
371{
372 UINT32 nD1 = piSrc1->nDigits;
373 UINT32 nD2 = piSrc2->nDigits;
374
375 UINT32 res;
376
377 if( nD1 == nD2 )
378 {
380 } else if( nD1 < nD2 ) {
382 res |= ~SymCryptFdefRawIsZero( &SYMCRYPT_FDEF_INT_PUINT32( piSrc2 )[ nD1 * SYMCRYPT_FDEF_DIGIT_NUINT32 ], nD2 - nD1 );
383 } else {
386 }
387
388 return res;
389}
390
391
392VOID
395 _In_ PCSYMCRYPT_INT piSrc,
396 _Out_ PSYMCRYPT_INT piDst )
397{
398 UINT32 nDigits = piDst->nDigits;
399 SYMCRYPT_ASSERT( piSrc->nDigits == nDigits );
400
402}
403
404
405VOID
408 _In_ PCSYMCRYPT_INT piSrc,
409 SIZE_T Exp,
410 _Out_ PSYMCRYPT_INT piDst )
411{
412 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
413
414 SIZE_T shiftWords = Exp / (8 * sizeof( UINT32 ) );
415 SIZE_T shiftBits = Exp % (8 * sizeof( UINT32 ) );
416
417 UINT32 nWords = piDst->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
418
419 if( shiftWords >= nWords )
420 {
421 SymCryptWipe( SYMCRYPT_FDEF_INT_PUINT32( piDst ), nWords * sizeof( UINT32 ) );
422 goto cleanup;
423 }
424
425 SIZE_T i = nWords;
426 while( i > shiftWords )
427 {
428 i--;
429 UINT64 t = (UINT64)SYMCRYPT_FDEF_INT_PUINT32( piSrc )[i - shiftWords] << 32;
430 if( i > shiftWords )
431 {
432 t |= SYMCRYPT_FDEF_INT_PUINT32( piSrc )[i - shiftWords - 1];
433 }
434 SYMCRYPT_FDEF_INT_PUINT32( piDst )[i] = (UINT32)(t >> (32 - shiftBits));
435 }
436
437 while( i > 0 )
438 {
439 i--;
440 SYMCRYPT_FDEF_INT_PUINT32( piDst )[i] = 0;
441 }
442
443cleanup:
444 ;
445}
446
447// In shift-based operations which we have no assembly for, and we'd like to use 32-bit words
448// on 32-bit architectures and 64-bit words on 64-bit architectures. So we use NATIVE_UINT &
449// friends.
450
451// Note that accessing the FDEF uint32 array as an array of NATIVE_UINTs relies on
452// the little-endianness of the target if NATIVE_UINT is larger than 32 bits.
453// AMD64 is little endian and ARM64 code is always expected to execute in little
454// endian mode, but this is not true in general for an arbitrary 64 bit platform.
455//
456// If we need to support a 64 bit big endian platform, we need to either
457// restrict its NATIVE_UINT to 32 bits, or introduce load and store macros.
458#define SYMCRYPT_FDEF_INT_PNATIVE_UINT(p) ((NATIVE_UINT*) SYMCRYPT_FDEF_INT_PUINT32( p ))
459// Ensure that sizeof(NATIVE_UINT) > 4 only when compiling for known little endian target
461
462#define SYMCRYPT_FDEF_DIGIT_NNATIVE_UINT ((NATIVE_UINT)(SYMCRYPT_FDEF_DIGIT_SIZE / NATIVE_BYTES))
463
464// Ensure that digit is divisible by native word size!
466
467VOID
470 _In_ PCSYMCRYPT_INT piSrc,
471 SIZE_T exp,
472 _Out_ PSYMCRYPT_INT piDst )
473{
474 SIZE_T shiftWords = exp / NATIVE_BITS;
475 SIZE_T shiftRightBits = exp % NATIVE_BITS;
476 SIZE_T shiftLeftBits = (NATIVE_BITS-1) - shiftRightBits;
477 NATIVE_UINT lowWord, highWord, highPart;
478 SIZE_T i = 0;
479
480 NATIVE_UINT nWords = piDst->nDigits * SYMCRYPT_FDEF_DIGIT_NNATIVE_UINT;
481
482 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
483
484 shiftWords = SYMCRYPT_MIN(shiftWords, nWords);
485 if( shiftWords < nWords )
486 {
487 lowWord = SYMCRYPT_FDEF_INT_PNATIVE_UINT(piSrc)[shiftWords];
488 while( i+shiftWords+1 < nWords )
489 {
490 highWord = SYMCRYPT_FDEF_INT_PNATIVE_UINT(piSrc)[i+shiftWords+1];
491
492 // We always shift highWord left by 1 to keep variable shiftLeftBits in range [0,NATIVE_BITS-1]
493 highPart = (highWord << shiftLeftBits)<<1;
494
495 SYMCRYPT_FDEF_INT_PNATIVE_UINT(piDst)[i] = (lowWord >> shiftRightBits) | highPart;
496
497 lowWord = highWord;
498 i++;
499 }
500 SYMCRYPT_FDEF_INT_PNATIVE_UINT(piDst)[i] = (lowWord >> shiftRightBits);
501 i++;
502 }
503
504 SYMCRYPT_ASSERT(i + shiftWords == nWords);
505
506 SymCryptWipe( &SYMCRYPT_FDEF_INT_PNATIVE_UINT( piDst )[nWords-shiftWords], shiftWords * NATIVE_BYTES );
507}
508
509VOID
512 UINT32 highestBit,
513 _In_ PCSYMCRYPT_INT piSrc,
514 _Out_ PSYMCRYPT_INT piDst )
515{
516 UINT32 nWords = piDst->nDigits * SYMCRYPT_FDEF_DIGIT_NNATIVE_UINT;
517
518 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
519 SYMCRYPT_ASSERT( highestBit < 2 );
520
521 SIZE_T i = 0;
523 NATIVE_UINT highWord = 0;
524 while( i+1 < nWords )
525 {
526 highWord = SYMCRYPT_FDEF_INT_PNATIVE_UINT(piSrc)[i+1];
527
528 SYMCRYPT_FDEF_INT_PNATIVE_UINT(piDst)[i] = (lowWord >> 1) | (highWord << (NATIVE_BITS - 1));
529
530 lowWord = highWord;
531 i++;
532 }
533
534 SYMCRYPT_FDEF_INT_PNATIVE_UINT(piDst)[i] = (lowWord >> 1) | ((NATIVE_UINT)highestBit) << (NATIVE_BITS - 1);
535}
536
537VOID
540 _In_ PCSYMCRYPT_INT piSrc,
541 SIZE_T exp,
542 _Out_ PSYMCRYPT_INT piDst )
543{
544 SIZE_T expWords = exp / 32; // index of word with the partial mask
545 SIZE_T expBits = exp % 32; // # bits to leave in that word
546
547 UINT32 nWords = piDst->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
548
549 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
550
551 if( piSrc != piDst )
552 {
553 memcpy( SYMCRYPT_FDEF_INT_PUINT32( piDst ), SYMCRYPT_FDEF_INT_PUINT32( piSrc ), nWords * sizeof( UINT32 ) );
554 }
555
556 if( expWords >= nWords )
557 {
558 // exp is so large that Dst = Src is sufficient.
559 goto cleanup;
560 }
561
562 for( SIZE_T i=expWords + 1; i < nWords; i++ )
563 {
564 SYMCRYPT_FDEF_INT_PUINT32( piDst )[i] = 0;
565 }
566
567 if( expBits != 0 )
568 {
569 SYMCRYPT_FDEF_INT_PUINT32( piDst )[expWords] &= ((UINT32) -1) >> (32 - expBits );
570 } else {
571 SYMCRYPT_FDEF_INT_PUINT32( piDst )[expWords] = 0;
572 }
573
574cleanup:
575 ;
576}
577
578UINT32
581 _In_ PCSYMCRYPT_INT piSrc,
582 UINT32 iBit )
583{
584 SYMCRYPT_ASSERT( iBit < piSrc->nDigits * SYMCRYPT_FDEF_DIGIT_BITS );
585
586 return (((SYMCRYPT_FDEF_INT_PUINT32( piSrc)[iBit / 32]) >> (iBit % 32)) & 1);
587}
588
589UINT32
592 _In_ PCSYMCRYPT_INT piSrc,
593 UINT32 iBit,
594 UINT32 nBits )
595{
596 UINT32 mainMask = 0;
597 UINT32 result = 0;
598
599 SYMCRYPT_ASSERT( (nBits > 0) &&
600 (nBits < 33) &&
601 (iBit < piSrc->nDigits * SYMCRYPT_FDEF_DIGIT_BITS) &&
602 (iBit + nBits <= piSrc->nDigits * SYMCRYPT_FDEF_DIGIT_BITS) );
603
604 mainMask = (UINT32)(-1) >> (32-nBits);
605
606 // Get the lower word first (it exists since iBit is smaller than the max bit)
607 result = SYMCRYPT_FDEF_INT_PUINT32(piSrc)[iBit/32];
608
609 // Shift to the right accordingly
610 result >>= (iBit%32);
611
612 // Get the upper word (if we need it)
613 // Note: the iBit and nBits values are public
614 if ((iBit%32!=0) && ( iBit/32 + 1 < piSrc->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32 ))
615 {
616 result |= ( SYMCRYPT_FDEF_INT_PUINT32(piSrc)[iBit/32+1] << (32 - iBit%32) );
617 }
618
619 // Mask out the top bits
620 result &= mainMask;
621
622 return result;
623}
624
625VOID
628 _In_ PSYMCRYPT_INT piDst,
630 UINT32 iBit,
631 UINT32 nBits )
632{
633 UINT32 mainMask = 0;
634
635 UINT32 alignedVal = 0;
636 UINT32 alignedMask = 0;
637
638 SYMCRYPT_ASSERT( (nBits > 0) &&
639 (nBits < 33) &&
640 (iBit < piDst->nDigits * SYMCRYPT_FDEF_DIGIT_BITS) &&
641 (iBit + nBits <= piDst->nDigits * SYMCRYPT_FDEF_DIGIT_BITS) );
642
643 // Zero out the not needed bits of the value
644 mainMask = (UINT32)(-1) >> (32-nBits);
645 value &= mainMask;
646
647 //
648 // Lower word
649 //
650
651 // Create the needed mask
652 alignedMask = mainMask << (iBit%32);
653
654 // Align the value
655 alignedVal = value << (iBit%32);
656
657 // Set the lower word first (it exists since iBit is smaller than the max bit)
658 SYMCRYPT_FDEF_INT_PUINT32(piDst)[iBit/32] = (SYMCRYPT_FDEF_INT_PUINT32(piDst)[iBit/32] & ~alignedMask) | alignedVal;
659
660 //
661 // Upper word
662 //
663
664 if ((iBit%32!=0) && ( iBit/32 + 1 < piDst->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32 ))
665 {
666 // Create the needed mask
667 alignedMask = mainMask >> (32 - iBit%32);
668
669 // Align the value
670 alignedVal = value >> (32 - iBit%32);
671
672 // Set the upper word
673 SYMCRYPT_FDEF_INT_PUINT32(piDst)[iBit/32 + 1] = (SYMCRYPT_FDEF_INT_PUINT32(piDst)[iBit/32 + 1] & ~alignedMask) | alignedVal;
674 }
675
676}
677
678
679UINT32
682 _In_ PCSYMCRYPT_INT piSrc1,
683 UINT32 Src2,
684 _Out_ PSYMCRYPT_INT piDst )
685{
686 UINT32 nWords = piDst->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
687
688 SYMCRYPT_ASSERT( piSrc1->nDigits == piDst->nDigits );
689
690 UINT64 c = 0;
691 for( UINT32 i=0; i<nWords; i++ )
692 {
693 c += SYMCRYPT_MUL32x32TO64( SYMCRYPT_FDEF_INT_PUINT32( piSrc1 )[i], Src2 );
694 SYMCRYPT_FDEF_INT_PUINT32( piDst )[i] = (UINT32) c;
695 c >>= 32;
696 }
697
698 return (UINT32) c;
699}
700
701
702VOID
705 _In_ PCSYMCRYPT_INT piSrc1,
706 _In_ PCSYMCRYPT_INT piSrc2,
707 _Out_ PSYMCRYPT_INT piDst,
710{
711 SymCryptFdefIntMulMixedSize( piSrc1, piSrc2, piDst, pbScratch, cbScratch );
712}
713
714VOID
717 _In_ PCSYMCRYPT_INT piSrc,
718 _Out_ PSYMCRYPT_INT piDst,
721{
722 UINT32 nS = piSrc->nDigits;
723 UINT32 nD = piDst->nDigits;
724
726
727 SYMCRYPT_ASSERT( 2*nS <= nD );
728
730
731 if( 2*nS < nD )
732 {
734 }
735}
736
737
738VOID
742 UINT32 nDigits1,
744 UINT32 nDigits2,
745 _Out_writes_((nDigits1+nDigits2)*SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst )
746{
747 UINT32 nWords1 = nDigits1 * SYMCRYPT_FDEF_DIGIT_NUINT32;
748 UINT32 nWords2 = nDigits2 * SYMCRYPT_FDEF_DIGIT_NUINT32;
749
750 // Set Dst to zero
751 SymCryptWipe( pDst, (nDigits1+nDigits2) * SYMCRYPT_FDEF_DIGIT_SIZE );
752
753 for( UINT32 i = 0; i < nWords1; i++ )
754 {
755 UINT32 m = pSrc1[i];
756 UINT64 c = 0;
757 for( UINT32 j = 0; j < nWords2; j++ )
758 {
759 // Invariant: c < 2^32
760 c += SYMCRYPT_MUL32x32TO64( pSrc2[j], m );
761 c += pDst[i+j];
762 // There is no overflow on C because the max value is
763 // (2^32 - 1) * (2^32 - 1) + 2^32 - 1 + 2^32 - 1 = 2^64 - 1.
764 pDst[i+j] = (UINT32) c;
765 c >>= 32;
766 }
767 pDst[i + nWords2] = (UINT32) c;
768 }
769}
770
771VOID
775 UINT32 nDigits1,
777 UINT32 nDigits2,
778 _Out_writes_((nDigits1+nDigits2)*SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst )
779{
780#if SYMCRYPT_CPU_AMD64
782 {
783 SymCryptFdefRawMulMulx( pSrc1, nDigits1, pSrc2, nDigits2, pDst );
784 } else {
785 SymCryptFdefRawMulAsm( pSrc1, nDigits1, pSrc2, nDigits2, pDst );
786 }
787#elif SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_ARM
788 SymCryptFdefRawMulAsm( pSrc1, nDigits1, pSrc2, nDigits2, pDst );
789#else
790 SymCryptFdefRawMulC( pSrc1, nDigits1, pSrc2, nDigits2, pDst );
791#endif
792}
793
794VOID
798 UINT32 nDigits,
800{
801 UINT32 nWords = nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
802
803 UINT32 m = 0;
804 UINT64 c = 0;
805
806 // Set Dst to zero
807 SymCryptWipe( pDst, (2*nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE );
808
809 // First Pass - Addition of the cross products x_i*x_j with i!=j
810 for( UINT32 i = 0; i < nWords; i++ )
811 {
812 m = pSrc[i];
813 c = 0;
814 for( UINT32 j = i+1; j < nWords; j++ )
815 {
816 // Invariant: c < 2^32
817 c += SYMCRYPT_MUL32x32TO64( pSrc[j], m );
818 c += pDst[i+j];
819 // There is no overflow on C because the max value is
820 // (2^32 - 1) * (2^32 - 1) + 2^32 - 1 + 2^32 - 1 = 2^64 - 1.
821 pDst[i+j] = (UINT32) c;
822 c >>= 32;
823 }
824 pDst[i + nWords] = (UINT32) c;
825 }
826
827 // Second Pass - Shifting all results 1 bit left
828 c = 0;
829 for( UINT32 i = 1; i < 2*nWords; i++ )
830 {
831 c |= (((UINT64)pDst[i])<<1);
832 pDst[i] = (UINT32)c;
833 c >>= 32;
834 }
835
836 // Third Pass - Adding the squares on the even columns and propagating the sum
837 c = 0;
838 for( UINT32 i = 0; i < nWords; i++ )
839 {
840 //
841 // Even column
842 //
843 m = pSrc[i];
844 c += SYMCRYPT_MUL32x32TO64( m, m );
845 c += pDst[2*i];
846 // There is no overflow on C because the max value is
847 // (2^32 - 1) * (2^32 - 1) + 2^32 - 1 + 2^32 - 1 = 2^64 - 1
848
849 pDst[2*i] = (UINT32) c;
850 c >>= 32;
851
852 //
853 // Odd column
854 //
855 c += pDst[2*i+1];
856 // There is no overflow on C because the max value is
857 // 2^32 - 1 + 2^32 - 1 = 2^33 - 2
858
859 pDst[2*i+1] = (UINT32) c;
860 c >>= 32;
861 }
862}
863
864VOID
868 UINT32 nDigits,
870{
871#if SYMCRYPT_CPU_AMD64
873 {
874 SymCryptFdefRawSquareMulx( pSrc, nDigits, pDst );
875 } else {
876 SymCryptFdefRawSquareAsm( pSrc, nDigits, pDst );
877 }
878#elif SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_ARM
879 SymCryptFdefRawSquareAsm( pSrc, nDigits, pDst );
880#elif SYMCRYPT_CPU_X86
881 SymCryptFdefRawMulAsm( pSrc, nDigits, pSrc, nDigits, pDst );
882#else
883 SymCryptFdefRawSquareC( pSrc, nDigits, pDst );
884#endif
885}
886
887VOID
890 _In_ PCSYMCRYPT_INT piSrc1,
891 _In_ PCSYMCRYPT_INT piSrc2,
892 _Out_ PSYMCRYPT_INT piDst,
895{
896 UINT32 nS1 = piSrc1->nDigits;
897 UINT32 nS2 = piSrc2->nDigits;
898 UINT32 nD = piDst ->nDigits;
899
901
902 SYMCRYPT_ASSERT( nS1 + nS2 <= nD );
903
905
906 if( nS1 + nS2 < nD )
907 {
908 SymCryptWipe( &SYMCRYPT_FDEF_INT_PUINT32( piDst )[(nS1 + nS2) * SYMCRYPT_FDEF_DIGIT_NUINT32], (nD - (nS1 + nS2)) * SYMCRYPT_FDEF_DIGIT_SIZE );
909 }
910}
911
912
916{
917 return &pdSrc->Int;
918}
919
920VOID
923 _In_ PCSYMCRYPT_INT piSrc,
925 UINT32 totalOperations,
929{
930 UINT32 W;
932 UINT32 nWords;
933 UINT32 bitToTest;
934 UINT64 P;
935
936 UNREFERENCED_PARAMETER( totalOperations );
938
939 SYMCRYPT_CHECK_MAGIC( piSrc );
940 SYMCRYPT_CHECK_MAGIC( pdDst );
941
942 SYMCRYPT_ASSERT( piSrc->nDigits == pdDst->nDigits );
943
945
946 //
947 // Copy the Int.
948 //
949 SymCryptFdefIntCopy( piSrc, &pdDst->Int );
950
951 //
952 // For an N-bit divisor M, and D-bit divisor digit size,
953 // the value W is defined as
954 // floor( (2^{N+D} - 1) / M } - 2^D
955 // which is the largest W such that (W * M + 2^D * M )< 2^{N+D}
956 // To compute W we use a binary search.
957 // This can be optimized, but this is the simplest side-channel safe solution.
958 // We can compute the upper bits of W * M + 2^D * M in a simple loop.
959 //
960 // For now we only compute a 32-bit W for a 32-bit digit divisor size.
961 //
962
963 nBits = SymCryptIntBitsizeOfValue( &pdDst->Int );
964
965 SYMCRYPT_ASSERT( nBits != 0 );
966 if( nBits == 0 )
967 {
968 // Can't create a divisor from a Int whose value is 0
969
970 // We really should not have any callers which get here (it is a requirement that Src != 0)
971 // We assert in CHKed builds
972 // In release set the divisor to 1 instead
973 SymCryptIntSetValueUint32( 1, &pdDst->Int );
974 }
975
976 pdDst->nBits = nBits;
977
978 nWords = (nBits + 31)/32;
979 bitToTest = (UINT32)1 << 31;
980 W = 0;
981 while( bitToTest > 0 )
982 {
983 W |= bitToTest;
984 // Do the multiplication
985 P = 0;
986 for( UINT32 i=0; i<nWords; i++ )
987 {
988 // Invariant:
989 // P <= 2^{2D} - 2 which ensures the mul-add doesn't generate an overflow
990 // P = floor( (W + 2^32)*M[0..i-1] / 2^{32*i} )
991 P += SYMCRYPT_MUL32x32TO64( W, SYMCRYPT_FDEF_INT_PUINT32( &pdDst->Int )[i] );
992 P >>= 32;
993 P += SYMCRYPT_FDEF_INT_PUINT32( &pdDst->Int )[i];
994 }
995 // We are interested in bit N+D, and P[0] is bit nWords*D, this shift brings the relevant bit to position 0
996 P >>= ((nBits+31) % 32) + 1;
997 // If the bit is 1, W*M is too large and we reset the corresponding bit in W.
998 W ^= bitToTest & (0 - ((UINT32)P & 1));
999 bitToTest >>= 1;
1000 }
1001 pdDst->td.fdef.W = W;
1002
1003 SYMCRYPT_SET_MAGIC( pdDst );
1004}
1005
1006UINT32
1009 _Inout_updates_( nUint32 + 1 ) PUINT32 pAcc,
1010 _In_reads_( nUint32 ) PCUINT32 pSrc1,
1011 UINT32 Src2,
1012 UINT32 nUint32 )
1013{
1014 //
1015 // pAcc -= pSrc1 * Src2
1016 // BEWARE: this is only used by the DivMod routine, and works in Words rather than Digits
1017 // making optimizations hard.
1018 //
1019
1020 UINT32 i;
1021 UINT64 tmul;
1022 UINT64 tsub;
1023 UINT32 c;
1024
1025 tmul = 0;
1026 c = 0;
1027 for( i=0; i<nUint32; i++ )
1028 {
1029 tmul += SYMCRYPT_MUL32x32TO64( pSrc1[i], Src2 );
1030 tsub = (UINT64)pAcc[i] - (UINT32) tmul - c;
1031 pAcc[i] = (UINT32) tsub;
1032 c = (tsub >> 32) & 1;
1033 tmul >>= 32;
1034 }
1035
1036 // Writing the last word is strictly speaking not necessary, but a really good check that things are going right.
1037 // We can remove the write, but still need the computation of c so it gains very little.
1038
1039 tsub = (UINT64) pAcc[i] - (UINT32) tmul - c;
1040 pAcc[i] = (UINT32) tsub;
1041 c = (tsub >> 32) & 1;
1042
1043 return c;
1044}
1045
1046UINT32
1049 _Inout_updates_( nUint32 ) PUINT32 pAcc,
1050 _In_reads_( nUint32 ) PCUINT32 pSrc,
1051 UINT32 mask,
1052 UINT32 nUint32 )
1053{
1054 UINT32 i;
1055 UINT64 t;
1056
1057 t = 0;
1058 for( i=0; i<nUint32; i++ )
1059 {
1060 t = t + pAcc[i] + (mask & pSrc[i]);
1061 pAcc[i] = (UINT32) t;
1062 t >>= 32;
1063 }
1064
1065 return (UINT32) t;
1066}
1067
1068UINT32
1073 UINT32 mask,
1074 UINT32 nDigits )
1075{
1076 return SymCryptFdefRawMaskedAddSubdigit( pAcc, pSrc, mask, nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32 );
1077}
1078
1079UINT32
1084 UINT32 mask,
1085 UINT32 nDigits )
1086{
1087 UINT32 i;
1088 UINT64 t;
1089 UINT32 c;
1090
1091 c = 0;
1092 for( i=0; i<nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32; i++ )
1093 {
1094 t = (UINT64) pAcc[i] - (mask & pSrc[i]) - c;
1095 pAcc[i] = (UINT32) t;
1096 c = (UINT32)(t >>= 32) & 1;
1097 }
1098
1099 return c;
1100}
1101
1102
1103
1104VOID
1108 UINT32 nDigits,
1109 _In_ PCSYMCRYPT_DIVISOR pdDivisor,
1111 _Out_writes_opt_(SYMCRYPT_OBJ_NUINT32(pdDivisor)) PUINT32 pRemainder,
1112 _Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1114{
1115 UINT32 nWords = nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
1116 UINT32 activeDivWords = (pdDivisor->nBits + 8 * sizeof(UINT32) - 1) / (8 * sizeof( UINT32 ) );
1117 UINT32 remainderWords = SYMCRYPT_OBJ_NUINT32( pdDivisor );
1118
1119 UINT32 cbScratchNeeded = (nWords+4) * sizeof( UINT32 );
1120 PUINT32 pTmp = (PUINT32) pbScratch;
1121 UINT32 Qest;
1122 UINT32 Q;
1123 UINT32 c;
1124 UINT32 d;
1125 UINT32 shift;
1126 UINT32 X0, X1;
1127 UINT32 W;
1128 UINT64 T;
1129 UINT32 nQ;
1130
1131 SYMCRYPT_ASSERT( cbScratch >= cbScratchNeeded );
1132 SYMCRYPT_ASSERT_ASYM_ALIGNED( pbScratch );
1133
1134 if( nWords < activeDivWords )
1135 {
1136 //
1137 // input is smaller in size than the significant size of the divisor, no division to do.
1138 // Note that both values in the if() statement are public, so this does not create a side channel.
1139 //
1140
1141 // Set quotient to zero, and the remainder to the input value
1142 if( pQuotient != NULL )
1143 {
1144 SymCryptWipe( pQuotient, nDigits * SYMCRYPT_FDEF_DIGIT_SIZE );
1145 }
1146
1147 if( pRemainder != NULL )
1148 {
1149 SYMCRYPT_ASSERT( remainderWords >= nWords );
1150 memcpy( pRemainder, pNum, nWords * sizeof( UINT32 ) );
1151 SymCryptWipe( &pRemainder[nWords], (remainderWords - nWords) * sizeof( UINT32 ) ); // clear the rest of the remainder words
1152 }
1153
1154 SymCryptFdefClaimScratch( pbScratch, cbScratch, cbScratchNeeded );
1155 goto cleanup;
1156 }
1157
1158 //
1159 // We have two zero words in front and two zero words behind the tmp value to allow unrestricted accesses.
1160 // We keep the explicit offset of 2 rather than adjust the pTmp pointer to avoid negative indexes which appear
1161 // to be buffer overflows, and cause trouble with unsigned computations of negative index values that overflow
1162 // to 2^32 - 1 on a 64-bit CPU.
1163 //
1164 pTmp[0] = pTmp[1] = 0;
1165 memcpy( &pTmp[2], pNum, nWords * sizeof( UINT32 ) );
1166 pTmp[nWords + 2] = pTmp[nWords + 3] = 0;
1167 shift = (0 - pdDivisor->nBits) & 31; // # bits we have to shift top words to the left to align with the W value
1168
1169 // We generate the quotient words one at a time, starting at the most significant position
1170 // The top (divWords - 1) words are always zero
1171
1172 if( pQuotient != NULL )
1173 {
1174 SymCryptWipe( &pQuotient[nWords - activeDivWords + 1], (activeDivWords - 1) * sizeof( UINT32 ) );
1175 }
1176
1177 nQ = nWords - activeDivWords + 1;
1178
1179 // There is always at least one word of Q to be computed, so we can use a do-while loop which
1180 // also avoids the UINT32 underflow.
1181 do
1182 {
1183 nQ--;
1184 X0 = ( ((UINT64) pTmp[nQ + activeDivWords + 2] << 32) + pTmp[nQ + activeDivWords + 1] ) >> (32 - shift);
1185 X1 = ( ((UINT64) pTmp[nQ + activeDivWords + 1] << 32) + pTmp[nQ + activeDivWords + 0] ) >> (32 - shift);
1186
1187 W = (UINT32) pdDivisor->td.fdef.W;
1188 T = SYMCRYPT_MUL32x32TO64( W, X0 ) + (((UINT64)X0) << 32) + X1 + ((W>>1) & ((UINT32)0 - (X1 >> 31)));
1189 Qest = (UINT32)(T >> 32);
1190 // At this point the estimator is correct or one too small, add one but don't overflow
1191 Qest += 1;
1192 Qest += SYMCRYPT_MASK32_ZERO( Qest );
1193
1194 c = SymCryptFdefRawMultSubUint32( &pTmp[nQ+2], SYMCRYPT_FDEF_INT_PUINT32( &pdDivisor->Int ), Qest, activeDivWords );
1195 Q = Qest - c;
1196 d = SymCryptFdefRawMaskedAddSubdigit( &pTmp[nQ+2], SYMCRYPT_FDEF_INT_PUINT32( &pdDivisor->Int ), (0-c), activeDivWords );
1197 SYMCRYPT_ASSERT( c == d );
1198 SYMCRYPT_ASSERT( pTmp[nQ + activeDivWords+2] == (0 - c) );
1199
1200 if( pQuotient != NULL )
1201 {
1202 pQuotient[nQ] = Q;
1203 }
1204 } while( nQ > 0 );
1205
1206 if( pRemainder != NULL )
1207 {
1208 memcpy( pRemainder, pTmp+2, activeDivWords * sizeof( UINT32 ) );
1209 SymCryptWipe( &pRemainder[activeDivWords], (remainderWords - activeDivWords) * sizeof( UINT32 ) );
1210 }
1211
1212cleanup:
1213 return; // label needs a statement to follow it...
1214}
1215
1216
1217VOID
1220 _In_ PCSYMCRYPT_INT piSrc,
1221 _In_ PCSYMCRYPT_DIVISOR pdDivisor,
1222 _Out_opt_ PSYMCRYPT_INT piQuotient,
1223 _Out_opt_ PSYMCRYPT_INT piRemainder,
1224 _Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1226{
1227 UINT32 nDigits = SYMCRYPT_OBJ_NDIGITS( piSrc );
1228
1229 SYMCRYPT_ASSERT( piQuotient == NULL || piQuotient->nDigits >= piSrc->nDigits );
1230 SYMCRYPT_ASSERT( piRemainder == NULL || piRemainder->nDigits >= pdDivisor->nDigits );
1231
1234 nDigits,
1235 pdDivisor,
1236 piQuotient == NULL ? NULL : SYMCRYPT_FDEF_INT_PUINT32( piQuotient ),
1237 piRemainder == NULL ? NULL : SYMCRYPT_FDEF_INT_PUINT32( piRemainder ),
1238 pbScratch,
1239 cbScratch
1240 );
1241
1242 if ((piQuotient != NULL) && (piQuotient->nDigits > piSrc->nDigits))
1243 {
1244 SymCryptWipe( &SYMCRYPT_FDEF_INT_PUINT32( piQuotient )[piSrc->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32], (piQuotient->nDigits - piSrc->nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE );
1245 }
1246
1247 if ((piRemainder != NULL) && (piRemainder->nDigits > pdDivisor->nDigits))
1248 {
1249 SymCryptWipe( &SYMCRYPT_FDEF_INT_PUINT32( piRemainder )[pdDivisor->nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32], (piRemainder->nDigits - pdDivisor->nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE );
1250 }
1251}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
unsigned int * PUINT32
Definition: basetsd.h:119
#define NULL
Definition: types.h:112
#define W(I)
#define P(row, col)
static void cleanup(void)
Definition: main.c:1335
VOID SYMCRYPT_CALL SymCryptFdefClaimScratch(PBYTE pbScratch, SIZE_T cbScratch, SIZE_T cbMin)
Definition: fdef_general.c:912
VOID SymCryptFdefIntCopy(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_general.c:259
UINT32 SYMCRYPT_CALL SymCryptFdefRawSubC(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_int.c:150
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntFromDivisor(_In_ PSYMCRYPT_DIVISOR pdSrc)
Definition: fdef_int.c:915
UINT32 SYMCRYPT_CALL SymCryptFdefIntAddSameSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:98
VOID SYMCRYPT_CALL SymCryptFdefIntShr1(UINT32 highestBit, _In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:511
UINT32 SYMCRYPT_CALL SymCryptFdefIntAddUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 u32Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:83
UINT32 SYMCRYPT_CALL SymCryptFdefIntGetBit(_In_ PCSYMCRYPT_INT piSrc, UINT32 iBit)
Definition: fdef_int.c:580
UINT32 SYMCRYPT_CALL SymCryptFdefRawMaskedAdd(_Inout_updates_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pAcc, _In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 mask, UINT32 nDigits)
Definition: fdef_int.c:1070
#define SYMCRYPT_FDEF_INT_PNATIVE_UINT(p)
Definition: fdef_int.c:458
VOID SYMCRYPT_CALL SymCryptFdefRawDivMod(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pNum, UINT32 nDigits, _In_ PCSYMCRYPT_DIVISOR pdDivisor, _Out_writes_opt_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pQuotient, _Out_writes_opt_(SYMCRYPT_OBJ_NUINT32(pdDivisor)) PUINT32 pRemainder, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: fdef_int.c:1106
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsZeroC(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, UINT32 nDigits)
Definition: fdef_int.c:336
UINT32 SYMCRYPT_CALL SymCryptFdefIntSubUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 u32Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:236
VOID SYMCRYPT_CALL SymCryptFdefIntToDivisor(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_DIVISOR pdDst, UINT32 totalOperations, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: fdef_int.c:922
VOID SYMCRYPT_CALL SymCryptFdefRawMulC(_In_reads_(nDigits1 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits1, _In_reads_(nDigits2 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc2, UINT32 nDigits2, _Out_writes_((nDigits1+nDigits2) *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
Definition: fdef_int.c:740
#define SYMCRYPT_FDEF_DIGIT_NNATIVE_UINT
Definition: fdef_int.c:462
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsLessThan(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, UINT32 nDigits)
Definition: fdef_int.c:322
UINT32 SYMCRYPT_CALL SymCryptFdefIntSubSameSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:248
VOID SYMCRYPT_CALL SymCryptFdefIntMulPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T Exp, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:407
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsLessThanC(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, UINT32 nDigits)
Definition: fdef_int.c:298
UINT32 SYMCRYPT_CALL SymCryptFdefIntMulUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:681
UINT32 SYMCRYPT_CALL SymCryptFdefRawMaskedSub(_Inout_updates_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pAcc, _In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 mask, UINT32 nDigits)
Definition: fdef_int.c:1081
UINT32 SYMCRYPT_CALL SymCryptFdefRawAdd(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_int.c:45
VOID SYMCRYPT_CALL SymCryptFdefIntMulMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: fdef_int.c:889
UINT32 SYMCRYPT_CALL SymCryptFdefIntGetBits(_In_ PCSYMCRYPT_INT piSrc, UINT32 iBit, UINT32 nBits)
Definition: fdef_int.c:591
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsZero(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, UINT32 nDigits)
Definition: fdef_int.c:355
UINT32 SYMCRYPT_CALL SymCryptFdefRawMaskedAddSubdigit(_Inout_updates_(nUint32) PUINT32 pAcc, _In_reads_(nUint32) PCUINT32 pSrc, UINT32 mask, UINT32 nUint32)
Definition: fdef_int.c:1048
VOID SYMCRYPT_CALL SymCryptFdefIntNeg(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:394
UINT32 SYMCRYPT_CALL SymCryptFdefRawAddC(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_int.c:23
VOID SYMCRYPT_CALL SymCryptFdefIntDivMod(_In_ PCSYMCRYPT_INT piSrc, _In_ PCSYMCRYPT_DIVISOR pdDivisor, _Out_opt_ PSYMCRYPT_INT piQuotient, _Out_opt_ PSYMCRYPT_INT piRemainder, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: fdef_int.c:1219
UINT32 SYMCRYPT_CALL SymCryptFdefRawMultSubUint32(_Inout_updates_(nUint32+1) PUINT32 pAcc, _In_reads_(nUint32) PCUINT32 pSrc1, UINT32 Src2, UINT32 nUint32)
Definition: fdef_int.c:1008
VOID SYMCRYPT_CALL SymCryptFdefIntSquare(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: fdef_int.c:716
VOID SYMCRYPT_CALL SymCryptFdefIntModPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:539
UINT32 SYMCRYPT_CALL SymCryptFdefIntIsLessThan(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: fdef_int.c:368
UINT32 SYMCRYPT_CALL SymCryptFdefRawSub(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_int.c:174
VOID SYMCRYPT_CALL SymCryptFdefIntMulSameSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: fdef_int.c:704
VOID SYMCRYPT_CALL SymCryptFdefRawSquare(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 nDigits, _Out_writes_(2 *nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
Definition: fdef_int.c:866
UINT32 SYMCRYPT_CALL SymCryptFdefRawNeg(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, UINT32 carryIn, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_int.c:213
UINT32 SYMCRYPT_CALL SymCryptFdefIntSubMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:260
VOID SYMCRYPT_CALL SymCryptFdefRawMul(_In_reads_(nDigits1 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits1, _In_reads_(nDigits2 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc2, UINT32 nDigits2, _Out_writes_((nDigits1+nDigits2) *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
Definition: fdef_int.c:773
UINT32 SYMCRYPT_CALL SymCryptFdefRawAddUint32(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 Src1, UINT32 Src2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 Dst, UINT32 nDigits)
Definition: fdef_int.c:61
UINT32 SYMCRYPT_CALL SymCryptFdefIntAddMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:113
VOID SYMCRYPT_CALL SymCryptFdefIntSetBits(_In_ PSYMCRYPT_INT piDst, UINT32 value, UINT32 iBit, UINT32 nBits)
Definition: fdef_int.c:627
VOID SYMCRYPT_CALL SymCryptFdefRawSquareC(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 nDigits, _Out_writes_(2 *nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
Definition: fdef_int.c:796
UINT32 SYMCRYPT_CALL SymCryptFdefRawSubUint32(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, UINT32 Src2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_int.c:190
VOID SYMCRYPT_CALL SymCryptFdefIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_int.c:469
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
const GLubyte * c
Definition: glext.h:8905
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define C_ASSERT(e)
Definition: intsafe.h:73
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define Dst
Definition: mesh.h:153
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define shift
Definition: input.c:3280
DWORD exp
Definition: msg.c:18625
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_updates_(s)
Definition: no_sal2.h:182
#define _Out_writes_opt_(s)
Definition: no_sal2.h:226
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
int nBits
Definition: pcmconverter.c:96
BYTE * PBYTE
Definition: pedump.c:66
#define T(num)
Definition: thunks.c:311
#define SYMCRYPT_CPU_FEATURES_FOR_MULX
Definition: sc_lib.h:314
#define SYMCRYPT_ASSERT_ASYM_ALIGNED(_p)
Definition: sc_lib.h:1912
#define SYMCRYPT_OBJ_NUINT32(_p)
Definition: sc_lib.h:1920
#define SYMCRYPT_OBJ_NDIGITS(_p)
Definition: sc_lib.h:1918
UINT32 SYMCRYPT_CALL SymCryptFdefRawSubAsm(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 pSrc2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 pDst, UINT32 nDigits)
VOID SYMCRYPT_CALL SymCryptFdefRawMulMulx(_In_reads_(nDigits1 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits1, _In_reads_(nDigits2 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc2, UINT32 nDigits2, _Out_writes_((nDigits1+nDigits2) *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
UINT32 NATIVE_UINT
Definition: sc_lib.h:77
#define NATIVE_BYTES
Definition: sc_lib.h:79
VOID SYMCRYPT_CALL SymCryptFdefRawSquareMulx(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 nDigits, _Out_writes_(2 *nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
VOID SYMCRYPT_CALL SymCryptFdefRawMulAsm(_In_reads_(nDigits1 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits1, _In_reads_(nDigits2 *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc2, UINT32 nDigits2, _Out_writes_((nDigits1+nDigits2) *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
UINT32 SYMCRYPT_CALL SymCryptFdefRawAddAsm(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 Src1, _In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCUINT32 Src2, _Out_writes_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PUINT32 Dst, UINT32 nDigits)
#define SYMCRYPT_FDEF_DIGIT_NUINT32
Definition: sc_lib.h:1916
#define NATIVE_BITS
Definition: sc_lib.h:78
VOID SYMCRYPT_CALL SymCryptFdefRawSquareAsm(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 nDigits, _Out_writes_(2 *nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst)
UINT32 UINT32 UINT32 UINT32 cbScratch
Definition: polytest.cpp:36
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_CALL
#define SYMCRYPT_CPU_AMD64
#define SYMCRYPT_FDEF_DIGIT_SIZE
#define SYMCRYPT_CPU_FEATURES_PRESENT(x)
#define SYMCRYPT_CPU_ARM64
#define SYMCRYPT_FDEF_DIGIT_BITS
const SYMCRYPT_DIVISOR * PCSYMCRYPT_DIVISOR
#define SYMCRYPT_MIN(_a, _b)
#define SYMCRYPT_SET_MAGIC(p)
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL(_nDigits)
const SYMCRYPT_INT * PCSYMCRYPT_INT
SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR
#define SYMCRYPT_MASK32_ZERO(_v)
#define SYMCRYPT_FDEF_INT_PUINT32(p)
const UINT32 * PCUINT32
SYMCRYPT_INT * PSYMCRYPT_INT
#define SYMCRYPT_CHECK_MAGIC(p)
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR(_nDigits)
UINT32 SYMCRYPT_CALL SymCryptIntBitsizeOfValue(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:223
VOID SYMCRYPT_CALL SymCryptIntSetValueUint32(UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:230
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
Definition: pdh_main.c:64