Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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);
}
Esempio n. 22
0
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;
}
Esempio n. 23
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;
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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;
}