Пример #1
0
void IBE_get_shared_secret_postprocess(byte_string_t s,
	char *id, preprocessed_key_t pk, params_t params)
{
    point_t Qid;
    fp2_t gid;

    fp2_init(gid);
    point_init(Qid);
    map_to_point(Qid, id, params);
    //calculate gid = e(Q_id, Phi(P_pub))
    point_Phi(Qid, Qid, params);
    tate_postprocess(gid, pk->mc, Qid, params->curve);

    hash_H(s, gid, params);

    fp2_clear(gid);
    point_clear(Qid);
}
Пример #2
0
void IBE_extract_byte_string(byte_string_t bs, byte_string_t master,
	byte_string_t id, params_t params)
//for testing purposes
{
    point_t key;
    mpz_t x;

    mpz_init(x);
    point_init(key);

    map_byte_string_to_point(key, id, params);

    mympz_set_byte_string(x, master);
    point_mul(key, x, key, params->curve);
    byte_string_set_point(bs, key);

    point_clear(key);
    mpz_clear(x);
}
Пример #3
0
//TODO: change this fn's name to something like calc_sphere_neuron_distribution
void calc_neuron_distribution(Neuron * neurons, int length) {

    // Electrostatic repulsion Force
    Point fer_i, distance;
    int i, j, iter;

    for( i = 0; i < length; i++) {
        // Initialice neuron i with random weigths
        neuron_init(  &(neurons[i]), MAX_SYNAPSIS_NUMBER );
    };


    //Calculate the neuron distribution
    for(iter = 0; iter < MAX_ITERATION_NUMBER; iter++){
        for(i = 0; i < length; i++) {

            point_init(&fer_i, 0, 0, 0);

            for(j = 0; j < length; j++) {

                distance.x = neurons[i].point.x - neurons[j].point.x;
                distance.y = neurons[i].point.y - neurons[j].point.y;
                distance.z = neurons[i].point.z - neurons[j].point.z;

                point_standarize( &distance );


                fer_i.x += distance.x;
                fer_i.y += distance.y;
                fer_i.z += distance.z;
            };

            //Calculate the position change due to the Electrostatic Repulsion Force aceleration
            neurons[i].point.x += fer_i.x * DLTT2;
            neurons[i].point.y += fer_i.y * DLTT2;
            neurons[i].point.z += fer_i.z * DLTT2;

            point_standarize(  &(neurons[i].point)  );
        };
    };
};
Пример #4
0
int read_key(ptr_point_t Q, bases_t d_bases)
{
	point_init(Q);
	bases_init(d_bases);

	char buffer [1024];
	FILE *pub, *priv;
	pub = fopen("./pub.key","r");
	if(pub != NULL){
		memset(buffer, '\0', sizeof(buffer));
		fgets(buffer,164,pub);
		string_to_bases(Q->_x,buffer);
		if(DEBUG)printf("%s\n",buffer);
		if(DEBUG)bases_print(Q->_x);
		if(DEBUG)printf("\n%d\n",ftell(pub));
		fseek(pub,164,SEEK_SET);
		if(DEBUG)printf("\n%d\n",ftell(pub));
		memset(buffer, '\0', sizeof(buffer));
		fgets(buffer,164,pub);
		string_to_bases(Q->_y,buffer);
		if(DEBUG)printf("%s\n",buffer);
		if(DEBUG)bases_print(Q->_y);
		if(DEBUG)printf("\n");
		fclose(pub);
	}
	else
		return ERROR;

	priv = fopen("./priv.key","r");
	if(priv != NULL){
		memset(buffer, '\0', sizeof(buffer));
		fgets(buffer,164,priv);
		string_to_bases(d_bases,buffer);
		fclose(priv);
	}
	else
		return ERROR;

	return NERROR;
}//read_key()
Пример #5
0
double line_get_distance_to_point(line_t *line, double x, double y)
{

  double a1;
  double a2;

  line_t hipotenus;

  double distance;
  double angleDiffrence;
  point_t point;

  point_init(&point,x,y);

  line_init(&hipotenus,&line->sp,&point);

  a1 = line->angle;
  a2 = hipotenus.angle;

  if(a1 < 0)
      a1 = M_PI + a1;
  if(a2 < 0)
      a2 = M_PI + a2;

  angleDiffrence = line->angle - hipotenus.angle;

  if(angleDiffrence < 0)
      angleDiffrence = -angleDiffrence;

  /*if(angleDiffrence > M_PI / 2)
      distance = 1000;
  else*/

  distance = sin(angleDiffrence)*hipotenus.length;

  return distance;

}
Пример #6
0
void ECDSA_verify_sign_file(char * path, ptr_curve_t E, ptr_point_t G, ptr_point_t Q, mpz_t r, mpz_t s)
{
	mpz_t n;
	mpz_init(n);
	mpz_ui_pow_ui(n,2,M);
	if(mpz_cmp(s,n)<0 && mpz_cmp_ui(s,0)>0)
	{
		printf("\t s is in ]0,n-1]\n");
	}
	else
	{
		printf("\t s isn't ]0,n-1]\n");
		printf("\t signature is false\n");
		return;
	}
	if(mpz_cmp(r,n)<0 && mpz_cmp_ui(r,0)>0)
	{
		printf("\t r is in ]0,n-1]\n");
	}
	else
	{
		printf("\t r isn't ]0,n-1]\n");
		printf("\t signature is false\n");
		return;
	}

	//sha-256 de m
	mpz_t z;
	char buffer[65];
	char buffer_M[40];

	//z = Hex_to_int(sha-256(M))
	sha256_file(path,buffer);
	strncpy(buffer_M,buffer,40);
	mpz_init_set_str(z,buffer_M,16);

	/*if(DEBUG)*/gmp_printf("\t\tn = %Zd\n",n);
	/*if(DEBUG)*/gmp_printf("\t\tz = %Zd\n",z);
	/*if(DEBUG)*/gmp_printf("\t\tr = %Zd\n",r);
	/*if(DEBUG)*/gmp_printf("\t\ts = %Zd\n",s);

	//w = s^-1 mod n
	mpz_t w;
	mpz_init(w);
	mpz_invert(w,s,n);

	//u1 = zw mod n & u2 = rw mod n
	mpz_t u1, u2, r0;
	mpz_init(u1);
	mpz_init(u2);
	mpz_init(r0);
	mpz_mul(r0,z,w);
	mpz_mod_2exp(u1,r0,M);
	mpz_mul(r0,r,w);
	mpz_mod_2exp(u2,r0,M);

	//(x1,y1) = u1 G + u2 Q
	point_t R;
	point_init(&R);
	point_t GQ;
	point_init(&GQ);
	addition_point_CE(E,G,Q,&GQ);

	bases_t g_bases, q_bases;
	bases_init(g_bases);
	bases_init(q_bases);
	int_to_bases(u1,g_bases);
	int_to_bases(u2,q_bases);
	/*if(DEBUG)*/gmp_printf("\t\tw = %Zd\n",w);
	/*if(DEBUG)*/gmp_printf("\t\tu1 = %Zd\n",u1);
	/*if(DEBUG)*/gmp_printf("\t\tu2 = %Zd\n",u2);
	multiple_addition_point_CE(E,g_bases,G,q_bases,Q,&GQ,&R);

	//res = R_x1 mod n (if r = res true else false sign)
	mpz_t res, x1;
	mpz_init(res);
	mpz_init(x1);
	bases_to_int(R._x,x1);
	mpz_mod(res,x1,n);

	if(mpz_cmp(res,r) == 0)
	{
		printf("\t signature is true\n");
	}
	else
	{
		printf("\t signature is false\n");
	}
}//ECDSA_verify_sign_file()
Пример #7
0
//============================================
//  楕円曲線の入出力テスト
//============================================
void test_io(const EC_GROUP ec)
{
    int i;
    unsigned long long int t1, t2;
    EC_POINT P, Q, R;

    size_t osize;
    unsigned char os[130];

    char str[262];

    point_init(P, ec);
    point_init(Q, ec);
    point_init(R, ec);

    //---------------------
    //  octet string
    //---------------------
    point_set_infinity(R);

    point_to_oct(os, &osize, R);
    point_from_oct(Q, os, osize);

    assert(point_is_infinity(Q));

    for (i = 0; i < 100; i++)
    {
        point_random(P);

        point_to_oct(os, &osize, P);
        point_from_oct(Q, os, osize);

        assert(point_cmp(P, Q) == 0);
    }

    t1 = rdtsc();
    for (i = 0; i < N; i++) { point_to_oct(os, &osize, P); }
    t2 = rdtsc();

    printf("point to octet string: %.2lf [clock]\n", (double)(t2 - t1) / N);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { point_from_oct(Q, os, osize); }
    t2 = rdtsc();

    printf("point from octet string: %.2lf [clock]\n", (double)(t2 - t1) / N);

    //---------------------
    //  string
    //---------------------
    point_set_infinity(R);

    point_get_str(str, R);
    point_set_str(Q, str);

    assert(point_is_infinity(Q));

    for (i = 0; i < 100; i++)
    {
        point_get_str(str, P);
        point_set_str(Q, str);

        assert(point_cmp(P, Q) == 0);
    }

    t1 = rdtsc();
    for (i = 0; i < N; i++) { point_get_str(str, P); }
    t2 = rdtsc();

    printf("point get string: %.2lf [clock]\n", (double)(t2 - t1) / N);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { point_set_str(Q, str); }
    t2 = rdtsc();

    printf("point set string: %.2lf [clock]\n", (double)(t2 - t1) / N);

    point_clear(P);
    point_clear(Q);
    point_clear(R);
}
Пример #8
0
/*
 * First obtain the setup.  Over the finite field randomize an scalar
 * secret value, and calculate the public point.
 */
