Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/symcrypt/lib/ec_twisted_edwards.c
15010 views
1
//
2
// ec_twisted_edwards.c Twisted Edwards Curve Implementation
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
#include "precomp.h"
8
9
VOID
10
SYMCRYPT_CALL
11
SymCryptTwistedEdwardsFillScratchSpaces( _In_ PSYMCRYPT_ECURVE pCurve )
12
{
13
UINT32 nDigits = SymCryptDigitsFromBits( pCurve->FModBitsize );
14
UINT32 cbModElement = pCurve->cbModElement;
15
UINT32 nDigitsFieldLength = pCurve->FModDigits;
16
17
//
18
// All the scratch space computations are upper bounded by the SizeofXXX bound (2^19) and
19
// the SCRATCH_BYTES_FOR_XXX bound (2^24) (see symcrypt_internal.h).
20
//
21
// One caveat is SymCryptSizeofEcpointFromCurve and SymCryptSizeofEcpointEx which calculate
22
// the size of EcPoint with 4 coordinates (each one a modelement of max size 2^17). Thus upper
23
// bounded by 2^20.
24
//
25
// Another is the precomp points computation where the nPrecompPoints are up to
26
// 2^SYMCRYPT_ECURVE_SW_DEF_WINDOW = 2^6 and the nRecodedDigits are equal to the
27
// GOrd bitsize < 2^20.
28
//
29
// Thus cbScratchScalarMulti is upper bounded by 2^6*2^20 + 2*2^20*2^4 ~ 2^26.
30
//
31
32
pCurve->cbScratchCommon = 8 * cbModElement + SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( nDigits );
33
34
pCurve->cbScratchScalar =
35
(pCurve->cbModElement) +
36
2 * SymCryptSizeofEcpointFromCurve( pCurve ) +
37
2 * SymCryptSizeofIntFromDigits( pCurve->GOrdDigits ) +
38
SYMCRYPT_MAX( pCurve->cbScratchCommon, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->GOrdDigits ));
39
40
pCurve->cbScratchScalarMulti =
41
pCurve->info.sw.nPrecompPoints * SymCryptSizeofEcpointFromCurve( pCurve ) +
42
((2*pCurve->info.sw.nRecodedDigits * sizeof(UINT32) + SYMCRYPT_ASYM_ALIGN_VALUE - 1 )/SYMCRYPT_ASYM_ALIGN_VALUE) * SYMCRYPT_ASYM_ALIGN_VALUE;
43
44
pCurve->cbScratchGetSetValue =
45
SymCryptSizeofEcpointEx(cbModElement, SYMCRYPT_ECPOINT_FORMAT_MAX_LENGTH) +
46
2 * cbModElement +
47
SYMCRYPT_MAX(SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(nDigitsFieldLength),
48
SYMCRYPT_SCRATCH_BYTES_FOR_MODINV(nDigitsFieldLength));
49
50
pCurve->cbScratchGetSetValue = SYMCRYPT_MAX( pCurve->cbScratchGetSetValue, SymCryptSizeofIntFromDigits( nDigits ) );
51
52
pCurve->cbScratchEckey =
53
SYMCRYPT_MAX( pCurve->cbModElement + SymCryptSizeofIntFromDigits(SymCryptEcurveDigitsofScalarMultiplier(pCurve)),
54
SymCryptSizeofEcpointFromCurve( pCurve ) ) +
55
SYMCRYPT_MAX( pCurve->cbScratchScalar + pCurve->cbScratchScalarMulti, pCurve->cbScratchGetSetValue );
56
}
57
58
VOID
59
SYMCRYPT_CALL
60
SymCryptTwistedEdwardsSetDistinguished(
61
_In_ PCSYMCRYPT_ECURVE pCurve,
62
_Out_ PSYMCRYPT_ECPOINT poDst,
63
_Out_writes_bytes_( cbScratch )
64
PBYTE pbScratch,
65
SIZE_T cbScratch )
66
{
67
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
68
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poDst->pCurve) );
69
70
UNREFERENCED_PARAMETER( pbScratch );
71
UNREFERENCED_PARAMETER( cbScratch );
72
73
SymCryptEcpointCopy( pCurve, pCurve->G, poDst );
74
}
75
76
UINT32
77
SYMCRYPT_CALL
78
SymCryptTwistedEdwardsIsZero(
79
_In_ PCSYMCRYPT_ECURVE pCurve,
80
_In_ PCSYMCRYPT_ECPOINT poSrc,
81
_Out_writes_bytes_( cbScratch )
82
PBYTE pbScratch,
83
SIZE_T cbScratch)
84
{
85
PSYMCRYPT_MODULUS pmMod = pCurve->FMod;
86
UINT32 dResX = 0, dResY = 0;
87
88
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
89
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) );
90
91
UNREFERENCED_PARAMETER( pbScratch );
92
UNREFERENCED_PARAMETER( cbScratch );
93
94
PSYMCRYPT_MODELEMENT peSrcX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc );
95
PSYMCRYPT_MODELEMENT peSrcY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc );
96
PSYMCRYPT_MODELEMENT peSrcZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc );
97
98
dResX = SymCryptModElementIsZero( pmMod, peSrcX );
99
dResY = SymCryptModElementIsEqual( pmMod, peSrcY, peSrcZ );
100
101
return ( dResX & dResY );
102
}
103
104
//
105
// Verify that
106
// a * x^2 + y^2 = 1 + d * x^2 * y^2
107
// x = X/Z, y = Y/Z,
108
// To avoid mod inv calculation which is expensive,
109
// we verify Z^2(aX^2 + Y^2) = Z^4 + d * X^2 * Y^2
110
//
111
UINT32
112
SYMCRYPT_CALL
113
SymCryptTwistedEdwardsOnCurve(
114
_In_ PCSYMCRYPT_ECURVE pCurve,
115
_In_ PCSYMCRYPT_ECPOINT poSrc,
116
_Out_writes_bytes_( cbScratch )
117
PBYTE pbScratch,
118
SIZE_T cbScratch)
119
{
120
PSYMCRYPT_MODELEMENT peTemp[4];
121
PSYMCRYPT_MODULUS pmMod = pCurve->FMod;
122
SIZE_T nBytes;
123
124
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
125
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) );
126
SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );
127
128
nBytes = SymCryptSizeofModElementFromModulus( pmMod );
129
130
SYMCRYPT_ASSERT( cbScratch >= 4*nBytes );
131
132
for (UINT32 i = 0; i < 4; ++i)
133
{
134
peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );
135
pbScratch += nBytes;
136
cbScratch -= nBytes;
137
}
138
139
PSYMCRYPT_MODELEMENT peSrcX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc );
140
PSYMCRYPT_MODELEMENT peSrcY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc );
141
PSYMCRYPT_MODELEMENT peSrcZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc );
142
143
// peTemp[0] = X^2
144
SymCryptModSquare( pmMod, peSrcX, peTemp[0], pbScratch, cbScratch);
145
146
// peTemp[1] = Y^2
147
SymCryptModSquare( pmMod, peSrcY, peTemp[1], pbScratch, cbScratch);
148
149
// peTemp[2] = Z^2
150
SymCryptModSquare( pmMod, peSrcZ, peTemp[2], pbScratch, cbScratch);
151
152
// peTemp[3] = a * X^2
153
SymCryptModMul( pmMod, pCurve->A, peTemp[0], peTemp[3], pbScratch, cbScratch );
154
155
// peTemp[3] = a * X^2 + Y^2
156
SymCryptModAdd( pmMod, peTemp[3], peTemp[1], peTemp[3], pbScratch, cbScratch );
157
158
// peTemp[3] = Z^2 (a * X^2 + Y^2)
159
SymCryptModMul( pmMod, peTemp[3], peTemp[2], peTemp[3], pbScratch, cbScratch );
160
161
// peTemp[1] = X^2 * Y^2
162
SymCryptModMul( pmMod, peTemp[0], peTemp[1], peTemp[1], pbScratch, cbScratch );
163
164
// peTemp[1] = d * X^2 *Y^2
165
SymCryptModMul( pmMod, pCurve->B, peTemp[1], peTemp[1], pbScratch, cbScratch );
166
167
// peTemp[2] = Z^4
168
SymCryptModMul( pmMod, peTemp[2], peTemp[2], peTemp[2], pbScratch, cbScratch );
169
170
// peTemp[1] = Z^4 + d * X^2 * Y^2
171
SymCryptModAdd( pmMod, peTemp[2], peTemp[1], peTemp[1], pbScratch, cbScratch );
172
173
return SymCryptModElementIsEqual( pmMod, peTemp[1], peTemp[3] );
174
}
175
176
//
177
// Point doubling: dbl-2008-hwcd, 5Mul + 4Square + 2Add + 5Sub
178
//
179
// poDst (X, Y, Z, T) = 2 * poSrc(X, Y, Z, T)
180
// 1. A = X1 ^ 2
181
// 2. B = Y1 ^ 2
182
// 3. C = 2 * Z1 ^ 2
183
// 4. D = a * A
184
// 5. E = (X1 + Y1) ^ 2 - A - B
185
// 6. G = D + B
186
// 7. F = G - C
187
// 8. H = D - B
188
// 9. X3 = E * F
189
// 10. Y3 = G * H
190
// 11. T3 = E * H
191
// 12. Z3 = F * G
192
//
193
VOID
194
SYMCRYPT_CALL
195
SymCryptTwistedEdwardsDouble(
196
_In_ PCSYMCRYPT_ECURVE pCurve,
197
_In_ PCSYMCRYPT_ECPOINT poSrc,
198
_Out_ PSYMCRYPT_ECPOINT poDst,
199
UINT32 flags,
200
_Out_writes_bytes_( cbScratch )
201
PBYTE pbScratch,
202
SIZE_T cbScratch)
203
{
204
PSYMCRYPT_MODELEMENT peTemp[8];
205
PSYMCRYPT_MODULUS pmMod = pCurve->FMod;
206
SIZE_T nBytes;
207
208
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
209
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) && SymCryptEcurveIsSame(pCurve, poDst->pCurve) );
210
SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );
211
212
UNREFERENCED_PARAMETER( flags );
213
214
nBytes = SymCryptSizeofModElementFromModulus( pmMod );
215
216
SYMCRYPT_ASSERT( cbScratch >= 8*nBytes );
217
218
for (UINT32 i = 0; i < 8; ++i)
219
{
220
peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );
221
pbScratch += nBytes;
222
cbScratch -= nBytes;
223
}
224
225
PSYMCRYPT_MODELEMENT peSrcX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc );
226
PSYMCRYPT_MODELEMENT peSrcY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc );
227
PSYMCRYPT_MODELEMENT peSrcZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc );
228
229
PSYMCRYPT_MODELEMENT peDstX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poDst );
230
PSYMCRYPT_MODELEMENT peDstY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poDst );
231
PSYMCRYPT_MODELEMENT peDstZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poDst );
232
PSYMCRYPT_MODELEMENT peDstT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poDst );
233
234
PSYMCRYPT_MODELEMENT peA = peTemp[0];
235
PSYMCRYPT_MODELEMENT peB = peTemp[1];
236
PSYMCRYPT_MODELEMENT peC = peTemp[2];
237
PSYMCRYPT_MODELEMENT peD = peTemp[3];
238
PSYMCRYPT_MODELEMENT peE = peTemp[4];
239
PSYMCRYPT_MODELEMENT peF = peTemp[5];
240
PSYMCRYPT_MODELEMENT peG = peTemp[6];
241
PSYMCRYPT_MODELEMENT peH = peTemp[7];
242
243
244
// A = X1^2
245
SymCryptModSquare( pmMod, peSrcX, peA, pbScratch, cbScratch );
246
247
// B = Y1^2
248
SymCryptModSquare( pmMod, peSrcY, peB, pbScratch, cbScratch );
249
250
// C1 = Z1^2
251
SymCryptModSquare( pmMod, peSrcZ, peC, pbScratch, cbScratch );
252
253
// C = C1 + C1 = Z1^2 + Z1^2 = 2 * Z1^2
254
SymCryptModAdd( pmMod, peC, peC, peC, pbScratch, cbScratch );
255
256
// D = a * A
257
SymCryptModMul( pmMod, pCurve->A, peA, peD, pbScratch, cbScratch );
258
259
// E1 = X1 + Y1
260
SymCryptModAdd( pmMod, peSrcX, peSrcY, peE, pbScratch, cbScratch );
261
262
// E2 = E1^2 = (X1 + Y1)^2
263
SymCryptModSquare( pmMod, peE, peE, pbScratch, cbScratch );
264
265
// E3 = E2 - A = (X1 + Y1)^2 - A
266
SymCryptModSub( pmMod, peE, peA, peE, pbScratch, cbScratch );
267
268
// E = E3 - B = (X1 + Y1)^2 - A - B
269
SymCryptModSub( pmMod, peE, peB, peE, pbScratch, cbScratch );
270
271
// G = D + B
272
SymCryptModAdd( pmMod, peD, peB, peG, pbScratch, cbScratch );
273
274
// F = G - C
275
SymCryptModSub( pmMod, peG, peC, peF, pbScratch, cbScratch );
276
277
// H = D - B
278
SymCryptModSub( pmMod, peD, peB, peH, pbScratch, cbScratch );
279
280
// X3 = E * F
281
SymCryptModMul( pmMod, peE, peF, peDstX, pbScratch, cbScratch );
282
283
// Y3 = G * H
284
SymCryptModMul( pmMod, peG, peH, peDstY, pbScratch, cbScratch );
285
286
// T3 = E * H
287
SymCryptModMul( pmMod, peE, peH, peDstT, pbScratch, cbScratch );
288
289
// Z3 = F * G
290
SymCryptModMul( pmMod, peF, peG, peDstZ, pbScratch, cbScratch );
291
}
292
293
294
//
295
// Point addition: add-2008-hwcd 11Mul + 3add + 4sub
296
//
297
// poDst(X, Y, Z, T) = poSrc(X, Y, Z, T) + poSrc2(X, Y, Z, T)
298
// 1. A = X1 * X2
299
// 2. B = Y1 * Y2
300
// 3. C = d * T1 * T2
301
// 4. D = Z1 * Z2
302
// 5. E = (X1 + Y1) * (X2 + Y2) - A - B
303
// 6. F = D - C
304
// 7. G = D + C
305
// 8. H = B - a * A
306
// 9. X3 = E * F
307
// 10. Y3 = G * H
308
// 11. T3 = E * H
309
// 12. Z3 = F * G
310
//
311
VOID
312
SYMCRYPT_CALL
313
SymCryptTwistedEdwardsAdd(
314
_In_ PCSYMCRYPT_ECURVE pCurve,
315
_In_ PCSYMCRYPT_ECPOINT poSrc1,
316
_In_ PCSYMCRYPT_ECPOINT poSrc2,
317
_Out_ PSYMCRYPT_ECPOINT poDst,
318
UINT32 flags,
319
_Out_writes_bytes_( cbScratch )
320
PBYTE pbScratch,
321
SIZE_T cbScratch )
322
{
323
PSYMCRYPT_MODELEMENT peTemp[8];
324
PSYMCRYPT_MODULUS pmMod = pCurve->FMod;
325
SIZE_T nBytes;
326
327
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
328
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc1->pCurve) && SymCryptEcurveIsSame(pCurve, poSrc2->pCurve) && SymCryptEcurveIsSame(pCurve, poDst->pCurve) );
329
SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );
330
331
UNREFERENCED_PARAMETER( flags );
332
333
nBytes = SymCryptSizeofModElementFromModulus( pmMod );
334
335
SYMCRYPT_ASSERT( cbScratch >= 8*nBytes );
336
337
for (UINT32 i = 0; i < 8; ++i)
338
{
339
peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );
340
pbScratch += nBytes;
341
cbScratch -= nBytes;
342
}
343
344
PSYMCRYPT_MODELEMENT peSrc1X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc1 );
345
PSYMCRYPT_MODELEMENT peSrc1Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc1 );
346
PSYMCRYPT_MODELEMENT peSrc1Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc1 );
347
PSYMCRYPT_MODELEMENT peSrc1T = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poSrc1 );
348
349
PSYMCRYPT_MODELEMENT peSrc2X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc2 );
350
PSYMCRYPT_MODELEMENT peSrc2Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc2 );
351
PSYMCRYPT_MODELEMENT peSrc2Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc2 );
352
PSYMCRYPT_MODELEMENT peSrc2T = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poSrc2 );
353
354
PSYMCRYPT_MODELEMENT peDstX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poDst );
355
PSYMCRYPT_MODELEMENT peDstY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poDst );
356
PSYMCRYPT_MODELEMENT peDstZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poDst );
357
PSYMCRYPT_MODELEMENT peDstT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poDst );
358
359
PSYMCRYPT_MODELEMENT peA = peTemp[0];
360
PSYMCRYPT_MODELEMENT peB = peTemp[1];
361
PSYMCRYPT_MODELEMENT peC = peTemp[2];
362
PSYMCRYPT_MODELEMENT peD = peTemp[3];
363
PSYMCRYPT_MODELEMENT peE = peTemp[4];
364
PSYMCRYPT_MODELEMENT peF = peTemp[5];
365
PSYMCRYPT_MODELEMENT peG = peTemp[6];
366
PSYMCRYPT_MODELEMENT peH = peTemp[7];
367
368
// A = X1 * X2
369
SymCryptModMul( pmMod, peSrc1X, peSrc2X, peA, pbScratch, cbScratch );
370
371
// B = Y1 * Y2
372
SymCryptModMul( pmMod, peSrc1Y, peSrc2Y, peB, pbScratch, cbScratch );
373
374
// C1 = T1 * T2
375
SymCryptModMul( pmMod, peSrc1T, peSrc2T, peC, pbScratch, cbScratch );
376
377
// C = d * C1 = d * T1 * T2
378
SymCryptModMul( pmMod, pCurve->B, peC, peC, pbScratch, cbScratch );
379
380
// D = Z1 * Z2
381
SymCryptModMul( pmMod, peSrc1Z, peSrc2Z, peD, pbScratch, cbScratch );
382
383
// E1 = X1 + Y1
384
SymCryptModAdd( pmMod, peSrc1X, peSrc1Y, peE, pbScratch, cbScratch );
385
386
// E2 = X2 + Y2
387
SymCryptModAdd( pmMod, peSrc2X, peSrc2Y, peF, pbScratch, cbScratch );
388
389
// E = E * F
390
SymCryptModMul( pmMod, peE, peF, peE, pbScratch, cbScratch );
391
392
// E = E - A
393
SymCryptModSub( pmMod, peE, peA, peE, pbScratch, cbScratch );
394
395
// E = E - B
396
SymCryptModSub( pmMod, peE, peB, peE, pbScratch, cbScratch );
397
398
// F = D - C
399
SymCryptModSub( pmMod, peD, peC, peF, pbScratch, cbScratch );
400
401
// G = D + C
402
SymCryptModAdd( pmMod, peD, peC, peG, pbScratch, cbScratch );
403
404
// H = a * A
405
SymCryptModMul( pmMod, pCurve->A, peA, peH, pbScratch, cbScratch );
406
407
// H = B - a * A
408
SymCryptModSub( pmMod, peB, peH, peH, pbScratch, cbScratch );
409
410
// X3 = E * F
411
SymCryptModMul( pmMod, peE, peF, peDstX, pbScratch, cbScratch );
412
413
// Y3 = G * H
414
SymCryptModMul( pmMod, peG, peH, peDstY, pbScratch, cbScratch );
415
416
// T3 = E * H
417
SymCryptModMul( pmMod, peE, peH, peDstT, pbScratch, cbScratch );
418
419
// Y3 = F * G
420
SymCryptModMul( pmMod, peF, peG, peDstZ, pbScratch, cbScratch );
421
}
422
423
VOID
424
SYMCRYPT_CALL
425
SymCryptTwistedEdwardsAddDiffNonZero(
426
_In_ PCSYMCRYPT_ECURVE pCurve,
427
_In_ PCSYMCRYPT_ECPOINT poSrc1,
428
_In_ PCSYMCRYPT_ECPOINT poSrc2,
429
_Out_ PSYMCRYPT_ECPOINT poDst,
430
_Out_writes_bytes_(cbScratch)
431
PBYTE pbScratch,
432
SIZE_T cbScratch )
433
{
434
SymCryptTwistedEdwardsAdd( pCurve, poSrc1, poSrc2, poDst, 0, pbScratch, cbScratch );
435
}
436
437
//
438
// Verify poSrc1(X1, Y1, Z1, T1) = poSrc2(X2, Y2, Z2, T2)
439
// To avoid ModInv for 1/Z, we do
440
// X1 * Z2 = X2 * Z1, and
441
// Y1 * Z2 = Y2 * Z1
442
//
443
// This function also do poSrc1 = -1 * poSrc check as flags indicates
444
//
445
UINT32
446
SYMCRYPT_CALL
447
SymCryptTwistedEdwardsIsEqual(
448
_In_ PCSYMCRYPT_ECURVE pCurve,
449
_In_ PCSYMCRYPT_ECPOINT poSrc1,
450
_In_ PCSYMCRYPT_ECPOINT poSrc2,
451
UINT32 flags,
452
_Out_writes_bytes_(cbScratch)
453
PBYTE pbScratch,
454
SIZE_T cbScratch)
455
{
456
PSYMCRYPT_MODELEMENT peTemp[2];
457
PSYMCRYPT_MODELEMENT peSrc1X, peSrc1Y, peSrc1Z;
458
PSYMCRYPT_MODELEMENT peSrc2X, peSrc2Y, peSrc2Z;
459
PSYMCRYPT_MODULUS pmMod = pCurve->FMod;
460
SIZE_T nBytes;
461
UINT32 dResX = 0;
462
UINT32 dResXN = 0;
463
UINT32 dResY = 0;
464
465
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
466
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc1->pCurve) && SymCryptEcurveIsSame(pCurve, poSrc2->pCurve) );
467
SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );
468
469
nBytes = SymCryptSizeofModElementFromModulus( pmMod );
470
471
SYMCRYPT_ASSERT( cbScratch >= 2*nBytes );
472
473
for (UINT32 i = 0; i < 2; ++i)
474
{
475
peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );
476
pbScratch += nBytes;
477
cbScratch -= nBytes;
478
}
479
480
peSrc1X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc1 );
481
peSrc1Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc1 );
482
peSrc1Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc1 );
483
484
peSrc2X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc2 );
485
peSrc2Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc2 );
486
peSrc2Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc2 );
487
488
// Setting the default flag if flags == 0
489
flags |= (SYMCRYPT_MASK32_ZERO(flags) & SYMCRYPT_FLAG_ECPOINT_EQUAL);
490
491
// peTemp[0] = X1 * Z2
492
SymCryptModMul( pmMod, peSrc1X, peSrc2Z, peTemp[0], pbScratch, cbScratch );
493
494
// peTemp[1] = X2 * Z1
495
SymCryptModMul( pmMod, peSrc2X, peSrc1Z, peTemp[1], pbScratch, cbScratch );
496
497
dResX = SymCryptModElementIsEqual( pmMod, peTemp[0], peTemp[1] );
498
499
// Neg peTemp[1]
500
SymCryptModNeg(pmMod, peTemp[1], peTemp[1], pbScratch, cbScratch);
501
dResXN = SymCryptModElementIsEqual(pmMod, peTemp[0], peTemp[1]);
502
503
// peTemp[0] = Y1 * Z2
504
SymCryptModMul( pmMod, peSrc1Y, peSrc2Z, peTemp[0], pbScratch, cbScratch );
505
506
// peTemp[1] = Y2 * Z1
507
SymCryptModMul( pmMod, peSrc2Y, peSrc1Z, peTemp[1], pbScratch, cbScratch );
508
509
dResY = SymCryptModElementIsEqual( pmMod, peTemp[0], peTemp[1] );
510
511
return (SYMCRYPT_MASK32_NONZERO( flags & SYMCRYPT_FLAG_ECPOINT_EQUAL ) & dResX & dResY ) |
512
(SYMCRYPT_MASK32_NONZERO( flags & SYMCRYPT_FLAG_ECPOINT_NEG_EQUAL ) & dResXN & dResY );
513
}
514
515
VOID
516
SYMCRYPT_CALL
517
SymCryptTwistedEdwardsSetZero(
518
_In_ PCSYMCRYPT_ECURVE pCurve,
519
_Out_ PSYMCRYPT_ECPOINT poDst,
520
_Out_writes_bytes_(cbScratch)
521
PBYTE pbScratch,
522
SIZE_T cbScratch)
523
{
524
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
525
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poDst->pCurve) );
526
SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );
527
528
PSYMCRYPT_MODULUS pmMod = pCurve->FMod;
529
530
PSYMCRYPT_MODELEMENT peDstX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poDst );
531
PSYMCRYPT_MODELEMENT peDstY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poDst );
532
PSYMCRYPT_MODELEMENT peDstZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poDst );
533
PSYMCRYPT_MODELEMENT peDstT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poDst );
534
535
SymCryptModElementSetValueUint32( 0, pmMod, peDstX, pbScratch, cbScratch );
536
SymCryptModElementSetValueUint32( 1, pmMod, peDstY, pbScratch, cbScratch );
537
SymCryptModElementSetValueUint32( 1, pmMod, peDstZ, pbScratch, cbScratch );
538
SymCryptModElementSetValueUint32( 0, pmMod, peDstT, pbScratch, cbScratch );
539
}
540
541
VOID
542
SYMCRYPT_CALL
543
SymCryptTwistedEdwardsNegate(
544
_In_ PCSYMCRYPT_ECURVE pCurve,
545
_Inout_ PSYMCRYPT_ECPOINT poSrc,
546
UINT32 mask,
547
_Out_writes_bytes_( cbScratch )
548
PBYTE pbScratch,
549
SIZE_T cbScratch )
550
{
551
PCSYMCRYPT_MODULUS FMod = pCurve->FMod;
552
PSYMCRYPT_MODELEMENT peX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0,pCurve, poSrc);
553
PSYMCRYPT_MODELEMENT peT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3,pCurve, poSrc);
554
555
PSYMCRYPT_MODELEMENT peTmp = NULL;
556
557
SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );
558
SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) );
559
SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->FModDigits ) + pCurve->cbModElement );
560
561
peTmp = SymCryptModElementCreate(
562
pbScratch,
563
pCurve->cbModElement,
564
FMod );
565
SYMCRYPT_ASSERT( peTmp != NULL);
566
567
pbScratch += pCurve->cbModElement;
568
cbScratch -= pCurve->cbModElement;
569
570
SymCryptModNeg( FMod, peX, peTmp, pbScratch, cbScratch );
571
SymCryptModElementMaskedCopy( FMod, peTmp, peX, mask );
572
573
SymCryptModNeg( FMod, peT, peTmp, pbScratch, cbScratch );
574
SymCryptModElementMaskedCopy( FMod, peTmp, peT, mask );
575
}
576
577