ReactOS 0.4.17-dev-1005-g171e1de
fdef_general.c File Reference
#include "precomp.h"
#include "smallPrimes32.h"
Include dependency graph for fdef_general.c:

Go to the source code of this file.

Macros

#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES   (18)
 
#define SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES   (16)
 
#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES   (25300)
 
#define SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME   (1<<22)
 

Functions

 C_ASSERT (SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME<=UINT32_MAX)
 
 C_ASSERT (SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME==((UINT32) SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME))
 
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)
 
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)
 
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)
 
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)
 
UINT32 SymCryptFdefDigitsFromBits (UINT32 nBits)
 
 C_ASSERT (SYMCRYPT_INT_MAX_BITS<(1<< 30))
 
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntAllocate (UINT32 nDigits)
 
UINT32 SYMCRYPT_CALL SymCryptFdefSizeofIntFromDigits (UINT32 nDigits)
 
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntCreate (_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
 
VOID SymCryptFdefIntCopyFixup (_In_ PCSYMCRYPT_INT pSrc, _Out_ PSYMCRYPT_INT pDst)
 
VOID SymCryptFdefIntCopy (_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
 
VOID SymCryptFdefIntMaskedCopy (_In_ PCSYMCRYPT_INT piSrc, _Inout_ PSYMCRYPT_INT piDst, UINT32 mask)
 
VOID SYMCRYPT_CALL SymCryptFdefIntConditionalCopy (_In_ PCSYMCRYPT_INT piSrc, _Inout_ PSYMCRYPT_INT piDst, UINT32 cond)
 
VOID SYMCRYPT_CALL SymCryptFdefIntConditionalSwap (_Inout_ PSYMCRYPT_INT piSrc1, _Inout_ PSYMCRYPT_INT piSrc2, UINT32 cond)
 
UINT32 SYMCRYPT_CALL SymCryptFdefIntBitsizeOfObject (_In_ PCSYMCRYPT_INT piSrc)
 
UINT32 SYMCRYPT_CALL SymCryptFdefNumberofDigitsFromInt (_In_ PCSYMCRYPT_INT piSrc)
 
SYMCRYPT_ERROR SymCryptFdefIntCopyMixedSize (_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
 
UINT32 SYMCRYPT_CALL SymCryptFdefBitsizeOfUint32 (UINT32 v)
 
UINT32 SYMCRYPT_CALL SymCryptFdefIntBitsizeOfValue (_In_ PCSYMCRYPT_INT piSrc)
 
VOID SYMCRYPT_CALL SymCryptFdefIntSetValueUint32 (UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
 
 C_ASSERT (SYMCRYPT_FDEF_DIGIT_SIZE >=8)
 
VOID SYMCRYPT_CALL SymCryptFdefIntSetValueUint64 (UINT64 u64Src, _Out_ PSYMCRYPT_INT piDst)
 
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)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefIntSetValue (_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT format, _Out_ PSYMCRYPT_INT piDst)
 
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)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefIntGetValue (_In_ PCSYMCRYPT_INT piSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format)
 
UINT32 SYMCRYPT_CALL SymCryptFdefIntGetValueLsbits32 (_In_ PCSYMCRYPT_INT piSrc)
 
UINT64 SYMCRYPT_CALL SymCryptFdefIntGetValueLsbits64 (_In_ PCSYMCRYPT_INT piSrc)
 
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsEqualUint32 (_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits, _In_ UINT32 u32Src2)
 
UINT32 SYMCRYPT_CALL SymCryptFdefIntIsEqualUint32 (_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
 
UINT32 SYMCRYPT_CALL SymCryptFdefIntIsEqual (_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
 
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorAllocate (UINT32 nDigits)
 
UINT32 SYMCRYPT_CALL SymCryptFdefSizeofDivisorFromDigits (UINT32 nDigits)
 
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorCreate (_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
 
VOID SymCryptFdefDivisorCopyFixup (_In_ PCSYMCRYPT_DIVISOR pdSrc, _Out_ PSYMCRYPT_DIVISOR pdDst)
 
VOID SymCryptFdefDivisorCopy (_In_ PCSYMCRYPT_DIVISOR pdSrc, _Out_ PSYMCRYPT_DIVISOR pdDst)
 
VOID SYMCRYPT_CALL SymCryptFdefClaimScratch (PBYTE pbScratch, SIZE_T cbScratch, SIZE_T cbMin)
 
UINT32 SymCryptTestTrialdivisionMaxSmallPrime (_In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext)
 
UINT64 SymCryptInverseMod2e64 (UINT64 m)
 
VOID SYMCRYPT_CALL SymCryptFdefInitTrialdivisionPrime (UINT32 prime, _Out_ PSYMCRYPT_TRIALDIVISION_PRIME pPrime)
 
FORCEINLINE UINT32 SymCryptIsMultipleOfSmallPrime (UINT64 value, PCSYMCRYPT_TRIALDIVISION_PRIME pPrime)
 
VOID SYMCRYPT_CALL SymCryptFdefInitTrialDivisionGroup (PSYMCRYPT_TRIALDIVISION_GROUP pGroup, UINT32 nPrimes, UINT32 primeProd)
 
UINT32 SYMCRYPT_CALL SymCryptGenerateSmallPrimes (UINT32 maxPrime, PUINT32 *ppList)
 
PCSYMCRYPT_TRIALDIVISION_CONTEXT SYMCRYPT_CALL SymCryptFdefCreateTrialDivisionContext (UINT32 nDigits)
 
VOID SYMCRYPT_CALL SymCryptFdefFreeTrialDivisionContext (PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext)
 
UINT32 SYMCRYPT_CALL SymCryptFdefIntFindSmallDivisor (_In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext, _In_ PCSYMCRYPT_INT piSrc, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 

Macro Definition Documentation

◆ SYMCRYPT_RABINMILLER_DIGIT_CYCLES

#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES   (25300)

Definition at line 29 of file fdef_general.c.

◆ SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES

#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES   (18)

Definition at line 27 of file fdef_general.c.

◆ SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES

#define SYMCRYPT_TRIALDIVISION_DIVIDE_TEST_CYCLES   (16)

Definition at line 28 of file fdef_general.c.

◆ SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME

#define SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME   (1<<22)

Definition at line 34 of file fdef_general.c.

Function Documentation

◆ C_ASSERT() [1/4]

C_ASSERT ( SYMCRYPT_FDEF_DIGIT_SIZE >=  8)

◆ C_ASSERT() [2/4]

C_ASSERT ( )

◆ C_ASSERT() [3/4]

C_ASSERT ( SYMCRYPT_TRIALDIVISION_MAX_SMALL_PRIME<=  UINT32_MAX)

◆ C_ASSERT() [4/4]

◆ SymCryptFdefBitsizeOfUint32()

UINT32 SYMCRYPT_CALL SymCryptFdefBitsizeOfUint32 ( UINT32  v)

Definition at line 399 of file fdef_general.c.

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}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
const GLdouble * v
Definition: gl.h:2040
GLuint res
Definition: glext.h:9613
GLenum GLint GLuint mask
Definition: glext.h:6028
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptFdefIntBitsizeOfValue().

◆ SymCryptFdefClaimScratch()

VOID SYMCRYPT_CALL SymCryptFdefClaimScratch ( PBYTE  pbScratch,
SIZE_T  cbScratch,
SIZE_T  cbMin 
)

◆ SymCryptFdefConditionalSwap()

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 at line 122 of file fdef_general.c.

127{
128 SymCryptFdefConditionalSwapC( pbSrc1, pbSrc2, nDigits, cond );
129}
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

Referenced by SymCryptFdefIntConditionalSwap(), and SymCryptFdefModElementConditionalSwap().

◆ SymCryptFdefConditionalSwapC()

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 at line 91 of file fdef_general.c.

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}
unsigned __int64 * PUINT64
Definition: basetsd.h:181
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
#define SYMCRYPT_FDEF_DIGIT_SIZE
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by SymCryptFdefConditionalSwap().

◆ SymCryptFdefCreateTrialDivisionContext()

PCSYMCRYPT_TRIALDIVISION_CONTEXT SYMCRYPT_CALL SymCryptFdefCreateTrialDivisionContext ( UINT32  nDigits)

Definition at line 1136 of file fdef_general.c.

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}
unsigned int * PUINT32
Definition: basetsd.h:119
#define NULL
Definition: types.h:112
#define M(row, col)
static void cleanup(void)
Definition: main.c:1335
#define SYMCRYPT_RABINMILLER_DIGIT_CYCLES
Definition: fdef_general.c:29
UINT32 SYMCRYPT_CALL SymCryptGenerateSmallPrimes(UINT32 maxPrime, PUINT32 *ppList)
VOID SYMCRYPT_CALL SymCryptFdefInitTrialdivisionPrime(UINT32 prime, _Out_ PSYMCRYPT_TRIALDIVISION_PRIME pPrime)
Definition: fdef_general.c:998
#define SYMCRYPT_TRIALDIVISION_DIGIT_REDUCTION_CYCLES
Definition: fdef_general.c:27
#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
GLdouble n
Definition: glext.h:7729
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 memcpy(s1, s2, n)
Definition: mkisofs.h:878
BYTE * PBYTE
Definition: pedump.c:66
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
struct _SYMCRYPT_TRIALDIVISION_PRIME SYMCRYPT_TRIALDIVISION_PRIME
struct _SYMCRYPT_TRIALDIVISION_CONTEXT SYMCRYPT_TRIALDIVISION_CONTEXT
struct _SYMCRYPT_TRIALDIVISION_GROUP * PSYMCRYPT_TRIALDIVISION_GROUP
struct _SYMCRYPT_TRIALDIVISION_PRIME * PSYMCRYPT_TRIALDIVISION_PRIME
#define SYMCRYPT_MIN(_a, _b)
#define SYMCRYPT_MAX(_a, _b)
UINT32 nPrimes
struct _SYMCRYPT_TRIALDIVISION_GROUP SYMCRYPT_TRIALDIVISION_GROUP
struct _SYMCRYPT_TRIALDIVISION_CONTEXT * PSYMCRYPT_TRIALDIVISION_CONTEXT

Referenced by SymCryptCreateTrialDivisionContext().

◆ SymCryptFdefDigitsFromBits()

UINT32 SymCryptFdefDigitsFromBits ( UINT32  nBits)

Definition at line 133 of file fdef_general.c.

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}
int nBits
Definition: pcmconverter.c:96
#define SYMCRYPT_INT_MAX_BITS
#define SYMCRYPT_FDEF_DIGITS_FROM_BITS(_bits)

Referenced by SymCryptDigitsFromBits().

◆ SymCryptFdefDivisorAllocate()

PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorAllocate ( UINT32  nDigits)

Definition at line 796 of file fdef_general.c.

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}
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: fdef_general.c:842
UINT32 SYMCRYPT_CALL SymCryptFdefSizeofDivisorFromDigits(UINT32 nDigits)
Definition: fdef_general.c:826
GLfloat GLfloat p
Definition: glext.h:8902
SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR

Referenced by SymCryptDivisorAllocate().

◆ SymCryptFdefDivisorCopy()

VOID SymCryptFdefDivisorCopy ( _In_ PCSYMCRYPT_DIVISOR  pdSrc,
_Out_ PSYMCRYPT_DIVISOR  pdDst 
)

Definition at line 891 of file fdef_general.c.

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}
VOID SymCryptFdefDivisorCopyFixup(_In_ PCSYMCRYPT_DIVISOR pdSrc, _Out_ PSYMCRYPT_DIVISOR pdDst)
Definition: fdef_general.c:878
#define SYMCRYPT_CHECK_MAGIC(p)

