Exemple #1
0
/* Check if y^2 = x^3 - 3x + b */
static int
ecc_valid_p (struct ecc_point *pub)
{
  mpz_t t, x, y;
  mpz_t lhs, rhs;
  int res;
  mp_size_t size;

  size = pub->ecc->size;

  /* First check range */
  if (mpn_cmp (pub->p, pub->ecc->p, size) >= 0
      || mpn_cmp (pub->p + size, pub->ecc->p, size) >= 0)
    return 0;

  mpz_init (lhs);
  mpz_init (rhs);

  mpz_roinit_n (x, pub->p, size);
  mpz_roinit_n (y, pub->p + size, size);

  mpz_mul (lhs, y, y);
  mpz_mul (rhs, x, x);
  mpz_sub_ui (rhs, rhs, 3);
  mpz_mul (rhs, rhs, x);
  mpz_add (rhs, rhs, mpz_roinit_n (t, pub->ecc->b, size));

  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p, size));
  
  mpz_clear (lhs);
  mpz_clear (rhs);

  return res;
}
Exemple #2
0
static PyObject *
GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *args)
{
    int res;
    MPZ_Object *tempy = NULL, *tempm = NULL;

    if (PyTuple_GET_SIZE(args) != 2) {
        TYPE_ERROR("is_congruent() requires 2 integer arguments");
        return NULL;
    }

    if (!(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) ||
        !(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) {

        Py_XDECREF((PyObject*)tempy);
        Py_XDECREF((PyObject*)tempm);
        TYPE_ERROR("is_congruent() requires 2 integer arguments");
        return NULL;
    }

    res = mpz_congruent_p(MPZ(self), tempy->z, tempm->z);
    Py_DECREF((PyObject*)tempy);
    Py_DECREF((PyObject*)tempm);
    if (res)
        Py_RETURN_TRUE;
    else
        Py_RETURN_FALSE;
}
/* Check if y^2 = x^3 - 3x + b */
static int
ecc_valid_p (struct ecc_point *pub)
{
  mpz_t t, x, y;
  mpz_t lhs, rhs;
  int res;
  mp_size_t size;

  size = pub->ecc->p.size;

  /* First check range */
  if (mpn_cmp (pub->p, pub->ecc->p.m, size) >= 0
      || mpn_cmp (pub->p + size, pub->ecc->p.m, size) >= 0)
    return 0;

  mpz_init (lhs);
  mpz_init (rhs);

  mpz_roinit_n (x, pub->p, size);
  mpz_roinit_n (y, pub->p + size, size);

  mpz_mul (lhs, y, y);
  
  if (pub->ecc->p.bit_size == 255)
    {
      /* Check that
	 121666 (1 + x^2 - y^2) = 121665 x^2 y^2 */
      mpz_t x2;
      mpz_init (x2);
      mpz_mul (x2, x, x); /* x^2 */
      mpz_mul (rhs, x2, lhs); /* x^2 y^2 */
      mpz_sub (lhs, x2, lhs); /* x^2 - y^2 */
      mpz_add_ui (lhs, lhs, 1); /* 1 + x^2 - y^2 */
      mpz_mul_ui (lhs, lhs, 121666);
      mpz_mul_ui (rhs, rhs, 121665);

      mpz_clear (x2);
    }
  else
    {
      /* Check y^2 = x^3 - 3 x + b */
      mpz_mul (rhs, x, x);
      mpz_sub_ui (rhs, rhs, 3);
      mpz_mul (rhs, rhs, x);
      mpz_add (rhs, rhs, mpz_roinit_n (t, pub->ecc->b, size));
    }
  res = mpz_congruent_p (lhs, rhs, mpz_roinit_n (t, pub->ecc->p.m, size));
  
  mpz_clear (lhs);
  mpz_clear (rhs);

  return res;
}
Exemple #4
0
void
check_one (mpz_srcptr a, mpz_srcptr c, mpz_srcptr d, int want)
{
  int   got;
  int   swap;

  for (swap = 0; swap <= 1; swap++)
    {
      got = (mpz_congruent_p (a, c, d) != 0);
      if (want != got)
        {
          printf ("mpz_congruent_p wrong\n");
          printf ("   expected %d got %d\n", want, got);
          mpz_trace ("   a", a);
          mpz_trace ("   c", c);
          mpz_trace ("   d", d);
          mp_trace_base = -16;
          mpz_trace ("   a", a);
          mpz_trace ("   c", c);
          mpz_trace ("   d", d);
          abort ();
        }

      if (mpz_fits_ulong_p (c) && mpz_fits_ulong_p (d))
        {
          unsigned long  uc = mpz_get_ui (c);
          unsigned long  ud = mpz_get_ui (d);
          got = (mpz_congruent_ui_p (a, uc, ud) != 0);
          if (want != got)
            {
              printf    ("mpz_congruent_ui_p wrong\n");
              printf    ("   expected %d got %d\n", want, got);
              mpz_trace ("   a", a);
              printf    ("   c=%lu\n", uc);
              printf    ("   d=%lu\n", ud);
              mp_trace_base = -16;
              mpz_trace ("   a", a);
              printf    ("   c=0x%lX\n", uc);
              printf    ("   d=0x%lX\n", ud);
              abort ();
            }
        }

      MPZ_SRCPTR_SWAP (a, c);
    }
}
Exemple #5
0
int
mpz_congruent_ui_p (mpz_srcptr a, unsigned long cu, unsigned long du)
{
  mp_srcptr  ap;
  mp_size_t  asize;
  mp_limb_t  c, d, r;

  if (UNLIKELY (du == 0))
    return (mpz_cmp_ui (a, cu) == 0);

  asize = SIZ(a);
  if (asize == 0)
    {
      if (cu < du)
        return cu == 0;
      else
        return (cu % du) == 0;
    }

  /* For nails don't try to be clever if c or d is bigger than a limb, just
     fake up some mpz_t's and go to the main mpz_congruent_p.  */
  if (du > GMP_NUMB_MAX || cu > GMP_NUMB_MAX)
    {
      mp_limb_t  climbs[2], dlimbs[2];
      mpz_t      cz, dz;

      ALLOC(cz) = 2;
      PTR(cz) = climbs;
      ALLOC(dz) = 2;
      PTR(dz) = dlimbs;

      mpz_set_ui (cz, cu);
      mpz_set_ui (dz, du);
      return mpz_congruent_p (a, cz, dz);
    }

  /* NEG_MOD works on limbs, so convert ulong to limb */
  c = cu;
  d = du;

  if (asize < 0)
    {
      asize = -asize;
      NEG_MOD (c, c, d);
    }

  ap = PTR (a);

  if (ABOVE_THRESHOLD (asize, BMOD_1_TO_MOD_1_THRESHOLD))
    {
      r = mpn_mod_1 (ap, asize, d);
      if (c < d)
        return r == c;
      else
        return r == (c % d);
    }

  if ((d & 1) == 0)
    {
      /* Strip low zero bits to get odd d required by modexact.  If
         d==e*2^n then a==c mod d if and only if both a==c mod 2^n
         and a==c mod e.  */

      unsigned  twos;

      if ((ap[0]-c) & LOW_ZEROS_MASK (d))
        return 0;

      count_trailing_zeros (twos, d);
      d >>= twos;
    }
void mpz_sqrtmp_r
	(mpz_ptr root, mpz_srcptr a, mpz_srcptr p)
{
	/* ? a \neq 0 */
	if (mpz_get_ui(a) != 0)
	{
		/* ? p = 3 (mod 4) */
		if (mpz_congruent_ui_p(p, 3L, 4L))
		{
			mpz_t foo;
			mpz_init_set(foo, p);
			mpz_add_ui(foo, foo, 1L);
			mpz_fdiv_q_2exp(foo, foo, 2L);
			mpz_powm(root, a, foo, p);
			mpz_clear(foo);
			return;
		}
		/* ! p = 1 (mod 4) */
		else
		{
			/* ! s = (p-1)/4 */
			mpz_t s;
			mpz_init_set(s, p);
			mpz_sub_ui(s, s, 1L);
			mpz_fdiv_q_2exp(s, s, 2L);
			/* ? p = 5 (mod 8) */
			if (mpz_congruent_ui_p(p, 5L, 8L))
			{
				mpz_t foo, b;
				mpz_init(foo);
				mpz_powm(foo, a, s, p);
				mpz_init_set(b, p);
				mpz_add_ui(b, b, 3L);
				mpz_fdiv_q_2exp(b, b, 3L);
				mpz_powm(root, a, b, p);
				/* ? a^{(p-1)/4} = 1 (mod p) */
				if (mpz_cmp_ui(foo, 1L) == 0)
				{
					mpz_clear(foo), mpz_clear(s), mpz_clear(b);
					return;
				}
				/* ! a^{(p-1)/4} = -1 (mod p) */
				else
				{
					do
						mpz_wrandomm(b, p);
					while (mpz_jacobi(b, p) != -1);
					mpz_powm(b, b, s, p);
					mpz_mul(root, root, b);
					mpz_mod(root, root, p);
					mpz_clear(foo), mpz_clear(s), mpz_clear(b);
					return;
				}
			}
			/* ! p = 1 (mod 8) */
			else
			{
				mpz_t foo, bar, b, t;
				mpz_init(foo), mpz_init(bar);
				mpz_powm(foo, a, s, p);
				/* while a^s = 1 (mod p) */
				while (mpz_cmp_ui(foo, 1L) == 0)
				{
					/* ? s odd */
					if (mpz_odd_p(s))
					{
						mpz_add_ui(s, s, 1L);
						mpz_fdiv_q_2exp(s, s, 1L);
						mpz_powm(root, a, s, p);
						mpz_clear(foo), mpz_clear(s);
						return;
					}
					/* ! s even */
					else
					{
						mpz_fdiv_q_2exp(s, s, 1L);
					}
					mpz_powm(foo, a, s, p);
				}
				/* ! a^s = -1 (mod p) */
				mpz_init(b);
				do
					mpz_wrandomm(b, p);
				while (mpz_jacobi(b, p) != -1);
				mpz_init_set(t, p);
				mpz_sub_ui(t, t, 1L);
				mpz_fdiv_q_2exp(t, t, 1L);
				/* while s even */
				while (mpz_even_p(s))
				{
					mpz_fdiv_q_2exp(s, s, 1L);
					mpz_fdiv_q_2exp(t, t, 1L);
					mpz_powm(foo, a, s, p);
					mpz_powm(bar, b, t, p);
					mpz_mul(foo, foo, bar);
					mpz_mod(foo, foo, p);
					mpz_set_si(bar, -1L);
					/* ? a^s * b^t = -1 (mod p) */
					if (mpz_congruent_p(foo, bar, p))
					{
						mpz_set(bar, p);
						mpz_sub_ui(bar, bar, 1L);
						mpz_fdiv_q_2exp(bar, bar, 1L);
						mpz_add(t, t, bar);
					}
				}
				mpz_add_ui(s, s, 1L);
				mpz_fdiv_q_2exp(s, s, 1L);
				mpz_fdiv_q_2exp(t, t, 1L);
				mpz_powm(foo, a, s, p);
				mpz_powm(bar, b, t, p);
				mpz_mul(root, foo, bar);
				mpz_mod(root, root, p);
				mpz_clear(foo), mpz_clear(bar);
				mpz_clear(s), mpz_clear(b), mpz_clear(t);
				return;
			}
		}
	}
	/* error, return zero root */
	mpz_set_ui(root, 0L);
}
static void
test_modulo (gmp_randstate_t rands, const struct ecc_modulo *m)
{
  mpz_t u;
  mpz_t v;
  mpz_t p;
  mpz_t r;
  mpz_t t;

  unsigned z, i;
  mp_limb_t *up;
  mp_limb_t *vp;
  mp_limb_t *rp;
  mp_limb_t *scratch;

  mpz_init (u);
  mpz_init (v);
  mpz_init (t);

  mpz_roinit_n (p, m->m, m->size);

  up = xalloc_limbs (m->size);
  vp = xalloc_limbs (m->size);
  rp = xalloc_limbs (2*m->size);
  scratch = xalloc_limbs (m->sqrt_itch);

  /* Find a non-square */
  for (z = 2; mpz_ui_kronecker (z, p) != -1; z++)
    ;

  if (verbose)
    fprintf(stderr, "Non square: %d\n", z);

  for (i = 0; i < COUNT; i++)
    {
      if (i & 1)
	{
	  mpz_rrandomb (u, rands, m->bit_size);
	  mpz_rrandomb (v, rands, m->bit_size);
	}
      else
	{
	  mpz_urandomb (u, rands, m->bit_size);
	  mpz_urandomb (v, rands, m->bit_size);
	}
      mpz_limbs_copy (up, u, m->size);
      mpz_limbs_copy (vp, v, m->size);
      if (!m->sqrt (m, rp, up, vp, scratch))
	{
	  mpz_mul_ui (u, u, z);
	  mpz_mod (u, u, p);
	  mpz_limbs_copy (up, u, m->size);
	  if (!m->sqrt (m, rp, up, vp, scratch))
	    {
	      fprintf (stderr, "m->sqrt returned failure, bit_size = %d\n"
		       "u = 0x",
		       m->bit_size);
	      mpz_out_str (stderr, 16, u);
	      fprintf (stderr, "\nv = 0x");
	      mpz_out_str (stderr, 16, v);
	      fprintf (stderr, "\n");
	      abort ();
	    }
	}
      /* Check that r^2 v = u */
      mpz_roinit_n (r, rp, m->size);
      mpz_mul (t, r, r);
      mpz_mul (t, t, v);
      if (!mpz_congruent_p (t, u, p))
	{
	  fprintf (stderr, "m->sqrt gave incorrect result, bit_size = %d\n"
		   "u = 0x",
		   m->bit_size);
	  mpz_out_str (stderr, 16, u);
	  fprintf (stderr, "\nv = 0x");
	  mpz_out_str (stderr, 16, v);
	  fprintf (stderr, "\nr = 0x");
	  mpz_out_str (stderr, 16, r);
	  fprintf (stderr, "\n");
	  abort ();
	}
    }
  mpz_clear (u);
  mpz_clear (v);
  mpz_clear (t);
  free (up);
  free (vp);
  free (rp);
  free (scratch);
}