CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(ab, primeLen) ); CHECK_MPI_OK( mp_read_unsigned_octets(&a, ab, primeLen) );  CHECK_MPI_OK( mp_mod(&a, &psub1, &a) );  if ( mp_cmp_d(&a, 2) < 0) continue;
if ( mp_cmp_d(&a, 2) < 0 || mp_cmp(&a, &psub1) >= 0) {  mp_set(&a, 3); }
DH_GenParam(int primeLen, DHParams **params){    PRArenaPool *arena;    DHParams *dhparams;    unsigned char *pb = NULL;    unsigned char *ab = NULL;    unsigned long counter = 0;    mp_int p, q, a, h, psub1, test;    mp_err err = MP_OKAY;    SECStatus rv = SECSuccess;    if (!params || primeLen < 0) {	PORT_SetError(SEC_ERROR_INVALID_ARGS);	return SECFailure;    }    arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);    if (!arena) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	return SECFailure;    }    dhparams = (DHParams *)PORT_ArenaAlloc(arena, sizeof(DHParams));    if (!dhparams) {	PORT_SetError(SEC_ERROR_NO_MEMORY);	PORT_FreeArena(arena, PR_TRUE);	return SECFailure;    }    dhparams->arena = arena;    MP_DIGITS(&p) = 0;    MP_DIGITS(&q) = 0;    MP_DIGITS(&a) = 0;    MP_DIGITS(&h) = 0;    MP_DIGITS(&psub1) = 0;    MP_DIGITS(&test) = 0;    CHECK_MPI_OK( mp_init(&p) );    CHECK_MPI_OK( mp_init(&q) );    CHECK_MPI_OK( mp_init(&a) );    CHECK_MPI_OK( mp_init(&h) );    CHECK_MPI_OK( mp_init(&psub1) );    CHECK_MPI_OK( mp_init(&test) );    /* generate prime with MPI, uses Miller-Rabin to generate strong prime. */    pb = PORT_Alloc(primeLen);    CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(pb, primeLen) );    pb[0]          |= 0x80; /* set high-order bit */    pb[primeLen-1] |= 0x01; /* set low-order bit  */    CHECK_MPI_OK( mp_read_unsigned_octets(&p, pb, primeLen) );    CHECK_MPI_OK( mpp_make_prime(&p, primeLen * 8, PR_TRUE, &counter) );    /* construct Sophie-Germain prime q = (p-1)/2. */    CHECK_MPI_OK( mp_sub_d(&p, 1, &psub1) );    CHECK_MPI_OK( mp_div_2(&psub1, &q)    );    /* construct a generator from the prime. */    ab = PORT_Alloc(primeLen);    do {	/* generate a candidate number a in p's field */	CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(ab, primeLen) );	CHECK_MPI_OK( mp_read_unsigned_octets(&a, ab, primeLen) );	/* force a < P-1 */	CHECK_MPI_OK( mp_mod(&a, &psub1, &a) );	/* check that a is in the range [2..P-1] */	if ( mp_cmp_d(&a, 2) < 0) continue;	/* check that a**q mod p != 1 */	CHECK_MPI_OK( mp_exptmod(&a, &q, &p, &test) );    } while ( mp_cmp_d(&test, 1) == 0 );    /* a is a generator, finish up */    MPINT_TO_SECITEM(&p, &dhparams->prime, arena);    MPINT_TO_SECITEM(&a, &dhparams->base, arena);    *params = dhparams;cleanup:    mp_clear(&p);    mp_clear(&q);    mp_clear(&a);    mp_clear(&h);    mp_clear(&psub1);    mp_clear(&test);    if (pb) PORT_ZFree(pb, primeLen);    if (ab) PORT_ZFree(ab, primeLen);    if (err) {	MP_TO_SEC_ERROR(err);	rv = SECFailure;    }    if (rv)	PORT_FreeArena(arena, PR_TRUE);    return rv;}