static gpg_err_code_t
generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
              gcry_mpi_t g_x, gcry_mpi_t g_y,
              gcry_mpi_t q_x, gcry_mpi_t q_y)
{
  gpg_err_code_t err;
  elliptic_curve_t E;
  gcry_mpi_t d;
  mpi_point_t Q;
  mpi_ec_t ctx;

  err = generate_curve (nbits, name, &E, &nbits);
  if (err)
    return err;

  if (DBG_CIPHER)
    {
      log_mpidump ("ecc generation   p", E.p);
      log_mpidump ("ecc generation   a", E.a);
      log_mpidump ("ecc generation   b", E.b);
      log_mpidump ("ecc generation   n", E.n);
      log_mpidump ("ecc generation  Gx", E.G.x);
      log_mpidump ("ecc generation  Gy", E.G.y);
      log_mpidump ("ecc generation  Gz", E.G.z);
    }

  if (DBG_CIPHER)
    log_debug ("choosing a random x of size %u\n", nbits);
  d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM); 

  /* Compute Q.  */
  point_init (&Q);
  ctx = _gcry_mpi_ec_init (E.p, E.a);
  _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);

  /* Copy the stuff to the key structures. */
  sk->E.p = mpi_copy (E.p);
  sk->E.a = mpi_copy (E.a);
  sk->E.b = mpi_copy (E.b);
  point_init (&sk->E.G);
  point_set (&sk->E.G, &E.G);
  sk->E.n = mpi_copy (E.n);
  point_init (&sk->Q);
  point_set (&sk->Q, &Q);
  sk->d    = mpi_copy (d);
  /* We also return copies of G and Q in affine coordinates if
     requested.  */
  if (g_x && g_y)
    {
      if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
        log_fatal ("ecc generate: Failed to get affine coordinates\n");
    }
  if (q_x && q_y)
    {
      if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
        log_fatal ("ecc generate: Failed to get affine coordinates\n");
    }
  _gcry_mpi_ec_free (ctx);

  point_free (&Q);
  mpi_free (d);
  curve_free (&E);

  /* Now we can test our keys (this should never fail!). */
  test_keys (sk, nbits - 64);

  return 0;
}
Пример #9
0
/* Verify an ECDSA signature.
 * Check if R and S verifies INPUT.
 */
gpg_err_code_t
_gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
                        gcry_mpi_t r, gcry_mpi_t s)
{
  gpg_err_code_t err = 0;
  gcry_mpi_t h, h1, h2, x;
  mpi_point_struct Q, Q1, Q2;
  mpi_ec_t ctx;

  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
    return GPG_ERR_BAD_SIGNATURE; /* Assertion	0 < r < n  failed.  */
  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
    return GPG_ERR_BAD_SIGNATURE; /* Assertion	0 < s < n  failed.  */

  h  = mpi_alloc (0);
  h1 = mpi_alloc (0);
  h2 = mpi_alloc (0);
  x = mpi_alloc (0);
  point_init (&Q);
  point_init (&Q1);
  point_init (&Q2);

  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
                                     pkey->E.p, pkey->E.a, pkey->E.b);

  /* h  = s^(-1) (mod n) */
  mpi_invm (h, s, pkey->E.n);
  /* h1 = hash * s^(-1) (mod n) */
  mpi_mulm (h1, input, h, pkey->E.n);
  /* Q1 = [ hash * s^(-1) ]G  */
  _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
  /* h2 = r * s^(-1) (mod n) */
  mpi_mulm (h2, r, h, pkey->E.n);
  /* Q2 = [ r * s^(-1) ]Q */
  _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
  /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);

  if (!mpi_cmp_ui (Q.z, 0))
    {
      if (DBG_CIPHER)
          log_debug ("ecc verify: Rejected\n");
      err = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }
  if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx))
    {
      if (DBG_CIPHER)
        log_debug ("ecc verify: Failed to get affine coordinates\n");
      err = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }
  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
  if (mpi_cmp (x, r))   /* x != r */
    {
      if (DBG_CIPHER)
        {
          log_mpidump ("     x", x);
          log_mpidump ("     r", r);
          log_mpidump ("     s", s);
        }
      err = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }

 leave:
  _gcry_mpi_ec_free (ctx);
  point_free (&Q2);
  point_free (&Q1);
  point_free (&Q);
  mpi_free (x);
  mpi_free (h2);
  mpi_free (h1);
  mpi_free (h);
  return err;
}
Пример #10
0
/*Run a benchmark with different curve parameters and print CSV result to out
 *Comma-Separated Values (CSV), RFC 4180: http://tools.ietf.org/html/rfc4180 */
void benchmark(FILE* out, int i)
{
	//Print CSV header
	fprintf(out, "Curve, Public key generation time, Signature generation time, Signature verification time, Operation time\r\n");

	//If the illiterator is invalid use default illiterator
	if(i < 1)
		i = DEFAULT_TEST_ILLITERATOR;	

	//Loop through all curves, since we're benchmarking them towards eachother.
	int curve_i;
	for(curve_i = 0;curve_i < NUMBER_OF_CURVES;curve_i++)
	{
		//Set initial timer
		clock_t start = clock();

		int test_i;

		//Load curve
		domain_parameters curve = domain_parameters_init();
		domain_parameters_load_curve(curve, curve_i);

		//Print curve name
		fprintf(out, "%s, ", curve->name);

		//Get a private key
		mpz_t d;mpz_init(d);
		mpz_sub_ui(d, curve->n, 2);	//Private key must be between 1 and n-1

		//Get a message to sign
		mpz_t m;mpz_init(m);
		mpz_sub_ui(m, curve->n, 2);	//Must be between 1 and n-1
		//NOTE: I assume we're using a hash algorithm giving result with the biggest bit-length possible

		//Initialize a signature
		signature sig = signature_init();

		//Initialize public key
		point Q = point_init();

		//Save time at the start of public key generation
		clock_t start_gen_Q = clock();

		//Generate public key
		for(test_i = 0; test_i < i; test_i++)		
			signature_generate_key(Q, d, curve);

		//Save time between public key generation and signature generation
		clock_t start_sign = clock();

		//Generate signature
		for(test_i = 0; test_i < i; test_i++)
			signature_sign(sig, m, d, curve);

		//Save time between signature generation and signature verification
		clock_t start_verify = clock();

		//Verify signature
		bool result;
		for(test_i = 0; test_i < i; test_i++)
			result = signature_verify(m, sig, Q, curve);

		//Save time after verification
		clock_t end_verify = clock();

		//Clear variables
		mpz_clear(d);
		domain_parameters_clear(curve);
		signature_clear(sig);
		mpz_clear(m);

		//Save time before printing
		clock_t end = clock();

		//Print public key generation time
		fprintf(out, "%.4f, ", ((double) (start_sign - start_gen_Q)) / CLOCKS_PER_SEC);

		//Print signature generation time
		fprintf(out, "%.4f, ", ((double) (start_verify - start_sign)) / CLOCKS_PER_SEC);

		//Print signature verification time
		fprintf(out, "%.4f, ", ((double) (end_verify - start_verify)) / CLOCKS_PER_SEC);

		//Print operation time
		if(result)
			fprintf(out, "%.4f", ((double) (end - start)) / CLOCKS_PER_SEC);
		else
			fprintf(out, "-1");

		//print a new line
		fprintf(out, "\r\n");	//Acoording to RFC4180 this must be done with CLRF
	}
}
Пример #11
0
/* Compute an EdDSA signature. See:
 *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
 *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
 *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
 *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
 *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
 *
 * Despite that this function requires the specification of a hash
 * algorithm, we only support what has been specified by the paper.
 * This may change in the future.  Note that we don't check the used
 * curve; the user is responsible to use Ed25519.
 *
 * Return the signature struct (r,s) from the message hash.  The caller
 * must have allocated R_R and S.
 */
