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

Go to the source code of this file.

Functions

UINT64 SYMCRYPT_CALL SymCryptUint64Gcd (UINT64 a, UINT64 b, UINT32 flags)
 
VOID SYMCRYPT_CALL SymCryptIntExtendedGcd (_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, UINT32 flags, _Out_opt_ PSYMCRYPT_INT piGcd, _Out_opt_ PSYMCRYPT_INT piLcm, _Out_opt_ PSYMCRYPT_INT piInvSrc1ModSrc2, _Out_opt_ PSYMCRYPT_INT piInvSrc2ModSrc1, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 

Function Documentation

◆ SymCryptIntExtendedGcd()

VOID SYMCRYPT_CALL SymCryptIntExtendedGcd ( _In_ PCSYMCRYPT_INT  piSrc1,
_In_ PCSYMCRYPT_INT  piSrc2,
UINT32  flags,
_Out_opt_ PSYMCRYPT_INT  piGcd,
_Out_opt_ PSYMCRYPT_INT  piLcm,
_Out_opt_ PSYMCRYPT_INT  piInvSrc1ModSrc2,
_Out_opt_ PSYMCRYPT_INT  piInvSrc2ModSrc1,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 176 of file gen_int.c.

186{
188 PSYMCRYPT_INT piA; // size nDigits
189 PSYMCRYPT_INT piB; // size nDigits, NOT ALLOCATED (part of the pdGcd divisor)
190 PSYMCRYPT_INT piTmp; // size nDigits
191 PSYMCRYPT_INT piA1; // size nDigits
192 PSYMCRYPT_INT piB1; // size nDigits
193 PSYMCRYPT_INT piTmpDbl; // size 2*nDigits
194 PSYMCRYPT_DIVISOR pdGcd; // size nDigits
195 PSYMCRYPT_DIVISOR pdTmp; // size nDigits
196 UINT32 cbInt;
197 UINT32 cbWideInt;
198 UINT32 cbDivisor;
199 SIZE_T cbFnScratch;
200 UINT32 t;
201 UINT32 c;
202 UINT32 d;
203
204 UNREFERENCED_PARAMETER( flags ); // Currently not used to improve performance.
205
206 // Compute how much scratch space we need for the functions we call
207 cbFnScratch = SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD( 2 * nDigits, nDigits );
208 cbFnScratch = SYMCRYPT_MAX( cbFnScratch, SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( 2*nDigits ) );
209 cbFnScratch = SYMCRYPT_MAX( cbFnScratch, SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( nDigits ) );
210
211 cbInt = SymCryptSizeofIntFromDigits( nDigits );
212 cbWideInt = SymCryptSizeofIntFromDigits( 2*nDigits );
213 cbDivisor = SymCryptSizeofDivisorFromDigits( nDigits );
214
215 SYMCRYPT_ASSERT( cbWideInt != 0 );
216 SYMCRYPT_ASSERT( cbScratch >= 4 * cbInt +
217 1 * cbWideInt +
218 2 * cbDivisor +
219 cbFnScratch );
220
221 piA = SymCryptIntCreate( pbScratch, cbInt, nDigits );
222 pbScratch += cbInt; cbScratch -= cbInt;
223 // piB is stored inside the pdGcd object created later
224 piTmp = SymCryptIntCreate( pbScratch, cbInt, nDigits );
225 pbScratch += cbInt; cbScratch -= cbInt;
226 piA1 = SymCryptIntCreate( pbScratch, cbInt, nDigits );
227 pbScratch += cbInt; cbScratch -= cbInt;
228 piB1 = SymCryptIntCreate( pbScratch, cbInt, nDigits );
229 pbScratch += cbInt; cbScratch -= cbInt;
230
231 piTmpDbl = SymCryptIntCreate( pbScratch, cbWideInt, 2 * nDigits );
232 pbScratch += cbWideInt; cbScratch -= cbWideInt;
233
234 pdGcd = SymCryptDivisorCreate( pbScratch, cbDivisor, nDigits );
235 pbScratch += cbDivisor; cbScratch -= cbDivisor;
236 piB = SymCryptIntFromDivisor( pdGcd );
237
238 pdTmp = SymCryptDivisorCreate( pbScratch, cbDivisor, nDigits );
239 pbScratch += cbDivisor; cbScratch -= cbDivisor;
240
241 SymCryptIntCopyMixedSize( piSrc1, piA ); // Ignore the error return value here as we know
242 SymCryptIntCopyMixedSize( piSrc2, piB ); // that the destination integers are large enough.
243
244 SymCryptIntSetValueUint32( 1, piA1 );
245 SymCryptIntSetValueUint32( 0, piB1 );
246
247 // Currently not supported: Src1 to be 0 or Src2 to be even
249 SYMCRYPT_ASSERT( (SymCryptIntGetValueLsbits32( piB ) & 1) != 0 );
250 if ( SymCryptIntIsEqualUint32( piA, 0 ) ||
251 ((SymCryptIntGetValueLsbits32( piB ) & 1) == 0) )
252 {
253 goto cleanup;
254 }
255
256 // Currently not supported: piInvSrc2ModSrc1 != NULL and max( Src1.nDigits, Src2.nDigits ) * 2 > SymCryptDigitsFromBits(SYMCRYPT_INT_MAX_BITS)
257 if( (piInvSrc2ModSrc1 != NULL) && (piTmpDbl == NULL) )
258 {
259 goto cleanup;
260 }
261
262 t = SymCryptIntBitsizeOfObject( piSrc1 ) + SymCryptIntBitsizeOfObject( piSrc2 ) - 1;
263 while( t > 0 )
264 {
265 t--;
266
267 //if A odd and A < B:
268 // Swap (A, A1) with (B, B1)
269 c = 1 & (SymCryptIntGetValueLsbits32( piA ) & SymCryptIntSubSameSize( piA, piB, piTmp ) );
270 SymCryptIntConditionalSwap( piA, piB, c );
271 SymCryptIntConditionalSwap( piA1, piB1, c );
272
273 //if A odd:
274 // A -= B; A1 -= B1 (mod S2);
275 c = 1 & SymCryptIntGetValueLsbits32( piA );
276 SymCryptIntSubSameSize( piA, piB, piTmp ); // Never a carry due to the previous conditional swap
277 SymCryptIntConditionalCopy( piTmp, piA, c );
278
279 d = SymCryptIntSubSameSize( piA1, piB1, piTmp );
280 SymCryptIntConditionalCopy( piTmp, piA1, c );
281 SymCryptIntAddMixedSize( piA1, piSrc2, piTmp );
282 SymCryptIntConditionalCopy( piTmp, piA1, c & d );
283
284 // A /= 2; A1 /= 2 (mod S2);
285 SYMCRYPT_ASSERT( (SymCryptIntGetValueLsbits32( piA ) & 1) == 0 );
286 SymCryptIntShr1( 0, piA, piA );
287 c = SymCryptIntGetValueLsbits32( piA1 ) & 1;
288 d = SymCryptIntAddMixedSize( piA1, piSrc2, piTmp );
289 SymCryptIntConditionalCopy( piTmp, piA1, c );
290 SymCryptIntShr1( c & d, piA1, piA1 );
291
292 }
293
294 // B = GCD, B1 * S1 = GCD (mod S2)
295 // A = 0, A1 is scratch
296 //
297 // Algorithm from here:
298 // GCD as divisor
299 // LCM = S1 * S2 / GCD.
300 // P2 = S2 / GCD, as divisor (only for InvS1ModS2)
301 // InvS1ModS2 = B1 mod P2
302 // InvS2ModS1 = -((B1*S1 - GCD) div S2) mod S1
303
304 if( piGcd != NULL )
305 {
306 SymCryptIntCopyMixedSize( piB, piGcd );
307 }
308
309 if( piLcm == NULL && piInvSrc1ModSrc2 == NULL && piInvSrc2ModSrc1 == NULL )
310 {
311 // Only GCD needed; don't do the other work
312 goto cleanup;
313 }
314
315 SymCryptIntCopyMixedSize( piB, SymCryptIntFromDivisor( pdGcd ) ); // copy into INT of the right size
316
317 // IntToDivisor requirement:
318 // Gcd !=0
319 SymCryptIntToDivisor( SymCryptIntFromDivisor( pdGcd ), pdGcd, 3, 0, pbScratch, cbScratch );
320
321 if( piLcm != NULL )
322 {
323 // LCM = S1 * S2 / GCD
324 SymCryptIntMulMixedSize( piSrc1, piSrc2, piLcm, pbScratch, cbScratch );
325 SymCryptIntDivMod( piLcm, pdGcd, piLcm, NULL, pbScratch, cbScratch );
326 }
327
328 if( piInvSrc1ModSrc2 != NULL )
329 {
330 // Future optimization: if GCD == 1 then we can just copy B1.
331 SymCryptIntDivMod( piSrc2, pdGcd, SymCryptIntFromDivisor( pdTmp ), NULL, pbScratch, cbScratch );
332
333 // IntToDivisor requirement:
334 // Src2 / pdGcd > 0
335 SymCryptIntToDivisor( SymCryptIntFromDivisor( pdTmp ), pdTmp, 1, 0, pbScratch, cbScratch );
336 SymCryptIntDivMod( piB1, pdTmp, NULL, piInvSrc1ModSrc2, pbScratch, cbScratch );
337 }
338
339 if( piInvSrc2ModSrc1 != NULL )
340 {
341 // InvS2ModS1 = - ( (B1*S1 - GCD)/S2 ) mod S1
342
343 // S2 as divisor
345
346 // IntToDivisor requirement:
347 // Src2 is odd --> Src2 != 0
348 SymCryptIntToDivisor( SymCryptIntFromDivisor( pdTmp ), pdTmp, 1, 0, pbScratch, cbScratch );
349
350 SymCryptIntMulMixedSize( piB1, piSrc1, piTmpDbl, pbScratch, cbScratch );
351 SymCryptIntSubMixedSize( piTmpDbl, piB, piTmpDbl ); // Never a borrow if B1 >= 1
352 SymCryptIntDivMod( piTmpDbl, pdTmp, piTmpDbl, NULL, pbScratch, cbScratch );
353
354 // and reduce modulo S1
356
357 // IntToDivisor requirement:
358 // Src1 > 0
359 SymCryptIntToDivisor( SymCryptIntFromDivisor( pdTmp ), pdTmp, 1, 0, pbScratch, cbScratch );
360 SymCryptIntDivMod( piTmpDbl, pdTmp, NULL, piInvSrc2ModSrc1, pbScratch, cbScratch );
361
362 // Negative modulo S1
363 SymCryptIntSubMixedSize( SymCryptIntFromDivisor( pdTmp ), piInvSrc2ModSrc1, piInvSrc2ModSrc1 ); // Never a borrow as piInvSrc2ModSrc1 < S1
364 }
365
366cleanup:
367 return; // Need a statement after a label...
368}
#define NULL
Definition: types.h:112
static void cleanup(void)
Definition: main.c:1335
GLdouble GLdouble t
Definition: gl.h:2047
const GLubyte * c
Definition: glext.h:8905
GLbitfield flags
Definition: glext.h:7161
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
UINT32 UINT32 UINT32 UINT32 cbScratch
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
#define SYMCRYPT_MAX(_a, _b)
SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR
SYMCRYPT_INT * PSYMCRYPT_INT
UINT32 SYMCRYPT_CALL SymCryptIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:270
UINT32 SYMCRYPT_CALL SymCryptSizeofDivisorFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:512
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL(_nResultDigits)
UINT32 SYMCRYPT_CALL SymCryptIntBitsizeOfObject(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:200
VOID SYMCRYPT_CALL SymCryptIntShr1(UINT32 highestBit, _In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:374
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD(_nSrcDigits, _nDivisorDigits)
UINT32 SYMCRYPT_CALL SymCryptIntSubMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:334
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntCopyMixedSize(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:214
UINT32 SYMCRYPT_CALL SymCryptIntDigitsizeOfObject(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:207
VOID SYMCRYPT_CALL SymCryptIntConditionalCopy(_In_ PCSYMCRYPT_INT piSrc, _Inout_ PSYMCRYPT_INT piDst, UINT32 cond)
Definition: a_dispatch.c:180
VOID SYMCRYPT_CALL SymCryptIntConditionalSwap(_Inout_ PSYMCRYPT_INT piSrc1, _Inout_ PSYMCRYPT_INT piSrc2, UINT32 cond)
Definition: a_dispatch.c:190
VOID SYMCRYPT_CALL SymCryptIntToDivisor(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_DIVISOR pdDst, UINT32 totalOperations, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:560
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_DIVISOR(_nDigits)
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromDivisor(_In_ PSYMCRYPT_DIVISOR pdSrc)
Definition: a_dispatch.c:553
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptDivisorCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:519
UINT32 SYMCRYPT_CALL SymCryptIntIsEqualUint32(_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
Definition: a_dispatch.c:424
VOID SYMCRYPT_CALL SymCryptIntMulMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:485
UINT32 SYMCRYPT_CALL SymCryptSizeofIntFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:134
VOID SYMCRYPT_CALL SymCryptIntSetValueUint32(UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:230
UINT32 SYMCRYPT_CALL SymCryptIntSubSameSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:324
VOID SYMCRYPT_CALL SymCryptIntDivMod(_In_ PCSYMCRYPT_INT piSrc, _In_ PCSYMCRYPT_DIVISOR pdDivisor, _Out_opt_ PSYMCRYPT_INT piQuotient, _Out_opt_ PSYMCRYPT_INT piRemainder, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:573
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:141
UINT32 SYMCRYPT_CALL SymCryptIntAddMixedSize(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:304
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptCrtGenerateForTwoCoprimes(), SymCryptRsakeyCalculatePrimesFromPrivateExponent(), and SymCryptRsakeyCalculatePrivateFields().

◆ SymCryptUint64Gcd()

UINT64 SYMCRYPT_CALL SymCryptUint64Gcd ( UINT64  a,
UINT64  b,
UINT32  flags 
)

Definition at line 12 of file gen_int.c.

13{
15 UINT64 tmp;
16 UINT64 a2;
17 UINT64 b2;
18 UINT32 i;
19
20/*
21 Algorithm outline:
22
23 if( b even )
24 swap (a,b)
25
26 loop:
27 { invariant: b is odd }
28 if( a even )
29 a = a/2
30 else
31 if a < b
32 swap (a,b)
33 a = (a - b) / 2
34
35 We ignore the data_public flag as we currently always use a side-channel safe implementation
36
37 to compute (a < b) on 64-bit values is hard if we want to avoid
38*/
41
42 // First we make sure that b is odd
43 // If b even: swap (a,b)
44 swap = ~(0 - (b & 1));
45 tmp = (a ^ b) & swap;
46 a ^= tmp;
47 b ^= tmp;
48
49 // Each loop iteration reduces len(a) + len(b) by at least 1, so looping 127 times is enough.
50 // For inputs (2^63, 2^63 + 1) we get 63 iterations to reduce a to 1, and then another 63 to get
51 // the other value to 1, plus one more to make it 0.
52 for( i=0; i < 127; i++ )
53 {
54 // Compute the result of the 'else' part of the if( a even ) into (a2, b2)
55 // First we evaluate (a < b), which is a bit tricky without access to the carry flag.
56 // a < b = (b>>63) if ((a^b) >> 63) == 1
57 // (a - b) >> 63 otherwise
58 tmp = a ^ b;
59 tmp = (tmp & b) | (~tmp & (a-b));
60 swap = 0 - (tmp >> 63);
61
62 // Now swap if a < b into (a2, b2)
63 tmp = (a ^ b) & swap;
64 a2 = a ^ tmp;
65 b2 = b ^ tmp;
66
67 //
68 a2 = (a2 - b2) / 2;
69
70 // Compute the (a is odd) condition
71 tmp = 0 - (a & 1);
72
73 // Assemble the final result
74 a = (tmp & a2) | (~tmp & a/2);
75 b = (tmp & b2) | (~tmp & b);
76 }
77
78 SYMCRYPT_ASSERT( a == 0 );
79 return b;
80}
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
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 b
Definition: ke_i.h:79
static const struct update_accum a2
Definition: msg.c:542
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:538
#define swap(a, b)
Definition: qsort.c:63
#define SYMCRYPT_FLAG_GCD_INPUTS_NOT_BOTH_EVEN

Referenced by SymCryptIntGenerateRandomPrime().