Referenced by SymCryptDivisorCopy().

◆ SymCryptFdefDivisorCopyFixup()

VOID SymCryptFdefDivisorCopyFixup ( _In_ PCSYMCRYPT_DIVISOR  pdSrc,
_Out_ PSYMCRYPT_DIVISOR  pdDst 
)

Definition at line 878 of file fdef_general.c.

881{
882 UNREFERENCED_PARAMETER( pdSrc );
883 UNREFERENCED_PARAMETER( pdDst );
884
885 SymCryptFdefIntCopyFixup( &pdSrc->Int, &pdDst->Int );
886
887 SYMCRYPT_SET_MAGIC( pdDst );
888}
VOID SymCryptFdefIntCopyFixup(_In_ PCSYMCRYPT_INT pSrc, _Out_ PSYMCRYPT_INT pDst)
Definition: fdef_general.c:248
#define SYMCRYPT_SET_MAGIC(p)

Referenced by SymCryptFdefDivisorCopy(), and SymCryptFdefModulusCopy().

◆ SymCryptFdefDivisorCreate()

PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptFdefDivisorCreate ( _Out_writes_bytes_(cbBuffer) PBYTE  pbBuffer,
SIZE_T  cbBuffer,
UINT32  nDigits 
)

Definition at line 842 of file fdef_general.c.

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}
int Int
Definition: definitions.h:37
#define SYMCRYPT_ASSERT_ASYM_ALIGNED(_p)
Definition: sc_lib.h:1912
SIZE_T cbBuffer
Definition: sc_lib_mldsa.h:405
#define SYMCRYPT_FIELD_OFFSET(type, field)
struct _SYMCRYPT_DIVISOR SYMCRYPT_DIVISOR
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