gpg_err_code_t
_gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
                      gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
{
  int rc;
  mpi_ec_t ctx = NULL;
  int b;
  unsigned int tmp;
  unsigned char *digest;
  gcry_buffer_t hvec[3];
  const void *mbuf;
  size_t mlen;
  unsigned char *rawmpi = NULL;
  unsigned int rawmpilen;
  unsigned char *encpk = NULL; /* Encoded public key.  */
  unsigned int encpklen;
  mpi_point_struct I;          /* Intermediate value.  */
  mpi_point_struct Q;          /* Public key.  */
  gcry_mpi_t a, x, y, r;

  memset (hvec, 0, sizeof hvec);

  if (!mpi_is_opaque (input))
    return GPG_ERR_INV_DATA;

  /* Initialize some helpers.  */
  point_init (&I);
  point_init (&Q);
  a = mpi_snew (0);
  x = mpi_new (0);
  y = mpi_new (0);
  r = mpi_new (0);
  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
                                     skey->E.p, skey->E.a, skey->E.b);
  b = (ctx->nbits+7)/8;
  if (b != 256/8)
    return GPG_ERR_INTERNAL; /* We only support 256 bit. */

  rc = _gcry_ecc_eddsa_compute_h_d (&digest, skey->d, ctx);
  if (rc)
    goto leave;
  _gcry_mpi_set_buffer (a, digest, 32, 0);

  /* Compute the public key if it has not been supplied as optional
     parameter.  */
  if (pk)
    {
      rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q,  &encpk, &encpklen);
      if (rc)
        goto leave;
      if (DBG_CIPHER)
        log_printhex ("* e_pk", encpk, encpklen);
      if (!_gcry_mpi_ec_curve_point (&Q, ctx))
        {
          rc = GPG_ERR_BROKEN_PUBKEY;
          goto leave;
        }
    }
  else
    {
      _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
      rc = _gcry_ecc_eddsa_encodepoint (&Q, ctx, x, y, 0, &encpk, &encpklen);
      if (rc)
        goto leave;
      if (DBG_CIPHER)
        log_printhex ("  e_pk", encpk, encpklen);
    }

  /* Compute R.  */
  mbuf = mpi_get_opaque (input, &tmp);
  mlen = (tmp +7)/8;
  if (DBG_CIPHER)
    log_printhex ("     m", mbuf, mlen);

  hvec[0].data = digest;
  hvec[0].off  = 32;
  hvec[0].len  = 32;
  hvec[1].data = (char*)mbuf;
  hvec[1].len  = mlen;
  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
  if (rc)
    goto leave;
  reverse_buffer (digest, 64);
  if (DBG_CIPHER)
    log_printhex ("     r", digest, 64);
  _gcry_mpi_set_buffer (r, digest, 64, 0);
  _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
  if (DBG_CIPHER)
    log_printpnt ("   r", &I, ctx);

  /* Convert R into affine coordinates and apply encoding.  */
  rc = _gcry_ecc_eddsa_encodepoint (&I, ctx, x, y, 0, &rawmpi, &rawmpilen);
  if (rc)
    goto leave;
  if (DBG_CIPHER)
    log_printhex ("   e_r", rawmpi, rawmpilen);

  /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
  hvec[0].data = rawmpi;  /* (this is R) */
  hvec[0].off  = 0;
  hvec[0].len  = rawmpilen;
  hvec[1].data = encpk;
  hvec[1].off  = 0;
  hvec[1].len  = encpklen;
  hvec[2].data = (char*)mbuf;
  hvec[2].off  = 0;
  hvec[2].len  = mlen;
  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
  if (rc)
    goto leave;

  /* No more need for RAWMPI thus we now transfer it to R_R.  */
  mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
  rawmpi = NULL;

  reverse_buffer (digest, 64);
  if (DBG_CIPHER)
    log_printhex (" H(R+)", digest, 64);
  _gcry_mpi_set_buffer (s, digest, 64, 0);
  mpi_mulm (s, s, a, skey->E.n);
  mpi_addm (s, s, r, skey->E.n);
  rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
  if (rc)
    goto leave;
  if (DBG_CIPHER)
    log_printhex ("   e_s", rawmpi, rawmpilen);
  mpi_set_opaque (s, rawmpi, rawmpilen*8);
  rawmpi = NULL;

  rc = 0;

 leave:
  _gcry_mpi_release (a);
  _gcry_mpi_release (x);
  _gcry_mpi_release (y);
  _gcry_mpi_release (r);
  xfree (digest);
  _gcry_mpi_ec_free (ctx);
  point_free (&I);
  point_free (&Q);
  xfree (encpk);
  xfree (rawmpi);
  return rc;
}
Пример #12
0
void IBE_setup(params_t params, byte_string_t master, int k, int qk, char *id)
/* generate system parameters
 * k = number of bits in p (should be at least 512)
 * qk = number of bits in q (size of subgroup, 160 is typical)
 * id = system ID
 */
{
    mpz_t p, q, r;
    mpz_t x;
    point_ptr P;

    int solinasa, solinasb;

    int kqk = k - qk - 4; //lose 4 bits since 12 is a 4-bit no.
    unsigned int seed;

    mpz_init(p); mpz_init(q); mpz_init(r); mpz_init(x);

    //find random k-bit prime p such that
    //p = 2 mod 3 and q = (p+1)/12r is prime as well for some r

    //now also want q to be a Solinas prime
    //we use rand() to help us find one: should be ok
    crypto_rand_bytes((unsigned char *) &seed, sizeof(int));
    srand(seed);

    for(;;) {
	//once q was just a random qk-bit prime
	//now it must be a Solinas one
	mpz_set_ui(q, 0);

	solinasa = qk - 1;

	mpz_setbit(q, solinasa);
	mpz_set_ui(r, 0);

	solinasb = rand() % qk;
	mpz_setbit(r, solinasb);
	if (rand() % 2) {
	    mpz_add(q, q, r);
	} else {
	    mpz_sub(q, q, r);
	    solinasb = -solinasb;
	}
	mpz_set_ui(r, 1);
	if (rand() % 2) {
	    mpz_add(q, q, r);
	} else {
	    mpz_sub(q, q, r);
	    solinasa = -solinasa;
	}

	if (!mpz_probab_prime_p(q, 10)) continue;
	mympz_randomb(r, kqk);
	//p = q * r
	mpz_mul(p, q, r);

	//r = (((p << 1) + p) << 2) (= 12p)
	mpz_mul_2exp(r, p, 1);
	mpz_add(r, r, p);
	mpz_mul_2exp(r, r, 2);

	//p = r - 1
	mpz_set_ui(p, 1);
	mpz_sub(p, r, p);
	if (mpz_probab_prime_p(p, 10)) break;
    }

    //pick master key x from F_q
    mympz_randomm(x, q);
    byte_string_set_mpz(master, x);

    mpz_init(params->p);
    mpz_init(params->q);
    mpz_set(params->p, p);
    mpz_set(params->q, q);

    initpq(params);

    //pick random point P of order q from E/F_p
    point_init(params->P);
    P = params->P;

    do {
	point_random(P, params->curve);
	point_make_order_q(P, params);
    } while (P->infinity);

    point_init(params->Ppub);
    point_mul(params->Ppub, x, P, params->curve);

    point_mul_preprocess(P, params->curve);

    miller_cache_init(params->Ppub_mc, params->curve);
    tate_preprocess(params->Ppub_mc, params->Ppub, params->curve);

    point_init(params->PhiPpub);
    point_Phi(params->PhiPpub, params->Ppub, params);

    params->id = (char *) malloc(strlen(id) + 1);
    strcpy(params->id, id);

    params->sharet = params->sharen = 0;
    params->version = (char *) malloc(strlen(IBE_VERSION) + 1);
    strcpy(params->version, IBE_VERSION);

    mpz_clear(p); mpz_clear(q); mpz_clear(r); mpz_clear(x);
}
Пример #13
0
int nlrf_add_point(line_map_t *lm,double angle,double x, double y, double dist, double relDist)
{
   point_t sp,ep;

   double distance;

   plinel_t *tpl;
   pointl_t *point;


   if(lm == NULL)
       return 0;

   tpl = lm->last;

   if(tpl != NULL && tpl->last != NULL)
   {
      distance = point_get_distance(tpl->last->x, tpl->last->y, x, y);

      if(distance < relDist)
      {
          point = lrf_create_point_list(angle,x,y,dist);

          if(point == NULL)
             return 0;

          point->pre = tpl->last;
          tpl->last->next = point;
          tpl->last = point;


          point_init(&sp, tpl->first->x, tpl->first->y);
          point_init(&ep, tpl->last->x, tpl->last->y);

          line_init(&tpl->line,&sp,&ep);
          tpl->point_cnt++;

          return 1;
      }

   }

   tpl = lrf_create_plinel();

   if(tpl == NULL)
     return 0;

   point = lrf_create_point_list(angle,x,y,dist);

   if(point == NULL)
   {
      free(tpl);
      return 0;
   }

   tpl->first = point;
   tpl->last  = point;
   tpl->point_cnt++;


   if(lm->first == NULL)
   {
     lm->first = tpl;
     lm->lineCount = 0;
   }
   if(lm->last != NULL)
     lm->last->next = tpl;

   tpl->pre = lm->last;
   lm->last = tpl;

   point_init(&sp, tpl->first->x, tpl->first->y);
   point_init(&ep, tpl->last->x, tpl->last->y);

   line_init(&tpl->line,&sp,&ep);

   tpl->point_cnt = 1;

   lm->lineCount++;

   return 1;
}
Пример #14
0
int nlrf_split_line(plinel_t *ll, double treshold)
{
    double dist;
    double maxdist;
    point_t p,sp,ep;
    if(ll == NULL)
        return 0;



    pointl_t *point = ll->first;

    pointl_t *uzakNokta = NULL;

    plinel_t *tpl;

    plinel_t *next;
    plinel_t *pre;

    maxdist = 0;

    ll->point_cnt = 0;
    while(point != NULL)
    {
        dist = line_get_distance_to_point(&ll->line,point->x, point->y);

        if(dist > maxdist &&  point != ll->first &&  point != ll->last)
        {
            maxdist = dist;
            uzakNokta = point;
        }
        point = point->next;

        ll->point_cnt++;
    }

    if(maxdist >= treshold && uzakNokta != NULL)
    {
        tpl = lrf_create_plinel();

        if(tpl == NULL)
             return 0;



        tpl->first = uzakNokta;
        ll->last  = uzakNokta->pre;

        ll->last->next = NULL;

        tpl->first->pre = NULL;
        tpl->last = ll->last;
        tpl->last->next = NULL;


        point_init(&sp, tpl->first->x, tpl->first->y);
        point_init(&ep, tpl->last->x, tpl->last->y);
        line_init(&tpl->line,&sp,&ep);


        point_init(&sp, ll->first->x, ll->first->y);
        point_init(&ep, ll->last->x, ll->last->y);
        line_init(&ll->line,&sp,&ep);


        next = ll->next;
        pre  = ll;

        if(pre != NULL)
        {
          pre->next = tpl;
        }
        tpl->pre = pre;
        if(next != NULL)
        {
            next->pre = tpl;
        }
        tpl->next = next;

        return 1;
    }
    else
        return 0;
}
Пример #15
0
//============================================
//  楕円曲線の演算テスト
//============================================
void test_arithmetic_operation(const EC_GROUP ec)
{
    int i;
    unsigned long long int t1, t2;
    EC_POINT a, b, c, d;

    Element dx, dy;

    mpz_t scalar;

    //-------------------
    //  init
    //-------------------
    point_init(a, ec);
    point_init(b, ec);
    point_init(c, ec);
    point_init(d, ec);

    //-------------------
    //  random
    //-------------------
    point_random(a);

    assert(point_is_on_curve(a));

    t1 = rdtsc();
    for (i = 0; i < M; i++) { point_random(a); }
    t2 = rdtsc();

    printf("point random: %.2lf [clock]\n", (double)(t2 - t1) / M);

    //-------------------
    //  add/dob
    //-------------------
    point_add(b, b, a);
    point_add(c, b, c);

    assert(point_cmp(b, a) == 0);
    assert(point_cmp(c, b) == 0);

    point_set_infinity(d);

    point_dob(d, d);

    assert(point_is_infinity(d));

    point_set_str(a, "[6D2E4115FA177379A504A0EE4EF53767DE51C6364AAB69D4064529EC1FD047A 635B2C858AA4F4A3DB8AA17A588B037CAFFD36678F76E3F3369DFC90C6878C7,193E877C82EFCA81EC2815906630B837BBC6976CC8A7958E6A40D1B190FF2E5F E8A77E88AFCEE9F806DC15BF50EADD138320F1A5A87E78DDE86FA7A867300D]");
    point_set_str(b, "[1A8F5DAB09EE4290F95FE4C824C153E355D55B6CF94B998C6203FEC3D81377CF 15A19F2704C4BDBAAE39A5E26772A3E4E7EC7A9E205651F8822298766DE044FF,1C566EB3917F06B05E0A786BD8030CAFCCDB62864DD0E2A22A9B6817B310FD53 6A0927BB33EB263F45CAB921A20E67A1BD8A791D6EB0415AC92C9B1F74D16D1]");
    point_set_str(d, "[143D414F99AA18C844B331064C9DD66363EBA3D852250CBCF8C9D4B33E0C4C1C 225865D85EC7A34647CA55E026BD1FA201E0C4E8C66F7A43E69AF708F410A0FF,FACA1388C034CF614A72E06EE60DEDC4880CDBD368E5BEC2795130B266FFB9E 1681217E50705AB9A21FEB62E0BF9A5657EB27C3AED3323FE9C57058358735A9]");

    point_add(c, a, b);

    assert(point_cmp(c, d) == 0);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { point_add(c, a, b); }
    t2 = rdtsc();

    printf("point add: %.2lf [clock]\n", (double)(t2 - t1) / N);

    element_init(dx, ec->field);
    element_init(dy, ec->field);

    element_set_str(dx, "33F550F9A63EF53C786BF7BDFDAB1538CD76A3FCED3C9DBC3307DD4F354775A C814AE99C91C71845F0B51E4349520908E48C70181313D70C05F6ED24EC1F36");
    element_set_str(dy, "3766ED0DD7C988DB76770081A298DAA924D0E3279726F9B5504129AFA3E57B9 520CE8A563F88AF882AB99086BFDBBDCEF9DE65879AB234DFF5AAFD5BEE7E4F");

    point_set_xy(d, dx, dy);

    point_dob(c, a);

    assert(point_cmp(c, d) == 0);

    t1 = rdtsc();
    for (i = 0; i < N; i++) { point_dob(c, a); }
    t2 = rdtsc();

    printf("point dob: %.2lf [clock]\n", (double)(t2 - t1) / N);

    element_clear(dx);
    element_clear(dy);

    //------------------
    // neg/sub
    //------------------
    point_neg(c, a);
    point_add(d, a, c);
    point_sub(b, a, a);

    assert(point_is_infinity(d));
    assert(point_is_infinity(b));

    //-------------------
    //  mul
    //-------------------
    mpz_init(scalar);

    mpz_set(scalar, ec->order);

    for (i = 0; i < 100; i++)
    {
        point_random(a);

        point_mul(b, scalar, a);

        ec_bn254_fp2_mul_end(c, scalar, a);

        assert(point_is_infinity(b));
        assert(point_cmp(c, b) == 0);
    }

    t1 = rdtsc();
    for (i = 0; i < M; i++) { point_mul(b, scalar, a); }
    t2 = rdtsc();

    printf("point mul with endomorphism: %.2lf [clock]\n", (double)(t2 - t1) / M);

    t1 = rdtsc();
    for (i = 0; i < M; i++) { ec_bn254_fp2_mul(b, scalar, a); }
    t2 = rdtsc();

    printf("point mul with binary method: %.2lf [clock]\n", (double)(t2 - t1) / M);

    mpz_clear(scalar);

    //-------------------
    //  clear
    //-------------------
    point_clear(a);
    point_clear(b);
    point_clear(c);
    point_clear(d);
}
Пример #16
0
/**
 * _gcry_ecc_eddsa_genkey - EdDSA version of the key generation.
 *
 * @sk:  A struct to receive the secret key.
 * @E:   Parameters of the curve.
 * @ctx: Elliptic curve computation context.
 * @flags: Flags controlling aspects of the creation.
 *
 * Return: An error code.
 *
 * The only @flags bit used by this function is %PUBKEY_FLAG_TRANSIENT
 * to use a faster RNG.
 */
