예제 #1
0
파일: mpi-gcd.c 프로젝트: 3null/fastsocket
/****************
 * Find the greatest common divisor G of A and B.
 * Return: true if this 1, false in all other cases
 */
int
mpi_gcd( MPI g, const MPI xa, const MPI xb )
{
    MPI a = NULL, b = NULL;

    if (mpi_copy(&a, xa) < 0)
	    goto nomem;

    if (mpi_copy(&b, xb) < 0)
	    goto nomem;

    /* TAOCP Vol II, 4.5.2, Algorithm A */
    a->sign = 0;
    b->sign = 0;
    while( mpi_cmp_ui( b, 0 ) ) {
	    if (mpi_fdiv_r( g, a, b ) < 0) /* g used as temorary variable */
		    goto nomem;
	    if (mpi_set(a,b) < 0)
		    goto nomem;
	    if (mpi_set(b,g) < 0)
		    goto nomem;
    }
    if (mpi_set(g, a) < 0)
	    goto nomem;

    mpi_free(a);
    mpi_free(b);
    return !mpi_cmp_ui( g, 1);

 nomem:
    mpi_free(a);
    mpi_free(b);
    return -ENOMEM;
}
예제 #2
0
파일: ec.c 프로젝트: Greenchik/libgcrypt
/* This function initialized a context for elliptic curve based on the
   field GF(p).  P is the prime specifying this field, A is the first
   coefficient.  CTX is expected to be zeroized.  */
static void
ec_p_init (mpi_ec_t ctx, gcry_mpi_t p, gcry_mpi_t a)
{
  int i;

  /* Fixme: Do we want to check some constraints? e.g.  a < p  */

  ctx->p = mpi_copy (p);
  ctx->a = mpi_copy (a);

  ec_get_reset (ctx);

  /* Allocate scratch variables.  */
  for (i=0; i< DIM(ctx->t.scratch); i++)
    ctx->t.scratch[i] = mpi_alloc_like (ctx->p);

  /* Prepare for fast reduction.  */
  /* FIXME: need a test for NIST values.  However it does not gain us
     any real advantage, for 384 bits it is actually slower than using
     mpi_mulm.  */
/*   ctx->nist_nbits = mpi_get_nbits (ctx->p); */
/*   if (ctx->nist_nbits == 192) */
/*     { */
/*       for (i=0; i < 4; i++) */
/*         ctx->s[i] = mpi_new (192); */
/*       ctx->c    = mpi_new (192*2); */
/*     } */
/*   else if (ctx->nist_nbits == 384) */
/*     { */
/*       for (i=0; i < 10; i++) */
/*         ctx->s[i] = mpi_new (384); */
/*       ctx->c    = mpi_new (384*2); */
/*     } */
}
예제 #3
0
파일: ecc-curves.c 프로젝트: Ri0n/libotr-vs
/* Return an MPI (or opaque MPI) described by NAME and the context EC.
   If COPY is true a copy is returned, if not a const MPI may be
   returned.  In any case mpi_free must be used.  */
gcry_mpi_t
_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
{
  if (!*name)
    return NULL;

  if (!strcmp (name, "p") && ec->p)
    return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
  if (!strcmp (name, "a") && ec->a)
    return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
  if (!strcmp (name, "b") && ec->b)
    return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
  if (!strcmp (name, "n") && ec->n)
    return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
  if (!strcmp (name, "d") && ec->d)
    return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);

  /* Return a requested point coordinate.  */
  if (!strcmp (name, "g.x") && ec->G && ec->G->x)
    return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
  if (!strcmp (name, "g.y") && ec->G && ec->G->y)
    return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
  if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
    return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
  if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
    return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);

  /* If the base point has been requested, return it in standard
     encoding.  */
  if (!strcmp (name, "g") && ec->G)
    return _gcry_mpi_ec_ec2os (ec->G, ec);

  /* If the public key has been requested, return it by default in
     standard uncompressed encoding or if requested in other
     encodings.  */
  if (*name == 'q' && (!name[1] || name[1] == '@'))
    {
      /* If only the private key is given, compute the public key.  */
      if (!ec->Q)
        ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL);

      if (!ec->Q)
        return NULL;

      if (name[1] != '@')
        return _gcry_mpi_ec_ec2os (ec->Q, ec);

      if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS)
        {
          unsigned char *encpk;
          unsigned int encpklen;

          if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL,
                                            &encpk, &encpklen))
            return mpi_set_opaque (NULL, encpk, encpklen*8);
        }
    }

  return NULL;
}
예제 #4
0
/*
 * Return a copy of a curve object.
 */
static elliptic_curve_t
curve_copy (elliptic_curve_t E)
{
  elliptic_curve_t R;

  R.p = mpi_copy (E.p);
  R.a = mpi_copy (E.a);
  R.b = mpi_copy (E.b);
  point_init (&R.G);
  point_set (&R.G, &E.G);
  R.n = mpi_copy (E.n);

  return R;
}
예제 #5
0
파일: mpi-div.c 프로젝트: 3null/fastsocket
int
mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor )
{
	int rc = -ENOMEM;
	int divisor_sign = divisor->sign;
	MPI temp_divisor = NULL;

	/* We need the original value of the divisor after the remainder has been
	 * preliminary calculated.	We have to copy it to temporary space if it's
	 * the same variable as REM.  */
	if( rem == divisor ) {
		if (mpi_copy( &temp_divisor, divisor ) < 0) goto nomem;
		divisor = temp_divisor;
	}

	if (mpi_tdiv_qr(NULL, rem, dividend, divisor ) < 0) goto nomem;
	if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
		if (mpi_add( rem, rem, divisor) < 0) goto nomem;

	rc = 0;

 nomem:
	if( temp_divisor )
		mpi_free(temp_divisor);
	return rc;
}
예제 #6
0
/* This function returns a new context for Barrett based operations on
   the modulus M.  This context needs to be released using
   _gcry_mpi_barrett_free.  If COPY is true M will be transferred to
   the context and the user may change M.  If COPY is false, M may not
   be changed until gcry_mpi_barrett_free has been called. */
