https://gitlab.inria.fr/ciao/pmns-for-sidh
Raw File
Tip revision: fc666429fa96e570fbcca250f27c25514f4ba638 authored by Cyril Bouvier on 04 November 2020, 15:12:51 UTC
Instructions on how to compile
Tip revision: fc66642
arith_ourtests.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <gmp.h>

#include "test_extras.h"

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
static void
fp2random_pmns_test (f2elm_t r)
{
  fprandom_pmns_test (r[0]);
  fprandom_pmns_test (r[1]);
}

static int
check_coeffs_size (digit_t *p, unsigned int n, unsigned int bound_log2)
{
  int ret = PASSED;
  unsigned int s = bound_log2 - 8*sizeof(digit_t)*(NWORDS_COEFF-1);

  for (unsigned int i = NWORDS_COEFF-1; i < NWORDS_FIELD; i += NWORDS_COEFF)
    if (p[i] >> s)
      ret = FAILED;

  return ret;
}

static void
fprandom_test (digit_t* a)
{
  unsigned int diff = MAXBITS_FIELD-NBITS_FIELD;
  unsigned char* string = (unsigned char*)a;
  for (unsigned int i = 0; i < 8*NWORDS64_FIELD; i++)
    *(string + i) = (unsigned char)rand();
  a[NWORDS64_FIELD-1] &= (((digit_t)(-1) << diff) >> diff);

  while (compare_words((digit_t*)p, a, NWORDS64_FIELD) < 1)
    mpn_sub_n ((unsigned long *) a, (unsigned long *) a, (unsigned long *) p, NWORDS64_FIELD);
}