gpg_err_code_t
_gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
                        int flags)
{
  gpg_err_code_t rc;
  int b = 256/8;             /* The only size we currently support.  */
  gcry_mpi_t a, x, y;
  mpi_point_struct Q;
  gcry_random_level_t random_level;
  char *dbuf;
  size_t dlen;
  gcry_buffer_t hvec[1];
  unsigned char *hash_d = NULL;

  point_init (&Q);
  memset (hvec, 0, sizeof hvec);

  if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
    random_level = GCRY_STRONG_RANDOM;
  else
    random_level = GCRY_VERY_STRONG_RANDOM;

  a = mpi_snew (0);
  x = mpi_new (0);
  y = mpi_new (0);

  /* Generate a secret.  */
  hash_d = xtrymalloc_secure (2*b);
  if (!hash_d)
    {
      rc = gpg_error_from_syserror ();
      goto leave;
    }
  dlen = b;
  dbuf = _gcry_random_bytes_secure (dlen, random_level);

  /* Compute the A value.  */
  hvec[0].data = dbuf;
  hvec[0].len = dlen;
  rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
  if (rc)
    goto leave;
  sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
  dbuf = NULL;
  reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
  hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
  hash_d[31] &= 0xf8;
  _gcry_mpi_set_buffer (a, hash_d, 32, 0);
  xfree (hash_d); hash_d = NULL;
  /* log_printmpi ("ecgen         a", a); */

  /* Compute Q.  */
  _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
  if (DBG_CIPHER)
    log_printpnt ("ecgen      pk", &Q, ctx);

  /* Copy the stuff to the key structures. */
  sk->E.model = E->model;
  sk->E.dialect = E->dialect;
  sk->E.p = mpi_copy (E->p);
  sk->E.a = mpi_copy (E->a);
  sk->E.b = mpi_copy (E->b);
  point_init (&sk->E.G);
  point_set (&sk->E.G, &E->G);
  sk->E.n = mpi_copy (E->n);
  point_init (&sk->Q);
  point_set (&sk->Q, &Q);

 leave:
  point_free (&Q);
  _gcry_mpi_release (a);
  _gcry_mpi_release (x);
  _gcry_mpi_release (y);
  xfree (hash_d);
  return rc;
}
Пример #17
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;
}
Пример #18
0
/* Verify an EdDSA signature.  See sign_eddsa for the reference.
 * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
 * parameters and PK is the EdDSA style encoded public key.
 */