mpi_barrett_t
_gcry_mpi_barrett_init (gcry_mpi_t m, int copy)
{
  mpi_barrett_t ctx;
  gcry_mpi_t tmp;

  mpi_normalize (m);
  ctx = xcalloc (1, sizeof *ctx);

  if (copy)
    {
      ctx->m = mpi_copy (m);
      ctx->m_copied = 1;
    }
  else
    ctx->m = m;

  ctx->k = mpi_get_nlimbs (m);
  tmp = mpi_alloc (ctx->k + 1);

  /* Barrett precalculation: y = floor(b^(2k) / m). */
  mpi_set_ui (tmp, 1);
  mpi_lshift_limbs (tmp, 2 * ctx->k);
  mpi_fdiv_q (tmp, tmp, m);

  ctx->y  = tmp;
  ctx->r1 = mpi_alloc ( 2 * ctx->k + 1 );
  ctx->r2 = mpi_alloc ( 2 * ctx->k + 1 );

  return ctx;
}
예제 #7
0
파일: mpi-div.c 프로젝트: 3null/fastsocket
int
mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor )
{
    int divisor_sign = divisor->sign;
    MPI temp_divisor = NULL;

    if( quot == divisor || rem == divisor ) {
	if (mpi_copy( &temp_divisor, divisor ) < 0)
		return -ENOMEM;
	divisor = temp_divisor;
    }

    if (mpi_tdiv_qr( quot, rem, dividend, divisor ) < 0)
	    goto nomem;

    if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
	    if (mpi_sub_ui( quot, quot, 1 ) < 0)
		    goto nomem;
	    if (mpi_add( rem, rem, divisor) < 0)
		    goto nomem;
    }

    if( temp_divisor )
	mpi_free(temp_divisor);

    return 0;

 nomem:
    mpi_free(temp_divisor);
    return -ENOMEM;
}
예제 #8
0
파일: ecdh.c 프로젝트: Cy-4AH/showtime
/*
 * Compute shared secret (SEC1 3.3.1)
 */
int ecdh_compute_shared( ecp_group *grp, mpi *z,
                         const ecp_point *Q, const mpi *d,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng )
{
    int ret;
    ecp_point P;

    ecp_point_init( &P );

    /*
     * Make sure Q is a valid pubkey before using it
     */
    MPI_CHK( ecp_check_pubkey( grp, Q ) );

    MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );

    if( ecp_is_zero( &P ) )
    {
        ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA;
        goto cleanup;
    }

    MPI_CHK( mpi_copy( z, &P.X ) );

cleanup:
    ecp_point_free( &P );

    return( ret );
}
예제 #9
0
파일: rsa.c 프로젝트: ahawad/opensgx
/*
 * Generate or update blinding values, see section 10 of:
 *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
 *  DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer
 *  Berlin Heidelberg, 1996. p. 104-113.
 */
static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf,
                 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
    int ret, count = 0;

#if defined(POLARSSL_THREADING_C)
    polarssl_mutex_lock( &ctx->mutex );
#endif

    if( ctx->Vf.p != NULL )
    {
        /* We already have blinding values, just update them by squaring */
        MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
        MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) );
        MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
        MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) );

        goto done;
    }

    /* Unblinding value: Vf = random number, invertible mod N */
    do {
        if( count++ > 10 )
            return( POLARSSL_ERR_RSA_RNG_FAILED );

        MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) );
        MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) );
    } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 );

    /* Blinding value: Vi =  Vf^(-e) mod N */
    MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) );
    MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) );

done:
    if( Vi != &ctx->Vi )
    {
        MPI_CHK( mpi_copy( Vi, &ctx->Vi ) );
        MPI_CHK( mpi_copy( Vf, &ctx->Vf ) );
    }

cleanup:
#if defined(POLARSSL_THREADING_C)
    polarssl_mutex_unlock( &ctx->mutex );
#endif

    return( ret );
}
예제 #10
0
/*
 * Return a copy of a curve object.
 */
elliptic_curve_t
_gcry_ecc_curve_copy (elliptic_curve_t E)
{
  elliptic_curve_t R;

  R.model = E.model;
  R.dialect = E.dialect;
  R.name = E.name;
  R.p = mpi_copy (E.p);
  R.a = mpi_copy (E.a);
  R.b = mpi_copy (E.b);
  _gcry_mpi_point_init (&R.G);
  point_set (&R.G, &E.G);
  R.n = mpi_copy (E.n);

  return R;
}
예제 #11
0
void
gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
{
  gcry_mpi_t vv = mpi_copy (v);
  vv->sign = ! vv->sign;
  gcry_mpi_add (w, u, vv);
  mpi_free (vv);
}
예제 #12
0
int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial )
{
    int ret;

    if( ( ret = mpi_copy( &ctx->serial, serial ) ) != 0 )
        return( ret );

    return( 0 );
}
예제 #13
0
파일: ec.c 프로젝트: Greenchik/libgcrypt
gcry_mpi_t
_gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
{
  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

  if (!strcmp (name, "p") && ec->p)
    return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
  if (!strcmp (name, "a") && ec->a)
    return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
  if (!strcmp (name, "b") && ec->b)
    return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
  if (!strcmp (name, "n") && ec->n)
    return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
  if (!strcmp (name, "d") && ec->d)
    return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);

  /* Return a requested point coordinate.  */
  if (!strcmp (name, "g.x") && ec->G && ec->G->x)
    return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
  if (!strcmp (name, "g.y") && ec->G && ec->G->y)
    return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
  if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
    return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
  if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
    return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);

  /* If a point has been requested, return it in standard encoding.  */
  if (!strcmp (name, "g") && ec->G)
    return _gcry_mpi_ec_ec2os (ec->G, ec);
  if (!strcmp (name, "q"))
    {
      /* If only the private key is given, compute the public key.  */
      if (!ec->Q && ec->d && ec->G && ec->p && ec->a)
        {
          ec->Q = gcry_mpi_point_new (0);
          _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
        }

      if (ec->Q)
        return _gcry_mpi_ec_ec2os (ec->Q, ec);
    }

  return NULL;
}
/****************
 * Find the greatest common divisor G of A and B.
 * Return: true if this 1, false in all other cases
 */
