static char * rw_serialize_pub (const dckey *key) { const rw_pub *pk = (const rw_pub *) key; char *res = NULL; if (cat_str (&res, rabin_1.name) || cat_str (&res, ":Pub,n=") || cat_mpz (&res, pk->n)) { free (res); res = NULL; } return res; }
static char * rw_encrypt (const dckey *key, const char *msg) { const rw_pub *pk = (const rw_pub *) key; mpz_t m; char *res = NULL; mpz_init (m); if (pre_encrypt (m, msg, pk->nbits)) { mpz_clear (m); return NULL; } E1 (m, m, pk->n); E2 (m, m, pk->n); cat_mpz (&res, m); mpz_clear (m); return res; }
static char * rw_sign (const dckey *key, const char *msg) { const rw_priv *sk = k2priv (key); sha1_ctx sc; mpz_t m; char *res = NULL; mpz_init (m); sha1_init (&sc); sha1_update (&sc, msg, strlen (msg)); if (pre_sign (m, &sc, sk->nbits)) { mpz_clear (m); return NULL; } E1 (m, m, sk->n); D2 (m, m, sk, prng_getword ()); cat_mpz (&res, m); mpz_clear (m); return res; }
void nidh (dckey *priv, dckey *pub, char *priv_id, char *pub_id, char *label) { rawpub rpub; rawpriv rpriv; int reserve; /* Let's name it that! */ /* step 0: check that the private and public keys are compatible, i.e., they use the same group parameters */ if ((-1 == get_rawpub (&rpub, pub)) || (-1 == get_rawpriv (&rpriv, priv))) { printf ("%s: trouble importing GMP values from ElGamal-like keys\n", getprogname ()); printf ("priv:\n%s\n", dcexport_priv (priv)); printf ("pub:\n%s\n", dcexport_pub (pub)); exit (-1); } else if (mpz_cmp (rpub.p, rpriv.p) || mpz_cmp (rpub.q, rpriv.q) || mpz_cmp (rpub.g, rpriv.g)) { printf ("%s: the private and public keys are incompatible\n", getprogname ()); printf ("priv:\n%s\n", dcexport_priv (priv)); printf ("pub:\n%s\n", dcexport_pub (pub)); exit (-1); } else { /* step 1a: compute the Diffie-Hellman secret (use mpz_init, mpz_powm, mpz_clear; look at elgamal.c in the libdcrypt source directory for sample usage */ char *Diffie_Hellman_Secret_String = 0; { mpz_t dhSecretInt; mpz_init(dhSecretInt); mpz_powm(dhSecretInt, rpub.y, rpriv.x, rpub.p); reserve = cat_mpz(&Diffie_Hellman_Secret_String, dhSecretInt); /* EC need 0; MALLOC */ mpz_clear(dhSecretInt); if (reserve) { free(Diffie_Hellman_Secret_String); printf("error allocating memory\n"); exit(1); } /* printf("Diffie_Hellman_Secret_String: %s\n",Diffie_Hellman_Secret_String); */ } /* step 1b: order the IDs lexicographically */ char *firstId = NULL, *secondId = NULL; if (strcmp (priv_id, pub_id) < 0) { firstId = priv_id; secondId = pub_id; } else { firstId = pub_id; secondId = priv_id; } /* step 1c: hash DH secret and ordered id pair into a master key */ char key_master[20]; { sha1_ctx shaCipherText; sha1_init(&shaCipherText); sha1_update(&shaCipherText, Diffie_Hellman_Secret_String, strlen(Diffie_Hellman_Secret_String)); char *id12; size_t len1, len2; len1 = strlen(firstId); len2 = strlen(secondId); id12 = (char*)malloc(len1+len2+1); /* +1 for \0 */ strcpy(id12, firstId); strcat(id12, secondId); assert(strlen(id12) == len1+len2); sha1_update(&shaCipherText, id12, len1+len2); free(id12); sha1_final(&shaCipherText, (void*)key_master); /*20 bytes*/ } /* step 2: derive the shared key from the label and the master key */ /*I will work with minimum requirement satisfaction model. Thanks to the open source community for providing me with enough reasoning for that.*/ char sizeofkey[32]; { char sizeofkey_0[20]; size_t len0 = strlen(label)+7; char *label0 = (char*)malloc(len0); strcpy(label0, label); strcat(label0, "AES-CTR"); hmac_sha1(key_master, 20, sizeofkey_0, label0, len0); free(label0); char sizeofkey_1[20]; size_t len1 = strlen(label)+9; char *label1 = (char*)malloc(len1); strcpy(label1, label); strcat(label1, "CBC-MAC"); hmac_sha1(key_master, 20, sizeofkey_1, label1, len1); free(label1); strncpy(sizeofkey, sizeofkey_0, 16); strncpy(sizeofkey+16, sizeofkey_1, 16); } /* step 3: armor the shared key and write it to file. Filename should be of the form <label>-<priv_id>.b64 size_t fn_len = strlen(label)+1+strlen(priv_id)+1+strlen(pub_id)+4+1; */ char *fn = (char *) malloc(32); fn = armor64(sizeofkey, 32); *(fn + 32) = '\0'; int fdsk; fdsk = open (label, O_WRONLY|O_TRUNC|O_CREAT, 0600); int status; status = write (fdsk, fn, strlen (fn)); printf("value of status: %d\n", status); status = write (fdsk, "\n", 1); printf("value of status: %d\n", status); free (fn); close (fdsk); } }