Path: blob/master/libs/symcrypt/lib/ec_twisted_edwards.c
15010 views
//1// ec_twisted_edwards.c Twisted Edwards Curve Implementation2//3// Copyright (c) Microsoft Corporation. Licensed under the MIT license.4//56#include "precomp.h"78VOID9SYMCRYPT_CALL10SymCryptTwistedEdwardsFillScratchSpaces( _In_ PSYMCRYPT_ECURVE pCurve )11{12UINT32 nDigits = SymCryptDigitsFromBits( pCurve->FModBitsize );13UINT32 cbModElement = pCurve->cbModElement;14UINT32 nDigitsFieldLength = pCurve->FModDigits;1516//17// All the scratch space computations are upper bounded by the SizeofXXX bound (2^19) and18// the SCRATCH_BYTES_FOR_XXX bound (2^24) (see symcrypt_internal.h).19//20// One caveat is SymCryptSizeofEcpointFromCurve and SymCryptSizeofEcpointEx which calculate21// the size of EcPoint with 4 coordinates (each one a modelement of max size 2^17). Thus upper22// bounded by 2^20.23//24// Another is the precomp points computation where the nPrecompPoints are up to25// 2^SYMCRYPT_ECURVE_SW_DEF_WINDOW = 2^6 and the nRecodedDigits are equal to the26// GOrd bitsize < 2^20.27//28// Thus cbScratchScalarMulti is upper bounded by 2^6*2^20 + 2*2^20*2^4 ~ 2^26.29//3031pCurve->cbScratchCommon = 8 * cbModElement + SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( nDigits );3233pCurve->cbScratchScalar =34(pCurve->cbModElement) +352 * SymCryptSizeofEcpointFromCurve( pCurve ) +362 * SymCryptSizeofIntFromDigits( pCurve->GOrdDigits ) +37SYMCRYPT_MAX( pCurve->cbScratchCommon, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->GOrdDigits ));3839pCurve->cbScratchScalarMulti =40pCurve->info.sw.nPrecompPoints * SymCryptSizeofEcpointFromCurve( pCurve ) +41((2*pCurve->info.sw.nRecodedDigits * sizeof(UINT32) + SYMCRYPT_ASYM_ALIGN_VALUE - 1 )/SYMCRYPT_ASYM_ALIGN_VALUE) * SYMCRYPT_ASYM_ALIGN_VALUE;4243pCurve->cbScratchGetSetValue =44SymCryptSizeofEcpointEx(cbModElement, SYMCRYPT_ECPOINT_FORMAT_MAX_LENGTH) +452 * cbModElement +46SYMCRYPT_MAX(SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(nDigitsFieldLength),47SYMCRYPT_SCRATCH_BYTES_FOR_MODINV(nDigitsFieldLength));4849pCurve->cbScratchGetSetValue = SYMCRYPT_MAX( pCurve->cbScratchGetSetValue, SymCryptSizeofIntFromDigits( nDigits ) );5051pCurve->cbScratchEckey =52SYMCRYPT_MAX( pCurve->cbModElement + SymCryptSizeofIntFromDigits(SymCryptEcurveDigitsofScalarMultiplier(pCurve)),53SymCryptSizeofEcpointFromCurve( pCurve ) ) +54SYMCRYPT_MAX( pCurve->cbScratchScalar + pCurve->cbScratchScalarMulti, pCurve->cbScratchGetSetValue );55}5657VOID58SYMCRYPT_CALL59SymCryptTwistedEdwardsSetDistinguished(60_In_ PCSYMCRYPT_ECURVE pCurve,61_Out_ PSYMCRYPT_ECPOINT poDst,62_Out_writes_bytes_( cbScratch )63PBYTE pbScratch,64SIZE_T cbScratch )65{66SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );67SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poDst->pCurve) );6869UNREFERENCED_PARAMETER( pbScratch );70UNREFERENCED_PARAMETER( cbScratch );7172SymCryptEcpointCopy( pCurve, pCurve->G, poDst );73}7475UINT3276SYMCRYPT_CALL77SymCryptTwistedEdwardsIsZero(78_In_ PCSYMCRYPT_ECURVE pCurve,79_In_ PCSYMCRYPT_ECPOINT poSrc,80_Out_writes_bytes_( cbScratch )81PBYTE pbScratch,82SIZE_T cbScratch)83{84PSYMCRYPT_MODULUS pmMod = pCurve->FMod;85UINT32 dResX = 0, dResY = 0;8687SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );88SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) );8990UNREFERENCED_PARAMETER( pbScratch );91UNREFERENCED_PARAMETER( cbScratch );9293PSYMCRYPT_MODELEMENT peSrcX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc );94PSYMCRYPT_MODELEMENT peSrcY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc );95PSYMCRYPT_MODELEMENT peSrcZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc );9697dResX = SymCryptModElementIsZero( pmMod, peSrcX );98dResY = SymCryptModElementIsEqual( pmMod, peSrcY, peSrcZ );99100return ( dResX & dResY );101}102103//104// Verify that105// a * x^2 + y^2 = 1 + d * x^2 * y^2106// x = X/Z, y = Y/Z,107// To avoid mod inv calculation which is expensive,108// we verify Z^2(aX^2 + Y^2) = Z^4 + d * X^2 * Y^2109//110UINT32111SYMCRYPT_CALL112SymCryptTwistedEdwardsOnCurve(113_In_ PCSYMCRYPT_ECURVE pCurve,114_In_ PCSYMCRYPT_ECPOINT poSrc,115_Out_writes_bytes_( cbScratch )116PBYTE pbScratch,117SIZE_T cbScratch)118{119PSYMCRYPT_MODELEMENT peTemp[4];120PSYMCRYPT_MODULUS pmMod = pCurve->FMod;121SIZE_T nBytes;122123SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );124SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) );125SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );126127nBytes = SymCryptSizeofModElementFromModulus( pmMod );128129SYMCRYPT_ASSERT( cbScratch >= 4*nBytes );130131for (UINT32 i = 0; i < 4; ++i)132{133peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );134pbScratch += nBytes;135cbScratch -= nBytes;136}137138PSYMCRYPT_MODELEMENT peSrcX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc );139PSYMCRYPT_MODELEMENT peSrcY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc );140PSYMCRYPT_MODELEMENT peSrcZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc );141142// peTemp[0] = X^2143SymCryptModSquare( pmMod, peSrcX, peTemp[0], pbScratch, cbScratch);144145// peTemp[1] = Y^2146SymCryptModSquare( pmMod, peSrcY, peTemp[1], pbScratch, cbScratch);147148// peTemp[2] = Z^2149SymCryptModSquare( pmMod, peSrcZ, peTemp[2], pbScratch, cbScratch);150151// peTemp[3] = a * X^2152SymCryptModMul( pmMod, pCurve->A, peTemp[0], peTemp[3], pbScratch, cbScratch );153154// peTemp[3] = a * X^2 + Y^2155SymCryptModAdd( pmMod, peTemp[3], peTemp[1], peTemp[3], pbScratch, cbScratch );156157// peTemp[3] = Z^2 (a * X^2 + Y^2)158SymCryptModMul( pmMod, peTemp[3], peTemp[2], peTemp[3], pbScratch, cbScratch );159160// peTemp[1] = X^2 * Y^2161SymCryptModMul( pmMod, peTemp[0], peTemp[1], peTemp[1], pbScratch, cbScratch );162163// peTemp[1] = d * X^2 *Y^2164SymCryptModMul( pmMod, pCurve->B, peTemp[1], peTemp[1], pbScratch, cbScratch );165166// peTemp[2] = Z^4167SymCryptModMul( pmMod, peTemp[2], peTemp[2], peTemp[2], pbScratch, cbScratch );168169// peTemp[1] = Z^4 + d * X^2 * Y^2170SymCryptModAdd( pmMod, peTemp[2], peTemp[1], peTemp[1], pbScratch, cbScratch );171172return SymCryptModElementIsEqual( pmMod, peTemp[1], peTemp[3] );173}174175//176// Point doubling: dbl-2008-hwcd, 5Mul + 4Square + 2Add + 5Sub177//178// poDst (X, Y, Z, T) = 2 * poSrc(X, Y, Z, T)179// 1. A = X1 ^ 2180// 2. B = Y1 ^ 2181// 3. C = 2 * Z1 ^ 2182// 4. D = a * A183// 5. E = (X1 + Y1) ^ 2 - A - B184// 6. G = D + B185// 7. F = G - C186// 8. H = D - B187// 9. X3 = E * F188// 10. Y3 = G * H189// 11. T3 = E * H190// 12. Z3 = F * G191//192VOID193SYMCRYPT_CALL194SymCryptTwistedEdwardsDouble(195_In_ PCSYMCRYPT_ECURVE pCurve,196_In_ PCSYMCRYPT_ECPOINT poSrc,197_Out_ PSYMCRYPT_ECPOINT poDst,198UINT32 flags,199_Out_writes_bytes_( cbScratch )200PBYTE pbScratch,201SIZE_T cbScratch)202{203PSYMCRYPT_MODELEMENT peTemp[8];204PSYMCRYPT_MODULUS pmMod = pCurve->FMod;205SIZE_T nBytes;206207SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );208SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) && SymCryptEcurveIsSame(pCurve, poDst->pCurve) );209SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );210211UNREFERENCED_PARAMETER( flags );212213nBytes = SymCryptSizeofModElementFromModulus( pmMod );214215SYMCRYPT_ASSERT( cbScratch >= 8*nBytes );216217for (UINT32 i = 0; i < 8; ++i)218{219peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );220pbScratch += nBytes;221cbScratch -= nBytes;222}223224PSYMCRYPT_MODELEMENT peSrcX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc );225PSYMCRYPT_MODELEMENT peSrcY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc );226PSYMCRYPT_MODELEMENT peSrcZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc );227228PSYMCRYPT_MODELEMENT peDstX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poDst );229PSYMCRYPT_MODELEMENT peDstY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poDst );230PSYMCRYPT_MODELEMENT peDstZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poDst );231PSYMCRYPT_MODELEMENT peDstT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poDst );232233PSYMCRYPT_MODELEMENT peA = peTemp[0];234PSYMCRYPT_MODELEMENT peB = peTemp[1];235PSYMCRYPT_MODELEMENT peC = peTemp[2];236PSYMCRYPT_MODELEMENT peD = peTemp[3];237PSYMCRYPT_MODELEMENT peE = peTemp[4];238PSYMCRYPT_MODELEMENT peF = peTemp[5];239PSYMCRYPT_MODELEMENT peG = peTemp[6];240PSYMCRYPT_MODELEMENT peH = peTemp[7];241242243// A = X1^2244SymCryptModSquare( pmMod, peSrcX, peA, pbScratch, cbScratch );245246// B = Y1^2247SymCryptModSquare( pmMod, peSrcY, peB, pbScratch, cbScratch );248249// C1 = Z1^2250SymCryptModSquare( pmMod, peSrcZ, peC, pbScratch, cbScratch );251252// C = C1 + C1 = Z1^2 + Z1^2 = 2 * Z1^2253SymCryptModAdd( pmMod, peC, peC, peC, pbScratch, cbScratch );254255// D = a * A256SymCryptModMul( pmMod, pCurve->A, peA, peD, pbScratch, cbScratch );257258// E1 = X1 + Y1259SymCryptModAdd( pmMod, peSrcX, peSrcY, peE, pbScratch, cbScratch );260261// E2 = E1^2 = (X1 + Y1)^2262SymCryptModSquare( pmMod, peE, peE, pbScratch, cbScratch );263264// E3 = E2 - A = (X1 + Y1)^2 - A265SymCryptModSub( pmMod, peE, peA, peE, pbScratch, cbScratch );266267// E = E3 - B = (X1 + Y1)^2 - A - B268SymCryptModSub( pmMod, peE, peB, peE, pbScratch, cbScratch );269270// G = D + B271SymCryptModAdd( pmMod, peD, peB, peG, pbScratch, cbScratch );272273// F = G - C274SymCryptModSub( pmMod, peG, peC, peF, pbScratch, cbScratch );275276// H = D - B277SymCryptModSub( pmMod, peD, peB, peH, pbScratch, cbScratch );278279// X3 = E * F280SymCryptModMul( pmMod, peE, peF, peDstX, pbScratch, cbScratch );281282// Y3 = G * H283SymCryptModMul( pmMod, peG, peH, peDstY, pbScratch, cbScratch );284285// T3 = E * H286SymCryptModMul( pmMod, peE, peH, peDstT, pbScratch, cbScratch );287288// Z3 = F * G289SymCryptModMul( pmMod, peF, peG, peDstZ, pbScratch, cbScratch );290}291292293//294// Point addition: add-2008-hwcd 11Mul + 3add + 4sub295//296// poDst(X, Y, Z, T) = poSrc(X, Y, Z, T) + poSrc2(X, Y, Z, T)297// 1. A = X1 * X2298// 2. B = Y1 * Y2299// 3. C = d * T1 * T2300// 4. D = Z1 * Z2301// 5. E = (X1 + Y1) * (X2 + Y2) - A - B302// 6. F = D - C303// 7. G = D + C304// 8. H = B - a * A305// 9. X3 = E * F306// 10. Y3 = G * H307// 11. T3 = E * H308// 12. Z3 = F * G309//310VOID311SYMCRYPT_CALL312SymCryptTwistedEdwardsAdd(313_In_ PCSYMCRYPT_ECURVE pCurve,314_In_ PCSYMCRYPT_ECPOINT poSrc1,315_In_ PCSYMCRYPT_ECPOINT poSrc2,316_Out_ PSYMCRYPT_ECPOINT poDst,317UINT32 flags,318_Out_writes_bytes_( cbScratch )319PBYTE pbScratch,320SIZE_T cbScratch )321{322PSYMCRYPT_MODELEMENT peTemp[8];323PSYMCRYPT_MODULUS pmMod = pCurve->FMod;324SIZE_T nBytes;325326SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );327SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc1->pCurve) && SymCryptEcurveIsSame(pCurve, poSrc2->pCurve) && SymCryptEcurveIsSame(pCurve, poDst->pCurve) );328SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );329330UNREFERENCED_PARAMETER( flags );331332nBytes = SymCryptSizeofModElementFromModulus( pmMod );333334SYMCRYPT_ASSERT( cbScratch >= 8*nBytes );335336for (UINT32 i = 0; i < 8; ++i)337{338peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );339pbScratch += nBytes;340cbScratch -= nBytes;341}342343PSYMCRYPT_MODELEMENT peSrc1X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc1 );344PSYMCRYPT_MODELEMENT peSrc1Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc1 );345PSYMCRYPT_MODELEMENT peSrc1Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc1 );346PSYMCRYPT_MODELEMENT peSrc1T = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poSrc1 );347348PSYMCRYPT_MODELEMENT peSrc2X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc2 );349PSYMCRYPT_MODELEMENT peSrc2Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc2 );350PSYMCRYPT_MODELEMENT peSrc2Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc2 );351PSYMCRYPT_MODELEMENT peSrc2T = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poSrc2 );352353PSYMCRYPT_MODELEMENT peDstX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poDst );354PSYMCRYPT_MODELEMENT peDstY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poDst );355PSYMCRYPT_MODELEMENT peDstZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poDst );356PSYMCRYPT_MODELEMENT peDstT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poDst );357358PSYMCRYPT_MODELEMENT peA = peTemp[0];359PSYMCRYPT_MODELEMENT peB = peTemp[1];360PSYMCRYPT_MODELEMENT peC = peTemp[2];361PSYMCRYPT_MODELEMENT peD = peTemp[3];362PSYMCRYPT_MODELEMENT peE = peTemp[4];363PSYMCRYPT_MODELEMENT peF = peTemp[5];364PSYMCRYPT_MODELEMENT peG = peTemp[6];365PSYMCRYPT_MODELEMENT peH = peTemp[7];366367// A = X1 * X2368SymCryptModMul( pmMod, peSrc1X, peSrc2X, peA, pbScratch, cbScratch );369370// B = Y1 * Y2371SymCryptModMul( pmMod, peSrc1Y, peSrc2Y, peB, pbScratch, cbScratch );372373// C1 = T1 * T2374SymCryptModMul( pmMod, peSrc1T, peSrc2T, peC, pbScratch, cbScratch );375376// C = d * C1 = d * T1 * T2377SymCryptModMul( pmMod, pCurve->B, peC, peC, pbScratch, cbScratch );378379// D = Z1 * Z2380SymCryptModMul( pmMod, peSrc1Z, peSrc2Z, peD, pbScratch, cbScratch );381382// E1 = X1 + Y1383SymCryptModAdd( pmMod, peSrc1X, peSrc1Y, peE, pbScratch, cbScratch );384385// E2 = X2 + Y2386SymCryptModAdd( pmMod, peSrc2X, peSrc2Y, peF, pbScratch, cbScratch );387388// E = E * F389SymCryptModMul( pmMod, peE, peF, peE, pbScratch, cbScratch );390391// E = E - A392SymCryptModSub( pmMod, peE, peA, peE, pbScratch, cbScratch );393394// E = E - B395SymCryptModSub( pmMod, peE, peB, peE, pbScratch, cbScratch );396397// F = D - C398SymCryptModSub( pmMod, peD, peC, peF, pbScratch, cbScratch );399400// G = D + C401SymCryptModAdd( pmMod, peD, peC, peG, pbScratch, cbScratch );402403// H = a * A404SymCryptModMul( pmMod, pCurve->A, peA, peH, pbScratch, cbScratch );405406// H = B - a * A407SymCryptModSub( pmMod, peB, peH, peH, pbScratch, cbScratch );408409// X3 = E * F410SymCryptModMul( pmMod, peE, peF, peDstX, pbScratch, cbScratch );411412// Y3 = G * H413SymCryptModMul( pmMod, peG, peH, peDstY, pbScratch, cbScratch );414415// T3 = E * H416SymCryptModMul( pmMod, peE, peH, peDstT, pbScratch, cbScratch );417418// Y3 = F * G419SymCryptModMul( pmMod, peF, peG, peDstZ, pbScratch, cbScratch );420}421422VOID423SYMCRYPT_CALL424SymCryptTwistedEdwardsAddDiffNonZero(425_In_ PCSYMCRYPT_ECURVE pCurve,426_In_ PCSYMCRYPT_ECPOINT poSrc1,427_In_ PCSYMCRYPT_ECPOINT poSrc2,428_Out_ PSYMCRYPT_ECPOINT poDst,429_Out_writes_bytes_(cbScratch)430PBYTE pbScratch,431SIZE_T cbScratch )432{433SymCryptTwistedEdwardsAdd( pCurve, poSrc1, poSrc2, poDst, 0, pbScratch, cbScratch );434}435436//437// Verify poSrc1(X1, Y1, Z1, T1) = poSrc2(X2, Y2, Z2, T2)438// To avoid ModInv for 1/Z, we do439// X1 * Z2 = X2 * Z1, and440// Y1 * Z2 = Y2 * Z1441//442// This function also do poSrc1 = -1 * poSrc check as flags indicates443//444UINT32445SYMCRYPT_CALL446SymCryptTwistedEdwardsIsEqual(447_In_ PCSYMCRYPT_ECURVE pCurve,448_In_ PCSYMCRYPT_ECPOINT poSrc1,449_In_ PCSYMCRYPT_ECPOINT poSrc2,450UINT32 flags,451_Out_writes_bytes_(cbScratch)452PBYTE pbScratch,453SIZE_T cbScratch)454{455PSYMCRYPT_MODELEMENT peTemp[2];456PSYMCRYPT_MODELEMENT peSrc1X, peSrc1Y, peSrc1Z;457PSYMCRYPT_MODELEMENT peSrc2X, peSrc2Y, peSrc2Z;458PSYMCRYPT_MODULUS pmMod = pCurve->FMod;459SIZE_T nBytes;460UINT32 dResX = 0;461UINT32 dResXN = 0;462UINT32 dResY = 0;463464SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );465SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc1->pCurve) && SymCryptEcurveIsSame(pCurve, poSrc2->pCurve) );466SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );467468nBytes = SymCryptSizeofModElementFromModulus( pmMod );469470SYMCRYPT_ASSERT( cbScratch >= 2*nBytes );471472for (UINT32 i = 0; i < 2; ++i)473{474peTemp[i] = SymCryptModElementCreate( pbScratch, nBytes, pmMod );475pbScratch += nBytes;476cbScratch -= nBytes;477}478479peSrc1X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc1 );480peSrc1Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc1 );481peSrc1Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc1 );482483peSrc2X = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poSrc2 );484peSrc2Y = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poSrc2 );485peSrc2Z = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poSrc2 );486487// Setting the default flag if flags == 0488flags |= (SYMCRYPT_MASK32_ZERO(flags) & SYMCRYPT_FLAG_ECPOINT_EQUAL);489490// peTemp[0] = X1 * Z2491SymCryptModMul( pmMod, peSrc1X, peSrc2Z, peTemp[0], pbScratch, cbScratch );492493// peTemp[1] = X2 * Z1494SymCryptModMul( pmMod, peSrc2X, peSrc1Z, peTemp[1], pbScratch, cbScratch );495496dResX = SymCryptModElementIsEqual( pmMod, peTemp[0], peTemp[1] );497498// Neg peTemp[1]499SymCryptModNeg(pmMod, peTemp[1], peTemp[1], pbScratch, cbScratch);500dResXN = SymCryptModElementIsEqual(pmMod, peTemp[0], peTemp[1]);501502// peTemp[0] = Y1 * Z2503SymCryptModMul( pmMod, peSrc1Y, peSrc2Z, peTemp[0], pbScratch, cbScratch );504505// peTemp[1] = Y2 * Z1506SymCryptModMul( pmMod, peSrc2Y, peSrc1Z, peTemp[1], pbScratch, cbScratch );507508dResY = SymCryptModElementIsEqual( pmMod, peTemp[0], peTemp[1] );509510return (SYMCRYPT_MASK32_NONZERO( flags & SYMCRYPT_FLAG_ECPOINT_EQUAL ) & dResX & dResY ) |511(SYMCRYPT_MASK32_NONZERO( flags & SYMCRYPT_FLAG_ECPOINT_NEG_EQUAL ) & dResXN & dResY );512}513514VOID515SYMCRYPT_CALL516SymCryptTwistedEdwardsSetZero(517_In_ PCSYMCRYPT_ECURVE pCurve,518_Out_ PSYMCRYPT_ECPOINT poDst,519_Out_writes_bytes_(cbScratch)520PBYTE pbScratch,521SIZE_T cbScratch)522{523SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );524SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poDst->pCurve) );525SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );526527PSYMCRYPT_MODULUS pmMod = pCurve->FMod;528529PSYMCRYPT_MODELEMENT peDstX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0, pCurve, poDst );530PSYMCRYPT_MODELEMENT peDstY = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 1, pCurve, poDst );531PSYMCRYPT_MODELEMENT peDstZ = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 2, pCurve, poDst );532PSYMCRYPT_MODELEMENT peDstT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3, pCurve, poDst );533534SymCryptModElementSetValueUint32( 0, pmMod, peDstX, pbScratch, cbScratch );535SymCryptModElementSetValueUint32( 1, pmMod, peDstY, pbScratch, cbScratch );536SymCryptModElementSetValueUint32( 1, pmMod, peDstZ, pbScratch, cbScratch );537SymCryptModElementSetValueUint32( 0, pmMod, peDstT, pbScratch, cbScratch );538}539540VOID541SYMCRYPT_CALL542SymCryptTwistedEdwardsNegate(543_In_ PCSYMCRYPT_ECURVE pCurve,544_Inout_ PSYMCRYPT_ECPOINT poSrc,545UINT32 mask,546_Out_writes_bytes_( cbScratch )547PBYTE pbScratch,548SIZE_T cbScratch )549{550PCSYMCRYPT_MODULUS FMod = pCurve->FMod;551PSYMCRYPT_MODELEMENT peX = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 0,pCurve, poSrc);552PSYMCRYPT_MODELEMENT peT = SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( 3,pCurve, poSrc);553554PSYMCRYPT_MODELEMENT peTmp = NULL;555556SYMCRYPT_ASSERT( SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE(pCurve) );557SYMCRYPT_ASSERT( SymCryptEcurveIsSame(pCurve, poSrc->pCurve) );558SYMCRYPT_ASSERT( cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->FModDigits ) + pCurve->cbModElement );559560peTmp = SymCryptModElementCreate(561pbScratch,562pCurve->cbModElement,563FMod );564SYMCRYPT_ASSERT( peTmp != NULL);565566pbScratch += pCurve->cbModElement;567cbScratch -= pCurve->cbModElement;568569SymCryptModNeg( FMod, peX, peTmp, pbScratch, cbScratch );570SymCryptModElementMaskedCopy( FMod, peTmp, peX, mask );571572SymCryptModNeg( FMod, peT, peTmp, pbScratch, cbScratch );573SymCryptModElementMaskedCopy( FMod, peTmp, peT, mask );574}575576577