int
mpi_gcd( MPI g, MPI xa, MPI xb )
{
    MPI a, b;

    a = mpi_copy(xa);
    b = mpi_copy(xb);

    /* TAOCP Vol II, 4.5.2, Algorithm A */
    a->sign = 0;
    b->sign = 0;
    while( mpi_cmp_ui( b, 0 ) ) {
	mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
	mpi_set(a,b);
	mpi_set(b,g);
    }
    mpi_set(g, a);

    mpi_free(a);
    mpi_free(b);
    return !mpi_cmp_ui( g, 1);
}
예제 #15
0
파일: ec.c 프로젝트: Greenchik/libgcrypt
gpg_err_code_t
_gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
                      gcry_ctx_t ctx)
{
  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);

  if (!strcmp (name, "p"))
    {
      mpi_free (ec->p);
      ec->p = mpi_copy (newvalue);
      ec_get_reset (ec);
    }
  else if (!strcmp (name, "a"))
    {
      mpi_free (ec->a);
      ec->a = mpi_copy (newvalue);
      ec_get_reset (ec);
    }
  else if (!strcmp (name, "b"))
    {
      mpi_free (ec->b);
      ec->b = mpi_copy (newvalue);
    }
  else if (!strcmp (name, "n"))
    {
      mpi_free (ec->n);
      ec->n = mpi_copy (newvalue);
    }
  else if (!strcmp (name, "d"))
    {
      mpi_free (ec->d);
      ec->d = mpi_copy (newvalue);
    }
  else
    return GPG_ERR_UNKNOWN_NAME;

  return 0;
}
예제 #16
0
파일: PKey.cpp 프로젝트: CheneyWong/fibjs
result_t PKey::copy(const pk_context &key)
{
    pk_type_t type = pk_get_type(&key);
    int ret;

    if (type == POLARSSL_PK_RSA)
    {
        rsa_context *rsa = pk_rsa(key);

        ret = pk_init_ctx(&m_key, pk_info_from_type(POLARSSL_PK_RSA));
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        rsa_context *rsa1 = pk_rsa(m_key);

        ret = rsa_copy(rsa1, rsa);
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        return 0;
    }

    if (type == POLARSSL_PK_ECKEY)
    {
        ecp_keypair *ecp = pk_ec(key);

        ret = pk_init_ctx(&m_key, pk_info_from_type(POLARSSL_PK_ECKEY));
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        ecp_keypair *ecp1 = pk_ec(m_key);

        ret = ecp_group_copy(&ecp1->grp, &ecp->grp);
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        ret = mpi_copy(&ecp1->d, &ecp->d);
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        ret = ecp_copy(&ecp1->Q, &ecp->Q);
        if (ret != 0)
            return CHECK_ERROR(_ssl::setError(ret));

        return 0;
    }

    return CHECK_ERROR(CALL_E_INVALID_CALL);
}
예제 #17
0
파일: mpi-add.c 프로젝트: BridgeNY/purdue
void
mpi_sub(MPI w, MPI u, MPI v)
{
    if( w == v ) {
	MPI vv = mpi_copy(v);
	vv->sign = !vv->sign;
	mpi_add( w, u, vv );
	mpi_free(vv);
    }
    else {
	/* fixme: this is not thread-save (we temp. modify v) */
	v->sign = !v->sign;
	mpi_add( w, u, v );
	v->sign = !v->sign;
    }
}
예제 #18
0
void Init_Direct_Mode(mp_image_t *mpi)
{
	if ((LCD_OUT & display_mode) == TV_OUT)
	{
		img_param.ipu_d_fmt |= (OUT_FMT_YUV422 | (1 << 16));
		img_param.in_bpp = 16;
	}
	else
	{
		img_param.ipu_d_fmt |= OUT_FMT_RGB888;
		img_param.in_bpp = 32;
	}

	if(display_mode & DECODE_BUFFER)
	{
  		img_param.y_buf = mpi->planes[0];
		img_param.u_buf = mpi->planes[1];
		img_param.v_buf = mpi->planes[2];
		stride.y = mpi->stride[0];
		stride.u = mpi->stride[1];
		stride.v = mpi->stride[2];
		lcd_flush_frame_all();
  		jz47_put_image_with_ipu = jz47_put_image_with_direct_ipu_nobuffer;
		printf("direct buf\n");
	}else
	{

		CreateImage(mpi->width,mpi->height,mpi->chroma_width,mpi->chroma_height,mpi->bpp);
		mpi_copy(yuv_cur,mpi);
		img_param.y_buf = yuv_cur->y_framebuf;
		img_param.u_buf = yuv_cur->u_framebuf;
		img_param.v_buf = yuv_cur->v_framebuf;
		stride.y = yuv_cur->ystride;
		stride.u = yuv_cur->ustride;
		stride.v = yuv_cur->vstride;
		yuv_cur = yuv_cur->nextframe;
		jz47_put_image_with_ipu = jz47_put_image_with_direct_ipu_buffer;
		printf("create buf\n");
	}
 	printf("stride.y = %d\n",stride.y);
  	printf("stride.u = %d\n",stride.u);
  	printf("stride.v = %d\n",stride.v);
	printf("display_mode = %x\n",display_mode);

	lcd_ioctl(&img_param, IOCTL_DMA1_TO_IPU);

}
예제 #19
0
int mpi_sub(MPI w, MPI u, MPI v)
{
	int rc;

	if (w == v) {
		MPI vv;
		if (mpi_copy(&vv, v) < 0)
			return -ENOMEM;
		vv->sign = !vv->sign;
		rc = mpi_add(w, u, vv);
		mpi_free(vv);
	} else {
		
		v->sign = !v->sign;
		rc = mpi_add(w, u, v);
		v->sign = !v->sign;
	}
	return rc;
}
예제 #20
0
void
_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
{
    int divisor_sign = divisor->sign;
    gcry_mpi_t temp_divisor = NULL;

    if( quot == divisor || rem == divisor ) {
	temp_divisor = mpi_copy( divisor );
	divisor = temp_divisor;
    }

    _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );

    if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
	gcry_mpi_sub_ui( quot, quot, 1 );
	gcry_mpi_add( rem, rem, divisor);
    }

    if( temp_divisor )
	mpi_free(temp_divisor);
}
예제 #21
0
static void
sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
{
    gcry_mpi_t k;
    gcry_mpi_t t   = mpi_alloc( mpi_get_nlimbs(a) );
    gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
    gcry_mpi_t p_1 = mpi_copy(skey->p);

   /*
    * b = (t * inv) mod (p-1)
    * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
    * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
    *
    */
    mpi_sub_ui(p_1, p_1, 1);
    k = gen_k( skey->p, 0 /* no small K ! */ );
    gcry_mpi_powm( a, skey->g, k, skey->p );
    mpi_mul(t, skey->x, a );
    mpi_subm(t, input, t, p_1 );
    mpi_invm(inv, k, p_1 );
    mpi_mulm(b, t, inv, p_1 );

#if 0
    if( DBG_CIPHER ) 
      {
	log_mpidump("elg sign p= ", skey->p);
	log_mpidump("elg sign g= ", skey->g);
	log_mpidump("elg sign y= ", skey->y);
	log_mpidump("elg sign x= ", skey->x);
	log_mpidump("elg sign k= ", k);
	log_mpidump("elg sign M= ", input);
	log_mpidump("elg sign a= ", a);
	log_mpidump("elg sign b= ", b);
      }
#endif
    mpi_free(k);
    mpi_free(t);
    mpi_free(inv);
    mpi_free(p_1);
}
예제 #22
0
void
_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
{
    int divisor_sign = divisor->sign;
    gcry_mpi_t temp_divisor = NULL;

    /* We need the original value of the divisor after the remainder has been
     * preliminary calculated.	We have to copy it to temporary space if it's
     * the same variable as REM.  */
    if( rem == divisor ) {
	temp_divisor = mpi_copy( divisor );
	divisor = temp_divisor;
    }

    _gcry_mpi_tdiv_r( rem, dividend, divisor );

    if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
	gcry_mpi_add( rem, rem, divisor);

    if( temp_divisor )
	mpi_free(temp_divisor);
}
예제 #23
0
파일: ecdh.c 프로젝트: Cy-4AH/showtime
/*
 * Get parameters from a keypair
 */