Referenced by SymCryptDivisorCreate(), SymCryptFdefDivisorAllocate(), and SymCryptFdefModulusCreate().

◆ SymCryptFdefFreeTrialDivisionContext()

VOID SYMCRYPT_CALL SymCryptFdefFreeTrialDivisionContext ( PCSYMCRYPT_TRIALDIVISION_CONTEXT  pContext)

Definition at line 1383 of file fdef_general.c.

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}

Referenced by SymCryptFreeTrialDivisionContext().

◆ SymCryptFdefInitTrialDivisionGroup()

VOID SYMCRYPT_CALL SymCryptFdefInitTrialDivisionGroup ( PSYMCRYPT_TRIALDIVISION_GROUP  pGroup,
UINT32  nPrimes,
UINT32  primeProd 
)

Definition at line 1016 of file fdef_general.c.

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}
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLfloat f
Definition: glext.h:7540
#define f
Definition: ke_i.h:83

Referenced by SymCryptFdefCreateTrialDivisionContext().

◆ SymCryptFdefInitTrialdivisionPrime()

VOID SYMCRYPT_CALL SymCryptFdefInitTrialdivisionPrime ( UINT32  prime,
_Out_ PSYMCRYPT_TRIALDIVISION_PRIME  pPrime 
)

Definition at line 998 of file fdef_general.c.

