ReactOS 0.4.17-dev-1005-g171e1de
crt.c
Go to the documentation of this file.
1//
2// crt.c Chinese Remainder Theorem Algorithms
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6
7#include "precomp.h"
8
15 _Out_ PSYMCRYPT_MODELEMENT peInvQModP,
16 _Out_ PSYMCRYPT_MODELEMENT peInvPModQ,
18 PBYTE pbScratch,
20{
21 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
22
23 PCSYMCRYPT_INT piSrc1 = NULL;
24 PCSYMCRYPT_INT piSrc2 = NULL;
25
26 PSYMCRYPT_INT piInvSrc1ModSrc2 = NULL;
27 PSYMCRYPT_INT piInvSrc2ModSrc1 = NULL;
28
29 UINT32 nDigits = 0;
30 UINT32 cbInt = 0;
31
32 BOOLEAN oddP = FALSE;
33
36
38
39 // Create two temporary integers
40 cbInt = SymCryptSizeofIntFromDigits( nDigits );
41
43
44 piInvSrc1ModSrc2 = SymCryptIntCreate( pbScratch, cbInt, nDigits ); pbScratch += cbInt; cbScratch -= cbInt;
45 piInvSrc2ModSrc1 = SymCryptIntCreate( pbScratch, cbInt, nDigits ); pbScratch += cbInt; cbScratch -= cbInt;
46
48 if (oddP)
49 {
52 }
53 else
54 {
57 }
58
59 // IntExtendedGcd requirements:
60 // - First argument > 0
61 // - Second argument odd
62 if( SymCryptIntIsEqualUint32(piSrc1, 0) ||
63 ((SymCryptIntGetValueLsbits32(piSrc2) & 1) != 1) )
64 {
65 scError = SYMCRYPT_INVALID_ARGUMENT;
66 goto cleanup;
67 }
68
69 // Extended GCD
70 SymCryptIntExtendedGcd( piSrc1, piSrc2, flags, NULL, NULL, piInvSrc1ModSrc2, piInvSrc2ModSrc1, pbScratch, cbScratch );
71
72 if (oddP)
73 {
74 SymCryptIntToModElement( piInvSrc2ModSrc1, pmQ, peInvPModQ, pbScratch, cbScratch );
75 SymCryptIntToModElement( piInvSrc1ModSrc2, pmP, peInvQModP, pbScratch, cbScratch );
76 }
77 else
78 {
79 SymCryptIntToModElement( piInvSrc2ModSrc1, pmP, peInvQModP, pbScratch, cbScratch );
80 SymCryptIntToModElement( piInvSrc1ModSrc2, pmQ, peInvPModQ, pbScratch, cbScratch );
81 }
82
84 return scError;
85}
86
87
91 UINT32 nCoprimes,
92 _In_reads_( nCoprimes ) PCSYMCRYPT_MODULUS * ppmCoprimes,
94 _Out_writes_( nCoprimes ) PSYMCRYPT_MODELEMENT * ppeCrtInverses,
97{
98 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
99
100 if (nCoprimes == 2)
101 {
103 ppmCoprimes[0],
104 ppmCoprimes[1],
105 flags,
106 ppeCrtInverses[0],
107 ppeCrtInverses[1],
108 pbScratch,
109 cbScratch );
110 }
111 else
112 {
113 scError = SYMCRYPT_INVALID_ARGUMENT;
114 goto cleanup;
115 }
116
117cleanup:
118 return scError;
119}
120
124 UINT32 nCoprimes,
125 _In_reads_( nCoprimes ) PCSYMCRYPT_MODULUS * ppmCoprimes,
126 _In_reads_( nCoprimes ) PCSYMCRYPT_MODELEMENT * ppeCrtInverses,
127 _In_reads_( nCoprimes ) PCSYMCRYPT_MODELEMENT * ppeCrtRemainders,
129 _Out_ PSYMCRYPT_INT piSolution,
132{
133 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
134
135 SYMCRYPT_ASSERT( nCoprimes >= 2 );
136
137 PSYMCRYPT_INT piTmp = NULL;
139
140 PSYMCRYPT_INT piDouble = NULL;
141
142 UINT32 nDigitsMax = 0;
143
144 UINT32 cbInt = 0;
146 UINT32 cbDouble = 0;
147
148 UINT32 carry = 0;
149
151
152 nDigitsMax = SYMCRYPT_MAX( SymCryptModulusDigitsizeOfObject( ppmCoprimes[0] ), SymCryptModulusDigitsizeOfObject( ppmCoprimes[1] ) );
153
154 cbInt = SymCryptSizeofIntFromDigits( nDigitsMax );
156 cbDouble = SymCryptSizeofIntFromDigits( 2*nDigitsMax );
157
158 if( cbDouble == 0 )
159 {
160 // It is possible that cbDouble would not fit within the maximum integer
161 scError = SYMCRYPT_INVALID_ARGUMENT;
162 goto cleanup;
163 }
164
165 SYMCRYPT_ASSERT( cbScratch >= cbInt + cbModElement + cbDouble +
167 SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( 2*nDigitsMax ) )
168 );
169
170 // Create temporaries
171 piTmp = SymCryptIntCreate( pbScratch, cbInt, nDigitsMax ); pbScratch += cbInt; cbScratch -= cbInt;
172
173 peTmp = SymCryptModElementCreate( pbScratch, cbModElement, ppmCoprimes[0] ); pbScratch += cbModElement; cbScratch -= cbModElement;
174
175 piDouble = SymCryptIntCreate( pbScratch, cbDouble, 2*nDigitsMax ); pbScratch += cbDouble; cbScratch -= cbDouble;
176
177 if (nCoprimes == 2)
178 {
179 //
180 // Let r0 and r1 be the two remainders modulo p and q respectively
181 // Then we calculate (q^{-1}(r0 - r1) mod p)*q + r1
182 //
183 SymCryptModElementToInt( ppmCoprimes[1], ppeCrtRemainders[1], piTmp, pbScratch, cbScratch ); // Convert r1 to Int
184 SymCryptIntToModElement( piTmp, ppmCoprimes[0], peTmp, pbScratch, cbScratch ); // Convert it to r1 mod p
185
186 SymCryptModSub( ppmCoprimes[0], ppeCrtRemainders[0], peTmp, peTmp, pbScratch, cbScratch ); // (r0 - r1) mod p
187 SymCryptModMul( ppmCoprimes[0], ppeCrtInverses[0], peTmp, peTmp, pbScratch, cbScratch ); // q^{-1}*(r0 - r1) mod p
188 SymCryptModElementToInt( ppmCoprimes[0], peTmp, piTmp, pbScratch, cbScratch ); // Convert it to integer
189
190 SymCryptIntMulMixedSize( piTmp, SymCryptIntFromModulus((PSYMCRYPT_MODULUS)ppmCoprimes[1]), piDouble, pbScratch, cbScratch ); // Multiply by q
191 scError = SymCryptIntCopyMixedSize( piDouble, piSolution ); // Copy it into the solution
192 if (scError != SYMCRYPT_NO_ERROR)
193 {
194 goto cleanup;
195 }
196
197 SymCryptModElementToInt( ppmCoprimes[1], ppeCrtRemainders[1], piTmp, pbScratch, cbScratch ); // Convert r1 to integer
198
199 carry = SymCryptIntAddMixedSize( piTmp, piSolution, piSolution ); // Add it to the solution
200
201 if (carry>0)
202 {
203 scError = SYMCRYPT_INVALID_ARGUMENT;
204 goto cleanup;
205 }
206 }
207 else
208 {
209 scError = SYMCRYPT_INVALID_ARGUMENT;
210 goto cleanup;
211 }
212
213cleanup:
214 return scError;
215}
unsigned char BOOLEAN
Definition: actypes.h:127
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCrtSolve(UINT32 nCoprimes, _In_reads_(nCoprimes) PCSYMCRYPT_MODULUS *ppmCoprimes, _In_reads_(nCoprimes) PCSYMCRYPT_MODELEMENT *ppeCrtInverses, _In_reads_(nCoprimes) PCSYMCRYPT_MODELEMENT *ppeCrtRemainders, UINT32 flags, _Out_ PSYMCRYPT_INT piSolution, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: crt.c:123
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCrtGenerateForTwoCoprimes(_In_ PCSYMCRYPT_MODULUS pmP, _In_ PCSYMCRYPT_MODULUS pmQ, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peInvQModP, _Out_ PSYMCRYPT_MODELEMENT peInvPModQ, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: crt.c:11
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptCrtGenerateInverses(UINT32 nCoprimes, _In_reads_(nCoprimes) PCSYMCRYPT_MODULUS *ppmCoprimes, UINT32 flags, _Out_writes_(nCoprimes) PSYMCRYPT_MODELEMENT *ppeCrtInverses, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: crt.c:90
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
GLbitfield flags
Definition: glext.h:7161
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BYTE * PBYTE
Definition: pedump.c:66
UINT32 UINT32 UINT32 UINT32 cbScratch
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_CALL
const SYMCRYPT_MODELEMENT * PCSYMCRYPT_MODELEMENT
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
#define SYMCRYPT_MAX(_a, _b)
UINT32 cbModElement
PSYMCRYPT_MODULUS pmQ
const SYMCRYPT_INT * PCSYMCRYPT_INT
PSYMCRYPT_MODULUS pmP
const SYMCRYPT_MODULUS * PCSYMCRYPT_MODULUS
SYMCRYPT_MODULUS * PSYMCRYPT_MODULUS
SYMCRYPT_INT * PSYMCRYPT_INT
UINT32 SYMCRYPT_CALL SymCryptIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:270
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL(_nResultDigits)
UINT32 SYMCRYPT_CALL SymCryptSizeofModElementFromModulus(PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:658
VOID SYMCRYPT_CALL SymCryptIntToModElement(_In_ PCSYMCRYPT_INT piSrc, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:749
VOID SYMCRYPT_CALL SymCryptModSub(_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:852
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntCopyMixedSize(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:214
#define SYMCRYPT_SCRATCH_BYTES_FOR_EXTENDED_GCD(_nDigits)
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 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
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits)
VOID SYMCRYPT_CALL SymCryptModElementToInt(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:762
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:720
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
UINT32 SYMCRYPT_CALL SymCryptModulusDigitsizeOfObject(_In_ PCSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:635
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
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: gen_int.c:176
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59