int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key,
                     ecdh_side side )
{
    int ret;

    if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 )
        return( ret );

    /* If it's not our key, just import the public part as Qp */
    if( side == POLARSSL_ECDH_THEIRS )
        return( ecp_copy( &ctx->Qp, &key->Q ) );

    /* Our key: import public (as Q) and private parts */
    if( side != POLARSSL_ECDH_OURS )
        return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );

    if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ||
        ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 )
        return( ret );

    return( 0 );
}
예제 #24
0
int jz47_put_image_with_direct_ipu_buffer (struct vf_instance_s* vf, mp_image_t *mpi, double pts)
{
#ifdef VERIFY_CRC32
  SwsContext *c = vf->priv->ctx;

        crc32_verify (mpi->planes[0], c->srcH, c->srcW, mpi->stride[0]);
        crc32_verify (mpi->planes[1], c->srcH / 2, c->srcW / 2, mpi->stride[1]);
        crc32_verify (mpi->planes[2], c->srcH / 2, c->srcW / 2, mpi->stride[2]);
#endif
	#if USE_OSD
		if(pFunction)
        pFunction(NULL);
    #endif

	if(yuv_next)
	{
			mpi_copy(yuv_next,mpi);
			yuv_next = yuv_next->nextframe;
	}
	if(yuv_cur)
	{
		// set Y(mpi->planes[0]), U(mpi->planes[1]), V addr (mpi->planes[2])
	 img_param.y_buf = yuv_cur->y_framebuf;
	// set U addr register (mpi->planes[1])
	 img_param.u_buf = yuv_cur->u_framebuf;
	// set V addr register (mpi->planes[2])
	 img_param.v_buf = yuv_cur->v_framebuf;

	// set Y(mpi->stride[0]) U(mpi->stride[1]) V(mpi->stride[2]) stride
	  stride.y = yuv_cur->ystride;
	  stride.u = yuv_cur->ustride;
	  stride.v = yuv_cur->vstride;
	  yuv_cur = yuv_cur->nextframe;
	  lcd_flush_frame_all();
	  ipu_ioctl((void *)0, IOCTL_IPU_CHANGE_BUFF);
	}
	return 1;
}
예제 #25
0
int
main (int argc, char **argv)
{
  const char *pgm;
  int last_argc = -1;
  int print_config = 0;
  int i, c;
  int state = 0;
  char strbuf[4096];
  int stridx = 0;

  if (argc)
    {
      pgm = strrchr (*argv, '/');
      if (pgm)
        pgm++;
      else
        pgm = *argv;
      argc--; argv++;
    }
  else
    pgm = "?";

  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--version")
               || !strcmp (*argv, "--help"))
        {
          printf ("%s " MPICALC_VERSION "\n"
                  "libgcrypt %s\n"
                  "Copyright (C) 1997, 2013  Werner Koch\n"
                  "License LGPLv2.1+: GNU LGPL version 2.1 or later "
                  "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
                  "This is free software: you are free to change and "
                  "redistribute it.\n"
                  "There is NO WARRANTY, to the extent permitted by law.\n"
                  "\n"
                  "Syntax: mpicalc [options]\n"
                  "Simple interactive big integer RPN calculator\n"
                  "\n"
                  "Options:\n"
                  "  --version           print version information\n"
                  "  --print-config      print the Libgcrypt config\n"
                  "  --disable-hwf NAME  disable feature NAME\n",
                  pgm, gcry_check_version (NULL));
          exit (0);
        }
      else if (!strcmp (*argv, "--print-config"))
        {
          argc--; argv++;
          print_config = 1;
        }
      else if (!strcmp (*argv, "--disable-hwf"))
        {
          argc--; argv++;
          if (argc)
            {
              if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
                fprintf (stderr, "%s: unknown hardware feature `%s'"
                         " - option ignored\n", pgm, *argv);
              argc--; argv++;
            }
        }
    }

  if (argc)
    {
      fprintf (stderr, "usage: %s [options]  (--help for help)\n", pgm);
      exit (1);
    }

  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
    {
      fprintf (stderr, "%s: Libgcrypt is too old (need %s, have %s)\n",
               pgm, NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
      exit (1);
    }
  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
  if (print_config)
    {
      gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
      exit (0);
    }

  for (i = 0; i < STACKSIZE; i++)
    stack[i] = NULL;
  stackidx = 0;

  while ((c = my_getc ()) != EOF)
    {
      if (!state) /* waiting */
	{
	  if (isdigit (c))
	    {
	      state = 1;
	      ungetc (c, stdin);
	      strbuf[0] = '0';
	      strbuf[1] = 'x';
	      stridx = 2;
	    }
	  else if (isspace (c))
	    ;
	  else
	    {
	      switch (c)
		{
                case '#':
                  state = 2;
                  break;
		case '+':
		  if ((c = my_getc ()) == '+')
		    do_inc ();
		  else
		    {
		      ungetc (c, stdin);
		      do_add ();
		    }
		  break;
                case '-':
		  if ((c = my_getc ()) == '-')
		    do_dec ();
		  else if (isdigit (c)
                           || (c >= 'A' && c <= 'F')
                           || (c >= 'a' && c <= 'f'))
		    {
		      state = 1;
		      ungetc (c, stdin);
		      strbuf[0] = '-';
		      strbuf[1] = '0';
		      strbuf[2] = 'x';
		      stridx = 3;
		    }
		  else
		    {
		      ungetc (c, stdin);
		      do_sub ();
		    }
		  break;
		case '*':
		  do_mul ();
		  break;
		case 'm':
		  do_mulm ();
		  break;
		case '/':
		  do_div ();
		  break;
		case '%':
		  do_rem ();
		  break;
		case '^':
		  do_powm ();
		  break;
		case '<':
		  do_lshift ();
		  break;
		case '>':
		  do_rshift ();
		  break;
		case 'I':
		  do_inv ();
		  break;
		case 'G':
		  do_gcd ();
		  break;
		case 'i':	/* dummy */
		  if (!stackidx)
		    fputs ("stack underflow\n", stderr);
		  else
		    {
		      mpi_release (stack[stackidx - 1]);
		      stackidx--;
		    }
		  break;
		case 'd':	/* duplicate the tos */
		  if (!stackidx)
		    fputs ("stack underflow\n", stderr);
		  else if (stackidx < STACKSIZE)
		    {
		      mpi_release (stack[stackidx]);
		      stack[stackidx] = mpi_copy (stack[stackidx - 1]);
		      stackidx++;
		    }
		  else
		    fputs ("stack overflow\n", stderr);
		  break;
		case 'r':	/* swap top elements */
		  if (stackidx < 2)
		    fputs ("stack underflow\n", stderr);
		  else if (stackidx < STACKSIZE)
		    {
		      gcry_mpi_t tmp = stack[stackidx-1];
                      stack[stackidx-1] = stack[stackidx - 2];
                      stack[stackidx-2] = tmp;
		    }
		  break;
                case 'b':
                  do_nbits ();
                  break;
                case 'P':
                  do_primecheck ();
                  break;
		case 'c':
		  for (i = 0; i < stackidx; i++)
                    {
                      mpi_release (stack[i]); stack[i] = NULL;
                    }
		  stackidx = 0;
		  break;
		case 'p':	/* print the tos */
		  if (!stackidx)
		    puts ("stack is empty");
		  else
		    {
		      print_mpi (stack[stackidx - 1]);
		      putchar ('\n');
		    }
		  break;
		case 'f':	/* print the stack */
		  for (i = stackidx - 1; i >= 0; i--)
		    {
		      printf ("[%2d]: ", i);
		      print_mpi (stack[i]);
		      putchar ('\n');
		    }
		  break;
                case '?':
                  print_help ();
                  break;
		default:
		  fputs ("invalid operator\n", stderr);
		}
	    }
	}
      else if (state == 1) /* In a number. */
	{
	  if (!isxdigit (c))
	    {
              /* Store the number */
	      state = 0;
	      ungetc (c, stdin);
	      if (stridx < sizeof strbuf)
		strbuf[stridx] = 0;

	      if (stackidx < STACKSIZE)
		{
		  if (!stack[stackidx])
		    stack[stackidx] = mpi_new (0);
		  if (scan_mpi (stack[stackidx], strbuf))
		    fputs ("invalid number\n", stderr);
		  else
		    stackidx++;
		}
	      else
		fputs ("stack overflow\n", stderr);
	    }
	  else
	    { /* Store a digit.  */
	      if (stridx < sizeof strbuf - 1)
		strbuf[stridx++] = c;
	      else if (stridx == sizeof strbuf - 1)
		{
		  strbuf[stridx] = 0;
		  fputs ("input too large - truncated\n", stderr);
		  stridx++;
		}
	    }
	}
      else if (state == 2) /* In a comment. */
        {
          if (c == '\n')
            state = 0;
        }

    }

  for (i = 0; i < stackidx; i++)
    mpi_release (stack[i]);
  return 0;
}
예제 #26
0
/****************
 * We do not need to use the strongest RNG because we gain no extra
 * security from it - The prime number is public and we could also
 * offer the factors for those who are willing to check that it is
 * indeed a strong prime.  With ALL_FACTORS set to true all afcors of
 * prime-1 are returned in FACTORS.
 *
 * mode 0: Standard
 *	1: Make sure that at least one factor is of size qbits.
 */