gpg_err_code_t
_gcry_ecc_eddsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
                        gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo,
                        gcry_mpi_t pk)
{
  int rc;
  mpi_ec_t ctx = NULL;
  int b;
  unsigned int tmp;
  mpi_point_struct Q;          /* Public key.  */
  unsigned char *encpk = NULL; /* Encoded public key.  */
  unsigned int encpklen;
  const void *mbuf, *rbuf;
  unsigned char *tbuf = NULL;
  size_t mlen, rlen;
  unsigned int tlen;
  unsigned char digest[64];
  gcry_buffer_t hvec[3];
  gcry_mpi_t h, s;
  mpi_point_struct Ia, Ib;

  if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
    return GPG_ERR_INV_DATA;
  if (hashalgo != GCRY_MD_SHA512)
    return GPG_ERR_DIGEST_ALGO;

  point_init (&Q);
  point_init (&Ia);
  point_init (&Ib);
  h = mpi_new (0);
  s = mpi_new (0);

  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
                                     pkey->E.p, pkey->E.a, pkey->E.b);
  b = ctx->nbits/8;
  if (b != 256/8)
    return GPG_ERR_INTERNAL; /* We only support 256 bit. */

  /* Decode and check the public key.  */
  rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q, &encpk, &encpklen);
  if (rc)
    goto leave;
  if (!_gcry_mpi_ec_curve_point (&Q, ctx))
    {
      rc = GPG_ERR_BROKEN_PUBKEY;
      goto leave;
    }
  if (DBG_CIPHER)
    log_printhex ("  e_pk", encpk, encpklen);
  if (encpklen != b)
    {
      rc = GPG_ERR_INV_LENGTH;
      goto leave;
    }

  /* Convert the other input parameters.  */
  mbuf = mpi_get_opaque (input, &tmp);
  mlen = (tmp +7)/8;
  if (DBG_CIPHER)
    log_printhex ("     m", mbuf, mlen);
  rbuf = mpi_get_opaque (r_in, &tmp);
  rlen = (tmp +7)/8;
  if (DBG_CIPHER)
    log_printhex ("     r", rbuf, rlen);
  if (rlen != b)
    {
      rc = GPG_ERR_INV_LENGTH;
      goto leave;
    }

  /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
  hvec[0].data = (char*)rbuf;
  hvec[0].off  = 0;
  hvec[0].len  = rlen;
  hvec[1].data = encpk;
  hvec[1].off  = 0;
  hvec[1].len  = encpklen;
  hvec[2].data = (char*)mbuf;
  hvec[2].off  = 0;
  hvec[2].len  = mlen;
  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
  if (rc)
    goto leave;
  reverse_buffer (digest, 64);
  if (DBG_CIPHER)
    log_printhex (" H(R+)", digest, 64);
  _gcry_mpi_set_buffer (h, digest, 64, 0);

  /* According to the paper the best way for verification is:
         encodepoint(sG - h·Q) = encodepoint(r)
     because we don't need to decode R. */
  {
    void *sbuf;
    unsigned int slen;

    sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
    slen = (tmp +7)/8;
    reverse_buffer (sbuf, slen);
    if (DBG_CIPHER)
      log_printhex ("     s", sbuf, slen);
    _gcry_mpi_set_buffer (s, sbuf, slen, 0);
    xfree (sbuf);
    if (slen != b)
      {
        rc = GPG_ERR_INV_LENGTH;
        goto leave;
      }
  }

  _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
  _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
  _gcry_mpi_neg (Ib.x, Ib.x);
  _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
  rc = _gcry_ecc_eddsa_encodepoint (&Ia, ctx, s, h, 0, &tbuf, &tlen);
  if (rc)
    goto leave;
  if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
    {
      rc = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }

  rc = 0;

 leave:
  xfree (encpk);
  xfree (tbuf);
  _gcry_mpi_ec_free (ctx);
  _gcry_mpi_release (s);
  _gcry_mpi_release (h);
  point_free (&Ia);
  point_free (&Ib);
  point_free (&Q);
  return rc;
}
Пример #19
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);
}
Пример #20
0
void	thin_driver(
					int nx, int ny, int nz,
					unsigned char *burn_cube,
					int *nloc, UINT32 **ma_loc, unsigned char **ma_bno)
{
	data_info   *datainfo;
	point_info  *ptinfo;
	char tp;

	char	conn_type;

	int	num_vox_removed, tot_vox_removed;
	int	itno, done;
	int	surface, bdry_alg, iso_or_dir, end_cond, clean_ends;
	int	ok;

	int	task = ERODE;

	int	csz = sizeof(char);

	tp = 'F';		// CSHL parameter
	surface = 0;
	bdry_alg = 1;
	iso_or_dir = 2;	// new condition: retain boundary voxel
	conn_type = (char)26;
	end_cond   = 1;
	clean_ends = 1;

	thin_input_obj_data(&datainfo,tp,conn_type,bdry_alg,nx,ny,nz,burn_cube);

    /* Program terminates if at any iteration the number of voxels */
    /* deleted is 0. A voxel is deleted if the corresponding entry */
    /* in datainfo->data is set to MATERIAL			   */

    ptinfo = point_init();  /* Set voxel and octant look up arrays */
	init_deuler_table();

	itno = 0;		tot_vox_removed = 0;
	done = 0;

	ok = ( iso_or_dir == 2 && end_cond == 2 && clean_ends == 2 ) ? 1:0;

	while( !done )
	{
		if( iso_or_dir == 1 )
		{
			num_vox_removed = thin_object_dir(datainfo,ptinfo,
											  surface,bdry_alg,0,
											  itno,conn_type,1);
		}
		else
		{
			num_vox_removed = thin_object_iso(datainfo,ptinfo,
											  surface,bdry_alg,0,
											  itno,conn_type,1,end_cond);
		}
		tot_vox_removed += num_vox_removed;
		itno++;
		if( num_vox_removed == 0 )
		{
			if( ok == 1 )
			{
				ok = 0;
				end_cond = 1;
			}
			else done = 1;
		}
    }
    free_point_info(ptinfo);
	pma_output(datainfo,nloc,ma_loc,ma_bno,burn_cube);

	PRINTF("tot_vox_removed %d, times_loop %d\n", tot_vox_removed,itno);
	free_data_info(datainfo);
}
Пример #21
0
/*
 * AS, c_iの順にシリアライズされている
 * まずint*3(num_policy, M->row, M->column)
 * その後、行列M,rho(i)
 * 最後にc_i
 */