1001{
1002 // Compute the inverse of the prime mod 2^64
1003 pPrime->invMod2e64 = SymCryptInverseMod2e64( prime );
1004 pPrime->compareLimit = ((UINT64) -1) / prime;
1005}
UINT64 SymCryptInverseMod2e64(UINT64 m)
Definition: fdef_general.c:932

Referenced by SymCryptFdefCreateTrialDivisionContext().

◆ SymCryptFdefIntAllocate()

PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntAllocate ( UINT32  nDigits)

Definition at line 165 of file fdef_general.c.

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}
UINT32 SYMCRYPT_CALL SymCryptFdefSizeofIntFromDigits(UINT32 nDigits)
Definition: fdef_general.c:196
SYMCRYPT_INT * PSYMCRYPT_INT

Referenced by SymCryptIntAllocate().

◆ SymCryptFdefIntBitsizeOfObject()

UINT32 SYMCRYPT_CALL SymCryptFdefIntBitsizeOfObject ( _In_ PCSYMCRYPT_INT  piSrc)

Definition at line 328 of file fdef_general.c.

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}
#define SYMCRYPT_FDEF_DIGIT_BITS

Referenced by SymCryptIntBitsizeOfObject().

◆ SymCryptFdefIntBitsizeOfValue()

UINT32 SYMCRYPT_CALL SymCryptFdefIntBitsizeOfValue ( _In_ PCSYMCRYPT_INT  piSrc)

Definition at line 451 of file fdef_general.c.

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}
UINT32 SYMCRYPT_CALL SymCryptFdefBitsizeOfUint32(UINT32 v)
Definition: fdef_general.c:399
#define d
Definition: ke_i.h:81
#define SYMCRYPT_OBJ_NUINT32(_p)
Definition: sc_lib.h:1920
#define SYMCRYPT_MASK32_NONZERO(_v)
#define SYMCRYPT_FDEF_INT_PUINT32(p)
#define SYMCRYPT_MASK32_SET

Referenced by SymCryptIntBitsizeOfValue().

◆ SymCryptFdefIntConditionalCopy()

VOID SYMCRYPT_CALL SymCryptFdefIntConditionalCopy ( _In_ PCSYMCRYPT_INT  piSrc,
_Inout_ PSYMCRYPT_INT  piDst,
UINT32  cond 
)