static gcry_err_code_t
prime_generate_internal (int mode,
			 gcry_mpi_t *prime_generated, unsigned int pbits,
			 unsigned int qbits, gcry_mpi_t g,
			 gcry_mpi_t **ret_factors,
			 gcry_random_level_t randomlevel, unsigned int flags,
                         int all_factors,
                         gcry_prime_check_func_t cb_func, void *cb_arg)
{
  gcry_err_code_t err = 0;
  gcry_mpi_t *factors_new = NULL; /* Factors to return to the
				     caller.  */
  gcry_mpi_t *factors = NULL;	/* Current factors.  */
  gcry_mpi_t *pool = NULL;	/* Pool of primes.  */
  unsigned char *perms = NULL;	/* Permutations of POOL.  */
  gcry_mpi_t q_factor = NULL;	/* Used if QBITS is non-zero.  */
  unsigned int fbits = 0;	/* Length of prime factors.  */
  unsigned int n = 0;		/* Number of factors.  */
  unsigned int m = 0;		/* Number of primes in pool.  */
  gcry_mpi_t q = NULL;		/* First prime factor.  */
  gcry_mpi_t prime = NULL;	/* Prime candidate.  */
  unsigned int nprime = 0;	/* Bits of PRIME.  */
  unsigned int req_qbits;       /* The original QBITS value.  */
  gcry_mpi_t val_2;             /* For check_prime().  */
  unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
  unsigned int count1 = 0, count2 = 0;
  unsigned int i = 0, j = 0;

  if (pbits < 48)
    return GPG_ERR_INV_ARG;

  /* If QBITS is not given, assume a reasonable value. */
  if (!qbits)
    qbits = pbits / 3;

  req_qbits = qbits;

  /* Find number of needed prime factors.  */
  for (n = 1; (pbits - qbits - 1) / n  >= qbits; n++)
    ;
  n--;

  val_2 = mpi_alloc_set_ui (2);

  if ((! n) || ((mode == 1) && (n < 2)))
    {
      err = GPG_ERR_INV_ARG;
      goto leave;
    }

  if (mode == 1)
    {
      n--;
      fbits = (pbits - 2 * req_qbits -1) / n;
      qbits =  pbits - req_qbits - n * fbits;
    }
  else
    {
      fbits = (pbits - req_qbits -1) / n;
      qbits = pbits - n * fbits;
    }
  
  if (DBG_CIPHER)
    log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
               pbits, req_qbits, qbits, fbits, n);

  prime = gcry_mpi_new (pbits);

  /* Generate first prime factor.  */
  q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
  
  if (mode == 1)
    q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
  
  /* Allocate an array to hold the factors + 2 for later usage.  */
  factors = gcry_calloc (n + 2, sizeof (*factors));
  if (!factors)
    {
      err = gpg_err_code_from_errno (errno);
      goto leave;
    }
      
  /* Make a pool of 3n+5 primes (this is an arbitrary value).  */
  m = n * 3 + 5;
  if (mode == 1) /* Need some more (for e.g. DSA).  */
    m += 5;
  if (m < 25)
    m = 25;
  pool = gcry_calloc (m , sizeof (*pool));
  if (! pool)
    {
      err = gpg_err_code_from_errno (errno);
      goto leave;
    }

  /* Permutate over the pool of primes.  */
  do
    {
    next_try:
      if (! perms)
        {
          /* Allocate new primes.  */
          for(i = 0; i < m; i++)
            {
              mpi_free (pool[i]);
              pool[i] = NULL;
            }

          /* Init m_out_of_n().  */
          perms = gcry_calloc (1, m);
          if (! perms)
            {
              err = gpg_err_code_from_errno (errno);
              goto leave;
            }
          for(i = 0; i < n; i++)
            {
              perms[i] = 1;
              pool[i] = gen_prime (fbits, is_secret,
                                   randomlevel, NULL, NULL);
              factors[i] = pool[i];
            }
        }
      else
        {
          m_out_of_n ((char*)perms, n, m);
          for (i = j = 0; (i < m) && (j < n); i++)
            if (perms[i])
              {
                if(! pool[i])
                  pool[i] = gen_prime (fbits, 0, 1, NULL, NULL);
                factors[j++] = pool[i];
              }
          if (i == n)
            {
              gcry_free (perms);
              perms = NULL;
              progress ('!');
              goto next_try;	/* Allocate new primes.  */
            }
        }

	/* Generate next prime candidate:
	   p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. 
        */
	mpi_set (prime, q);
	mpi_mul_ui (prime, prime, 2);
	if (mode == 1)
	  mpi_mul (prime, prime, q_factor);
	for(i = 0; i < n; i++)
	  mpi_mul (prime, prime, factors[i]);
	mpi_add_ui (prime, prime, 1);
	nprime = mpi_get_nbits (prime);

	if (nprime < pbits)
	  {
	    if (++count1 > 20)
	      {
		count1 = 0;
		qbits++;
		progress('>');
		mpi_free (q);
		q = gen_prime (qbits, 0, 0, NULL, NULL);
		goto next_try;
	      }
	  }
	else
	  count1 = 0;
        
	if (nprime > pbits)
	  {
	    if (++count2 > 20)
	      {
		count2 = 0;
		qbits--;
		progress('<');
		mpi_free (q);
		q = gen_prime (qbits, 0, 0, NULL, NULL);
		goto next_try;
	      }
	  }
	else
	  count2 = 0;
    }
  while (! ((nprime == pbits) && check_prime (prime, val_2, cb_func, cb_arg)));

  if (DBG_CIPHER)
    {
      progress ('\n');
      log_mpidump ("prime    : ", prime);
      log_mpidump ("factor  q: ", q);
      if (mode == 1)
        log_mpidump ("factor q0: ", q_factor);
      for (i = 0; i < n; i++)
        log_mpidump ("factor pi: ", factors[i]);
      log_debug ("bit sizes: prime=%u, q=%u",
                 mpi_get_nbits (prime), mpi_get_nbits (q));
      if (mode == 1)
        log_debug (", q0=%u", mpi_get_nbits (q_factor));
      for (i = 0; i < n; i++)
        log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
      progress('\n');
    }

  if (ret_factors)
    {
      /* Caller wants the factors.  */
      factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
      if (! factors_new)
        {
          err = gpg_err_code_from_errno (errno);
          goto leave;
        }

      if (all_factors)
        {
          i = 0;
          factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
          factors_new[i++] = mpi_copy (q);
          if (mode == 1)
            factors_new[i++] = mpi_copy (q_factor);
          for(j=0; j < n; j++)
            factors_new[i++] = mpi_copy (factors[j]);
        }
      else
        {
          i = 0;
          if (mode == 1)
            {
              factors_new[i++] = mpi_copy (q_factor);
              for (; i <= n; i++)
                factors_new[i] = mpi_copy (factors[i]);
            }
          else
            for (; i < n; i++ )
              factors_new[i] = mpi_copy (factors[i]);
        }
    }
  
  if (g)
    {
      /* Create a generator (start with 3).  */
      gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
      gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
      gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
      
      if (mode == 1)
        err = GPG_ERR_NOT_IMPLEMENTED;
      else
        {
          factors[n] = q;
          factors[n + 1] = mpi_alloc_set_ui (2);
          mpi_sub_ui (pmin1, prime, 1);
          mpi_set_ui (g, 2);
          do
            {
              mpi_add_ui (g, g, 1);
              if (DBG_CIPHER)
                {
                  log_debug ("checking g:");
                  gcry_mpi_dump (g);
                  log_printf ("\n");
                }
              else
                progress('^');
              for (i = 0; i < n + 2; i++)
                {
                  mpi_fdiv_q (tmp, pmin1, factors[i]);
                  /* No mpi_pow(), but it is okay to use this with mod
                     prime.  */
                  gcry_mpi_powm (b, g, tmp, prime);
                  if (! mpi_cmp_ui (b, 1))
                    break;
                }
              if (DBG_CIPHER)
                progress('\n');
            } 
          while (i < n + 2);

          mpi_free (factors[n+1]);
          mpi_free (tmp);
          mpi_free (b);
          mpi_free (pmin1);
        }
    }
  
  if (! DBG_CIPHER)
    progress ('\n');


 leave:
  if (pool)
    {
      for(i = 0; i < m; i++)
	mpi_free (pool[i]);
      gcry_free (pool);
    }
  if (factors)
    gcry_free (factors);  /* Factors are shallow copies.  */
  if (perms)
    gcry_free (perms);

  mpi_free (val_2);
  mpi_free (q);
  mpi_free (q_factor);

  if (! err)
    {
      *prime_generated = prime;
      if (ret_factors)
	*ret_factors = factors_new;
    }
  else
    {
      if (factors_new)
	{
	  for (i = 0; factors_new[i]; i++)
	    mpi_free (factors_new[i]);
	  gcry_free (factors_new);
	}
      mpi_free (prime);
    }

  return err;
}
예제 #27
0
/****************
 * Generate a random secret exponent k from prime p, so that k is
 * relatively prime to p-1.  With SMALL_K set, k will be selected for
 * better encryption performance - this must never be used signing!
 */