void tfel_deserialize_ciphertext_cp(AccessStructure *AS, basis *c_i, unsigned char *bin_ct_buf, size_t max_len, EC_PAIRING p) {
    int i, j, t;
    unsigned char *buf_ptr = NULL;
    size_t buf_len;
    size_t *result_len = NULL;
    result_len = &buf_len;
    *result_len = 0;
    buf_ptr = bin_ct_buf;
    size_t length;
    
    //引数の初期化
    init_AccessStructure(AS);
    
    //num_policy, 行列のrow,columnのdeserialize
    AS->num_policy = *((int*)buf_ptr);
    *result_len += sizeof(int);
    buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
    AS->S->row = *((int*)buf_ptr);
    *result_len += sizeof(int);
    buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
    AS->S->column = *((int*)buf_ptr);
    *result_len += sizeof(int);

    //Mのdeserialize
    char *mpz_temp;
    // 不具合あったら下の0428のコメント解除して個々の部分消す↓
    mpz_temp = (char*)malloc(sizeof(char)*MAX_STRING);
    
    AS->S->M = (mpz_t**)malloc(sizeof(mpz_t*)*AS->S->row);
    for (i = 0; i < AS->S->row; i++) {
        AS->S->M[i] = (mpz_t*)malloc(sizeof(mpz_t)*AS->S->column);
        for (j = 0; j < AS->S->column; j++) {
            buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
            memset(mpz_temp, '\0', sizeof(char)*MAX_STRING);//4はEnc.hのシリアライズの方に合わせてる
            strncpy(mpz_temp, (char*)buf_ptr, MAX_STRING); //1は変えたほうがいいかも
            mpz_init_set_str(AS->S->M[i][j], mpz_temp, 16);
            *result_len += sizeof(char)*MAX_STRING;
        }
    }
    free(mpz_temp);

    rho_i *rho_ptr;
    rho_ptr = (rho_i*)malloc(sizeof(rho_i));
    init_rho_i(rho_ptr);
    AS->rho = rho_ptr;
    for (i = 0; i < AS->num_policy; i++) { //ここの記述だるすぎでしょ……
        buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
        rho_ptr->t = *((int*)buf_ptr);
        buf_ptr += sizeof(int);
        rho_ptr->v_t[0] = *((int*)buf_ptr);
        buf_ptr += sizeof(int);
        rho_ptr->v_t[1] = *((int*)buf_ptr);
        buf_ptr += sizeof(int);
        rho_ptr->is_negated = *(Bool*)buf_ptr;
        buf_ptr += sizeof(int);
        *result_len += sizeof(int)*3 + sizeof(Bool);
        if (i < AS->num_policy -1) {
            rho_ptr->next = (rho_i*)malloc(sizeof(rho_i));
            init_rho_i(rho_ptr->next);
            rho_ptr = rho_ptr->next;
        }
    }
    rho_ptr->next = NULL;
    rho_ptr = AS->rho;
    
    //c(i)のdeserialize
    c_i->dim = AS->num_policy+1;
    c_i->M = (EC_POINT**)malloc(sizeof(EC_POINT*)*c_i->dim);
    for(i = 0; i < c_i->dim; i++) {
        //printf("i = %d\n", i);
        if(*(int*)result_len > max_len) {
            printf("import c(i) error\n");
            exit(1);
        }
        if(i == 0) t = 5;
        else t = 7;
        c_i->M[i] = (EC_POINT*)malloc(sizeof(EC_POINT)*t);
        for(j = 0; j < t; j++) {
            point_init(c_i->M[i][j], p->g1);
            //printf("j = %d\n", j);
            buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
            length = *(int*)buf_ptr;
            //printf("length = %zd\n", length);
            *result_len += sizeof(int);
            buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
            point_from_oct(c_i->M[i][j], buf_ptr, length);
            *result_len += length;
        }
    }
    
    return;
}
Пример #22
0
/* Compute an ECDSA signature.
 * Return the signature struct (r,s) from the message hash.  The caller
 * must have allocated R and S.
 */
gpg_err_code_t
_gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
                      gcry_mpi_t r, gcry_mpi_t s,
                      int flags, int hashalgo)
{
  gpg_err_code_t err = 0;
  int extraloops = 0;
  gcry_mpi_t k, dr, sum, k_1, x;
  mpi_point_struct I;
  gcry_mpi_t hash;
  const void *abuf;
  unsigned int abits, qbits;
  mpi_ec_t ctx;

  if (DBG_CIPHER)
    log_mpidump ("ecdsa sign hash  ", input );

  qbits = mpi_get_nbits (skey->E.n);

  /* Convert the INPUT into an MPI if needed.  */
  if (mpi_is_opaque (input))
    {
      abuf = gcry_mpi_get_opaque (input, &abits);
      err = gpg_err_code (gcry_mpi_scan (&hash, GCRYMPI_FMT_USG,
                                         abuf, (abits+7)/8, NULL));
      if (err)
        return err;
      if (abits > qbits)
        gcry_mpi_rshift (hash, hash, abits - qbits);
    }
  else
    hash = input;


  k = NULL;
  dr = mpi_alloc (0);
  sum = mpi_alloc (0);
  k_1 = mpi_alloc (0);
  x = mpi_alloc (0);
  point_init (&I);

  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
                                     skey->E.p, skey->E.a, skey->E.b);

  /* Two loops to avoid R or S are zero.  This is more of a joke than
     a real demand because the probability of them being zero is less
     than any hardware failure.  Some specs however require it.  */
  do
    {
      do
        {
          mpi_free (k);
          k = NULL;
          if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
            {
              /* Use Pornin's method for deterministic DSA.  If this
                 flag is set, it is expected that HASH is an opaque
                 MPI with the to be signed hash.  That hash is also
                 used as h1 from 3.2.a.  */
              if (!mpi_is_opaque (input))
                {
                  err = GPG_ERR_CONFLICT;
                  goto leave;
                }

              abuf = gcry_mpi_get_opaque (input, &abits);
              err = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
                                             abuf, (abits+7)/8,
                                             hashalgo, extraloops);
              if (err)
                goto leave;
              extraloops++;
            }
          else
            k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);

          _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
          if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
            {
              if (DBG_CIPHER)
                log_debug ("ecc sign: Failed to get affine coordinates\n");
              err = GPG_ERR_BAD_SIGNATURE;
              goto leave;
            }
          mpi_mod (r, x, skey->E.n);  /* r = x mod n */
        }
      while (!mpi_cmp_ui (r, 0));

      mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
      mpi_addm (sum, hash, dr, skey->E.n);  /* sum = hash + (d*r) mod n  */
      mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
      mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
    }
  while (!mpi_cmp_ui (s, 0));

  if (DBG_CIPHER)
    {
      log_mpidump ("ecdsa sign result r ", r);
      log_mpidump ("ecdsa sign result s ", s);
    }

 leave:
  _gcry_mpi_ec_free (ctx);
  point_free (&I);
  mpi_free (x);
  mpi_free (k_1);
  mpi_free (sum);
  mpi_free (dr);
  mpi_free (k);

  if (hash != input)
    mpi_free (hash);

  return err;
}
Пример #23
0
int tfel_deserialize_ciphertext_kp(attribute_set *Delta, basis *c_i, unsigned char *bin_ct_buf, size_t max_len, EC_PAIRING p) {
    int i, j, t;
    unsigned char *buf_ptr = NULL;
    size_t buf_len;
    size_t *result_len = NULL;
    result_len = &buf_len;
    *result_len = 0;
    buf_ptr = bin_ct_buf;
    size_t length;
    
    /*
     KPでやること
     Deltaの初期化→Delta->valueを作るためにDelta.numが必要なので最初にdを引き出す
     その後、Delta->valueをmallocしvalueを引き出す
     */
    //dをつくる
    v_vector *v_ptr = NULL;
    v_ptr = (v_vector*)malloc(sizeof(v_vector));
    if (v_ptr == NULL) return -1;
    Delta->value = v_ptr;
    Delta->num = *((int*)buf_ptr);
    *result_len += sizeof(int);
    //x_tを引き出す
    buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
    for (i = 0; i < Delta->num; i++) {
        init_vector(v_ptr, i);
        v_ptr->x_t[1] = *((int*)buf_ptr);
        *result_len += sizeof(int);
        buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
        v_ptr->next = (v_vector*)malloc(sizeof(v_vector));
        if (v_ptr->next == NULL) {
            clear_att_set_value(Delta->value);
            return -1;
        }
        if (i == Delta->num-1) {
            free(v_ptr->next);
            v_ptr->next = NULL;
        }
        else v_ptr = v_ptr->next;
    }
    
    //c(i)のdeserialize
    c_i->dim = Delta->num+1;
    c_i->M = (EC_POINT**)malloc(sizeof(EC_POINT*)*c_i->dim);
    if (c_i->M == NULL) {
        //error処理
    }
    for(i = 0; i < c_i->dim; i++) {
        //printf("i = %d\n", i);
        if(*(int*)result_len > max_len) {
            printf("import c(i) error\n");
            exit(1);
        }
        if(i == 0) t = 5;
        else t = 7;
        c_i->M[i] = (EC_POINT*)malloc(sizeof(EC_POINT)*t);
        for(j = 0; j < t; j++) {
            point_init(c_i->M[i][j], p->g1);
            //printf("j = %d\n", j);
            buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
            length = *(int*)buf_ptr;
            //printf("length = %zd\n", length);
            *result_len += sizeof(int);
            buf_ptr = (unsigned char*)(bin_ct_buf + *result_len);
            point_from_oct(c_i->M[i][j], buf_ptr, length);
            *result_len += length;
        }
    }
    
    return 0;
}
Пример #24
0
/*
 * Check if R and S verifies INPUT.
 */
