VOID generateDlGroups()

in unittest/lib/testDh.cpp [165:316]


VOID generateDlGroups()
{
    // Fill up our array of key blobs with generated keys
    UINT32 desiredFixedGroupSizes[] = {
        (4096 << 16) + 1, // 1 keys of 4096 bits
        (3072 << 16) + 2, // 2 keys of 3072 bits
        (2048 << 16) + 5,
        (1536 << 16) + 2,
        (1024 << 16) + 5,
        (768  << 16) + 2,
        (512  << 16) + 2,
        0,
        };
    UINT32 bitSize;
    UINT32 primResult;

    char * sep = " [group safeprime:";
    UINT32 previousSize = 0;

    if( g_nDlgroups >= MAX_TEST_DLGROUPS )
    {
        goto cleanup;
    }

    for( int i = 0; i<ARRAY_SIZE(g_safePrimeTypes); i++)
    {
        SYMCRYPT_ERROR scError;
        SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE eDhSafePrimeType = g_safePrimeTypes[i];

        iprint( sep );
        switch(eDhSafePrimeType)
        {
        case SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_IKE_3526:
            sep = " IKE";
            break;
        case SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_TLS_7919:
            sep = " TLS";
            break;
        default:
            sep = " ???";
            break;
        }

        UINT32 maxBitSize = g_maxSafePrimeGroupBitSize;
        while( TRUE )
        {
            PSYMCRYPT_DLGROUP pGroup = SymCryptDlgroupAllocate( maxBitSize, maxBitSize );
            CHECK( pGroup != NULL, "?" );

            scError = SymCryptDlgroupSetValueSafePrime( eDhSafePrimeType, pGroup );
            // Assume we've reached the minimum supported size
            if( scError == SYMCRYPT_INVALID_ARGUMENT )
            {
                SymCryptDlgroupFree( pGroup );
                break;
            }

            CHECK( scError == SYMCRYPT_NO_ERROR, "Error setting DL safe-prime group" );

            CHECK(pGroup->isSafePrimeGroup, "DL safe-prime group initialized incorrectly")
            CHECK(pGroup->nBitsOfP <= maxBitSize,   "DL safe-prime group P is wrong size");
            CHECK(pGroup->nBitsOfQ <= maxBitSize-1, "DL safe-prime group Q is wrong size");

            iprint( "%s%d", sep, pGroup->nBitsOfP );
            sep = ",";
            maxBitSize = pGroup->nBitsOfP-1;

            // Check that the constants selected by SetValueSafePrime are indeed prime
            primResult = SymCryptIntMillerRabinPrimalityTest(
                SymCryptIntFromModulus( pGroup->pmP ),
                pGroup->nBitsOfP,
                8, // nIterations - reduce runtime overhead as this should always pass
                SYMCRYPT_FLAG_DATA_PUBLIC, //flags
                g_dlGroupScratch,
                SYMCRYPT_SCRATCH_BYTES_FOR_INT_IS_PRIME( pGroup->pmP->nDigits ) );
            CHECK(primResult != 0, "Primality test failed for DL safe-prime group P");

            primResult = SymCryptIntMillerRabinPrimalityTest(
                SymCryptIntFromModulus( pGroup->pmQ ),
                pGroup->nBitsOfQ,
                8, // nIterations - reduce runtime overhead as this should always pass
                SYMCRYPT_FLAG_DATA_PUBLIC, //flags
                g_dlGroupScratch,
                SYMCRYPT_SCRATCH_BYTES_FOR_INT_IS_PRIME( pGroup->pmQ->nDigits ) );
            CHECK(primResult != 0, "Primality test failed for DL safe-prime group Q");

            // Need to enable DH keypairs larger than 4096b in CNG before testing with these groups
            if (pGroup->nBitsOfP <= 4096)
            {
                g_nDhNamedGroups++;
                addDlgroupToGlobalTestBlobArray( pGroup->nBitsOfP, pGroup );
            }
            else
            {
                SymCryptDlgroupFree( pGroup );
            }
        }
    }

    sep = "]\n     [group gen: ";

    for( int i = 0; desiredFixedGroupSizes[i] != 0; i++ )
    {
        bitSize = desiredFixedGroupSizes[i] >> 16;
        int n = desiredFixedGroupSizes[i] & 0xff;
        while( n-- && g_nDlgroups < MAX_TEST_DLGROUPS )
        {
            if( bitSize == previousSize )
            {
                iprint( "." );
            } else {
                iprint( "%s%d", sep, bitSize );
                sep = ",";
                previousSize = bitSize;
            }

            addOneDlgroup( bitSize, FALSE );
        }
    }

    // And we fill the rest with randomly-sized keys
    // For performance we favor the smaller key sizes.
    while( g_nDlgroups < MAX_TEST_DLGROUPS )
    {
        UINT32 r = g_rng.uint32();
        // We use prime moduli as they are almost independent
        if( (r % 51) == 0 )
        {
            bitSize = (UINT32) g_rng.sizet( 2048, 4096 );
        } else if ( (r % 5) == 0 ) {
            bitSize = (UINT32) g_rng.sizet( 1024, 2049 );
        } else {
            bitSize = (UINT32) g_rng.sizet( 512, 1025 );
        }

        if( bitSize == previousSize )
        {
            iprint( "." );
        } else {
            iprint( "%s%d", sep, bitSize );
            sep = ",";
            previousSize = bitSize;
        }

        addOneDlgroup( bitSize, TRUE );
    }

    iprint( "]" );

cleanup:
    return;
}