static gcry_mpi_t
gen_k( gcry_mpi_t p, int small_k )
{
  gcry_mpi_t k = mpi_alloc_secure( 0 );
  gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
  gcry_mpi_t p_1 = mpi_copy(p);
  unsigned int orig_nbits = mpi_get_nbits(p);
  unsigned int nbits, nbytes;
  char *rndbuf = NULL;

  if (small_k)
    {
      /* Using a k much lesser than p is sufficient for encryption and
       * it greatly improves the encryption performance.  We use
       * Wiener's table and add a large safety margin. */
      nbits = wiener_map( orig_nbits ) * 3 / 2;
      if( nbits >= orig_nbits )
        BUG();
    }
  else
    nbits = orig_nbits;


  nbytes = (nbits+7)/8;
  if( DBG_CIPHER )
    log_debug("choosing a random k ");
  mpi_sub_ui( p_1, p, 1);
  for(;;) 
    {
      if( !rndbuf || nbits < 32 ) 
        {
          gcry_free(rndbuf);
          rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
        }
      else
        { 
          /* Change only some of the higher bits.  We could improve
             this by directly requesting more memory at the first call
             to get_random_bytes() and use this the here maybe it is
             easier to do this directly in random.c Anyway, it is
             highly inlikely that we will ever reach this code. */
          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
          memcpy( rndbuf, pp, 4 );
          gcry_free(pp);
	}
      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
        
      for(;;)
        {
          if( !(mpi_cmp( k, p_1 ) < 0) )  /* check: k < (p-1) */
            {
              if( DBG_CIPHER )
                progress('+');
              break; /* no  */
            }
          if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
            {
              if( DBG_CIPHER )
                progress('-');
              break; /* no */
            }
          if (gcry_mpi_gcd( temp, k, p_1 ))
            goto found;  /* okay, k is relative prime to (p-1) */
          mpi_add_ui( k, k, 1 );
          if( DBG_CIPHER )
            progress('.');
	}
    }
 found:
  gcry_free(rndbuf);
  if( DBG_CIPHER )
    progress('\n');
  mpi_free(p_1);
  mpi_free(temp);

  return k;
}
예제 #28
0
/****************
 * RES = (BASE[0] ^ EXP[0]) *  (BASE[1] ^ EXP[1]) * ... * mod M
 */