static gpg_err_code_t
verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
{
  gpg_err_code_t err = 0;
  gcry_mpi_t h, h1, h2, x, y;
  mpi_point_t Q, Q1, Q2;
  mpi_ec_t ctx;

  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
    return GPG_ERR_BAD_SIGNATURE; /* Assertion	0 < r < n  failed.  */
  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
    return GPG_ERR_BAD_SIGNATURE; /* Assertion	0 < s < n  failed.  */

  h  = mpi_alloc (0);
  h1 = mpi_alloc (0);
  h2 = mpi_alloc (0);
  x = mpi_alloc (0);
  y = mpi_alloc (0);
  point_init (&Q);
  point_init (&Q1);
  point_init (&Q2);

  ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a);

  /* h  = s^(-1) (mod n) */
  mpi_invm (h, s, pkey->E.n);
/*   log_mpidump ("   h", h); */
  /* h1 = hash * s^(-1) (mod n) */
  mpi_mulm (h1, input, h, pkey->E.n);
/*   log_mpidump ("  h1", h1); */
  /* Q1 = [ hash * s^(-1) ]G  */
  _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
/*   log_mpidump ("Q1.x", Q1.x); */
/*   log_mpidump ("Q1.y", Q1.y); */
/*   log_mpidump ("Q1.z", Q1.z); */
  /* h2 = r * s^(-1) (mod n) */
  mpi_mulm (h2, r, h, pkey->E.n);
/*   log_mpidump ("  h2", h2); */
  /* Q2 = [ r * s^(-1) ]Q */
  _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
/*   log_mpidump ("Q2.x", Q2.x); */
/*   log_mpidump ("Q2.y", Q2.y); */
/*   log_mpidump ("Q2.z", Q2.z); */
  /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
/*   log_mpidump (" Q.x", Q.x); */
/*   log_mpidump (" Q.y", Q.y); */
/*   log_mpidump (" Q.z", Q.z); */

  if (!mpi_cmp_ui (Q.z, 0))
    {
      if (DBG_CIPHER)
          log_debug ("ecc verify: Rejected\n");
      err = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }
  if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
    {
      if (DBG_CIPHER)
        log_debug ("ecc verify: Failed to get affine coordinates\n");
      err = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }
  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
  if (mpi_cmp (x, r))   /* x != r */
    {
      if (DBG_CIPHER)
        {
          log_mpidump ("   x", x);
          log_mpidump ("   y", y);
          log_mpidump ("   r", r);
          log_mpidump ("   s", s);
          log_debug ("ecc verify: Not verified\n");
        }
      err = GPG_ERR_BAD_SIGNATURE;
      goto leave;
    }
  if (DBG_CIPHER)
    log_debug ("ecc verify: Accepted\n");

 leave:
  _gcry_mpi_ec_free (ctx);
  point_free (&Q2);
  point_free (&Q1);
  point_free (&Q);
  mpi_free (y);
  mpi_free (x);
  mpi_free (h2);
  mpi_free (h1);
  mpi_free (h);
  return err;
}
Пример #25
0
void ECDSA_sign_file (char * path, ptr_curve_t E, ptr_point_t G, ptr_point_t Q, bases_t d_bases, mpz_t r, mpz_t s)
{
	printf("\n\tStrat EC-DSA algo\n");
	mpz_t k_inv, r0, r1, r2, n, d, k, z, x1;
	mpz_init(k_inv);
	mpz_init(r0);
	mpz_init(r1);
	mpz_init(r2);
	mpz_init(s);
	mpz_init(k);
	mpz_init(z);
	mpz_init(x1);
	mpz_init(r);

	bases_t k_bases;
	bases_init(k_bases);

	point_t X;
	point_init(&X);

	//sha-256 de m
	char buffer[65];
	char buffer_M[40];
	mpz_init(n);
	mpz_ui_pow_ui(n,2,M);
	mpz_init(d);
	bases_to_int(d_bases,d);

	mpz_t seed;
	mpz_init_set_str(seed,"85e25bfe5c86226cdb12016f7553f9d0e693a268",16);
	gmp_randstate_t rand_stat;
	gmp_randinit_default(rand_stat);
	gmp_randseed(rand_stat,seed);
	//gmp_randseed_ui(rand_stat,time(NULL));
	//k*G=(x1,y1) (un scalaire fois un point)

	int step_3 = 0;
	while(!step_3)
	{
		mpz_urandomb(k,rand_stat,M);
		if(DEBUG)gmp_printf("%Zd\n",k);
		int_to_bases(k,k_bases);
		multiple_point_CE(E,G,k_bases,&X);

		if(DEBUG)point_print(&X,"X");

		//r=x1 mod n (x1 est transformé en integer)
		bases_to_int(X._x,x1);

		if(DEBUG)gmp_printf("%Zd\n",x1);
		mpz_mod_2exp(r,x1,M);
		if(mpz_cmp_ui(r,0)<=0)
		{
			printf("\tRestart EC-DSA algo because r = 0\n");
			continue;
		}

		if(DEBUG)gmp_printf("r = x1 mod n, r = %Zd\n", r);
		//z = Hex_to_int(sha-256(M))
		sha256_file(path,buffer);
		strncpy(buffer_M,buffer,40);
		mpz_init_set_str(z,buffer_M,16);

		//s= k^-1(z+r*d) mod n (multiplication d'integers)
		mpz_invert(k_inv,k,n);
		mpz_mul(r0,r,d);
		mpz_add(r1,z,r0);
		mpz_mul(r2,k_inv,r1);
		mpz_mod_2exp(s,r2,M);
		//if s = 0 go to step_3
		if(mpz_cmp_ui(s,0)>0)
		{
			step_3 = 1;
		}
		else
		{
			printf("\tRestart EC-DSA algo because s = 0\n");
		}
	}
	printf("\t\thash : sha-256(M) = %s\n", buffer);
	gmp_printf("\t\tz = %Zd\n",z);
	gmp_printf("\t\tr = %Zd\n",r);
	gmp_printf("\t\ts = %Zd\n",s);
	printf("\tEnd EC-DSA algo\n");
}//ECDSA_sign_file()
Пример #26
0
/* Scalar point multiplication - the main function for ECC.  If takes
   an integer SCALAR and a POINT as well as the usual context CTX.
   RESULT will be set to the resulting point. */