Definition at line 298 of file fdef_general.c.

302{
303 SYMCRYPT_CHECK_MAGIC( piSrc );
304 SYMCRYPT_CHECK_MAGIC( piDst );
305
306 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
307
309}
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

Referenced by SymCryptIntConditionalCopy().

◆ SymCryptFdefIntConditionalSwap()

VOID SYMCRYPT_CALL SymCryptFdefIntConditionalSwap ( _Inout_ PSYMCRYPT_INT  piSrc1,
_Inout_ PSYMCRYPT_INT  piSrc2,
UINT32  cond 
)

Definition at line 313 of file fdef_general.c.

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}
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

Referenced by SymCryptIntConditionalSwap().

◆ SymCryptFdefIntCopy()

VOID SymCryptFdefIntCopy ( _In_ PCSYMCRYPT_INT  piSrc,
_Out_ PSYMCRYPT_INT  piDst 
)

Definition at line 259 of file fdef_general.c.

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}
#define SYMCRYPT_OBJ_NBYTES(_p)
Definition: sc_lib.h:1919

Referenced by SymCryptFdefIntToDivisor(), and SymCryptIntCopy().

◆ SymCryptFdefIntCopyFixup()

VOID SymCryptFdefIntCopyFixup ( _In_ PCSYMCRYPT_INT  pSrc,
_Out_ PSYMCRYPT_INT  pDst 
)

Definition at line 248 of file fdef_general.c.

251{
253 UNREFERENCED_PARAMETER( pDst ); // not used in FRE builds...
254
255 SYMCRYPT_SET_MAGIC( pDst );
256}

Referenced by SymCryptFdefDivisorCopyFixup().

◆ SymCryptFdefIntCopyMixedSize()

SYMCRYPT_ERROR SymCryptFdefIntCopyMixedSize ( _In_ PCSYMCRYPT_INT  piSrc,
_Out_ PSYMCRYPT_INT  piDst 
)

Definition at line 343 of file fdef_general.c.

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}
#define SYMCRYPT_FDEF_DIGIT_NUINT32
Definition: sc_lib.h:1916
SYMCRYPT_ERROR
Definition: symcrypt.h:227

Referenced by SymCryptIntCopyMixedSize().

◆ SymCryptFdefIntCreate()

PSYMCRYPT_INT SYMCRYPT_CALL SymCryptFdefIntCreate ( _Out_writes_bytes_(cbBuffer) PBYTE  pbBuffer,
SIZE_T  cbBuffer,
UINT32  nDigits 
)

Definition at line 213 of file fdef_general.c.

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}
struct _SYMCRYPT_INT SYMCRYPT_INT

Referenced by SymCryptIntCreate().

◆ SymCryptFdefIntFindSmallDivisor()

UINT32 SYMCRYPT_CALL SymCryptFdefIntFindSmallDivisor ( _In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT  pContext,
_In_ PCSYMCRYPT_INT  piSrc,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 1393 of file fdef_general.c.

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}
FORCEINLINE UINT32 SymCryptIsMultipleOfSmallPrime(UINT64 value, PCSYMCRYPT_TRIALDIVISION_PRIME pPrime)
const UINT32 * PCUINT32

Referenced by SymCryptIntFindSmallDivisor().

◆ SymCryptFdefIntGetValue()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefIntGetValue ( _In_ PCSYMCRYPT_INT  piSrc,
_Out_writes_bytes_(cbDst) PBYTE  pbDst,
SIZE_T  cbDst,
SYMCRYPT_NUMBER_FORMAT  format 
)

Definition at line 695 of file fdef_general.c.

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}
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
PCBYTE PBYTE pbDst

Referenced by SymCryptIntGetValue().

◆ SymCryptFdefIntGetValueLsbits32()

UINT32 SYMCRYPT_CALL SymCryptFdefIntGetValueLsbits32 ( _In_ PCSYMCRYPT_INT  piSrc)

Definition at line 713 of file fdef_general.c.

714{
715 // nDigits cannot be zero, so we don't have to test
716 return SYMCRYPT_FDEF_INT_PUINT32( piSrc )[0];
717}

Referenced by SymCryptIntGetValueLsbits32().

◆ SymCryptFdefIntGetValueLsbits64()