int
mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
{
	int rc = -ENOMEM;
	int k;	/* number of elements */
	int t;	/* bit size of largest exponent */
	int i, j, idx;
	MPI *G = NULL;	/* table with precomputed values of size 2^k */
	MPI tmp = NULL;

	for(k=0; basearray[k]; k++ )
		;
	if (!k) { printk("mpi_mulpowm: assert(k) failed\n"); BUG(); }
	for(t=0, i=0; (tmp=exparray[i]); i++ ) {
		j = mpi_get_nbits(tmp);
		if( j > t )
			t = j;
	}
	if (i!=k) { printk("mpi_mulpowm: assert(i==k) failed\n"); BUG(); }
	if (!t)	  { printk("mpi_mulpowm: assert(t) failed\n"); BUG(); }
	if (k>=10) { printk("mpi_mulpowm: assert(k<10) failed\n"); BUG(); }

//daveti: hack
	//G = kzalloc( (1<<k) * sizeof *G, GFP_KERNEL );
	G = kzalloc( (1<<k) * sizeof *G, GFP_ATOMIC );
	if (!G) goto nomem;

	/* and calculate */
	tmp =  mpi_alloc( mpi_get_nlimbs(m)+1 ); if (!tmp) goto nomem;
	if (mpi_set_ui( res, 1 ) < 0) goto nomem;
	for(i = 1; i <= t; i++ ) {
		if (mpi_mulm(tmp, res, res, m ) < 0) goto nomem;
		idx = build_index( exparray, k, i, t );
		if (!(idx >= 0 && idx < (1<<k))) {
			printk("mpi_mulpowm: assert(idx >= 0 && idx < (1<<k)) failed\n");
			BUG();
		}
		if( !G[idx] ) {
			if( !idx ) {
				G[0] = mpi_alloc_set_ui( 1 );
				if (!G[0]) goto nomem;
			}
			else {
				for(j=0; j < k; j++ ) {
					if( (idx & (1<<j) ) ) {
						if( !G[idx] ) {
							if (mpi_copy( &G[idx], basearray[j] ) < 0)
								goto nomem;
						}
						else {
							if (mpi_mulm(G[idx],G[idx],basearray[j],m) < 0)
								goto nomem;
						}
					}
				}
				if( !G[idx] ) {
					G[idx] = mpi_alloc(0);
					if (!G[idx]) goto nomem;
				}
			}
		}
		if (mpi_mulm(res, tmp, G[idx], m ) < 0) goto nomem;
	}

	rc = 0;
 nomem:
	/* cleanup */
	mpi_free(tmp);
	for(i=0; i < (1<<k); i++ )
		mpi_free(G[i]);
	kfree(G);
	return rc;
}
예제 #29
0
파일: ec.c 프로젝트: Greenchik/libgcrypt
/* 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
}
예제 #30
0
/*
 * Return true if n is probably a prime
 */
