ReactOS 0.4.17-dev-1005-g171e1de
fdef_general.c
Go to the documentation of this file.
1//
2// fdef_general.c General functions of the default format.
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6//
7//
8
9#include "precomp.h"
10
11#include "smallPrimes32.h" // For SymCryptTestTrialdivisionMaxSmallPrime
12
13#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64
14
15#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES (16) // Measured on amd64
16#define SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES (2) // Measured on amd64
17#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES (43000) // Measured on amd64
18
19#elif SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM
20
21#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES (18) // Measured on x86
22#define SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES (16) // Measured on x86
23#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES (25300) // Measured on x86
24
25#else
26
27#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES (18) // Measured on x86
28#define SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES (16) // Measured on x86
29#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES (25300) // Measured on x86
30
31#endif
32
33
34#define SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME (1<<22) // Some large limit to bound memory usage
37
38VOID
43 UINT32 nDigits,
44 UINT32 mask )
45 /*
46 This function is dangerous, and would create a buffer overflow if nDigits > nDigits for pbDst
47 It also appears that it is never called. Consider removing it if it is not needed.
48 */
49{
50 UINT64 m64 = (UINT64)0 - (mask & 1);
51 PUINT64 pSrc = (PUINT64) pbSrc; // should be a const pointer to match pSrc
52 PUINT64 pDst = (PUINT64) pbDst;
53 SIZE_T i;
54
55 // This allows 0xffffffff and 0, is that what you wanted?
56 // If so, ( mask == 0xffffffff || mask == 0 )
57 // would be more readable. It is also odd that 1 is not valid, but it results in exactly the
58 // same code flow as ~0.
59 SYMCRYPT_ASSERT( (mask + 1) < 2 ); // Check that mask is valid
60
61 // This - nDigits * SYMCRYPT_FDEF_DIGIT_SIZE / sizeof( UINT64 )
62 // seems to occur often. Consider a macro with a name that explains what you are doing
63 // A comment on the macro which explains why this multiplication is never a problem would be
64 // helpful - I'm fairly sure it is not a problem.
65 for( i=0; i< nDigits * SYMCRYPT_FDEF_DIGIT_SIZE / sizeof( UINT64 ); i += 2 )
66 {
67 pDst[i ] = (pSrc[i ] & m64) | (pDst[i ] & ~m64 );
68 pDst[i+1] = (pSrc[i+1] & m64) | (pDst[i+1] & ~m64 );
69 }
70}
71
72VOID
77 UINT32 nDigits,
78 UINT32 mask )
79{
80#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_ARM
84#else
86#endif
87}
88
89VOID
94 UINT32 nDigits,
95 UINT32 cond )
96{
97 /*
98 Some documentation as to what the cond argument means would be helpful.
99 */
100 UINT64 m64 = (UINT64)0 - (cond & 1);
101 PUINT64 pSrc1 = (PUINT64) pbSrc1;
102 PUINT64 pSrc2 = (PUINT64) pbSrc2;
103 UINT64 tmp1 = 0;
104 UINT64 tmp2 = 0;
105 SIZE_T i;
106
107 // Unlike the previous function, this only allows 0 and 1 why?
108 SYMCRYPT_ASSERT( cond < 2 ); // Check that the condition is valid
109
110 for( i=0; i< nDigits * SYMCRYPT_FDEF_DIGIT_SIZE / sizeof( UINT64 ); i += 2 )
111 {
112 tmp1 = (pSrc1[i ] ^ pSrc2[i ]) & m64;
113 tmp2 = (pSrc1[i+1] ^ pSrc2[i+1]) & m64;
114
115 pSrc1[i ] ^= tmp1; pSrc2[i ] ^= tmp1;
116 pSrc1[i+1] ^= tmp2; pSrc2[i+1] ^= tmp2;
117 }
118}
119
120VOID
125 UINT32 nDigits,
126 UINT32 cond )
127{
128 SymCryptFdefConditionalSwapC( pbSrc1, pbSrc2, nDigits, cond );
129}
130
131
132UINT32
134{
135 UINT32 res;
136
137 if( nBits == 0 )
138 {
139 res = 1;
140 }
141 else
142 {
144
145 // Callers with integers larger than SYMCRYPT_INT_MAX_BITS should not occur in real use cases
146 // To avoid overflow issues, return the 0 digits to indicate an error which can be handled by
147 // callers, or flow through into object allocation which will in turn recognize the invalid
148 // digit count.
150 {
151 res = 0;
152 } else {
154 }
155 }
156
157 return res;
158}
159
160// Let's limit max bits to the number of bits we actually test
161C_ASSERT( SYMCRYPT_INT_MAX_BITS < (1 << 30) ); // Larger values can cause overflows and sign confusion
162
166{
167 PVOID p = NULL;
168 UINT32 cb;
170
171 //
172 // The nDigits requirements are enforced by SymCryptFdefSizeofIntFromDigits. Thus
173 // the result does not overflow and is upper bounded by 2^18.
174 //
176
177 if( cb != 0 )
178 {
180 }
181
182 if( p == NULL )
183 {
184 goto cleanup;
185 }
186
187 res = SymCryptIntCreate( p, cb, nDigits );
188
189cleanup:
190 return res;
191}
192
193
194UINT32
197{
198 SYMCRYPT_ASSERT( nDigits != 0 );
200
201 // Ensure we do not overflow the following calculation when provided with invalid inputs
202 if( nDigits == 0 || nDigits > SYMCRYPT_FDEF_UPB_DIGITS )
203 {
204 return 0;
205 }
206
207 // Note: ti stands for 'Type-Int' and it helps catch type errors when type-casting macros are used.
209}
210
216 UINT32 nDigits )
217{
218 PSYMCRYPT_INT pInt = NULL;
220
221 SYMCRYPT_ASSERT( cb >= sizeof(SYMCRYPT_INT) );
223 if( (cb == 0) || (cbBuffer < cb) )
224 {
225 goto cleanup; // return NULL
226 }
227
229 pInt = (PSYMCRYPT_INT) pbBuffer;
230
231 pInt->type = 'gI' << 16;
232 pInt->nDigits = nDigits;
233
234 //
235 // The nDigits requirements are enforced by SymCryptFdefSizeofIntFromDigits. Thus
236 // the result does not overflow and is upper bounded by 2^18.
237 //
238 pInt->cbSize = cb;
239
240 SYMCRYPT_SET_MAGIC( pInt );
241
242cleanup:
243 return pInt;
244}
245
246
247VOID
249 _In_ PCSYMCRYPT_INT pSrc,
250 _Out_ PSYMCRYPT_INT pDst )
251{
253 UNREFERENCED_PARAMETER( pDst ); // not used in FRE builds...
254
255 SYMCRYPT_SET_MAGIC( pDst );
256}
257
258VOID
260 _In_ PCSYMCRYPT_INT piSrc,
261 _Out_ PSYMCRYPT_INT piDst )
262{
263 SYMCRYPT_CHECK_MAGIC( piSrc );
264 SYMCRYPT_CHECK_MAGIC( piDst );
265
266 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
267
268 //
269 // in-place copy is somewhat common, and addresses are always public, so we can test for a no-op copy.
270 //
271 if( piSrc != piDst )
272 {
273 // This is normally considered a banned, unsafe function. A note about why it is safe in this use
274 // would be good.
276 }
277}
278
279VOID
281 _In_ PCSYMCRYPT_INT piSrc,
283 UINT32 mask )
284 /*
285 Function notes would be helpful - what is mask, what does it do?
286 */
287{
288 SYMCRYPT_CHECK_MAGIC( piSrc );
289 SYMCRYPT_CHECK_MAGIC( piDst );
290
291 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
292
294}
295
296VOID
299 _In_ PCSYMCRYPT_INT piSrc,
301 UINT32 cond )
302{
303 SYMCRYPT_CHECK_MAGIC( piSrc );
304 SYMCRYPT_CHECK_MAGIC( piDst );
305
306 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
307
309}
310
311VOID
314 _Inout_ PSYMCRYPT_INT piSrc1,
315 _Inout_ PSYMCRYPT_INT piSrc2,
316 UINT32 cond )
317{
318 SYMCRYPT_CHECK_MAGIC( piSrc1 );
319 SYMCRYPT_CHECK_MAGIC( piSrc2 );
320
321 SYMCRYPT_ASSERT( piSrc1->nDigits == piSrc2->nDigits );
322
323 SymCryptFdefConditionalSwap( (PBYTE) SYMCRYPT_FDEF_INT_PUINT32( piSrc1 ), (PBYTE) SYMCRYPT_FDEF_INT_PUINT32( piSrc2 ), piSrc1->nDigits, cond );
324}
325
326UINT32
329{
330 // This does not overflow since the nDigits field is
331 // bounded by SYMCRYPT_FDEF_UPB_DIGITS.
332 return SYMCRYPT_FDEF_DIGIT_BITS * piSrc->nDigits;
333}
334
335UINT32
338{
339 return piSrc->nDigits;
340}
341
344 _In_ PCSYMCRYPT_INT piSrc,
345 _Out_ PSYMCRYPT_INT piDst )
346{
347 UINT32 n;
348 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
349
350 SYMCRYPT_CHECK_MAGIC( piSrc );
351 SYMCRYPT_CHECK_MAGIC( piDst );
352
353 // in-place copy is somewhat common, and addresses are always public, so we can test for a no-op copy.
354 if( piSrc == piDst )
355 {
356 goto cleanup;
357 }
358
359 //
360 // Copy the digits that are available in both
361 //
362 n = SYMCRYPT_MIN( piSrc->nDigits, piDst->nDigits );
364
365 if( piDst->nDigits > n )
366 {
368 }
369
370 if( piSrc->nDigits > n )
371 {
372 // Check that the rest of the source is zero
374 UINT64 v = 0;
375 UINT32 i = (piSrc->nDigits - n) * SYMCRYPT_FDEF_DIGIT_SIZE / sizeof( UINT64 );
376 while( i > 0 )
377 {
378 v |= *p++;
379 i--;
380 }
381
382 //
383 // If the Src doesn't fit, we are allowed to publish that fact, so we can use an IF.
384 //
385 if( v != 0 )
386 {
387 scError = SYMCRYPT_BUFFER_TOO_SMALL;
388 goto cleanup;
389 }
390 }
391
392cleanup:
393 return scError;
394}
395
396
397UINT32
400{
401 UINT32 res;
402 UINT32 mask;
403 UINT32 vUpper;
404 UINT32 vBit1;
405
406 // This is tricky to do side-channel safe using only defined behaviour of the C language.
407
408 // This is very difficult to make any sense of. A comment containing the C code that one would normally
409 // write to do the same thing would be helpful. I will need to come back to this.
410 // Also, there is no test coverage of this function. There should be a unit test to show that it does the same thing
411 // as the code one would normally write.
412
413 vUpper = v & 0xffff0000;
414 mask = (UINT32) ( (0 -(UINT64)(vUpper)) >> 32 ); // mask = 0 or 0xffffffff
415 res = mask & 16; // Why do we want the 9th bit? Also, 0x10 would be better here
416 v = ((v & 0xffff) & ~mask) | ((vUpper >> 16) & mask);
417
418 vUpper = v & 0xff00;
419 mask = (0 - vUpper) >> 16; // mask = 0 or 0xffff
420 res |= mask & 8;
421 v = ((v & 0xff) & ~mask) | ((v >> 8) & mask);
422
423 vUpper = v & 0xf0;
424 mask = (0 - vUpper) >> 16;
425 res |= mask & 4;
426 v = ((v & 0xf) & ~mask) | ((v >> 4) & mask );
427
428 vUpper = v & 0xc;
429 mask = (0 - vUpper) >> 16;
430 res |= mask & 2;
431 v = ((v & 0x3) & ~mask) | ((v >> 2) & mask);
432
433 //
434 // Only 2 bits left.
435 //
436 vBit1 = (v >> 1) & 1;
437 res |= vBit1;
438
439 //
440 // Now we have the bit number of the MSbit set in res.
441 // We need to increase this by one if v was nonzero, so that we
442 // get 0 for v==0, and the # bits needed for v > 0
443 //
444 res += (v | vBit1) & 1;
445
446 return res;
447}
448
449UINT32
452{
453 UINT32 nUint32 = SYMCRYPT_OBJ_NUINT32( piSrc );
454
455 UINT32 res = 0;
456 UINT32 msNonzeroWord = 0; // most significant nonzero digit
457 UINT32 searchingMask = SYMCRYPT_MASK32_SET; // Set if still searching, 0 otherwise
458 UINT32 d;
459 UINT32 dIsNonzeroMask;
460 UINT32 foundMask;
461
462 SYMCRYPT_CHECK_MAGIC( piSrc );
463
464 // This while loop reveals the value of nUint32, is that OK?
465 // If so, document why
466 while( nUint32 > 0 )
467 {
468 //
469 // Invariant:
470 // If no nonzero digit has been found, res = 0 and updateMask = -1.
471 // If a nonzero digit has been found:
472 // msNonzeroDigit = most significant nonzero digit in Src
473 // res = index where most-significant nonzero digit was found
474 // updateMask = 0
475 //
476
477 nUint32--;
478 d = SYMCRYPT_FDEF_INT_PUINT32( piSrc )[nUint32];
479
480 dIsNonzeroMask = SYMCRYPT_MASK32_NONZERO( d );
481 foundMask = dIsNonzeroMask & searchingMask;
482 res |= nUint32 & foundMask;
483 msNonzeroWord |= d & foundMask;
484 searchingMask &= ~foundMask;
485 }
486
487 //
488 // If all words are zero, then res == 0 and msNonzeroDigit == 0.
489 //
490 res = res * 8 * sizeof( UINT32 ) + SymCryptFdefBitsizeOfUint32( msNonzeroWord );
491
492 return res;
493}
494
495VOID
498 UINT32 u32Src,
499 _Out_ PSYMCRYPT_INT piDst )
500{
501 SYMCRYPT_CHECK_MAGIC( piDst );
502
504 SYMCRYPT_FDEF_INT_PUINT32( piDst )[0] = u32Src;
505}
506
507C_ASSERT( SYMCRYPT_FDEF_DIGIT_SIZE >= 8 ); // Code below fails if this doesn't hold
508
509VOID
512 UINT64 u64Src,
513 _Out_ PSYMCRYPT_INT piDst )
514{
515 SYMCRYPT_CHECK_MAGIC( piDst );
516
518 SYMCRYPT_FDEF_INT_PUINT32( piDst )[0] = (UINT32) u64Src;
519 SYMCRYPT_FDEF_INT_PUINT32( piDst )[1] = (UINT32)(u64Src >> 32);
520}
521
526 SIZE_T cbSrc,
529 UINT32 nDigits )
530{
531 SYMCRYPT_ERROR scError;
532 UINT32 b;
533 INT32 step;
534 UINT32 w;
535 UINT32 windex;
536 UINT32 i;
537 UINT32 nWords = nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
538
539 //
540 // This is a very simple and slow generic implementation;
541 // We'll create optimized versions for specific CPU platforms
542 // (e.g. use of memcpy)
543 //
544
545 // I assume the number format is public?
546 switch( format )
547 {
549 step = 1;
550 break;
552 step = -1;
553 pbSrc += cbSrc; // avoid tripping pointer overflow sanitizer with cbSrc == 0
554 pbSrc--;
555 break;
556 default:
557 scError = SYMCRYPT_INVALID_ARGUMENT;
558 goto cleanup;
559 }
560
561 for( windex = 0; windex < nWords; windex++ )
562 {
563 w = 0;
564 for( i=0; i<4; i++ )
565 {
566 // read the next byte into b
567 if( cbSrc > 0 )
568 {
569 b = *pbSrc;
570 cbSrc -= 1;
571 pbSrc += step;
572 w |= b << 8*i;
573 }
574 }
575 pDst[windex] = w;
576 }
577
578 // Inspect any remaining input bytes
579 b = 0;
580 while( cbSrc > 0 )
581 {
582 b |= *pbSrc;
583 pbSrc += step;
584 cbSrc -= 1;
585 }
586
587 if( b > 0 )
588 {
589 scError = SYMCRYPT_BUFFER_TOO_SMALL;
590 goto cleanup;
591 }
592
593 scError = SYMCRYPT_NO_ERROR;
594
595cleanup:
596 return scError;
597}
598
603 SIZE_T cbSrc,
605 _Out_ PSYMCRYPT_INT piDst )
606{
607 SYMCRYPT_ERROR scError;
608
609 SYMCRYPT_CHECK_MAGIC( piDst );
610
611 scError = SymCryptFdefRawSetValue( pbSrc, cbSrc, format, SYMCRYPT_FDEF_INT_PUINT32( piDst ), piDst->nDigits );
612
613 return scError;
614}
615
616
621 UINT32 nDigits,
623 SIZE_T cbDst,
625{
626 SYMCRYPT_ERROR scError;
627 UINT32 b;
628 INT32 step;
629 UINT32 w;
630 UINT32 windex;
631 UINT32 i;
632 UINT32 nWords = nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
633
634 //
635 // This is a very simple and slow generic implementation;
636 // We'll create optimized versions for specific CPU platforms
637 // (e.g. use of memcpy)
638 //
639
640 switch( format )
641 {
643 step = 1;
644 break;
646 step = -1;
647 pbDst += cbDst; // avoid tripping pointer overflow sanitizer with cbSrc == 0
648 pbDst--;
649 break;
650 default:
651 scError = SYMCRYPT_INVALID_ARGUMENT;
652 goto cleanup;
653 }
654
655 for( windex = 0; windex < nWords; windex++ )
656 {
657 w = pSrc[windex];
658 for( i=0; i<4; i++ )
659 {
660 b = w & 0xff;
661 w >>= 8;
662
663 // write the next byte
664 if( cbDst > 0 )
665 {
666 *pbDst = (BYTE)b;
667 cbDst -= 1;
668 pbDst += step;
669 } else {
670 if( b != 0 )
671 {
672 scError = SYMCRYPT_BUFFER_TOO_SMALL;
673 goto cleanup;
674 }
675 }
676 }
677 }
678
679 // Zero any remaining output bytes
680 while( cbDst > 0 )
681 {
682 *pbDst = 0;
683 pbDst += step;
684 cbDst -= 1;
685 }
686
687 scError = SYMCRYPT_NO_ERROR;
688
689cleanup:
690 return scError;
691}
692
696 _In_ PCSYMCRYPT_INT piSrc,
698 SIZE_T cbDst,
700{
701 SYMCRYPT_ERROR scError;
702
703 SYMCRYPT_CHECK_MAGIC( piSrc );
704
705 scError = SymCryptFdefRawGetValue( &SYMCRYPT_FDEF_INT_PUINT32( piSrc )[0], piSrc->nDigits, pbDst, cbDst, format );
706
707 return scError;
708}
709
710
711UINT32
714{
715 // nDigits cannot be zero, so we don't have to test
716 return SYMCRYPT_FDEF_INT_PUINT32( piSrc )[0];
717}
718
719UINT64
722{
723 // nDigits cannot be zero, so we don't have to test
725 return ((UINT64)(p[1]) << 32) | p[0];
726}
727
728UINT32
732 UINT32 nDigits,
733 _In_ UINT32 u32Src2 )
734{
735 UINT32 d;
736 UINT32 nWords = nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
737
738 d = pSrc1[0] ^ u32Src2;
739 for( UINT32 i=1; i<nWords; i++)
740 {
741 d |= pSrc1[i];
742 }
743
744 return SYMCRYPT_MASK32_ZERO( d );
745}
746
747UINT32
750 _In_ PCSYMCRYPT_INT piSrc1,
751 _In_ UINT32 u32Src2 )
752{
753 return SymCryptFdefRawIsEqualUint32( &SYMCRYPT_FDEF_INT_PUINT32( piSrc1 )[0], piSrc1->nDigits, u32Src2 );
754}
755
756UINT32
759 _In_ PCSYMCRYPT_INT piSrc1,
760 _In_ PCSYMCRYPT_INT piSrc2 )
761{
762 UINT32 d;
763 UINT32 n1 = SYMCRYPT_OBJ_NUINT32( piSrc1 );
764 UINT32 n2 = SYMCRYPT_OBJ_NUINT32( piSrc2 );
765 UINT32 i;
766 UINT32 n;
767 PCUINT32 pSrc1 = SYMCRYPT_FDEF_INT_PUINT32( piSrc1 );
768 PCUINT32 pSrc2 = SYMCRYPT_FDEF_INT_PUINT32( piSrc2 );
769
770 n = SYMCRYPT_MIN( n1, n2 );
771 d = 0;
772 for( i=0; i < n ; i++ )
773 {
774 d |= pSrc1[i] ^ pSrc2[i];
775 }
776
777 // i == n1 or i == n2, so at most one of the 2 loops below is ever run
778
779 while( i < n1 )
780 {
781 d |= pSrc1[i];
782 i++;
783 }
784
785 while( i < n2 )
786 {
787 d |= pSrc2[i];
788 i++;
789 }
790
791 return SYMCRYPT_MASK32_ZERO( d );
792}
793
797{
798 PVOID p = NULL;
799 UINT32 cb;
801
802 //
803 // The nDigits requirements are enforced by SymCryptFdefSizeofDivisorFromDigits. Thus
804 // the result does not overflow and is upper bounded by 2^19.
805 //
807
808 if( cb != 0 )
809 {
811 }
812
813 if( p == NULL )
814 {
815 goto cleanup;
816 }
817
818 res = SymCryptFdefDivisorCreate( p, cb, nDigits );
819
820cleanup:
821 return res;
822}
823
824UINT32
827{
828 SYMCRYPT_ASSERT( nDigits != 0 );
830
831 // Ensure we do not overflow the following calculation when provided with invalid inputs
832 if( nDigits == 0 || nDigits > SYMCRYPT_FDEF_UPB_DIGITS )
833 {
834 return 0;
835 }
836
838}
839
845 UINT32 nDigits )
846{
847 PSYMCRYPT_DIVISOR pdDiv = NULL;
849
850 SYMCRYPT_ASSERT( cb >= sizeof(SYMCRYPT_DIVISOR) );
852 if( (cb == 0) || (cbBuffer < cb) )
853 {
854 goto cleanup; // return NULL
855 }
856
858 pdDiv = (PSYMCRYPT_DIVISOR) pbBuffer;
859
860 pdDiv->type = 'gD' << 16;
861 pdDiv->nDigits = nDigits;
862
863 //
864 // The nDigits requirements are enforced by SymCryptFdefSizeofDivisorFromDigits. Thus
865 // the result does not overflow and is upper bounded by 2^19.
866 //
867 pdDiv->cbSize = cb;
868
869 SYMCRYPT_SET_MAGIC( pdDiv );
870
872
873cleanup:
874 return pdDiv;
875}
876
877VOID
881{
882 UNREFERENCED_PARAMETER( pdSrc );
883 UNREFERENCED_PARAMETER( pdDst );
884
885 SymCryptFdefIntCopyFixup( &pdSrc->Int, &pdDst->Int );
886
887 SYMCRYPT_SET_MAGIC( pdDst );
888}
889
890VOID
894{
895 SYMCRYPT_CHECK_MAGIC( pdSrc );
896 SYMCRYPT_CHECK_MAGIC( pdDst );
897
898 SYMCRYPT_ASSERT( pdSrc->nDigits == pdDst->nDigits );
899
900 // in-place copy is somewhat common, and addresses are always public, so we can test for a no-op copy.
901 if( pdSrc != pdDst )
902 {
903 memcpy( pdDst, pdSrc, pdDst->cbSize );
904
905 SymCryptFdefDivisorCopyFixup( pdSrc, pdDst );
906 }
907}
908
909
910VOID
913{
914#if SYMCRYPT_DEBUG
915 SYMCRYPT_ASSERT( cbScratch >= cbMin );
916 SymCryptWipe( pbScratch, cbMin );
917#else
918 UNREFERENCED_PARAMETER( pbScratch );
920 UNREFERENCED_PARAMETER( cbMin );
921#endif
922}
923
924UINT32
927{
928 return pContext->maxTrialPrime;
929}
930
931UINT64
933{
934 // Compute the inv64 value such that inv64 * m = 1 mod 2^64 for odd m.
935 // If m is even, there exists no inverse, this function will return a
936 // useless value in constant time.
937 //
938 // We use Newton's method to search for a zero of f(x) := x^-1 - m, working modulo 2^64
939 // We get the iteration formula
940 // x_{i+1} = x_i - f(x_i)/f'(x_i)
941 // = x_i - (x_i^-1 - m)/(-x_i^-2)
942 // = x_i + x_i^2(1/x_i - m)
943 // = x_i + x_i - (x_i^2 * m)
944 // = x_i (2 - x_i*m)
945 //
946 // Let x_i = d + 2^n * e where d = inv64 = m^-1 mod 2^64, and 2^n * e is the error term that is zero in the n least
947 // significant bits. We have
948 // x_{i+1} = (d + 2^n * e) (2 - (d + 2^n * e) * m)
949 // = (d + 2^n * e) (2 - d*m - 2^n * e * m)
950 // = (d + 2^n * e) (2 - 1 - 2^n * e * m)
951 // = (d + 2^n * e) (1 - 2^n * e * m)
952 // = d - (2^n * e * (d*m)) + (2^n * e) - (2^{2n} * e^2 * m)
953 // = d - (2^{2n} * e^2 * m)
954 // In other words, the error has been squared and multiplied by m. In our case, working modulo 2^64, the number of correct bits
955 // on the least significant side is doubled.
956 //
957 // To get a 4-bit correct estimate for m^-1 given odd m, we consider the least significant 4 bits of m and inv:
958 // m = ... m_3 m_2 m_1 m_0
959 // inv = ... i_3 i_2 i_1 i_0
960 // We want to directly compute i_[3..0] s.t. (m*inv) & 0xf == 1
961 // working through some simple simultaneous equations it is easily shown that:
962 // i_0 = m_0 = 1
963 // i_1 = m_1
964 // i_2 = m_2
965 // i_3 = m_1 ^ m_2 ^ m_3
966 // Once we have 4 correct bits, we can double that multiple times using Newton's method.
967 //
968 // We use 32-bit operations for most of the iterations for speed on 32-bit platforms.
969 //
970 UINT32 inv32;
972 UINT32 m32;
973
974 m32 = (UINT32)m;
975
976 inv32 = m32 ^ (((m32 - 1) * 0x6) & 0x8); // sets inv32 bits [3..0]
977 SYMCRYPT_ASSERT( ((m&1) == 0) || (((inv32 * m32) & 0xf) == 1) );
978
979 inv32 = inv32 * (2 - inv32 * m32 );
980 SYMCRYPT_ASSERT( ((m&1) == 0) || (((inv32 * m32) & 0xff) == 1) );
981
982 inv32 = inv32 * (2 - inv32 * m32 );
983 SYMCRYPT_ASSERT( ((m&1) == 0) || (((inv32 * m32) & 0xffff) == 1) );
984
985 inv32 = inv32 * (2 - inv32 * m32 );
986 SYMCRYPT_ASSERT( ((m&1) == 0) || ((inv32 * m32) == 1) );
987
988 inv64 = inv32;
989 inv64 = inv64 * (2 - inv64 * m );
990 SYMCRYPT_ASSERT( ((m&1) == 0) || ((inv64 * m) == 1) );
991
992 return inv64;
993}
994
995
996VOID
999 UINT32 prime,
1001{
1002 // Compute the inverse of the prime mod 2^64
1003 pPrime->invMod2e64 = SymCryptInverseMod2e64( prime );
1004 pPrime->compareLimit = ((UINT64) -1) / prime;
1005}
1006
1008UINT32
1010{
1011 return (value * pPrime->invMod2e64) <= pPrime->compareLimit;
1012}
1013
1014VOID
1017{
1018 UINT32 f;
1019 UINT32 r;
1020 UINT32 i;
1021
1022 pGroup->nPrimes = nPrimes;
1023
1024 // These % operations are expensive; maybe we can optimize this further.
1025 // In assembler we can do the UINT64 % UINT32 -> UINT32
1026 // hopefully the compiler is smart enough...
1027
1028 f = (UINT32) (((UINT64)1 << 32) % primeProd);
1029 pGroup->factor[0] = f;
1030 r = f;
1031 for( i=1; i<9; i++ )
1032 {
1033 r = (UINT32) (SYMCRYPT_MUL32x32TO64( r, f ) % primeProd);
1034 pGroup->factor[i] = r;
1035 }
1036}
1037
1038UINT32
1041{
1042 // returns a list of small primes, excluding 2, 3, 5, and 17.
1043 UINT32 nPrimes = 0;
1044 PUINT32 pList = NULL;
1045
1046 // pSieve[i] corresponds to 2*i+1
1047 // value X is in location X/2
1048 UINT32 nSieve;
1049 PBYTE pSieve;
1050
1051 UINT32 pi;
1052 UINT32 p;
1053 UINT32 si;
1054 UINT32 i;
1055
1056 maxPrime = SYMCRYPT_MAX( maxPrime, 32 ); // simplify error handling by always producing primes at least up to 32
1057 maxPrime = SYMCRYPT_MIN( maxPrime, 1 << 24 ); // Limit prime list to something sane (sieve = 8 MB, list = 4 MB or so).
1058
1059 // highest index is (maxPrime - 1)/2 which encodes maxPrime if odd, or maxPrime-1 if even
1060 nSieve = (maxPrime - 1) / 2 + 1;
1061
1062 pSieve = SymCryptCallbackAlloc( nSieve );
1063 if( pSieve == NULL )
1064 {
1065 goto cleanup;
1066 }
1067
1068 SymCryptWipe( pSieve, nSieve );
1069
1070
1071 pi = 1; // index of first prime 3
1072 p = 2*pi + 1; // prime value
1073 for(;;)
1074 {
1075 si = 2*(pi*pi + pi); // index of p^2
1076 if( si > nSieve )
1077 {
1078 break; // We're done sieving
1079 }
1080 while( si < nSieve )
1081 {
1082 pSieve[si] = 1;
1083 si += p;
1084 }
1085 // Search for the next prime
1086 do {
1087 pi += 1;
1088 } while( pSieve[pi] != 0 );
1089 p = 2*pi + 1;
1090 }
1091
1092 // Eliminate 3, 5, and 17
1093 pSieve[1] = 1;
1094 pSieve[2] = 1;
1095 pSieve[8] = 1;
1096
1097 for( i=1; i<nSieve; i++ )
1098 {
1099 nPrimes += 1 - pSieve[i];
1100 }
1101
1102 // dcl - I suspect that this is not a problem, but please document
1103 // why this multiplication cannot overflow. I assume there is a practical limit on nPrimes, but unsure
1104 // what that would be.
1105 pList = SymCryptCallbackAlloc( nPrimes * sizeof( UINT32 ) );
1106 if( pList == NULL )
1107 {
1108 goto cleanup;
1109 }
1110
1111 pi = 0;
1112 for( i=1; i<nSieve; i++ )
1113 {
1114 if( pSieve[i] == 0 )
1115 {
1116 pList[pi++] = 2*i+1;
1117 }
1118 }
1119
1121
1122cleanup:
1123 if( pSieve != NULL )
1124 {
1125 SymCryptWipe( pSieve, nSieve );
1126 SymCryptCallbackFree( pSieve );
1127 }
1128
1129 *ppList = pList;
1130 return nPrimes;
1131}
1132
1133
1137{
1139 PBYTE pAlloc;
1140 UINT32 nBytes;
1141 UINT32 iPrime;
1142 UINT32 iGroup;
1144 UINT32 nGroups;
1145 UINT32 M;
1146 UINT32 iGroupSpec;
1147 UINT32 i;
1148 UINT32 j;
1149 UINT64 cRabinMillerCost;
1150 UINT64 cPerPrimeCost;
1151 UINT64 tmp64;
1152 UINT32 maxPrime;
1153 UINT32 minPrime;
1154 UINT32 nSmallPrimes = 0;
1155 UINT32 n;
1156 UINT32 nP;
1157 UINT32 nG;
1158 PUINT32 pSmallPrimeList = NULL;
1159
1160 // First we estimate the largest prime we will do trial division with
1161 // Inputs:
1162 // - cycles/digit of reduction per group of primes
1163 // - cycles/prime of divide test
1164 // - cycles per digit^3 for a Rabin-Miller test
1165 // We optimize in this model, which is pretty accurate for large inputs but underestimates the RM cost
1166 // for smaller sizes.
1167
1168 // Compute the Rabin-Miller cost estimate. We reduce it by 20% because our cost model does not take
1169 // into account some of the trial-division cost such as memory footprint, cache pressure,
1170 // setup cost, etc. Reducing the Rabin-Miller cost leads us to do fewer trial divisions to approximately
1171 // balance the hidden costs.
1172
1173 if( nDigits <= 1000 )
1174 {
1175 // nDigits is small enough to not have any overflows in this computation
1176 if( nDigits == 0 )
1177 {
1178 goto cleanup; // return NULL
1179 }
1180
1181 cRabinMillerCost = (UINT64) nDigits * nDigits * nDigits * (SYMCRYPT_RABINMILLER_DIGIT_CYCLES * 8 / 10);
1182 i = 0;
1183 minPrime = 0;
1184 for(;;)
1185 {
1190
1191 // If the last group isn't worth it, we shouldn't go to even fewer primes
1192 if( nGroups == 0 || maxPrime * cPerPrimeCost >= cRabinMillerCost)
1193 {
1194 break;
1195 }
1196 i++;
1197 minPrime = maxPrime;
1198 }
1199
1200 // Now we know how many primes are in the last groups, let's find out how large the largest prime should be
1201 tmp64 = cRabinMillerCost / cPerPrimeCost;
1203 maxPrime = (UINT32) tmp64;
1204 maxPrime = SYMCRYPT_MAX( maxPrime, minPrime ); // Make sure we don't fall into the previous group size that we don't want
1205 }
1206 else
1207 {
1209 }
1210
1211 nSmallPrimes = SymCryptGenerateSmallPrimes( maxPrime, &pSmallPrimeList );
1212
1213 // Find out how many groups we'll have, and how many actual primes we'll use
1214 n = nSmallPrimes;
1215 nG = 0;
1216 nP = 0;
1217 i = 0;
1218 for(;;)
1219 {
1222
1223 if( n < nPrimes * nGroups || nGroups == 0 )
1224 {
1225 // At the right nPrimes, compute exactly how many groups to add
1226 n = n / nPrimes;
1227 nG += n;
1228 nP += n * nPrimes;
1229 n = 0; // No primes left
1230 break;
1231 }
1232
1233 // Use up all the groups of this size...
1234 nG += nGroups;
1235 nP += nPrimes * nGroups;
1236 n -= nPrimes * nGroups;
1237 i++;
1238 }
1239
1240 // dcl - Potential integer overflow
1241 // Need to document sizes, and limits of nG, nP, and confirm
1242 // an overflow is not possible, also recall that size_t varies in size, but nBytes is 32-bit
1243 nBytes = sizeof( SYMCRYPT_TRIALDIVISION_CONTEXT )
1244 + (nG + 1) * sizeof( SYMCRYPT_TRIALDIVISION_GROUP ) // + 1 for 0 sentinel
1245 + (nP + 1) * sizeof( SYMCRYPT_TRIALDIVISION_PRIME ) // + 1 for 0 sentinel
1246 + (nP + 1) * sizeof( UINT32 ); // + 1 for 0 sentinel
1247
1248 pAlloc = SymCryptCallbackAlloc( nBytes );
1249 if( pAlloc == NULL )
1250 {
1251 goto cleanup;
1252 }
1253
1254 pRes = (PSYMCRYPT_TRIALDIVISION_CONTEXT) pAlloc;
1255 pAlloc += sizeof( *pRes );
1256
1257 pRes->nBytesAlloc = nBytes;
1258
1260 pAlloc += (nG + 1) * sizeof( SYMCRYPT_TRIALDIVISION_GROUP );
1261
1263 pAlloc += (nP + 1) * sizeof( SYMCRYPT_TRIALDIVISION_PRIME );
1264
1265 pRes->pPrimes = (PUINT32) pAlloc;
1266 pAlloc += (nP + 1) * sizeof( UINT32 );
1267
1268 SYMCRYPT_ASSERT( nBytes == (SIZE_T)(pAlloc - (PBYTE)pRes) );
1269
1270 // Initialize the primes 3, 5, and 17
1274
1275 memcpy( pRes->pPrimes, pSmallPrimeList, nP * sizeof( UINT32 ) );
1276 pRes->pPrimes[nP] = 0;
1277 pRes->maxTrialPrime = pRes->pPrimes[nP-1];
1278
1279 /*
1280 *** Old code to decrypt the nibble encoding. Keep in case we want it back later...
1281 // Generate the other primes from the difference table.
1282 // We initialize the prime structures, and a list of the primes that is used to compute the group specs
1283
1284 pNibs = &g_SymCryptSmallPrimeDifferenceNibbles[0];
1285
1286 smallPrime = 3;
1287 nPrimes = 0;
1288 while( smallPrime < SYMCRYPT_MAX_SMALL_PRIME )
1289 {
1290 b = *pNibs++;
1291 nib = b & 0xf;
1292
1293 if( nib == 0 )
1294 {
1295 smallPrime += 30;
1296 // No check for termination here as we wouldn't encode a 0 if there wasn't another prime.
1297 } else {
1298 smallPrime += 2*nib;
1299 pRes->pPrimes[nPrimes] = smallPrime;
1300 SymCryptFdefInitTrialdivisionPrime( smallPrime, &pRes->pPrimeList[nPrimes] );
1301 nPrimes++;
1302 if( smallPrime >= SYMCRYPT_MAX_SMALL_PRIME )
1303 {
1304 break;
1305 }
1306 }
1307 nib = b >> 4;
1308 if( nib == 0 )
1309 {
1310 smallPrime += 30;
1311 } else {
1312 smallPrime += 2*nib;
1313 pRes->pPrimes[nPrimes] = smallPrime;
1314 SymCryptFdefInitTrialdivisionPrime( smallPrime, &pRes->pPrimeList[nPrimes] );
1315 nPrimes++;
1316 }
1317 }
1318 SYMCRYPT_ASSERT( smallPrime == SYMCRYPT_MAX_SMALL_PRIME && nPrimes == SYMCRYPT_N_SMALL_PRIMES_ENCODED );
1319 */
1320
1321 for( iPrime = 0; iPrime < nP; iPrime++ )
1322 {
1323 SymCryptFdefInitTrialdivisionPrime( pRes->pPrimes[iPrime], &pRes->pPrimeList[iPrime] );
1324 }
1325
1326 // Add the trailing 0s
1327 pRes->pPrimeList[nP].invMod2e64 = 0;
1328 pRes->pPrimeList[nP].compareLimit = 0;
1329
1330 // Make sure we have the 32-bit tables, not the 64-bit ones.
1331 // dcl - warning suppression is not portable. Also, if it is a compile time constant, shouldn't it be a compile assert?
1332#pragma warning( suppress: 4127 ) // conditional expression is constant
1334
1335 iGroup = 0;
1336 iPrime = 0;
1337 iGroupSpec = 0;
1339 nGroups = g_SymCryptSmallPrimeGroupsSpec[iGroupSpec].nGroups;
1340 while( iPrime < nP )
1341 {
1342 if( nGroups == 0 )
1343 {
1344 iGroupSpec +=1 ;
1346 nGroups = g_SymCryptSmallPrimeGroupsSpec[iGroupSpec].nGroups;
1347 if( nGroups == 0 )
1348 {
1349 nGroups = nG - iGroup;
1350 }
1351 }
1352
1353 SYMCRYPT_ASSERT( iPrime + nPrimes <= nP );
1354 M = pRes->pPrimes[iPrime++];
1355 for( j=1; j<nPrimes; j++ )
1356 {
1357 SYMCRYPT_ASSERT( M <= SYMCRYPT_MAX_SMALL_PRIME_GROUP_PRODUCT / pRes->pPrimes[iPrime] );
1358 M *= pRes->pPrimes[iPrime++];
1359 }
1361 iGroup++;
1362
1363 nGroups--;
1364 }
1365
1366 SYMCRYPT_ASSERT( iPrime == nP && iGroup == nG );
1367
1368 // Add the trailing sentinel group
1369 pRes->pGroupList[iGroup].nPrimes = 0;
1370
1371cleanup:
1372 if( pSmallPrimeList != NULL )
1373 {
1374 SymCryptWipe( pSmallPrimeList, nSmallPrimes * sizeof( UINT32 ) );
1375 SymCryptCallbackFree( pSmallPrimeList );
1376 pSmallPrimeList = NULL;
1377 }
1378 return pRes;
1379}
1380
1381VOID
1384{
1385 // No security reason to wipe it, but our test code verifies that we wipe everything...
1386 // Perf cost is minor
1387 SymCryptWipe( (PBYTE) pContext, pContext->nBytesAlloc );
1389}
1390
1391UINT32
1395 _In_ PCSYMCRYPT_INT piSrc,
1396 _Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1398{
1399 PCUINT32 pSrc = SYMCRYPT_FDEF_INT_PUINT32( piSrc );
1400 PCUINT32 p;
1401 UINT32 nDigits = piSrc->nDigits;
1402 UINT32 nUint32 = nDigits * SYMCRYPT_FDEF_DIGIT_NUINT32;
1403 UINT64 Acc;
1407 UINT32 res;
1408
1409 // Check for 2. Not really needed for prime generation, but it makes the function easier to test/document/describe.
1410 if( (*pSrc & 1) == 0 )
1411 {
1412 res = 2;
1413 goto cleanup;
1414 }
1415
1416 // Check the factors 3, 5, 17. These are special as they divide 2^32 - 1
1417 // (We could also do 257 and 65537 but that doesn't seem worth the added complexity.)
1418 Acc = 0;
1419 p = pSrc;
1420 do {
1421#if SYMCRYPT_FDEF_DIGIT_SIZE == 16
1422 Acc = Acc + p[0] + p[1] + p[2] + p[3];
1423 p += 4;
1424#elif (SYMCRYPT_FDEF_DIGIT_SIZE % 32) == 0
1425 Acc = Acc + p[0] + p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + p[7];
1426 p += 8;
1427#else
1428 // dcl - ideally, #error would have a descriptive message so it is easily found in code if encountered, same below
1429#error ??
1430#endif
1431 } while( p < pSrc + nUint32 );
1432
1433 if( SymCryptIsMultipleOfSmallPrime( Acc, &pContext->Primes3_5_17[0] ) )
1434 {
1435 res = 3;
1436 goto cleanup;
1437 }
1438
1439 if( SymCryptIsMultipleOfSmallPrime( Acc, &pContext->Primes3_5_17[1] ) )
1440 {
1441 res = 5;
1442 goto cleanup;
1443 }
1444
1445 if( SymCryptIsMultipleOfSmallPrime( Acc, &pContext->Primes3_5_17[2] ) )
1446 {
1447 res = 17;
1448 goto cleanup;
1449 }
1450
1451 pGroup = pContext->pGroupList;
1452 pPrime = pContext->pPrimeList;
1453 while( (nPrimes = pGroup->nPrimes) != 0 )
1454 {
1455 // Reduce Src modulo the group product to a 64-bit value
1456 Acc = 0;
1457 p = pSrc + nUint32;
1458
1459#if SYMCRYPT_FDEF_DIGIT_SIZE == 16
1460 if( (nUint32 & 4) != 0 )
1461 {
1462 // nUInt32 is 4 mod 8, process the top 4 words only
1463 p -= 4;
1464 Acc =
1465 p[0] +
1466 SYMCRYPT_MUL32x32TO64( p[1], pGroup->factor[0] ) +
1467 SYMCRYPT_MUL32x32TO64( p[2], pGroup->factor[1] ) +
1468 SYMCRYPT_MUL32x32TO64( p[3], pGroup->factor[2] );
1469 } else {
1470 // Process 8 words to start
1471 p -= 8;
1472 Acc =
1473 p[0] +
1474 SYMCRYPT_MUL32x32TO64( p[1], pGroup->factor[0] ) +
1475 SYMCRYPT_MUL32x32TO64( p[2], pGroup->factor[1] ) +
1476 SYMCRYPT_MUL32x32TO64( p[3], pGroup->factor[2] ) +
1477 SYMCRYPT_MUL32x32TO64( p[4], pGroup->factor[3] ) +
1478 SYMCRYPT_MUL32x32TO64( p[5], pGroup->factor[4] ) +
1479 SYMCRYPT_MUL32x32TO64( p[6], pGroup->factor[5] ) +
1480 SYMCRYPT_MUL32x32TO64( p[7], pGroup->factor[6] );
1481 }
1482#elif (SYMCRYPT_FDEF_DIGIT_SIZE % 32) == 0
1483
1484 p -= 8;
1485 Acc =
1486 p[0] +
1487 SYMCRYPT_MUL32x32TO64( p[1], pGroup->factor[0] ) +
1488 SYMCRYPT_MUL32x32TO64( p[2], pGroup->factor[1] ) +
1489 SYMCRYPT_MUL32x32TO64( p[3], pGroup->factor[2] ) +
1490 SYMCRYPT_MUL32x32TO64( p[4], pGroup->factor[3] ) +
1491 SYMCRYPT_MUL32x32TO64( p[5], pGroup->factor[4] ) +
1492 SYMCRYPT_MUL32x32TO64( p[6], pGroup->factor[5] ) +
1493 SYMCRYPT_MUL32x32TO64( p[7], pGroup->factor[6] );
1494
1495#else
1496#error ??
1497#endif
1498 while( p > pSrc )
1499 {
1500 p -= 8;
1501 Acc =
1502 p[0] +
1503 SYMCRYPT_MUL32x32TO64( p[1], pGroup->factor[0] ) +
1504 SYMCRYPT_MUL32x32TO64( p[2], pGroup->factor[1] ) +
1505 SYMCRYPT_MUL32x32TO64( p[3], pGroup->factor[2] ) +
1506 SYMCRYPT_MUL32x32TO64( p[4], pGroup->factor[3] ) +
1507 SYMCRYPT_MUL32x32TO64( p[5], pGroup->factor[4] ) +
1508 SYMCRYPT_MUL32x32TO64( p[6], pGroup->factor[5] ) +
1509 SYMCRYPT_MUL32x32TO64( p[7], pGroup->factor[6] ) +
1510 SYMCRYPT_MUL32x32TO64( (UINT32) Acc , pGroup->factor[7] ) +
1511 SYMCRYPT_MUL32x32TO64( (UINT32)(Acc >> 32), pGroup->factor[8] );
1512 }
1513
1514 // Now we check whether we have a multiple of one of the primes
1515 while( nPrimes > 0 )
1516 {
1517 if( SymCryptIsMultipleOfSmallPrime( Acc, pPrime ) )
1518 {
1519 res = pContext->pPrimes[ (pPrime - pContext->pPrimeList) ]; // pointer subtraction auto-divides by size...
1520 goto cleanup;
1521 }
1522 pPrime++;
1523 nPrimes--;
1524 }
1525
1526 pGroup++;
1527 }
1528
1529 UNREFERENCED_PARAMETER( pbScratch );
1531
1532 // Did not find a small factor, return zero
1533 res = 0;
1534
1535cleanup:
1536 return res;
1537}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
unsigned int * PUINT32
Definition: basetsd.h:119
unsigned __int64 * PUINT64
Definition: basetsd.h:181
int Int
Definition: definitions.h:37
#define NULL
Definition: types.h:112
#define m32
#define M(row, col)
static void cleanup(void)
Definition: main.c:1335
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
#define UINT32_MAX
Definition: stdint.h:85
#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES
Definition: fdef_general.c:29
UINT32 SYMCRYPT_CALL SymCryptFdefIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: fdef_general.c:713
VOID SymCryptFdefIntMaskedCopy(_In_ PCSYMCRYPT_INT piSrc, _Inout_ PSYMCRYPT_INT piDst, UINT32 mask)
Definition: fdef_general.c:280
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsEqualUint32(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits, _In_ UINT32 u32Src2)
Definition: fdef_general.c:730
VOID SYMCRYPT_CALL SymCryptFdefConditionalSwapC(_Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbSrc1, _Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbSrc2, UINT32 nDigits, UINT32 cond)
Definition: fdef_general.c:91
VOID SYMCRYPT_CALL SymCryptFdefMaskedCopyC(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCBYTE pbSrc, _Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbDst, UINT32 nDigits, UINT32 mask)
Definition: fdef_general.c:40
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: fdef_general.c:842
VOID SYMCRYPT_CALL SymCryptFdefIntConditionalSwap(_Inout_ PSYMCRYPT_INT piSrc1, _Inout_ PSYMCRYPT_INT piSrc2, UINT32 cond)
Definition: fdef_general.c:313
VOID SYMCRYPT_CALL SymCryptFdefFreeTrialDivisionContext(PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext)
VOID SYMCRYPT_CALL SymCryptFdefMaskedCopy(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCBYTE pbSrc, _Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbDst, UINT32 nDigits, UINT32 mask)
Definition: fdef_general.c:74
UINT32 SYMCRYPT_CALL SymCryptFdefIntFindSmallDivisor(_In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext, _In_ PCSYMCRYPT_INT piSrc, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
UINT32 SYMCRYPT_CALL SymCryptGenerateSmallPrimes(UINT32 maxPrime, PUINT32 *ppList)
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefRawSetValue(_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT format, _Out_writes_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PUINT32 pDst, UINT32 nDigits)
Definition: fdef_general.c:524
UINT32 SYMCRYPT_CALL SymCryptFdefIntBitsizeOfValue(_In_ PCSYMCRYPT_INT piSrc)
Definition: fdef_general.c:451
VOID SymCryptFdefDivisorCopy(_In_ PCSYMCRYPT_DIVISOR pdSrc, _Out_ PSYMCRYPT_DIVISOR pdDst)
Definition: fdef_general.c:891
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntAllocate(UINT32 nDigits)
Definition: fdef_general.c:165
UINT32 SymCryptFdefDigitsFromBits(UINT32 nBits)
Definition: fdef_general.c:133
UINT32 SYMCRYPT_CALL SymCryptFdefIntIsEqualUint32(_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
Definition: fdef_general.c:749
PCSYMCRYPT_TRIALDIVISION_CONTEXT SYMCRYPT_CALL SymCryptFdefCreateTrialDivisionContext(UINT32 nDigits)
VOID SYMCRYPT_CALL SymCryptFdefConditionalSwap(_Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbSrc1, _Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbSrc2, UINT32 nDigits, UINT32 cond)
Definition: fdef_general.c:122
VOID SymCryptFdefDivisorCopyFixup(_In_ PCSYMCRYPT_DIVISOR pdSrc, _Out_ PSYMCRYPT_DIVISOR pdDst)
Definition: fdef_general.c:878
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefIntSetValue(_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT format, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_general.c:601
UINT32 SYMCRYPT_CALL SymCryptFdefIntBitsizeOfObject(_In_ PCSYMCRYPT_INT piSrc)
Definition: fdef_general.c:328
UINT32 SYMCRYPT_CALL SymCryptFdefIntIsEqual(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: fdef_general.c:758
VOID SYMCRYPT_CALL SymCryptFdefInitTrialdivisionPrime(UINT32 prime, _Out_ PSYMCRYPT_TRIALDIVISION_PRIME pPrime)
Definition: fdef_general.c:998
UINT32 SYMCRYPT_CALL SymCryptFdefSizeofDivisorFromDigits(UINT32 nDigits)
Definition: fdef_general.c:826
VOID SymCryptFdefIntCopyFixup(_In_ PCSYMCRYPT_INT pSrc, _Out_ PSYMCRYPT_INT pDst)
Definition: fdef_general.c:248
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefIntGetValue(_In_ PCSYMCRYPT_INT piSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format)
Definition: fdef_general.c:695
#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES
Definition: fdef_general.c:27
UINT32 SYMCRYPT_CALL SymCryptFdefNumberofDigitsFromInt(_In_ PCSYMCRYPT_INT piSrc)
Definition: fdef_general.c:337
UINT32 SYMCRYPT_CALL SymCryptFdefBitsizeOfUint32(UINT32 v)
Definition: fdef_general.c:399
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: fdef_general.c:213
UINT64 SymCryptInverseMod2e64(UINT64 m)
Definition: fdef_general.c:932
VOID SYMCRYPT_CALL SymCryptFdefIntConditionalCopy(_In_ PCSYMCRYPT_INT piSrc, _Inout_ PSYMCRYPT_INT piDst, UINT32 cond)
Definition: fdef_general.c:298
C_ASSERT(SYMCRYPT_INT_MAX_BITS<(1<< 30))
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorAllocate(UINT32 nDigits)
Definition: fdef_general.c:796
SYMCRYPT_ERROR SymCryptFdefIntCopyMixedSize(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_general.c:343
VOID SYMCRYPT_CALL SymCryptFdefClaimScratch(PBYTE pbScratch, SIZE_T cbScratch, SIZE_T cbMin)
Definition: fdef_general.c:912
UINT32 SYMCRYPT_CALL SymCryptFdefSizeofIntFromDigits(UINT32 nDigits)
Definition: fdef_general.c:196
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefRawGetValue(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc, UINT32 nDigits, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format)
Definition: fdef_general.c:619
VOID SYMCRYPT_CALL SymCryptFdefIntSetValueUint32(UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_general.c:497
VOID SymCryptFdefIntCopy(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_general.c:259
UINT32 SymCryptTestTrialdivisionMaxSmallPrime(_In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext)
Definition: fdef_general.c:925
VOID SYMCRYPT_CALL SymCryptFdefIntSetValueUint64(UINT64 u64Src, _Out_ PSYMCRYPT_INT piDst)
Definition: fdef_general.c:511
#define SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES
Definition: fdef_general.c:28
VOID SYMCRYPT_CALL SymCryptFdefInitTrialDivisionGroup(PSYMCRYPT_TRIALDIVISION_GROUP pGroup, UINT32 nPrimes, UINT32 primeProd)
#define SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME
Definition: fdef_general.c:34
FORCEINLINE UINT32 SymCryptIsMultipleOfSmallPrime(UINT64 value, PCSYMCRYPT_TRIALDIVISION_PRIME pPrime)
UINT64 SYMCRYPT_CALL SymCryptFdefIntGetValueLsbits64(_In_ PCSYMCRYPT_INT piSrc)
Definition: fdef_general.c:721
FxChildList * pList
const GLdouble * v
Definition: gl.h:2040
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLenum GLint GLuint mask
Definition: glext.h:6028
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
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
void SYMCRYPT_CALL SymCryptCallbackFree(void *ptr)
Definition: implglue.c:42
void *SYMCRYPT_CALL SymCryptCallbackAlloc(SIZE_T size)
Definition: implglue.c:37
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
#define b
Definition: ke_i.h:79
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Inout_updates_bytes_(s)
Definition: no_sal2.h:184
#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
int n2
Definition: dwarfget.c:147
int n1
Definition: dwarfget.c:147
#define SYMCRYPT_ASSERT_ASYM_ALIGNED(_p)
Definition: sc_lib.h:1912
#define SYMCRYPT_OBJ_NUINT32(_p)
Definition: sc_lib.h:1920
#define SYMCRYPT_OBJ_NBYTES(_p)
Definition: sc_lib.h:1919
VOID SYMCRYPT_CALL SymCryptFdefMaskedCopyAsm(_In_reads_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PCBYTE pbSrc, _Inout_updates_bytes_(nDigits *SYMCRYPT_FDEF_DIGIT_SIZE) PBYTE pbDst, UINT32 nDigits, UINT32 mask)
#define SYMCRYPT_FDEF_DIGIT_NUINT32
Definition: sc_lib.h:1916
UINT32 UINT32 UINT32 UINT32 cbScratch
SIZE_T cbBuffer
Definition: sc_lib_mldsa.h:405
const SYMCRYPT_SMALL_PRIME_GROUPS_SPEC g_SymCryptSmallPrimeGroupsSpec[]
Definition: smallPrimes32.h:22
#define SYMCRYPT_MAX_SMALL_PRIME_GROUP_PRODUCT
Definition: smallPrimes32.h:20
SYMCRYPT_TRIALDIVISION_PRIME Primes3_5_17[3]
PSYMCRYPT_TRIALDIVISION_PRIME pPrimeList
PSYMCRYPT_TRIALDIVISION_GROUP pGroupList
#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
enum _SYMCRYPT_NUMBER_FORMAT SYMCRYPT_NUMBER_FORMAT
@ SYMCRYPT_NUMBER_FORMAT_MSB_FIRST
Definition: symcrypt.h:7017
@ SYMCRYPT_NUMBER_FORMAT_LSB_FIRST
Definition: symcrypt.h:7016
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_MASK32_NONZERO(_v)
PCBYTE pbSrc
#define SYMCRYPT_CALL
struct _SYMCRYPT_TRIALDIVISION_PRIME SYMCRYPT_TRIALDIVISION_PRIME
#define SYMCRYPT_FDEF_DIGIT_SIZE
struct _SYMCRYPT_TRIALDIVISION_CONTEXT SYMCRYPT_TRIALDIVISION_CONTEXT
UINT64 inv64
#define SYMCRYPT_FDEF_UPB_DIGITS
#define SYMCRYPT_FDEF_DIGIT_BITS
struct _SYMCRYPT_TRIALDIVISION_GROUP * PSYMCRYPT_TRIALDIVISION_GROUP
const SYMCRYPT_DIVISOR * PCSYMCRYPT_DIVISOR
struct _SYMCRYPT_TRIALDIVISION_PRIME * PSYMCRYPT_TRIALDIVISION_PRIME
struct _SYMCRYPT_INT SYMCRYPT_INT
#define SYMCRYPT_MIN(_a, _b)
#define SYMCRYPT_MAX(_a, _b)
UINT32 nPrimes
struct _SYMCRYPT_TRIALDIVISION_GROUP SYMCRYPT_TRIALDIVISION_GROUP
#define SYMCRYPT_SET_MAGIC(p)
#define SYMCRYPT_INT_MAX_BITS
PCBYTE PBYTE pbDst
#define SYMCRYPT_FIELD_OFFSET(type, field)
const SYMCRYPT_INT * PCSYMCRYPT_INT
struct _SYMCRYPT_TRIALDIVISION_CONTEXT * PSYMCRYPT_TRIALDIVISION_CONTEXT
SYMCRYPT_MAGIC_FIELD SYMCRYPT_ASYM_ALIGN union @5237 ti
struct _SYMCRYPT_DIVISOR SYMCRYPT_DIVISOR
#define SYMCRYPT_FDEF_DIGITS_FROM_BITS(_bits)
const BYTE * PCBYTE
SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR
#define SYMCRYPT_MASK32_ZERO(_v)
#define SYMCRYPT_FDEF_INT_PUINT32(p)
const UINT32 * PCUINT32
#define SYMCRYPT_MASK32_SET
SYMCRYPT_INT * PSYMCRYPT_INT
#define SYMCRYPT_CHECK_MAGIC(p)
UINT32 SYMCRYPT_CALL SymCryptSizeofDivisorFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:512
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:141
int32_t INT32
Definition: typedefs.h:58
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
Definition: pdh_main.c:64
#define FORCEINLINE
Definition: wdftypes.h:67
unsigned char BYTE
Definition: xxhash.c:193