UINT64 SYMCRYPT_CALL SymCryptFdefIntGetValueLsbits64 ( _In_ PCSYMCRYPT_INT  piSrc)

Definition at line 721 of file fdef_general.c.

722{
723 // nDigits cannot be zero, so we don't have to test
725 return ((UINT64)(p[1]) << 32) | p[0];
726}

Referenced by SymCryptIntGetValueLsbits64().

◆ SymCryptFdefIntIsEqual()

UINT32 SYMCRYPT_CALL SymCryptFdefIntIsEqual ( _In_ PCSYMCRYPT_INT  piSrc1,
_In_ PCSYMCRYPT_INT  piSrc2 
)

Definition at line 758 of file fdef_general.c.

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}
int n2
Definition: dwarfget.c:147
int n1
Definition: dwarfget.c:147
#define SYMCRYPT_MASK32_ZERO(_v)

Referenced by SymCryptIntIsEqual().

◆ SymCryptFdefIntIsEqualUint32()

UINT32 SYMCRYPT_CALL SymCryptFdefIntIsEqualUint32 ( _In_ PCSYMCRYPT_INT  piSrc1,
_In_ UINT32  u32Src2 
)

Definition at line 749 of file fdef_general.c.

752{
753 return SymCryptFdefRawIsEqualUint32( &SYMCRYPT_FDEF_INT_PUINT32( piSrc1 )[0], piSrc1->nDigits, u32Src2 );
754}
UINT32 SYMCRYPT_CALL SymCryptFdefRawIsEqualUint32(_In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32 pSrc1, UINT32 nDigits, _In_ UINT32 u32Src2)
Definition: fdef_general.c:730

Referenced by SymCryptIntIsEqualUint32().

◆ SymCryptFdefIntMaskedCopy()

VOID SymCryptFdefIntMaskedCopy ( _In_ PCSYMCRYPT_INT  piSrc,
_Inout_ PSYMCRYPT_INT  piDst,
UINT32  mask 
)

Definition at line 280 of file fdef_general.c.

287{
288 SYMCRYPT_CHECK_MAGIC( piSrc );
289 SYMCRYPT_CHECK_MAGIC( piDst );
290
291 SYMCRYPT_ASSERT( piSrc->nDigits == piDst->nDigits );
292
294}

Referenced by SymCryptIntMaskedCopy().

◆ SymCryptFdefIntSetValue()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptFdefIntSetValue ( _In_reads_bytes_(cbSrc) PCBYTE  pbSrc,
SIZE_T  cbSrc,
SYMCRYPT_NUMBER_FORMAT  format,
_Out_ PSYMCRYPT_INT  piDst 
)

Definition at line 601 of file fdef_general.c.

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}
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
PCBYTE pbSrc

Referenced by SymCryptIntSetValue().

◆ SymCryptFdefIntSetValueUint32()

VOID SYMCRYPT_CALL SymCryptFdefIntSetValueUint32 ( UINT32  u32Src,
_Out_ PSYMCRYPT_INT  piDst 
)

Definition at line 497 of file fdef_general.c.

500{
501 SYMCRYPT_CHECK_MAGIC( piDst );
502
504 SYMCRYPT_FDEF_INT_PUINT32( piDst )[0] = u32Src;
505}

Referenced by SymCryptIntSetValueUint32().

◆ SymCryptFdefIntSetValueUint64()

VOID SYMCRYPT_CALL SymCryptFdefIntSetValueUint64 ( UINT64  u64Src,
_Out_ PSYMCRYPT_INT  piDst 
)

Definition at line 511 of file fdef_general.c.

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}

Referenced by SymCryptIntSetValueUint64().

◆ SymCryptFdefMaskedCopy()

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 at line 74 of file fdef_general.c.

79{
80#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_ARM
84#else
86#endif
87}
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
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)

Referenced by SymCryptEcpointMaskedCopy(), SymCryptFdefIntConditionalCopy(), SymCryptFdefIntMaskedCopy(), SymCryptFdefModAddGeneric(), SymCryptFdefModElementMaskedCopy(), SymCryptFdefModSubGeneric(), and SymCryptFdefMontgomeryReduceC().

◆ SymCryptFdefMaskedCopyC()

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 at line 40 of file fdef_general.c.

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}

Referenced by SymCryptFdefMaskedCopy().

◆ SymCryptFdefNumberofDigitsFromInt()

