int SetupDHAgreement (unsigned char *publicValue, unsigned char *privateValue, unsigned int privateValueLen, DH_KEY *params, R_RANDOM_STRUCT *randomStruct) { int status; UINT4 g[MAX_DIGITS_LEN], p[MAX_DIGITS_LEN], x[MAX_DIGITS_LEN], y[MAX_DIGITS_LEN]; unsigned int pDigits, xDigits; BIGNUM_Decode (p, MAX_DIGITS_LEN, params->prime, params->primeLen); pDigits = BIGNUM_Digits (p, MAX_DIGITS_LEN); BIGNUM_Decode (g, pDigits, params->generator, params->generatorLen); /* Generate private value. */ status = GenerateBytes (privateValue, privateValueLen, randomStruct); if (0 != status) return (status); BIGNUM_Decode (x, pDigits, privateValue, privateValueLen); xDigits = BIGNUM_Digits (x, pDigits); /* Compute y = g^x mod p. */ BIGNUM_ModExp (y, g, x, xDigits, p, pDigits); BIGNUM_Encode (publicValue, params->primeLen, y, pDigits); /* Zeroize sensitive information. */ memset ((POINTER)x, 0, sizeof (x)); return (0); }
/* * Pseudorandomly generate a mpz number of exactly k bits */ u32 GenerateNumber ( u32 k, /* desired bit length of number */ mpz_t n, /* number to generate pseudorandomly */ RANDOM_STRUCT *r /* PRNG */ ) { u8 *buffer; u32 bufferlen; u32 e, c; if (r == NULL) return PRNG_NOT_INIT; /* Assert (n is initialized by caller) */ /* buffer to store pseudorandom bytes */ bufferlen = ceil (k/8.0); if ((buffer = (u8 *)malloc(bufferlen)) == NULL) { fprintf (stderr, "error in GenerateNumber: out of memory,\n"); exit(1); } /* * Generate number */ c = GenerateBytes (buffer, bufferlen, r); if (c != PRNG_NO_ERROR) return c; /* if k is not a multiple of 8, clear the unwanted most significant bits * Set most significant bit to 1 so it is exactly k bit long. */ if ( (e=(k % 8)) > 0 ) { buffer[0] &= 0xFF >> (8-e); buffer[0] |= 0x01 << (e-1); } else
/* PSEC-KEM key encapsulation mechanism Return: TRUE if succeed; otherwise FALSE */ u8 PSEC_KEM_KEM( PSEC_KEM_PUB_KEY *publicKey, /* PSEC_KEM public key */ PSEC_KEM_KEY_ENCAPSULATION *keyEncapsulation, /* returned keyEncapsulation */ PSEC_KEM_KEY_MATERIAL *keyMaterial, /* returned key material */ EC_PARAM *E, PSEC_KEM_EC_ENCODING_FORMAT format ) { mpz_t s, u, res, v; u8 *s_raw, *u_raw, *t_raw, *mgf_arg_1, *mgf_arg_2, *res_raw, *v_raw, *PEH_raw; u8 *EG_raw; s32 i; u32 hoLen, uoLen, EGoLen, PEHoLen, qoLen; EC_POINT h_tilde, g_tilde; mpz_init(s); mpz_init(u); mpz_init(res); mpz_init(v); hoLen = (publicKey->hLen) >> 3; uoLen = (u32)ceil(E->pLen/8.0) + 16; keyMaterial->KoLen = (publicKey->outputKeyLen) >> 3; qoLen = (u32)ceil(E->qLen/8.0); if (format == COMPRESSED) { EGoLen = 1 + qoLen; PEHoLen = 1 + qoLen; } else { EGoLen = 1 + 2*qoLen; PEHoLen = 1 + 2*qoLen; } if ((publicKey->pk).inf_id == EC_O) PEHoLen = 1; if ((E->P).inf_id == EC_O) EGoLen = 1; #ifdef DEBUG printf("hoLen = %u\n", hoLen); printf("uoLen = %u\n", uoLen); printf("keyMaterial->KoLen = %u\n", keyMaterial->KoLen); printf("EGoLen = %u\n", EGoLen); printf("PEHoLen = %u\n", PEHoLen); #endif EC_initPoint ( &h_tilde ); EC_initPoint ( &g_tilde); s_raw = (BYTE *) malloc (hoLen); u_raw = (BYTE *) malloc (uoLen); t_raw = (BYTE *) malloc (uoLen + keyMaterial->KoLen); mgf_arg_1 = (u8 *) malloc (4 + hoLen); mgf_arg_2 = (u8 *) malloc (4 + EGoLen + PEHoLen); res_raw = (u8 *) malloc (hoLen); v_raw = (u8 *) malloc (hoLen); PEH_raw = (u8 *) malloc (PEHoLen); EG_raw = (u8 *) malloc (EGoLen); /* generate s */ GenerateBytes(s_raw, hoLen, global_prng); BYTE2WORD (s, s_raw, hoLen); #ifdef DEBUG printf("s = 0x%s\n", mpz_get_str(NULL, 16, s)); printf("\n"); fflush(stdout); #endif /* compute t = MGF1(0 || s) */ U32TO8_BIG(mgf_arg_1, 0L); memcpy(mgf_arg_1+4, s_raw, hoLen); MGF1( t_raw, 8 * (uoLen + keyMaterial->KoLen), mgf_arg_1, 4 + hoLen); #ifdef DEBUG printf("t = "); printAsHex(t_raw, uoLen+keyMaterial->KoLen); printf("\n"); fflush(stdout); #endif /* parse t as t = u || K */ memcpy( u_raw, t_raw, uoLen ); BYTE2WORD( u, u_raw, uoLen ); memcpy( keyMaterial->K_raw, t_raw+uoLen, keyMaterial->KoLen ); #ifdef DEBUG printf("u = 0x%s\n", mpz_get_str(NULL, 16, u)); printf("keyMaterial = "); printAsHex(keyMaterial->K_raw, keyMaterial->KoLen); printf("\n"); fflush(stdout); #endif /* compute h_tilde = u * publicKey->pk */ EC_Mult( &h_tilde, u, &(publicKey->pk), E ); ec2os (PEH_raw, &h_tilde, E, format); #ifdef DEBUG printf("h_tilde.x = 0x%s\n", mpz_get_str(NULL, 16, h_tilde.x)); printf("h_tilde.y = 0x%s\n", mpz_get_str(NULL, 16, h_tilde.y)); printf("PEH = "); printAsHex(PEH_raw, PEHoLen); printf("\n"); fflush(stdout); #endif /* compute g_tilde = u * E->P */ EC_Mult( &g_tilde, u, &(E->P), E ); #ifdef DEBUG printf("g_tilde.x = 0x%s\n", mpz_get_str(NULL, 16, g_tilde.x)); printf("g_tilde.y = 0x%s\n", mpz_get_str(NULL, 16, g_tilde.y)); printf("g_tilde.inf_id = %u\n", g_tilde.inf_id); #endif /* convert g_tilde's EC point to an octet string according to P1363 E.2.3.2 */ ec2os( EG_raw, &g_tilde, E, format); #ifdef DEBUG printf("EG = "); printAsHex(EG_raw, EGoLen); printf("\n"); fflush(stdout); #endif /* compute res = MGF1( 1 || EG || PEH ) */ U32TO8_BIG ( mgf_arg_2, 1L ); memcpy( mgf_arg_2 + 4, EG_raw, EGoLen ); memcpy( mgf_arg_2 + 4 + EGoLen, PEH_raw, PEHoLen ); MGF1( res_raw, publicKey->hLen, mgf_arg_2, 4 + EGoLen + PEHoLen); BYTE2WORD( res, res_raw, hoLen); #ifdef DEBUG printf("res = 0x%s\n", mpz_get_str(NULL, 16, res)); printf("\n"); fflush(stdout); #endif /* compute v = s \xor res */ mpz_xor(v, s, res); WORD2BYTE(v_raw, v, hoLen); #ifdef DEBUG printf("v = 0x%s\n", mpz_get_str(NULL, 16, v)); printf("\n"); fflush(stdout); #endif /* output C0 = EG || v */ memcpy( keyEncapsulation->C0, EG_raw, EGoLen); memcpy( keyEncapsulation->C0 + EGoLen, v_raw, hoLen); #ifdef DEBUG printf("C0 = "); printAsHex(keyEncapsulation->C0, keyEncapsulation->C0oLen); printf("\n"); fflush(stdout); #endif /* clean up */ mpz_clear(s); mpz_clear(u); mpz_clear(res); mpz_clear(v); memset(s_raw, 0, hoLen); memset(u_raw, 0, uoLen); memset(t_raw, 0, uoLen + keyMaterial->KoLen); memset(mgf_arg_1, 0, 4+hoLen); memset(mgf_arg_2, 0, 4 + EGoLen + PEHoLen); memset(res_raw, 0, hoLen); memset(v_raw, 0, hoLen); memset(PEH_raw, 0, PEHoLen); memset(EG_raw, 0, EGoLen); free(s_raw); free(u_raw); free(t_raw); free(mgf_arg_1); free(mgf_arg_2); free(res_raw); free(v_raw); free(PEH_raw); free(EG_raw); EC_clearPoint ( &h_tilde ); EC_clearPoint ( &g_tilde ); return TRUE; }