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

Go to the source code of this file.

Macros

#define MIN_WINDOW_SIZE   (4)
 
#define SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP   (1<<(SYMCRYPT_FDEF_MAX_WINDOW_MODEXP-1))
 
#define SYMCRYPT_MODMULTIEXP_WINDOW_SIZE   (5)
 

Functions

VOID SYMCRYPT_CALL SymCryptModExpWindowed (_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, UINT32 nBitsExp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 
VOID SYMCRYPT_CALL SymCryptModExpSquareAndMultiply32 (_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 
VOID SYMCRYPT_CALL SymCryptModExpGeneric (_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, UINT32 nBitsExp, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 
 C_ASSERT ((1<<(SYMCRYPT_MODMULTIEXP_WINDOW_SIZE-1))<=SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP)
 
VOID SYMCRYPT_CALL SymCryptModExpPrecomputation (_In_ PCSYMCRYPT_MODULUS pmP, UINT32 nPrecomputedPowers, _In_reads_(SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP) PSYMCRYPT_MODELEMENT *pePIs, PSYMCRYPT_MODELEMENT peTemp, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 
VOID SYMCRYPT_CALL SymCryptModMultiExpWnafWithInterleaving (_In_ PCSYMCRYPT_MODULUS pmMod, _In_reads_(nBases) PCSYMCRYPT_MODELEMENT *peBaseArray, _In_reads_(nBases) PCSYMCRYPT_INT *piExpArray, UINT32 nBases, UINT32 nBitsExp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptModMultiExpGeneric (_In_ PCSYMCRYPT_MODULUS pmMod, _In_reads_(nBases) PCSYMCRYPT_MODELEMENT *peBaseArray, _In_reads_(nBases) PCSYMCRYPT_INT *piExpArray, UINT32 nBases, UINT32 nBitsExp, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 

Variables

static const UINT32 cutoffs []
 
static const UINT32 nCuttoffs = sizeof(cutoffs) / sizeof(cutoffs[0])
 

Macro Definition Documentation

◆ MIN_WINDOW_SIZE

#define MIN_WINDOW_SIZE   (4)

Definition at line 41 of file modexp.c.

◆ SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP

#define SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP   (1<<(SYMCRYPT_FDEF_MAX_WINDOW_MODEXP-1))

Definition at line 244 of file modexp.c.

◆ SYMCRYPT_MODMULTIEXP_WINDOW_SIZE

#define SYMCRYPT_MODMULTIEXP_WINDOW_SIZE   (5)

Definition at line 249 of file modexp.c.

Function Documentation

◆ C_ASSERT()

C_ASSERT ( (1<<(SYMCRYPT_MODMULTIEXP_WINDOW_SIZE-1))<=  SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP)

◆ SymCryptModExpGeneric()

VOID SYMCRYPT_CALL SymCryptModExpGeneric ( _In_ PCSYMCRYPT_MODULUS  pmMod,
_In_ PCSYMCRYPT_MODELEMENT  peBase,
_In_ PCSYMCRYPT_INT  piExp,
UINT32  nBitsExp,
UINT32  flags,
_Out_ PSYMCRYPT_MODELEMENT  peDst,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 217 of file modexp.c.

226{
227 if ( ((flags & SYMCRYPT_FLAG_DATA_PUBLIC)!=0) && (nBitsExp <= sizeof(UINT32)*8) )
228 {
229 SymCryptModExpSquareAndMultiply32( pmMod, peBase, piExp, peDst, pbScratch, cbScratch );
230 }
231 else
232 {
233 SymCryptModExpWindowed( pmMod, peBase, piExp, nBitsExp, peDst, pbScratch, cbScratch ); // This is the default
234 }
235}
GLbitfield flags
Definition: glext.h:7161
VOID SYMCRYPT_CALL SymCryptModExpWindowed(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, UINT32 nBitsExp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: modexp.c:56
VOID SYMCRYPT_CALL SymCryptModExpSquareAndMultiply32(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: modexp.c:162
UINT32 UINT32 UINT32 UINT32 cbScratch
#define SYMCRYPT_FLAG_DATA_PUBLIC
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptModExp().

◆ SymCryptModExpPrecomputation()

VOID SYMCRYPT_CALL SymCryptModExpPrecomputation ( _In_ PCSYMCRYPT_MODULUS  pmP,
UINT32  nPrecomputedPowers,
_In_reads_(SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP) PSYMCRYPT_MODELEMENT *  pePIs,
PSYMCRYPT_MODELEMENT  peTemp,
_Out_writes_bytes_opt_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 260 of file modexp.c.

270{
271 SYMCRYPT_ASSERT(nPrecomputedPowers>=2);
272
273 // Calculate B^2
274 SymCryptModSquare( pmP, pePIs[0], peTemp, pbScratch, cbScratch );
275
276 for (UINT32 i=1; i<nPrecomputedPowers; i++)
277 {
278 // B[i] = B^2*B[i-1]
279 SymCryptModMul( pmP, peTemp, pePIs[i-1], pePIs[i], pbScratch, cbScratch );
280 }
281}
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_ASSERT(_x)
Definition: symcrypt.h:10807
PSYMCRYPT_MODULUS pmP
VOID SYMCRYPT_CALL SymCryptModMul(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc1, _In_ PCSYMCRYPT_MODELEMENT peSrc2, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:867
VOID SYMCRYPT_CALL SymCryptModSquare(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:881

Referenced by SymCryptModMultiExpWnafWithInterleaving().

◆ SymCryptModExpSquareAndMultiply32()

VOID SYMCRYPT_CALL SymCryptModExpSquareAndMultiply32 ( _In_ PCSYMCRYPT_MODULUS  pmMod,
_In_ PCSYMCRYPT_MODELEMENT  peBase,
_In_ PCSYMCRYPT_INT  piExp,
_Out_ PSYMCRYPT_MODELEMENT  peDst,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 162 of file modexp.c.

169{
171
174
175 // The bits of the exponent when this function is called are
176 // always less than 32.
178
180
181 // Create the temporary modelements
182 peT1 = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
183 SYMCRYPT_ASSERT( peT1 != NULL );
184 pbScratch += cbModElement;
186 peT2 = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
187 SYMCRYPT_ASSERT( peT2 != NULL );
188 pbScratch += cbModElement;
190
191 if (exp == 0)
192 {
193 SymCryptModElementSetValueUint32( 1, pmMod, peDst, pbScratch, cbScratch );
194 }
195 else
196 {
197 SymCryptModElementSetValueUint32( 1, pmMod, peT1, pbScratch, cbScratch );
198 SymCryptModElementCopy( pmMod, peBase, peT2 );
199
200 while (exp>1)
201 {
202 if (exp%2 == 1)
203 {
204 SymCryptModMul( pmMod, peT1, peT2, peT1, pbScratch, cbScratch );
205 }
206
207 SymCryptModSquare( pmMod, peT2, peT2, pbScratch, cbScratch );
208 exp /= 2;
209 }
210
211 SymCryptModMul( pmMod, peT1, peT2, peDst, pbScratch, cbScratch );
212 }
213}
#define NULL
Definition: types.h:112
DWORD exp
Definition: msg.c:18625
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
UINT32 cbModElement
UINT32 SYMCRYPT_CALL SymCryptIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:270
UINT32 SYMCRYPT_CALL SymCryptSizeofModElementFromModulus(PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:658
VOID SymCryptModElementCopy(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst)
Definition: a_dispatch.c:683
PSYMCRYPT_MODELEMENT SYMCRYPT_CALL SymCryptModElementCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:665
VOID SYMCRYPT_CALL SymCryptModElementSetValueUint32(UINT32 value, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:908
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits)

Referenced by SymCryptModExpGeneric().

◆ SymCryptModExpWindowed()

VOID SYMCRYPT_CALL SymCryptModExpWindowed ( _In_ PCSYMCRYPT_MODULUS  pmMod,
_In_ PCSYMCRYPT_MODELEMENT  peBase,
_In_ PCSYMCRYPT_INT  piExp,
UINT32  nBitsExp,
_Out_ PSYMCRYPT_MODELEMENT  peDst,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 56 of file modexp.c.

64{
65 UINT32 W = 0;
66 UINT32 nTableElements = 0;
67
68 SYMCRYPT_SCSTABLE scsPrecomp = { 0 };
69 UINT32 cbScsPrecomp = 0;
70
72
75
76 UINT32 nIterations = 0;
77 UINT32 iBit = 0;
78 UINT32 nBits = 0;
79 UINT32 index = 0;
80
81 // Truncate the nBitsExp if above the object size
82 nBitsExp = SYMCRYPT_MIN( nBitsExp, SymCryptIntBitsizeOfObject(piExp) );
83
84 // Calculate the window size
86 while ((W-MIN_WINDOW_SIZE < nCuttoffs) && (cutoffs[W-MIN_WINDOW_SIZE]<nBitsExp))
87 {
88 W++;
89 }
90 nTableElements = (1<<W);
91
92 // Initialize the table of temporary modelements
93 cbScsPrecomp = SymCryptScsTableInit( &scsPrecomp, nTableElements, cbModElement );
94
96
97 SymCryptScsTableSetBuffer( &scsPrecomp, pbScratch, cbScsPrecomp );
98 pbScratch += cbScsPrecomp;
99 cbScratch -= cbScsPrecomp;
100
101 // Create the temporary modelement
102 peT1 = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
103 SYMCRYPT_ASSERT( peT1 != NULL );
104 pbScratch += cbModElement;
106 peT2 = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
107 SYMCRYPT_ASSERT( peT2 != NULL );
108 pbScratch += cbModElement;
110
111 // Fill the first element with 1 (**note: this will cause 0^0 = 1)
112 // and the second with peBase
113 SYMCRYPT_ASSERT( nTableElements >= 2 );
114
115 SymCryptModElementSetValueUint32( 1, pmMod, peT1, pbScratch, cbScratch );
116 SymCryptScsTableStore( &scsPrecomp, 0, (PBYTE)peT1, cbModElement );
117
118 SymCryptModElementCopy( pmMod, peBase, peT1 );
119 SymCryptScsTableStore( &scsPrecomp, 1, (PBYTE)peT1, cbModElement );
120
121 // Fill the table with the powers of peBase
122 for (UINT32 i=2; i<nTableElements; i++)
123 {
124 // TODO: Future improvement, use squarings for this table.
125 SymCryptModMul( pmMod, peT1, peBase, peT1, pbScratch, cbScratch );
126 SymCryptScsTableStore( &scsPrecomp, i, (PBYTE)peT1, cbModElement );
127 }
128
129 // Find the number of iterations (minus one) and the starting position bit
130 SYMCRYPT_ASSERT( nBitsExp != 0 );
131 nIterations = (nBitsExp - 1) / W;
132 iBit = nIterations * W;
133
134 // Do the first chunk (it might be smaller than W bits)
135 nBits = nBitsExp - iBit;
136 index = SymCryptIntGetBits( piExp, iBit, nBits );
137 SymCryptScsTableLoad( &scsPrecomp, index, (PBYTE)peT1, cbModElement );
138
139 // Work in batches of W bits in the exponent
140 for (UINT32 i=0; i<nIterations; i++)
141 {
142 // Square W times
143 for (UINT32 j=0; j<W; j++)
144 {
145 SymCryptModSquare( pmMod, peT1, peT1, pbScratch, cbScratch );
146 }
147
148 iBit -= W;
149 index = SymCryptIntGetBits( piExp, iBit, W );
150 SymCryptScsTableLoad( &scsPrecomp, index, (PBYTE)peT2, cbModElement );
151
152 SymCryptModMul( pmMod, peT1, peT2, peT1, pbScratch, cbScratch );
153 }
154
155 SYMCRYPT_ASSERT( iBit == 0 );
156
157 SymCryptModElementCopy( pmMod, peT1, peDst );
158}
#define W(I)
GLuint index
Definition: glext.h:6031
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
static const UINT32 cutoffs[]
Definition: modexp.c:43
static const UINT32 nCuttoffs
Definition: modexp.c:52
#define MIN_WINDOW_SIZE
Definition: modexp.c:41
int nBits
Definition: pcmconverter.c:96
BYTE * PBYTE
Definition: pedump.c:66
Definition: polytest.cpp:36
#define SYMCRYPT_MIN(_a, _b)
UINT32 SYMCRYPT_CALL SymCryptIntBitsizeOfObject(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:200
UINT32 SYMCRYPT_CALL SymCryptScsTableInit(_Out_ PSYMCRYPT_SCSTABLE pScsTable, UINT32 nElements, UINT32 elementSize)
Definition: ScsTable.c:56
VOID SYMCRYPT_CALL SymCryptScsTableSetBuffer(_Inout_ PSYMCRYPT_SCSTABLE pScsTable, _Inout_updates_bytes_(cbBuffer) PBYTE pbBuffer, UINT32 cbBuffer)
Definition: ScsTable.c:98
VOID SYMCRYPT_CALL SymCryptScsTableStore(_Inout_ PSYMCRYPT_SCSTABLE pScsTable, UINT32 iIndex, _In_reads_bytes_(cbData) PCBYTE pbData, UINT32 cbData)
Definition: ScsTable.c:334
VOID SYMCRYPT_CALL SymCryptScsTableLoad(_In_ PSYMCRYPT_SCSTABLE pScsTable, UINT32 iIndex, _Out_writes_bytes_(cbData) PBYTE pbData, UINT32 cbData)
Definition: ScsTable.c:358
UINT32 SYMCRYPT_CALL SymCryptIntGetBits(_In_ PCSYMCRYPT_INT piSrc, UINT32 iBit, UINT32 nBits)
Definition: a_dispatch.c:403

Referenced by SymCryptModExpGeneric(), and SymCryptModMultiExpGeneric().

◆ SymCryptModMultiExpGeneric()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptModMultiExpGeneric ( _In_ PCSYMCRYPT_MODULUS  pmMod,
_In_reads_(nBases) PCSYMCRYPT_MODELEMENT *  peBaseArray,
_In_reads_(nBases) PCSYMCRYPT_INT *  piExpArray,
UINT32  nBases,
UINT32  nBitsExp,
UINT32  flags,
_Out_ PSYMCRYPT_MODELEMENT  peDst,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 449 of file modexp.c.

459{
460 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
461
462 if ( (nBases > SYMCRYPT_MODMULTIEXP_MAX_NBASES) ||
464 {
465 scError = SYMCRYPT_INVALID_ARGUMENT;
466 goto cleanup;
467 }
468
470 {
471 SymCryptModMultiExpWnafWithInterleaving( pmMod, peBaseArray, piExpArray, nBases, nBitsExp, peDst, pbScratch, cbScratch );
472 }
473 else
474 {
476 PSYMCRYPT_MODELEMENT peTemp = NULL;
478
479 // Use two temporary modelements to store the results
480 // *** Make sure that the scratch space is enough i.e. the scratch space of ModMultiExp is
481 // at least 2 modelements bigger than the scratch space of ModExp
483
487
488 peTemp = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
489 pbScratch += cbModElement; cbScratch -= cbModElement;
490
491 peAcc = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
492 pbScratch += cbModElement; cbScratch -= cbModElement;
493
494 // Set peAcc to 1
495 SymCryptModElementSetValueUint32( 1, pmMod, peAcc, pbScratch, cbScratch );
496
497 for (UINT32 i=0; i<nBases; i++)
498 {
499 SymCryptModExpWindowed( pmMod, peBaseArray[i], piExpArray[i], nBitsExp, peTemp, pbScratch, cbScratch );
500
501 SymCryptModMul( pmMod, peAcc, peTemp, peAcc, pbScratch, cbScratch );
502 }
503
504 // Copy the result into the destination
505 SymCryptModElementCopy( pmMod, peAcc, peDst );
506 }
507
508cleanup:
509 return scError;
510}
static void cleanup(void)
Definition: main.c:1335
VOID SYMCRYPT_CALL SymCryptModMultiExpWnafWithInterleaving(_In_ PCSYMCRYPT_MODULUS pmMod, _In_reads_(nBases) PCSYMCRYPT_MODELEMENT *peBaseArray, _In_reads_(nBases) PCSYMCRYPT_INT *piExpArray, UINT32 nBases, UINT32 nBitsExp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: modexp.c:289
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODMULTIEXP(_nDigits, _nBases, _nBitsExp)
#define SYMCRYPT_MODMULTIEXP_MAX_NBASES
#define SYMCRYPT_MODMULTIEXP_MAX_NBITSEXP
UINT32 SYMCRYPT_CALL SymCryptModulusDigitsizeOfObject(_In_ PCSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:635
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP(_nDigits)

Referenced by SymCryptModMultiExp().

◆ SymCryptModMultiExpWnafWithInterleaving()

VOID SYMCRYPT_CALL SymCryptModMultiExpWnafWithInterleaving ( _In_ PCSYMCRYPT_MODULUS  pmMod,
_In_reads_(nBases) PCSYMCRYPT_MODELEMENT *  peBaseArray,
_In_reads_(nBases) PCSYMCRYPT_INT *  piExpArray,
UINT32  nBases,
UINT32  nBitsExp,
_Out_ PSYMCRYPT_MODELEMENT  peDst,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 289 of file modexp.c.

298{
299 UINT32 i, j;
300
301 UINT32 w = 0;
302 UINT32 nPrecompPoints = 0;
303 UINT32 nRecodedDigits = 0;
304
305 // Masks
307 UINT32 fOneTot = 0xffffffff; // Final result 1
308
309 UINT32 fZeroExp = 0; // Zero exponent
310 UINT32 fZeroTot = 0; // Final result 0
311
313
314 // ====================================================
315 // Temporaries
317 PSYMCRYPT_MODELEMENT peTemp = NULL;
319
320 PUINT32 absofKIs = NULL;
321 // ===================================================
322
323 // Calculate the window size
325 nPrecompPoints = (1 << (w-1)); // We only store odd powers of the base point
326
327 // Number of recoded digits
328 nRecodedDigits = nBitsExp;
329
330 //
331 // From symcrypt_internal.h we have:
332 // - sizeof results are upper bounded by 2^19
333 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
334 // - nBases, nPrecompPoints, and nRecodedDigits are bounded by SYMCRYPT_MODMULTIEXP_MAX_NBASES,
335 // SYMCRYPT_MODMULTIEXP_MAX_NBITSEXP, and SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP, respectively.
336 // Thus the following calculation does not overflow cbScratch.
337 //
340
341 // Creating temporary precomputed modelements
342 for (i=0; i<nBases*nPrecompPoints; i++)
343 {
345 pePIs[i] = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
346 SYMCRYPT_ASSERT( pePIs[i] != NULL );
347 pbScratch += cbModElement;
349 }
350
352 2*cbModElement +
355
356 // Creating temporary points
357 peTemp = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
358 SYMCRYPT_ASSERT( peTemp != NULL );
359 pbScratch += cbModElement;
361
362 peOne = SymCryptModElementCreate( pbScratch, cbModElement, pmMod );
363 SYMCRYPT_ASSERT( peOne != NULL );
364 pbScratch += cbModElement;
366
367 // Fixing pointers to recoded digits (be careful that the remaining space is SYMCRYPT_ASYM_ALIGNed)
368 absofKIs = (PUINT32) pbScratch;
369 pbScratch += nBases * nRecodedDigits * sizeof(UINT32);
370 cbScratch -= nBases * nRecodedDigits * sizeof(UINT32);
371
372 // Update cbScratch first using pbScratch, as the amount of scratch skipped for alignment depends upon the alignment of pbScratch
373 cbScratch -= ( ((SIZE_T)pbScratch + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1) ) - (SIZE_T)pbScratch;
374 pbScratch = (PBYTE) ( ((SIZE_T)pbScratch + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1) );
375
376
377 //
378 // Main algorithm
379 //
380
381 // Set peOne to 1
382 SymCryptModElementSetValueUint32( 1, pmMod, peOne, pbScratch, cbScratch );
383
384 // Zero-out all recoded digits
385 SymCryptWipe( (PBYTE)absofKIs, nBases*nRecodedDigits*sizeof(UINT32) );
386
387 for (j = 0; j<nBases; j++)
388 {
389 // Check if the exponent is zero
390 fZeroExp = SymCryptIntIsEqualUint32( piExpArray[j], 0 );
391
392 // Check if the result is 0 (i.e. 0^e with e!=0)
393 if( !fZeroExp && SymCryptModElementIsZero(pmMod, peBaseArray[j]) )
394 {
395 fZeroTot = 0xffffffff;
396 break;
397 }
398
399 // Check if the exponent is 0 or if the base point is 1
400 fOne[j] = ( fZeroExp | SymCryptModElementIsEqual( pmMod, peBaseArray[j], peOne ) );
401 fOneTot &= fOne[j];
402
403 // Skip the recoding stage (and all remaining steps) if this point will give result 1
404 if (!fOne[j])
405 {
406 // Recoding stage
407 SymCryptPositiveWidthNafRecoding( w, piExpArray[j], nBitsExp, &absofKIs[j*nRecodedDigits], nRecodedDigits );
408
409 // Copy the base in the start of the pePIs array
410 SymCryptModElementCopy( pmMod, peBaseArray[j], pePIs[j*nPrecompPoints] );
411
412 // Precomputation stage
413 SymCryptModExpPrecomputation( pmMod, nPrecompPoints, &pePIs[j*nPrecompPoints], peTemp, pbScratch, cbScratch );
414 }
415 }
416
417 if (fZeroTot)
418 {
419 SymCryptModElementSetValueUint32( 0, pmMod, peDst, pbScratch, cbScratch );
420 }
421 else
422 {
423 SymCryptModElementSetValueUint32( 1, pmMod, peTemp, pbScratch, cbScratch );
424
425 if (!fOneTot)
426 {
427 // Main loop
428 for (INT32 i = nRecodedDigits-1; i>-1; i--)
429 {
430 SymCryptModSquare( pmMod, peTemp, peTemp, pbScratch, cbScratch );
431
432 for (j = 0; j<nBases; j++)
433 {
434 if (absofKIs[j*nRecodedDigits + i] != 0)
435 {
436 SymCryptModMul( pmMod, peTemp, pePIs[j*nPrecompPoints + absofKIs[j*nRecodedDigits + i]/2], peTemp, pbScratch, cbScratch );
437 }
438 }
439 }
440 }
441
442 // Copy the result into the destination
443 SymCryptModElementCopy( pmMod, peTemp, peDst );
444 }
445}
unsigned int * PUINT32
Definition: basetsd.h:119
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
#define SYMCRYPT_MODMULTIEXP_WINDOW_SIZE
Definition: modexp.c:249
VOID SYMCRYPT_CALL SymCryptModExpPrecomputation(_In_ PCSYMCRYPT_MODULUS pmP, UINT32 nPrecomputedPowers, _In_reads_(SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP) PSYMCRYPT_MODELEMENT *pePIs, PSYMCRYPT_MODELEMENT peTemp, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: modexp.c:260
#define SYMCRYPT_MODMULTIEXP_MAX_NPRECOMP
Definition: modexp.c:244
VOID SYMCRYPT_CALL SymCryptPositiveWidthNafRecoding(UINT32 W, _In_ PCSYMCRYPT_INT piK, UINT32 nBitsExp, _Out_writes_(nRecodedDigits) PUINT32 absofKIs, UINT32 nRecodedDigits)
Definition: recoding.c:180
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_ASYM_ALIGN_VALUE
UINT32 SYMCRYPT_CALL SymCryptModElementIsZero(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc)
Definition: a_dispatch.c:828
UINT32 SYMCRYPT_CALL SymCryptModElementIsEqual(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc1, _In_ PCSYMCRYPT_MODELEMENT peSrc2)
Definition: a_dispatch.c:818
UINT32 SYMCRYPT_CALL SymCryptIntIsEqualUint32(_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
Definition: a_dispatch.c:424
int32_t INT32
Definition: typedefs.h:58
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by SymCryptModMultiExpGeneric().

Variable Documentation

◆ cutoffs

const UINT32 cutoffs[]
static
Initial value:
=
{
321,
}

Definition at line 43 of file modexp.c.

Referenced by SymCryptModExpWindowed().

◆ nCuttoffs

const UINT32 nCuttoffs = sizeof(cutoffs) / sizeof(cutoffs[0])
static

Definition at line 52 of file modexp.c.

Referenced by SymCryptModExpWindowed().