int FMT_crypt_load(const char *fname, byte_string_t bs, const char *password) { FILE *infp; byte_string_t K, W; int result = 0; infp = fopen(fname, "r"); if (!infp) return 0; byte_string_set(K, password); advance_to("W:", infp); mime_get(W, infp); if (1 != crypto_decrypt(bs, W, K)) { fprintf(stderr, "crypto_decrypt() failed!\n"); } else { result = 1; } fclose(infp); byte_string_clear(K); byte_string_clear(W); return result; }
void byte_string_set_point(byte_string_t bs, point_t P) { byte_string_t bs1, bs2; byte_string_set_fp2(bs1, P->x); byte_string_set_fp2(bs2, P->y); byte_string_join(bs, bs1, bs2); byte_string_clear(bs1); byte_string_clear(bs2); }
void byte_string_set_fp2(byte_string_t bs, fp2_t x) { byte_string_t bs1, bs2; byte_string_set_mpz(bs1, x->a); byte_string_set_mpz(bs2, x->b); byte_string_join(bs, bs1, bs2); byte_string_clear(bs1); byte_string_clear(bs2); }
void point_set_byte_string(point_t P, byte_string_t bs) { byte_string_t bs1, bs2; byte_string_split(bs1, bs2, bs); fp2_set_byte_string(P->x, bs1); fp2_set_byte_string(P->y, bs2); byte_string_clear(bs1); byte_string_clear(bs2); }
void fp2_set_byte_string(fp2_t x, byte_string_t bs) { byte_string_t bs1, bs2; byte_string_split(bs1, bs2, bs); mympz_set_byte_string(x->a, bs1); mympz_set_byte_string(x->b, bs2); byte_string_clear(bs1); byte_string_clear(bs2); }
int FMT_crypt_save_fp(FILE *outfp, byte_string_t bs, const char *password) { byte_string_t K, W; byte_string_set(K, password); crypto_encrypt(W, bs, K); fprintf(outfp, "\nW:\n"); mime_put(W, outfp); byte_string_clear(K); byte_string_clear(W); return 1; }
int main(void) { char *id = "argp at domain cs.tcd.ie"; params_t params; byte_string_t U; byte_string_t secret; byte_string_t key; byte_string_t master; IBE_init(); IBE_setup(params, master, 512, 160, "test"); printf("system parameters generated!\n"); printf("IBE test program\n"); printf("Test ID: %s\n", id); printf("generating key...\n"); IBE_KEM_encrypt(secret, U, id, params); printf("U ="); byte_string_printf(U, " %02X"); printf("\n"); printf("secret ="); byte_string_printf(secret, " %02X"); printf("\n"); byte_string_clear(secret); printf("extracting...\n"); IBE_extract(key, master, id, params); printf("recovering secret...\n"); IBE_KEM_decrypt(secret, U, key, params); /* hopefully it will be the same as above */ printf("secret ="); byte_string_printf(secret, " %02X"); printf("\n"); params_clear(params); IBE_clear(); byte_string_clear(U); byte_string_clear(key); byte_string_clear(secret); byte_string_clear(master); return(0); }
int IBE_serialize_params(byte_string_t bs, params_t params) //put system parameters into a byte_string { int i, j; byte_string_t *bsa; i = 0; bsa = (byte_string_t *) malloc(sizeof(byte_string_t) * (2 * params->sharen + 20)); byte_string_set(bsa[i++], params->version); byte_string_set(bsa[i++], params->id); byte_string_set_mpz(bsa[i++], params->p); byte_string_set_mpz(bsa[i++], params->q); byte_string_set_point(bsa[i++], params->P); byte_string_set_point(bsa[i++], params->Ppub); byte_string_set_int(bsa[i++], params->sharet); byte_string_set_int(bsa[i++], params->sharen); for (j=0; j<params->sharen; j++) { byte_string_set_mpz(bsa[i++], params->robustx[j]); byte_string_set_point(bsa[i++], params->robustP[j]); } byte_string_encode_array(bs, bsa, i); for (j=0; j<i; j++) { byte_string_clear(bsa[j]); } return 1; }
int FMT_split_master(char **fname, byte_string_t master, int t, int n, params_t params) { int i; /* byte_string_t mshare[n]; */ byte_string_t *mshare; int result = 1; mshare = (byte_string_t *)malloc((sizeof(byte_string_t) * n)); IBE_split_master(mshare, master, t, n, params); for (i=0; i<n; i++) { if (1 != FMT_save_byte_string(fname[i], mshare[i])) { fprintf(stderr, "error writing to %s\n", fname[i]); result = 0; break; } } for (i=0; i<n; i++) { byte_string_clear(mshare[i]); } free(mshare); return result; }
int FMT_load_raw_byte_string(byte_string_t bs, char *file) //load a raw byte string from a file { int max = 1024; int len = 0; FILE *fp; fp = fopen(file, "r"); if (!fp) { return 0; } byte_string_init(bs, max); for(;;) { len += fread(&bs->data[len], 1, max - len, fp); if (len == max) { max *= 2; byte_string_reinit(bs, max); } else { if (!feof(fp)) { fclose(fp); byte_string_clear(bs); return 0; } fclose(fp); break; } } byte_string_reinit(bs, len); return 1; }
static void map_to_point(point_t d, const char *id, params_t params) //converts id into a point of order q on E/F_p { byte_string_t bsid; byte_string_set(bsid, id); map_byte_string_to_point(d, bsid, params); byte_string_clear(bsid); }
void IBE_extract(byte_string_t bs, byte_string_t master, const char *id, params_t params) //same as above, char * version { byte_string_t bsid; byte_string_set(bsid, id); IBE_extract_byte_string(bs, master, bsid, params); byte_string_clear(bsid); }
void IBE_extract_share(byte_string_t share, byte_string_t mshare, const char *id, params_t params) //same as above except takes in char * instead of byte_string { byte_string_t bsid; byte_string_set(bsid, id); IBE_extract_share_byte_string(share, mshare, bsid, params); byte_string_clear(bsid); }
int IBE_deserialize_params(params_t params, byte_string_t bs) //get system parameters from a byte_string { byte_string_t *bsa; int n; int i, j; byte_string_decode_array(&bsa, &n, bs); //TODO: check n is big enough i = 0; params->version = charstar_from_byte_string(bsa[i++]); params->id = charstar_from_byte_string(bsa[i++]); mpz_init(params->p); mpz_init(params->q); mympz_set_byte_string(params->p, bsa[i++]); mympz_set_byte_string(params->q, bsa[i++]); initpq(params); point_init(params->P); point_init(params->Ppub); point_set_byte_string(params->P, bsa[i++]); point_set_byte_string(params->Ppub, bsa[i++]); point_init(params->PhiPpub); point_Phi(params->PhiPpub, params->Ppub, params); params->sharet = int_from_byte_string(bsa[i++]); params->sharen = int_from_byte_string(bsa[i++]); params->robustx = (mpz_t *) malloc(params->sharen * sizeof(mpz_t)); params->robustP = (point_t *) malloc(params->sharen * sizeof(point_t)); for (j=0; j<params->sharen; j++) { mpz_init(params->robustx[j]); mympz_set_byte_string(params->robustx[j], bsa[i++]); //TODO: check it's different from others point_init(params->robustP[j]); point_set_byte_string(params->robustP[j], bsa[i++]); } point_mul_preprocess(params->P, params->curve); miller_cache_init(params->Ppub_mc, params->curve); tate_preprocess(params->Ppub_mc, params->Ppub, params->curve); for(i=0; i<n; i++) { byte_string_clear(bsa[i]); } free(bsa); return 1; }
void hash_H(byte_string_t md_value, fp2_t x, params_t params) //hash a point of E/F_p^2 to a byte_string { byte_string_t bs; byte_string_set_fp2(bs, x); crypto_hash(md_value, bs); byte_string_clear(bs); }
void hash_G(mpz_t h, byte_string_t bs, params_t params) //hash a byte_string to an element of Z_p { byte_string_t md_value; crypto_hash(md_value, bs); mympz_from_hash(h, params->p, md_value); byte_string_clear(md_value); }
int FMT_save_params(char *filename, params_t params) { int result; byte_string_t bs; IBE_serialize_params(bs, params); result = FMT_save_byte_string(filename, bs); byte_string_clear(bs); return result; }
void IBE_extract_share_byte_string(byte_string_t share, byte_string_t mshare, byte_string_t id, params_t params) //extract a private key share from an ID and master share { mpz_t y; int i; byte_string_t bs1, bs2; point_t yd; point_t d; point_init(yd); point_init(d); mpz_init(y); byte_string_split(bs1, bs2, mshare); i = int_from_byte_string(bs1); mympz_set_byte_string(y, bs2); byte_string_clear(bs1); byte_string_clear(bs2); map_byte_string_to_point(d, id, params); point_mul(yd, y, d, params->curve); byte_string_set_int(bs1, i); byte_string_set_point(bs2, yd); byte_string_join(share, bs1, bs2); byte_string_clear(bs1); byte_string_clear(bs2); point_clear(yd); point_clear(d); mpz_clear(y); }
int FMT_load_params(params_t params, char *filename) { byte_string_t bs; int result; result = FMT_load_byte_string(filename, bs); if (!result) { return 0; } result = IBE_deserialize_params(params, bs); byte_string_clear(bs); return result; }
int FMT_construct_master(byte_string_t master, char **fname, int t, params_t params) { int i; /* byte_string_t mshare[t]; */ byte_string_t *mshare; mshare = (byte_string_t *)malloc((sizeof(byte_string_t) * t)); for (i=0; i<t; i++) { if (1 != FMT_load_byte_string(fname[i], mshare[i])) { fprintf(stderr, "error loading %s\n", fname[i]); return 0; } } IBE_construct_master(master, mshare, params); for (i=0; i<t; i++) { byte_string_clear(mshare[i]); } free(mshare); return 1; }
void FMT_encrypt_stream_array(char **id, int idcount, FILE *infp, FILE *outfp, params_t params) { byte_string_t U, K; byte_string_t *V; unsigned char in[crypt_buf_size]; unsigned char *out; int inl, outl; crypto_ctx_t ctx; EVP_ENCODE_CTX mime; unsigned char data[1024]; int i; int count; out = (unsigned char *) alloca(crypt_buf_size + crypto_block_size()); V = (byte_string_t *) alloca(sizeof(byte_string_t) * idcount); fprintf(outfp, "\n-----BEGIN IBE-----\n"); crypto_generate_key(K); IBE_hide_key_array(U, V, id, idcount, K, params); fprintf(outfp, "\nU:\n"); mime_put(U, outfp); fprintf(outfp, "\n"); for (i=0; i<idcount; i++) { fprintf(outfp, "\nID:\n"); fprintf(outfp, "%s\n", id[i]); fprintf(outfp, "\nV:\n"); mime_put(V[i], outfp); fprintf(outfp, "\n"); byte_string_clear(V[i]); } fprintf(outfp, "\nW:\n"); crypto_ctx_init(ctx); crypto_encrypt_init(ctx, K); EVP_EncodeInit(&mime); for (;;) { inl = fread(in, 1, crypt_buf_size, infp); if (inl < 0) { fprintf(stderr, "read error\n"); exit(1); } crypto_encrypt_update(ctx, out, &outl, in, inl); EVP_EncodeUpdate(&mime, data, &count, out, outl); fwrite(data, 1, count, outfp); if (feof(infp)) break; } crypto_encrypt_final(ctx, out, &outl); crypto_ctx_clear(ctx); EVP_EncodeUpdate(&mime, data, &count, out, outl); fwrite(data, 1, count, outfp); EVP_EncodeFinal(&mime, data, &count); fwrite(data, 1, count, outfp); fprintf(outfp, "\n-----END IBE-----\n"); byte_string_clear(K); byte_string_clear(U); }
int main(int argc, char **argv) { char defaultcnffile[] = "gen.cnf"; char *cnffile; CONF_CTX *cnfctx; int t, n; int bits, qbits; char *systemid; char *paramsfile; char **sharefile; char *dfltlist[3]; char dl0[] = "share"; char dl1[] = "share2"; int i; byte_string_t master; params_t params; if (argc < 2) { cnffile = defaultcnffile; } else { cnffile = argv[1]; } cnfctx = LoadConfig(cnffile); if (!cnfctx) { fprintf(stderr, "error opening %s\n", cnffile); fprintf(stderr, "using default values\n"); cnfctx = constructCTX(); //exit(1); } t = GetIntParam(cnfctx, "threshold", 0, 2); n = GetIntParam(cnfctx, "shares", 0, 2); bits = GetIntParam(cnfctx, "pbits", 0, 1024); qbits = GetIntParam(cnfctx, "qbits", 0, 160); systemid = GetStringParam(cnfctx, "system", 0, "noname"); paramsfile = GetPathParam(cnfctx, "params", 0, "params.txt"); dfltlist[0] = dl0; dfltlist[1] = dl1; sharefile = GetListParam(cnfctx, "sharefiles", 0, dfltlist); printf("Generating IBE public parameters and secret...\n"); printf("Parameters:\n"); printf("system name: %s\n", systemid); printf("params file: %s\n", paramsfile); printf("%d-out-of-%d sharing\n", t, n); printf("%d-bit prime\n", bits); printf("%d-bit subgroup\n", qbits); printf("share files:\n"); for (i=0; i<n; i++) { if (sharefile[i] == NULL) { fprintf(stderr, "not enough filenames given\n"); exit(1); } printf(" %s\n", sharefile[i]); } IBE_init(); IBE_setup(params, master, bits, qbits, systemid); FMT_split_master(sharefile, master, t, n, params); FMT_save_params(paramsfile, params); // test it works if (0) { byte_string_t key; //FMT_construct_master(key, sharefile, t); IBE_extract(key, master, "*****@*****.**", params); byte_string_clear(key); } byte_string_clear(master); params_clear(params); IBE_clear(); return 0; }
int IBE_construct_master(byte_string_t master, byte_string_t *mshare, params_t params) //reconstruct the master from master shares //(shouldn't normally be used since they should never be in one place) { int i, j; int indexi, indexj; int t = params->sharet; mpz_t x; mpz_t y; mpz_t z; mpz_t num, denom; byte_string_t bs1, bs2; mpz_init(x); mpz_init(y); mpz_init(z); mpz_init(num); mpz_init(denom); mpz_set_ui(x, 0); for (i=0; i<t; i++) { mpz_set_ui(num, 1); mpz_set_ui(denom, 1); byte_string_split(bs1, bs2, mshare[i]); indexi = int_from_byte_string(bs1); byte_string_clear(bs1); mympz_set_byte_string(y, bs2); byte_string_clear(bs2); for (j=0; j<t; j++) { if (j != i) { byte_string_split(bs1, bs2, mshare[j]); indexj = int_from_byte_string(bs1); byte_string_clear(bs1); byte_string_clear(bs2); mpz_mul(num, num, params->robustx[indexj]); mpz_mod(num, num, params->q); mpz_sub(z, params->robustx[indexj], params->robustx[indexi]); mpz_mul(denom, denom, z); mpz_mod(denom, denom, params->q); } } mpz_invert(denom, denom, params->q); mpz_mul(z, num, denom); mpz_mod(z, z, params->q); mpz_mul(z, z, y); mpz_mod(z, z, params->q); mpz_add(x, x, z); if (mpz_cmp(x, params->q) >= 0) { mpz_sub(x, x, params->q); } } byte_string_set_mpz(master, x); mpz_clear(x); mpz_clear(y); mpz_clear(z); mpz_clear(num); mpz_clear(denom); return 1; }
void IBE_split_master(byte_string_t *mshare, byte_string_t master, int t, int n, params_t params) //split the master key into n pieces //t of them are required to generate a key { mpz_t * poly = malloc(sizeof(mpz_t)*t); mpz_t *x; mpz_t *y = malloc(sizeof(mpz_t)*n); mpz_t z; mpz_t r; int i, j; byte_string_t bs1, bs2; //start with random polynomial with degree <= t-2 //(in F_q) //whose constant term = master mpz_init(r); mpz_init(poly[0]); mympz_set_byte_string(poly[0], master); for (i=1; i<t; i++) { mpz_init(poly[i]); mympz_randomm(r, params->q); mpz_set(poly[i], r); } mpz_init(z); if (0) { printf("secret poly: "); for (i=0; i<t; i++) { printf(" "); mpz_out_str(NULL, 0, poly[i]); } printf("\n"); } params->robustx = (mpz_t *) malloc(n * sizeof(mpz_t)); params->robustP = (point_t *) malloc(n * sizeof(point_t)); params->sharet = t; params->sharen = n; x = params->robustx; for (i=0; i<n; i++) { mympz_randomm(r, params->q); mpz_init(x[i]); mpz_set(x[i], r); //Horner's rule mpz_set_ui(z, 0); for (j=t-1; j>=0; j--) { mpz_mul(z, z, x[i]); mpz_add(z, z, poly[j]); mpz_mod(z, z, params->q); } mpz_init_set(y[i], z); byte_string_set_int(bs1, i); byte_string_set_mpz(bs2, z); byte_string_join(mshare[i], bs1, bs2); byte_string_clear(bs1); byte_string_clear(bs2); } for (i=0; i<n; i++) { point_init(params->robustP[i]); point_mul(params->robustP[i], y[i], params->Ppub, params->curve); } for (i=0; i<t; i++) { mpz_clear(poly[i]); } for (i=0; i<n; i++) { mpz_clear(y[i]); } mpz_clear(z); mpz_clear(r); }
int IBE_combine(byte_string_t key, byte_string_t *kshare, params_t params) //reconstruct a key from key shares, or a certificate from certificate shares { int i, j; int indexi, indexj; point_t yP; mpz_t num, denom; mpz_t z; point_t d; byte_string_t bs1, bs2; int *index; index = (int *) malloc(params->sharet * sizeof(int)); for (i=0; i<params->sharet; i++) { byte_string_split(bs1, bs2, kshare[i]); byte_string_clear(bs2); index[i] = int_from_byte_string(bs1); byte_string_clear(bs1); for (j=0; j<i; j++) { if (index[i] == index[j]) { return 0; } } } point_init(yP); mpz_init(z); mpz_init(num); mpz_init(denom); point_init(d); point_set_O(d); for (i=0; i<params->sharet; i++) { byte_string_split(bs1, bs2, kshare[i]); indexi = index[i]; byte_string_clear(bs1); point_set_byte_string(yP, bs2); byte_string_clear(bs2); mpz_set_ui(num, 1); mpz_set_ui(denom, 1); for (j=0; j<params->sharet; j++) { if (j != i) { indexj = index[j]; mpz_mul(num, num, params->robustx[indexj]); mpz_mod(num, num, params->q); mpz_sub(z, params->robustx[indexj], params->robustx[indexi]); mpz_mul(denom, denom, z); mpz_mod(denom, denom, params->q); } } mpz_invert(denom, denom, params->q); mpz_mul(z, num, denom); mpz_mod(z, z, params->q); point_mul(yP, z, yP, params->curve); point_add(d, d, yP, params->curve); } byte_string_set_point(key, d); point_clear(yP); mpz_clear(z); mpz_clear(num); mpz_clear(denom); point_clear(d); return 1; }
int FMT_decrypt_stream(char *id, byte_string_t key, FILE *infp, FILE *outfp, params_t params) { byte_string_t U; byte_string_t K, V; crypto_ctx_t ctx; unsigned char in[crypt_buf_size]; unsigned char out[200]; //TODO: what should this be? int inl, outl; unsigned char data[1024]; int count; EVP_ENCODE_CTX mime; int result = 0; char *s, slen; int status; advance_to("-----BEGIN IBE-----", infp); advance_to("U:", infp); mime_get(U, infp); slen = strlen(id) + 2; s = (char *) alloca(sizeof(char) * slen); for(;;) { advance_to("ID:", infp); if (feof(infp)) { //ID not found return 0; } fgets(s, slen, infp); if (s[strlen(id)] == '\n') { //correct length? if (!strncmp(s, id, strlen(id))) { //compares? break; //email has ID for us } } } advance_to("V:", infp); mime_get(V, infp); status = IBE_reveal_key(K, U, V, key, params); if (status != 1) { fprintf(outfp, "WARNING: KMAC MISMATCH. INVALID CIPHERTEXT!\n"); byte_string_clear(V); byte_string_clear(K); return result; } advance_to("W:", infp); crypto_ctx_init(ctx); crypto_decrypt_init(ctx, K); EVP_DecodeInit(&mime); for (;;) { fgets(in, crypt_buf_size, infp); inl = strlen(in); if (inl < 0) { fprintf(stderr, "read error\n"); exit(1); } if (inl < 2) break; EVP_DecodeUpdate(&mime, data, &count, in, inl); crypto_decrypt_update(ctx, out, &outl, data, count); fwrite(out, 1, outl, outfp); } EVP_DecodeFinal(&mime, data, &count); crypto_decrypt_update(ctx, out, &outl, data, count); fwrite(out, 1, outl, outfp); if (1 != crypto_decrypt_final(ctx, out, &outl)) { fprintf(outfp, "crypto_decrypt_final() failed!\n"); } else { result = 1; } fwrite(out, 1, outl, outfp); crypto_ctx_clear(ctx); byte_string_clear(K); byte_string_clear(U); byte_string_clear(V); return result; }