/******************************************************************************/
/******************************************************************************/
/******************************************************************************/
static int
test_PMNS_conversion ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t t1 = {0}, t2 = {0}, tmp = {0};

    fprandom_test (t1);
    to_PMNS (t1, tmp);
    from_PMNS (tmp, t2);
    if (compare_words (t1, t2, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (tmp, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;

    fprandom_pmns_test (tmp);
    from_PMNS (tmp, t1);
    to_PMNS (t1, tmp);
    from_PMNS (tmp, t2);
    if (compare_words (t1, t2, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (tmp, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_conversion ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t t1 = {0}, t2 = {0}, tmp = {0};

    fprandom_test (t1);
    to_mont (t1, tmp);
    from_mont (tmp, t2);
    if (compare_words (t1, t2, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (tmp, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;

    fprandom_pmns_test (tmp);
    from_mont (tmp, t1);
    to_mont (t1, tmp);
    from_mont (tmp, t2);
    if (compare_words (t1, t2, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (tmp, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_add ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t a = {0}, b = {0}, c = {0}, r = {0}, pa = {0}, pb = {0}, pc = {0};

    fprandom_pmns_test (pa);
    fprandom_pmns_test (pb);
    fpadd (pa, pb, pc);

    from_mont (pa, a);
    from_mont (pb, b);
    from_mont (pc, c);

    mpn_add_n ((mp_ptr) r, (mp_srcptr) a, (mp_srcptr) b, NWORDS_FIELD); /* assumes not carry */
    if (mpn_cmp ((mp_srcptr) r, (mp_srcptr) p, NWORDS64_FIELD) >= 0)
      mpn_sub_n ((mp_ptr) r, (mp_srcptr) r, (mp_srcptr) p, NWORDS64_FIELD);

    if (compare_words (r, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pc, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_sub ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    mp_limb_t borrow;
    felm_t a = {0}, b = {0}, c = {0}, r = {0}, pa = {0}, pb = {0}, pc = {0};

    fprandom_pmns_test (pa);
    fprandom_pmns_test (pb);
    fpsub (pa, pb, pc);

    from_mont (pa, a);
    from_mont (pb, b);
    from_mont (pc, c);

    borrow = mpn_sub_n ((mp_ptr) r, (mp_srcptr) a, (mp_srcptr) b, NWORDS64_FIELD);
    if (borrow)
      mpn_add_n ((mp_ptr) r, (mp_srcptr) r, (mp_srcptr) p, NWORDS64_FIELD);

    if (compare_words (r, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pc, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_neg ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t a = {0}, c = {0}, pa = {0}, r = {0};

    fprandom_pmns_test (pa);
    from_mont (pa, a);

    fpneg (pa);

    from_mont (pa, c);
    mpn_sub_n ((mp_ptr) r, (mp_srcptr) p, (mp_srcptr) a, NWORDS64_FIELD);

    if (compare_words (r, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pa, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_div2 ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t a = {0}, c = {0}, pa = {0}, pb = {0}, r = {0};

    fprandom_pmns_test (pa);

    fpdiv2 (pa, pb);

    from_mont (pa, a);
    from_mont (pb, c);

    if (a[0] & 1) /* a is odd */
      mpn_add_n ((mp_ptr) r, (mp_srcptr) a, (mp_srcptr) p, NWORDS64_FIELD);
    else
      mpn_copyi ((mp_ptr) r, (mp_srcptr) a, NWORDS_FIELD);
    mpn_rshift ((mp_ptr) r, (mp_srcptr) r, NWORDS_FIELD, 1); /* div by 2 */

    if (compare_words (r, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pb, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_fpmul_mont ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t a = {0}, b = {0}, c = {0}, pa = {0}, pb = {0}, pc = {0}, r = {0};
    digit_t q[NWORDS64_FIELD+1];
    dfelm_t t = {0};

    fprandom_pmns_test (pa);
    fprandom_pmns_test (pb);

    fpmul_mont (pa, pb, pc);

    from_mont (pa, a);
    from_mont (pb, b);
    from_mont (pc, c);

    mpn_mul_n ((mp_ptr) t, (mp_srcptr) a, (mp_srcptr) b, NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r, 0, (mp_srcptr) t, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);

    if (compare_words (r, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pc, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_fpsqr_mont ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    felm_t a = {0}, c = {0}, pa = {0}, pc = {0}, r = {0};
    digit_t q[NWORDS64_FIELD+1];
    dfelm_t t = {0};

    fprandom_pmns_test (pa);

    fpsqr_mont (pa, pc);

    from_mont (pa, a);
    from_mont (pc, c);

    mpn_mul_n ((mp_ptr) t, (mp_ptr) a, (mp_srcptr) a, NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r, 0, (mp_srcptr) t, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);

    if (compare_words (r, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pc, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_fpinv_mont ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 100; i++)
  {
    mp_size_t inv_n;
    felm_t a = {0}, c = {0}, pa = {0}, g = {0}, inv = {0}, pr = {0};
    mpn_copyi ((mp_ptr) pr, (mp_srcptr) p, NWORDS64_FIELD);

    fprandom_pmns_test (pa);
    from_mont (pa, a);

    fpinv_mont (pa);

    from_mont (pa, c);

    mpn_gcdext ((mp_ptr) g, (mp_ptr) inv, &inv_n, (mp_ptr) a, NWORDS64_FIELD, (mp_ptr) pr, NWORDS64_FIELD);
    if (inv_n < 0)
      mpn_sub_n ((mp_ptr) inv, (mp_srcptr) p, (mp_srcptr) inv, NWORDS64_FIELD);

    if (compare_words (inv, c, NWORDS_FIELD) != 0)
      ret = FAILED;
    if (check_coeffs_size (pa, NWORDS_FIELD, PMNS_K) != PASSED)
      ret = FAILED;
  }

  return ret;
}

static int
test_fp2_conversion ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    f2elm_t t1, t2, tmp;
    fp2zero (t1); fp2zero (t2);
    fp2zero (tmp);

    fprandom_test (t1[0]);
    fprandom_test (t1[1]);

    to_fp2mont (t1, tmp);
    from_fp2mont (tmp, t2);
    for (unsigned int j = 0; j < 2; j++)
    {
      if (compare_words (t1[j], t2[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (tmp[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }

    fp2random_pmns_test (tmp);
    from_fp2mont (tmp, t1);
    to_fp2mont (t1, tmp);
    from_fp2mont (tmp, t2);
    for (unsigned int j = 0; j < 2; j++)
    {
      if (compare_words (t1[j], t2[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (tmp[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}

static int
test_fp2_add ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    f2elm_t a, b, c, r, pa, pb, pc;
    fp2zero (a); fp2zero (b); fp2zero (c); fp2zero (r);
    fp2zero (pa); fp2zero (pb); fp2zero (pc);

    fp2random_pmns_test (pa);
    fp2random_pmns_test (pb);

    fp2add (pa, pb, pc);

    from_fp2mont (pa, a);
    from_fp2mont (pb, b);
    from_fp2mont (pc, c);

    for (unsigned int j = 0; j < 2; j++)
    {
      mpn_add_n ((mp_ptr) r[j], (mp_srcptr) a[j], (mp_srcptr) b[j], NWORDS_FIELD); /* assumes not carry */
      if (mpn_cmp ((mp_srcptr) r[j], (mp_srcptr) p, NWORDS64_FIELD) >= 0)
        mpn_sub_n ((mp_ptr) r[j], (mp_srcptr) r[j], (mp_srcptr) p, NWORDS64_FIELD);

      if (compare_words (r[j], c[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pc[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}

static int
test_fp2_sub ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    mp_limb_t borrow;
    f2elm_t a, b, c, r, pa, pb, pc;
    fp2zero (a); fp2zero (b); fp2zero (c); fp2zero (r);
    fp2zero (pa); fp2zero (pb); fp2zero (pc);

    fp2random_pmns_test (pa);
    fp2random_pmns_test (pb);

    fp2sub (pa, pb, pc);

    from_fp2mont (pa, a);
    from_fp2mont (pb, b);
    from_fp2mont (pc, c);

    for (unsigned int j = 0; j < 2; j++)
    {
      borrow = mpn_sub_n ((mp_ptr) r[j], (mp_srcptr) a[j], (mp_srcptr) b[j], NWORDS64_FIELD);
      if (borrow)
        mpn_add_n ((mp_ptr) r[j], (mp_srcptr) r[j], (mp_srcptr) p, NWORDS64_FIELD);

      if (compare_words (r[j], c[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pc[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}

static int
test_fp2_neg ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    f2elm_t a, c, pa, r;
    fp2zero (a); fp2zero (c); fp2zero (pa); fp2zero (r);

    fp2random_pmns_test (pa);
    from_fp2mont (pa, a);

    fp2neg (pa);

    from_fp2mont (pa, c);

    for (unsigned int j = 0; j < 2; j++)
    {
      mpn_sub_n ((mp_ptr) r[j], (mp_srcptr) p, (mp_srcptr) a[j], NWORDS64_FIELD);

      if (compare_words (r[j], c[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pa[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}

static int
test_fp2_div2 ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    f2elm_t a, c, pa, pc, r;
    fp2zero (a); fp2zero (c); fp2zero (pa); fp2zero (pc);
    fp2zero (r);

    fp2random_pmns_test (pa);

    fp2div2 (pa, pc);

    from_fp2mont (pa, a);
    from_fp2mont (pc, c);

    for (unsigned int j = 0; j < 2; j++)
    {
      if (a[j][0] & 1) /* a is odd */
        mpn_add_n ((mp_ptr) r[j], (mp_srcptr) a[j], (mp_srcptr) p, NWORDS64_FIELD);
      else
        mpn_copyi ((mp_ptr) r[j], (mp_srcptr) a[j], NWORDS_FIELD);
      mpn_rshift ((mp_ptr) r[j], (mp_srcptr) r[j], NWORDS_FIELD, 1); /* div by 2 */

      if (compare_words (r[j], c[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pc[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}


static int
test_fp2mul_mont ()
{
  int ret = PASSED;
  unsigned int borrow;

  for (unsigned int i = 0; i < 10000; i++)
  {
    f2elm_t a, b, c, cc, pa, pb, pc;
    fp2zero (a); fp2zero (b); fp2zero (c); fp2zero (cc);
    fp2zero (pa); fp2zero (pb); fp2zero (pc);

    felm_t r1 = {0}, r2 = {0};
    digit_t q[NWORDS64_FIELD+1];
    dfelm_t t1 = {0}, t2 = {0};

    fp2random_pmns_test (pa);
    fp2random_pmns_test (pb);

    /* c = a*b */
    fp2mul_mont (pa, pb, pc);

    from_fp2mont (pa, a);
    from_fp2mont (pb, b);
    from_fp2mont (pc, c);

    /* a[0]*b[0] - a[1]*b[1] == c[0] */
    mpn_mul_n ((mp_ptr) t1, (mp_srcptr) a[0], (mp_srcptr) b[0], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r1, 0, (mp_srcptr) t1, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    mpn_mul_n ((mp_ptr) t2, (mp_srcptr) a[1], (mp_srcptr) b[1], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r2, 0, (mp_srcptr) t2, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    borrow = mpn_sub_n ((mp_ptr) cc[0], (mp_srcptr) r1, (mp_srcptr) r2, NWORDS64_FIELD);
    if (borrow)
      mpn_add_n ((mp_ptr) cc[0], (mp_srcptr) cc[0], (mp_srcptr) p, NWORDS64_FIELD);

    /* a[0]*b[1] + a[1]*b[0] == c[1] */
    mpn_mul_n ((mp_ptr) t1, (mp_srcptr) a[0], (mp_srcptr) b[1], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r1, 0, (mp_srcptr) t1, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    mpn_mul_n ((mp_ptr) t2, (mp_srcptr) a[1], (mp_srcptr) b[0], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r2, 0, (mp_srcptr) t2, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    mpn_add_n ((mp_ptr) cc[1], (mp_srcptr) r1, (mp_srcptr) r2, NWORDS64_FIELD);
    if (mpn_cmp ((mp_srcptr) cc[1], (mp_srcptr) p, NWORDS64_FIELD) >= 0)
      mpn_sub_n ((mp_ptr) cc[1], (mp_srcptr) cc[1], (mp_srcptr) p, NWORDS64_FIELD);

    for (unsigned int j = 0; j < 2; j++)
    {
      if (compare_words (c[j], cc[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pc[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}

static int
test_fp2sqr_mont ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 10000; i++)
  {
    mp_limb_t borrow;
    f2elm_t a, c, pa, pc, r;
    fp2zero (a); fp2zero (c); fp2zero (r);
    fp2zero (pa); fp2zero (pc);

    felm_t m = {0};
    digit_t q[NWORDS64_FIELD+1];
    dfelm_t t = {0};

    fp2random_pmns_test (pa);

    fp2sqr_mont (pa, pc);

    from_fp2mont (pa, a);
    from_fp2mont (pc, c);

    /* r[0] = a[0]^2-a[1]^2 */
    mpn_mul_n ((mp_ptr) t, (mp_ptr) a[0], (mp_srcptr) a[0], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r[0], 0, (mp_srcptr) t, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    mpn_mul_n ((mp_ptr) t, (mp_ptr) a[1], (mp_srcptr) a[1], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) m, 0, (mp_srcptr) t, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    borrow = mpn_sub_n ((mp_ptr) r[0], (mp_srcptr) r[0], (mp_srcptr) m, NWORDS64_FIELD);
    if (borrow)
      mpn_add_n ((mp_ptr) r[0], (mp_srcptr) r[0], (mp_srcptr) p, NWORDS64_FIELD);

    /* r[1] = 2*a[0]*a[1] */
    mpn_mul_n ((mp_ptr) t, (mp_ptr) a[0], (mp_srcptr) a[1], NWORDS64_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r[1], 0, (mp_srcptr) t, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    mpn_lshift ((mp_ptr) r[1], (mp_srcptr) r[1], NWORDS64_FIELD, 1);
    if (mpn_cmp ((mp_srcptr) r[1], (mp_srcptr) p, NWORDS64_FIELD) >= 0)
      mpn_sub_n ((mp_ptr) r[1], (mp_srcptr) r[1], (mp_srcptr) p, NWORDS64_FIELD);

    for (unsigned int j = 0; j < 2; j++)
    {
      if (compare_words (r[j], c[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pc[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}

static int
test_fp2inv_mont ()
{
  int ret = PASSED;

  for (unsigned int i = 0; i < 100; i++)
  {
    mp_size_t inv_n;
    f2elm_t a, c, pa, r;
    fp2zero (a); fp2zero (c); fp2zero (r);
    fp2zero (pa);

    felm_t norm = {0}, pr = {0}, q = {0}, g = {0}, inv = {0};
    dfelm_t t0 = {0}, t1 = {0};
    mpn_copyi ((mp_ptr) pr, (mp_srcptr) p, NWORDS64_FIELD);

    fp2random_pmns_test (pa);
    from_fp2mont (pa, a);

    fp2inv_mont (pa);

    from_fp2mont (pa, c);

    /* norm = a[0]^2+a[1]^2 */
    mpn_mul_n ((mp_ptr) t0, (mp_ptr) a[0], (mp_srcptr) a[0], NWORDS_FIELD);
    mpn_mul_n ((mp_ptr) t1, (mp_ptr) a[1], (mp_srcptr) a[1], NWORDS_FIELD);
    mpn_add_n ((mp_ptr) t0, (mp_ptr) t0, (mp_srcptr) t1, 2*NWORDS_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) norm, 0, (mp_srcptr) t0, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);

    /* inv = norm^-1 */
    mpn_gcdext ((mp_ptr) g, (mp_ptr) inv, &inv_n, (mp_ptr) norm, NWORDS64_FIELD, (mp_ptr) pr, NWORDS64_FIELD);
    if (inv_n < 0)
      mpn_sub_n ((mp_ptr) inv, (mp_srcptr) p, (mp_srcptr) inv, NWORDS64_FIELD);

    /* r[0] = a[0]*inv */
    mpn_mul_n ((mp_ptr) t0, (mp_ptr) a[0], (mp_srcptr) inv, NWORDS_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r[0], 0, (mp_srcptr) t0, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);

    /* r[1] = -a[1]*inv */
    mpn_mul_n ((mp_ptr) t0, (mp_ptr) a[1], (mp_srcptr) inv, NWORDS_FIELD);
    mpn_tdiv_qr ((mp_ptr) q, (mp_ptr) r[1], 0, (mp_srcptr) t0, 2*NWORDS64_FIELD, (mp_srcptr) p, NWORDS64_FIELD);
    mpn_sub_n ((mp_ptr) r[1], (mp_srcptr) p, (mp_srcptr) r[1], NWORDS64_FIELD);

    for (unsigned int j = 0; j < 2; j++)
    {
      if (compare_words (r[j], c[j], NWORDS_FIELD) != 0)
        ret = FAILED;
      if (check_coeffs_size (pa[j], NWORDS_FIELD, PMNS_K) != PASSED)
        ret = FAILED;
    }
  }

  return ret;
}


int
main (int argc, char* argv[])
{
  int Status = PASSED, ret = PASSED;
  unsigned int seed = time(NULL);
  if (argc == 2)
    seed = atoi(argv[1]);
  printf ("# seed = %u\n", seed);
  srand(seed);

  /* PMNS conversion */
  Status = test_PMNS_conversion();
  printf("test_PMNS_conversion: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* PMNS + Montgomery conversion */
  Status = test_conversion();
  printf("test_conversion: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* addition on Fp */
  Status = test_add();
  printf("test_add: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* substraction on Fp */
  Status = test_sub();
  printf("test_sub: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* negation on Fp */
  Status = test_neg();
  printf("test_neg: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* div2 on Fp */
  Status = test_div2();
  printf("test_div2: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* mul on Fp */
  Status = test_fpmul_mont();
  printf("test_fpmul_mont: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* sqr on Fp */
  Status = test_fpsqr_mont();
  printf("test_fpsqr_mont: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* inv on Fp */
  Status = test_fpinv_mont();
  printf("test_fpinv_mont: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* PMNS + Montgomery conversion on Fp2 */
  Status = test_fp2_conversion();
  printf("test_fp2_conversion: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* add on Fp2 */
  Status = test_fp2_add();
  printf("test_fp2_add: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* sub on Fp2 */
  Status = test_fp2_sub();
  printf("test_fp2_sub: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* neg on Fp2 */
  Status = test_fp2_neg();
  printf("test_fp2_neg: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* div2 on Fp2 */
  Status = test_fp2_div2();
  printf("test_fp2_div2: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* mul_mont on Fp2 */
  Status = test_fp2mul_mont ();
  printf("test_fp2mul_mont: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* sqr_mont on Fp2 */
  Status = test_fp2sqr_mont ();
  printf("test_fp2sqr_mont: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  /* inv_mont on Fp2 */
  Status = test_fp2inv_mont ();
  printf("test_fp2inv_mont: %s\n", Status == PASSED ? "passed" : "failed");
  if (Status != PASSED)
    ret = FAILED;

  if (ret != PASSED)
    fprintf (stderr, "\n\n*** SOME TESTS FAILED ***\n");
  return ret;
}

back to top