static int
is_prime (gcry_mpi_t n, int steps, unsigned int *count)
{
  gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
  gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
  gcry_mpi_t q;
  unsigned i, j, k;
  int rc = 0;
  unsigned nbits = mpi_get_nbits( n );

  mpi_sub_ui( nminus1, n, 1 );

  /* Find q and k, so that n = 1 + 2^k * q . */
  q = mpi_copy ( nminus1 );
  k = mpi_trailing_zeros ( q );
  mpi_tdiv_q_2exp (q, q, k);

  for (i=0 ; i < steps; i++ )
    {
      ++*count;
      if( !i )
        {
          mpi_set_ui( x, 2 );
        }
      else
        {
          gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );

          /* Make sure that the number is smaller than the prime and
             keep the randomness of the high bit. */
          if ( mpi_test_bit ( x, nbits-2) )
            {
              mpi_set_highbit ( x, nbits-2); /* Clear all higher bits. */
            }
          else
            {
              mpi_set_highbit( x, nbits-2 );
              mpi_clear_bit( x, nbits-2 );
            }
          assert ( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
	}
      gcry_mpi_powm ( y, x, q, n);
      if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
        {
          for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
            {
              gcry_mpi_powm(y, y, a2, n);
              if( !mpi_cmp_ui( y, 1 ) )
                goto leave; /* Not a prime. */
            }
          if (mpi_cmp( y, nminus1 ) )
            goto leave; /* Not a prime. */
	}
      progress('+');
    }
  rc = 1; /* May be a prime. */

 leave:
  mpi_free( x );
  mpi_free( y );
  mpi_free( z );
  mpi_free( nminus1 );
  mpi_free( q );
  mpi_free( a2 );

  return rc;
}