void
_gcry_mpi_ec_mul_point (mpi_point_t result,
                        gcry_mpi_t scalar, mpi_point_t point,
                        mpi_ec_t ctx)
{
#if 0
  /* Simple left to right binary method.  GECC Algorithm 3.27 */
  unsigned int nbits;
  int i;

  nbits = mpi_get_nbits (scalar);
  mpi_set_ui (result->x, 1);
  mpi_set_ui (result->y, 1);
  mpi_set_ui (result->z, 0);

  for (i=nbits-1; i >= 0; i--)
    {
      _gcry_mpi_ec_dup_point (result, result, ctx);
      if (mpi_test_bit (scalar, i) == 1)
        _gcry_mpi_ec_add_points (result, result, point, ctx);
    }

#else
  gcry_mpi_t x1, y1, z1, k, h, yy;
  unsigned int i, loops;
  mpi_point_struct p1, p2, p1inv;

  x1 = mpi_alloc_like (ctx->p);
  y1 = mpi_alloc_like (ctx->p);
  h  = mpi_alloc_like (ctx->p);
  k  = mpi_copy (scalar);
  yy = mpi_copy (point->y);

  if ( mpi_is_neg (k) )
    {
      k->sign = 0;
      ec_invm (yy, yy, ctx);
    }

  if (!mpi_cmp_ui (point->z, 1))
    {
      mpi_set (x1, point->x);
      mpi_set (y1, yy);
    }
  else
    {
      gcry_mpi_t z2, z3;

      z2 = mpi_alloc_like (ctx->p);
      z3 = mpi_alloc_like (ctx->p);
      ec_mulm (z2, point->z, point->z, ctx);
      ec_mulm (z3, point->z, z2, ctx);
      ec_invm (z2, z2, ctx);
      ec_mulm (x1, point->x, z2, ctx);
      ec_invm (z3, z3, ctx);
      ec_mulm (y1, yy, z3, ctx);
      mpi_free (z2);
      mpi_free (z3);
    }
  z1 = mpi_copy (mpi_const (MPI_C_ONE));

  mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */
  loops = mpi_get_nbits (h);
  if (loops < 2)
    {
      /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
         LOOPs will be zero.  To avoid an underflow of I in the main
         loop we set LOOP to 2 and the result to (0,0,0).  */
      loops = 2;
      mpi_clear (result->x);
      mpi_clear (result->y);
      mpi_clear (result->z);
    }
  else
    {
      mpi_set (result->x, point->x);
      mpi_set (result->y, yy);
      mpi_set (result->z, point->z);
    }
  mpi_free (yy); yy = NULL;

  p1.x = x1; x1 = NULL;
  p1.y = y1; y1 = NULL;
  p1.z = z1; z1 = NULL;
  point_init (&p2);
  point_init (&p1inv);

  for (i=loops-2; i > 0; i--)
    {
      _gcry_mpi_ec_dup_point (result, result, ctx);
      if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
        {
          point_set (&p2, result);
          _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
        }
      if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
        {
          point_set (&p2, result);
          /* Invert point: y = p - y mod p  */
          point_set (&p1inv, &p1);
          ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
          _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
        }
    }

  point_free (&p1);
  point_free (&p2);
  point_free (&p1inv);
  mpi_free (h);
  mpi_free (k);
#endif
}
int main(int argc, char* argv[])
{
	// 3 local magnitudes and angles
	long double mag_a, mag_b, mag_c;
	
	// error validation
	char* end_ptr_a;
	char* end_ptr_b;

	// local output strings
	char* edge_t;
	char* angle_t;

	// check for correct number of args
	if(argc != 7)
	{
		printf("error\n");
		return -1;
	}

	//make 3 points, if any intializations fail, return and display errors.....
	//	inputs of '\0' will be treated as 0...
	// point a
	if(point_init(&p_a, strtoll(argv[1], &end_ptr_a, 10), strtoll(argv[2], &end_ptr_b, 10)) == -1)
	{
		printf("error\n");
		return -1;
	}
	if(*end_ptr_a != 0 || *end_ptr_b != 0)
	{
		printf("error\n");
		return -1;	
	}
	// point b
	if(point_init(&p_b, strtoll(argv[3], &end_ptr_a, 10), strtoll(argv[4], &end_ptr_b, 10)) == -1)
	{
		printf("error\n");
		return -1;
	}
	if(*end_ptr_a != 0 || *end_ptr_b != 0)
	{
		printf("error\n");
		return -1;	
	}
	// point c
	if(point_init(&p_c, strtoll(argv[5], &end_ptr_a, 10), strtoll(argv[6], &end_ptr_b, 10)) == -1)
	{
		printf("error\n");
		return -1;
	}
	if(*end_ptr_a != 0 || *end_ptr_b != 0)
	{
		printf("error\n");
		return -1;	
	}
	
	// if one of the coordinates was non-numeric
	if(errno == EINVAL)
	{
		printf("error\n");
		return -1;
	}

	// get three edge magnitudes (squared)
	mag_a = get_mag(&p_a, &p_b);
	mag_b = get_mag(&p_b, &p_c);
	mag_c = get_mag(&p_c, &p_a);

	//check for colinear points
	 //x_1(y_2-y_3)+x_2(y_3-y_1)+x_3(y_1-y_2)=0. 
	if((p_a.x*(p_b.y - p_c.y) + p_b.x*(p_c.y - p_a.y) + p_c.x*(p_a.y - p_b.y)) == 0)
	{
		printf("not a triangle\n");
		return 0;
	}

	// if all three edges are the same length...
	if(fabsl(mag_a - mag_b) < 0.00000001 && fabsl(mag_b - mag_c) < 0.00000001 && fabsl(mag_c - mag_a) < 0.00000001)
	{
		edge_t = "equilateral";    	
	}
	// else if all three edges have unique lengths...
	else if(mag_a != mag_b && mag_a != mag_c && mag_b != mag_c)
	{
		edge_t = "scalene"; 
	}
	// else if two edge lengths are identical     
	else
	{
		edge_t = "isosceles";
	}

	if(strcmp(edge_t, "equilateral") == 0)
	{
		angle_t = "acute";
		printf("%s %s\n", edge_t, angle_t);
		return 0;
	}
	
// 	Let "c" be the longest side on each set of three numbers.
	// If c^2 = a^2+b^2, the triangle is right
	// If c^2 > a^2 + b^2, the triangle is obtuse
	// If c^2 < a^2 + b^2, the triangle is acute.

	if(get_longest_side(mag_a, mag_b, mag_c) == 'a')
	{
		if(mag_a == (mag_b + mag_c))
		{
			angle_t = "right";
		}
		else if(mag_a > (mag_b + mag_c))
		{
			angle_t = "obtuse";
		}
		else
		{
			angle_t = "acute";
		}
	}
	else if(get_longest_side(mag_a, mag_b, mag_c) == 'b')
	{
		if(mag_b == (mag_a + mag_c))
		{
			angle_t = "right";
		}
		else if(mag_b > (mag_a + mag_c))
		{
			angle_t = "obtuse";
		}
		else
		{
			angle_t = "acute";
		}
	}
	else
	{	
		if(mag_c == (mag_a + mag_b))
		{
			angle_t = "right";
		}
		else if(mag_c > (mag_a + mag_b))
		{
			angle_t = "obtuse";
		}
		else
		{
			angle_t = "acute";
		}
	}

	// ******** assert both output strings were assigned values before completing ***********
	assert(edge_t != 0);
	assert(angle_t != 0);

	printf("%s %s\n", edge_t, angle_t);
}