UINT32 SYMCRYPT_CALL SymCryptFdefNumberofDigitsFromInt ( _In_ PCSYMCRYPT_INT  piSrc)

Definition at line 337 of file fdef_general.c.

338{
339 return piSrc->nDigits;
340}

◆ SymCryptFdefRawGetValue()

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 at line 619 of file fdef_general.c.

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}
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
#define b
Definition: ke_i.h:79
@ SYMCRYPT_NUMBER_FORMAT_MSB_FIRST
Definition: symcrypt.h:7017
@ SYMCRYPT_NUMBER_FORMAT_LSB_FIRST
Definition: symcrypt.h:7016
int32_t INT32
Definition: typedefs.h:58
unsigned char BYTE
Definition: xxhash.c:193

Referenced by SymCryptFdefDecideModulusType(), SymCryptFdefIntGetValue(), and SymCryptFdefModElementGetValue().

◆ SymCryptFdefRawIsEqualUint32()

UINT32 SYMCRYPT_CALL SymCryptFdefRawIsEqualUint32 ( _In_reads_(nDigits *SYMCRYPT_FDEF_DIGIT_NUINT32) PCUINT32  pSrc1,
UINT32  nDigits,
_In_ UINT32  u32Src2 
)

Definition at line 730 of file fdef_general.c.

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}

Referenced by SymCryptDlkeyGenerate(), SymCryptFdefIntIsEqualUint32(), and SymCryptFdefModNegGeneric().

◆ SymCryptFdefRawSetValue()

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 at line 524 of file fdef_general.c.

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}

Referenced by SymCryptFdefIntSetValue(), and SymCryptFdefModElementSetValueGeneric().

◆ SymCryptFdefSizeofDivisorFromDigits()

UINT32 SYMCRYPT_CALL SymCryptFdefSizeofDivisorFromDigits ( UINT32  nDigits)

Definition at line 826 of file fdef_general.c.

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}
#define SYMCRYPT_FDEF_UPB_DIGITS

Referenced by SymCryptFdefDivisorAllocate(), SymCryptFdefModulusCopyFixupMontgomery(), SymCryptFdefModulusInitMontgomeryInternal(), SymCryptFdefSizeofModulusFromDigits(), and SymCryptSizeofDivisorFromDigits().

◆ SymCryptFdefSizeofIntFromDigits()

UINT32 SYMCRYPT_CALL SymCryptFdefSizeofIntFromDigits ( UINT32  nDigits)

Definition at line 196 of file fdef_general.c.

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}
SYMCRYPT_MAGIC_FIELD SYMCRYPT_ASYM_ALIGN union @5237 ti

Referenced by SymCryptFdefIntAllocate(), SymCryptFdefIntCreate(), SymCryptFdefSizeofDivisorFromDigits(), and SymCryptSizeofIntFromDigits().

◆ SymCryptGenerateSmallPrimes()

UINT32 SYMCRYPT_CALL SymCryptGenerateSmallPrimes ( UINT32  maxPrime,
PUINT32 *  ppList 
)

Definition at line 1040 of file fdef_general.c.

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}
FxChildList * pList
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39

Referenced by SymCryptFdefCreateTrialDivisionContext().

◆ SymCryptInverseMod2e64()

UINT64 SymCryptInverseMod2e64 ( UINT64  m)

Definition at line 932 of file fdef_general.c.

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}
#define m32
const GLfloat * m
Definition: glext.h:10848
UINT64 inv64

Referenced by SymCryptFdefInitTrialdivisionPrime(), and SymCryptFdefIntToModulus().

◆ SymCryptIsMultipleOfSmallPrime()

FORCEINLINE UINT32 SymCryptIsMultipleOfSmallPrime ( UINT64  value,
PCSYMCRYPT_TRIALDIVISION_PRIME  pPrime 
)

Definition at line 1009 of file fdef_general.c.

1010{
1011 return (value * pPrime->invMod2e64) <= pPrime->compareLimit;
1012}
Definition: pdh_main.c:64

Referenced by SymCryptFdefIntFindSmallDivisor().

◆ SymCryptTestTrialdivisionMaxSmallPrime()

UINT32 SymCryptTestTrialdivisionMaxSmallPrime ( _In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT  pContext)

Definition at line 925 of file fdef_general.c.

927{
928 return pContext->maxTrialPrime;
929}