예제 #1
0
EpidStatus NewFq6(Epid2Params const* param, FiniteField* Fq2, FfElement* xi,
                  FiniteField** Fq6) {
  EpidStatus result = kEpidErr;
  FiniteField* Ff = NULL;
  FfElement* neg_xi = NULL;
  if (!param || !Fq2 || !Fq6) {
    return kEpidBadArgErr;
  }
  do {
    result = NewFfElement(Fq2, &neg_xi);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfNeg(Fq2, xi, neg_xi);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFiniteFieldViaBinomalExtension(Fq2, neg_xi, 3, &Ff);
    if (kEpidNoErr != result) {
      break;
    }
    *Fq6 = Ff;
    result = kEpidNoErr;
  } while (0);

  DeleteFfElement(&neg_xi);

  return result;
}
예제 #2
0
파일: msclean.c 프로젝트: momtx/meataxe
int MsClean(const MatrixSet_t *set, Matrix_t *mat)
{
   int i;
   MatrixSetElement_t *l;

   /* Check the arguments.
      -------------------- */
   if (!MsIsValid(set) || !MatIsValid(mat)) {
      return -1;
   }
   if (set->Len > 0) {
      Matrix_t *mat0 = set->List[0].Matrix;
      if ((mat->Field != mat0->Field) || (mat->Nor != mat0->Nor)
          || (mat->Noc != mat0->Noc)) {
         MTX_ERROR1("Cannot clean: %E",MTX_ERR_INCOMPAT);
         return -1;
      }
   }

   /* Clean the matrix.
      ----------------- */
   for (i = 0, l = set->List; i < set->Len; ++i, ++l) {
      FEL f = FfExtract(MatGetPtr(mat,l->PivRow),l->PivCol);
      if (f != FF_ZERO) {
         MatAddMul(mat,l->Matrix,FfNeg(FfDiv(f,l->PivMark)));
      }
   }
   return 0;
}
예제 #3
0
EpidStatus NewGT(FiniteField* Fq6, FiniteField** GT) {
  EpidStatus result = kEpidErr;
  FiniteField* Ff = NULL;
  FfElement* v = NULL;
  FfElement* neg_v = NULL;

  const Fq6ElemStr v_str = {
      {{{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
         {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}},
       {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}},
         {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}},
       {{{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
         {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}}}}}};

  if (!Fq6 || !GT) {
    return kEpidBadArgErr;
  }
  do {
    result = NewFfElement(Fq6, &v);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(Fq6, &neg_v);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq6, &v_str, sizeof(v_str), v);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfNeg(Fq6, v, neg_v);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFiniteFieldViaBinomalExtension(Fq6, neg_v, 2, &Ff);
    if (kEpidNoErr != result) {
      break;
    }
    *GT = Ff;
    result = kEpidNoErr;
  } while (0);

  DeleteFfElement(&v);
  DeleteFfElement(&neg_v);

  return result;
}
예제 #4
0
파일: matinv.c 프로젝트: momtx/meataxe
MTX_DEFINE_FILE_INFO

////////////////////////////////////////////////////////////////////////////////////////////////////

static int zmatinv(PTR mat, PTR result)
{
   PTR xj1, xj2, xk1, xk2;
   FEL f1 = FF_ZERO, f2;
   long j, k;

   // initialize result with identity matrix
   for (j = 0, xj1 = result; j < FfNoc; ++j, FfStepPtr(&xj1)) {
      FfMulRow(xj1,FF_ZERO);
      FfInsert(xj1,j,FF_ONE);
   }

   // matrix inversion
   xj1 = mat;
   xj2 = result;
   for (j = 0; j < FfNoc; ++j) {

      for (xk1 = xj1, k = j;
           k < FfNoc && (f1 = FfExtract(xk1,j)) == FF_ZERO;
           ++k, FfStepPtr(&xk1)) {
      }
      if (f1 == FF_ZERO) {
         MTX_ERROR1("%E",MTX_ERR_DIV0);
         return -1;
      }
      if (k > j) {      /* Swap rows */
         FfSwapRows(xk1,xj1);
/*	    xk2 = FfGetPtr(xj2,k-j,FfNoc);*/
         xk2 = (PTR)((char *)xj2 + (k - j) * FfCurrentRowSize);
         FfSwapRows(xk2,xj2);
      }
      f2 = FfInv(f1);
      FfMulRow(xj1,f2);
      FfMulRow(xj2,f2);
      xk1 = mat;
      xk2 = result;
      for (k = 0; k < FfNoc; ++k) {
         if (k != j) {
            f1 = FfNeg(FfExtract(xk1,j));
            FfAddMulRow(xk1,xj1,f1);
            FfAddMulRow(xk2,xj2,f1);
         }
         FfStepPtr(&xk1);
         FfStepPtr(&xk2);
      }
      FfStepPtr(&xj1);
      FfStepPtr(&xj2);
   }
   return 0;
}
예제 #5
0
파일: berlekmp.c 프로젝트: momtx/meataxe
static Matrix_t *makekernel(const Poly_t *pol)
{
    Matrix_t *materg;
    PTR rowptr;
    FEL *xbuf, *pbuf = pol->Data;
    long pdeg = pol->Degree;
    int k, xshift;
    long fl = pol->Field;

    materg = MatAlloc(fl,pdeg,pdeg);
    rowptr = materg->Data;

    xbuf = NALLOC(FEL,pdeg+1);
    for (k = 0; k <= pdeg; ++k) 
	xbuf[k] = FF_ZERO;
    xbuf[0] = FF_ONE;

    for (k = 0; k < pdeg; ++k)
    {
	int l;
	for (l = 0; l < pdeg; ++l) 
	    FfInsert(rowptr,l,xbuf[l]);
	FfInsert(rowptr,k,FfSub(xbuf[k],FF_ONE));
	FfStepPtr(&rowptr);
        for (xshift = (int) fl; xshift > 0; )
	{
	    FEL f;
	    int d;

	    /* Find leading pos */
	    for (l = pdeg-1; xbuf[l] == FF_ZERO && l >= 0; --l);

	    /* Shift left as much as possible */
	    if ((d = pdeg - l) > xshift) d = xshift;
	    for (; l >= 0; l--) xbuf[l+d] = xbuf[l];
	    for (l = d-1; l >= 0; --l) xbuf[l] = FF_ZERO;
	    xshift -= d;
	    if (xbuf[pdeg] == FF_ZERO) continue;

	    /* Reduce with pol */
	    f = FfNeg(FfDiv(xbuf[pdeg],pbuf[pdeg]));
	    for (l = pdeg-1; l >= 0; --l)
		xbuf[l] = FfAdd(xbuf[l],FfMul(pbuf[l],f));
	    xbuf[pdeg] = FF_ZERO;
	}
    }
    SysFree(xbuf);
    return MatNullSpace__(materg);
 } 
예제 #6
0
EpidStatus NewFq2(Epid2Params const* param, FiniteField* Fq,
                  FiniteField** Fq2) {
  EpidStatus result = kEpidErr;
  FiniteField* Ff = NULL;
  FfElement* beta = NULL;
  FfElement* neg_beta = NULL;
  if (!param || !Fq || !Fq2) {
    return kEpidBadArgErr;
  }
  do {
    result = NewFfElement(Fq, &beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFfElement(Fq, &neg_beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = ReadFfElement(Fq, &param->beta, sizeof(param->beta), beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = FfNeg(Fq, beta, neg_beta);
    if (kEpidNoErr != result) {
      break;
    }
    result = NewFiniteFieldViaBinomalExtension(Fq, neg_beta, 2, &Ff);
    if (kEpidNoErr != result) {
      break;
    }
    *Fq2 = Ff;
    result = kEpidNoErr;
  } while (0);

  DeleteFfElement(&neg_beta);
  DeleteFfElement(&beta);

  return result;
}
예제 #7
0
파일: signbasic.c 프로젝트: 01org/linux-sgx
EpidStatus EpidSignBasic(MemberCtx const* ctx, void const* msg, size_t msg_len,
                         void const* basename, size_t basename_len,
                         BasicSignature* sig, BigNumStr* rnd_bsn) {
  EpidStatus sts = kEpidErr;

  EcPoint* B = NULL;
  EcPoint* t = NULL;  // temp value in G1
  EcPoint* k = NULL;
  EcPoint* e = NULL;
  FfElement* R2 = NULL;
  FfElement* p2y = NULL;
  FfElement* t1 = NULL;
  FfElement* t2 = NULL;

  FfElement* a = NULL;
  FfElement* b = NULL;
  FfElement* rx = NULL;
  FfElement* ra = NULL;
  FfElement* rb = NULL;

  struct p2x_t {
    uint32_t i;
    uint8_t bsn[1];
  }* p2x = NULL;

  FfElement* t3 = NULL;  // temporary for multiplication
  FfElement* c = NULL;
  uint8_t* digest = NULL;

  PreComputedSignature curr_presig = {0};

  if (!ctx || !sig) {
    return kEpidBadArgErr;
  }
  if (!msg && (0 != msg_len)) {
    // if message is non-empty it must have both length and content
    return kEpidBadArgErr;
  }
  if (!basename && (0 != basename_len)) {
    // if basename is non-empty it must have both length and content
    return kEpidBadArgErr;
  }
  if (!ctx->epid2_params) {
    return kEpidBadArgErr;
  }

  do {
    FiniteField* Fp = ctx->epid2_params->Fp;
    SignCommitOutput commit_out = {0};
    FpElemStr c_str = {0};
    EcGroup* G1 = ctx->epid2_params->G1;
    FiniteField* GT = ctx->epid2_params->GT;

    FiniteField* Fq = ctx->epid2_params->Fq;
    PairingState* ps_ctx = ctx->epid2_params->pairing_state;
    const BigNumStr kOne = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
    BigNumStr t1_str = {0};
    BigNumStr t2_str = {0};
    size_t digest_size = 0;
    uint16_t* rf_ctr = (uint16_t*)&ctx->rf_ctr;
    FfElement const* x = ctx->x;

    if (basename) {
      if (!IsBasenameAllowed(ctx->allowed_basenames, basename, basename_len)) {
        sts = kEpidBadArgErr;
        BREAK_ON_EPID_ERROR(sts);
      }
    }

    sts = NewEcPoint(G1, &B);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(G1, &k);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(G1, &t);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewEcPoint(G1, &e);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(GT, &R2);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fq, &p2y);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &t1);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &t2);
    BREAK_ON_EPID_ERROR(sts);
    p2x = (struct p2x_t*)SAFE_ALLOC(sizeof(struct p2x_t) + basename_len - 1);
    if (!p2x) {
      sts = kEpidMemAllocErr;
      break;
    }

    sts = NewFfElement(Fp, &a);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &b);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &rx);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &ra);
    BREAK_ON_EPID_ERROR(sts);
    sts = NewFfElement(Fp, &rb);
    BREAK_ON_EPID_ERROR(sts);

    sts = MemberGetPreSig((MemberCtx*)ctx, &curr_presig);
    BREAK_ON_EPID_ERROR(sts);

    // 3.  If the pre-computed signature pre-sigma exists, the member
    //     loads (B, K, T, a, b, rx, rf, ra, rb, R1, R2) from
    //     pre-sigma. Refer to Section 4.4 for the computation of
    //     these values.
    sts = ReadFfElement(Fp, &curr_presig.a, sizeof(curr_presig.a), a);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.b, sizeof(curr_presig.b), b);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.rx, sizeof(curr_presig.rx), rx);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.ra, sizeof(curr_presig.ra), ra);
    BREAK_ON_EPID_ERROR(sts);
    sts = ReadFfElement(Fp, &curr_presig.rb, sizeof(curr_presig.rb), rb);
    BREAK_ON_EPID_ERROR(sts);

    // If the basename is provided, use it, otherwise use presig B
    if (basename) {
      // 3.a. The member computes (B, i2, y2) = G1.tpmHash(bsn).
      sts = EcHash(G1, basename, basename_len, ctx->hash_alg, B, &p2x->i);
      BREAK_ON_EPID_ERROR(sts);
      p2x->i = htonl(p2x->i);
      sts = WriteEcPoint(G1, B, &commit_out.B, sizeof(commit_out.B));
      BREAK_ON_EPID_ERROR(sts);
      sts = ReadFfElement(Fq, &commit_out.B.y, sizeof(commit_out.B.y), p2y);
      BREAK_ON_EPID_ERROR(sts);

      // b.i. (KTPM, LTPM, ETPM, counterTPM) = TPM2_Commit(P1=h1,(s2, y2) = (i2
      // || bsn, y2)).
      // b.ii.K = KTPM.
      if (0 !=
          memcpy_S((void*)p2x->bsn, basename_len, basename, basename_len)) {
        sts = kEpidBadArgErr;
        break;
      }
      sts =
          Tpm2Commit(ctx->tpm2_ctx, ctx->h1, p2x, sizeof(p2x->i) + basename_len,
                     p2y, k, t, e, (uint16_t*)&ctx->rf_ctr);
      BREAK_ON_EPID_ERROR(sts);
      sts = WriteEcPoint(G1, k, &commit_out.K, sizeof(commit_out.K));
      BREAK_ON_EPID_ERROR(sts);
      // c.i. The member computes R1 = LTPM.
      sts = WriteEcPoint(G1, t, &commit_out.R1, sizeof(commit_out.R1));
      BREAK_ON_EPID_ERROR(sts);
      // c.ii. e12rf = pairing(ETPM, g2)
      sts = Pairing(ps_ctx, e, ctx->epid2_params->g2, R2);
      BREAK_ON_EPID_ERROR(sts);
      // c.iii. R2 = GT.sscmMultiExp(ea2, t1, e12rf, 1, e22, t2, e2w,ra).
      // 4.i. The member computes t1 = (- rx) mod p.
      sts = FfNeg(Fp, rx, t1);
      BREAK_ON_EPID_ERROR(sts);
      // 4.j. The member computes t2 = (rb - a * rx) mod p.
      sts = FfMul(Fp, a, rx, t2);
      BREAK_ON_EPID_ERROR(sts);
      sts = FfNeg(Fp, t2, t2);
      BREAK_ON_EPID_ERROR(sts);
      sts = FfAdd(Fp, rb, t2, t2);
      BREAK_ON_EPID_ERROR(sts);

      sts = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str));
      BREAK_ON_EPID_ERROR(sts);
      sts = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str));
      BREAK_ON_EPID_ERROR(sts);
      {
        FfElement const* points[4];
        BigNumStr const* exponents[4];
        points[0] = ctx->ea2;
        points[1] = R2;
        points[2] = ctx->e22;
        points[3] = ctx->e2w;
        exponents[0] = &t1_str;
        exponents[1] = &kOne;
        exponents[2] = &t2_str;
        exponents[3] = (BigNumStr*)&curr_presig.ra;
        sts = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2);
        BREAK_ON_EPID_ERROR(sts);
      }

      sts = WriteFfElement(GT, R2, &commit_out.R2, sizeof(commit_out.R2));
      BREAK_ON_EPID_ERROR(sts);
      // d. The member over-writes the counterTPM, B, K, R1 and R2 values.
    } else {
      if (!rnd_bsn) {
        sts = kEpidBadArgErr;
        break;
      }
      sts = ReadEcPoint(G1, &curr_presig.B, sizeof(curr_presig.B), B);
      BREAK_ON_EPID_ERROR(sts);
      commit_out.B = curr_presig.B;
      commit_out.K = curr_presig.K;
      commit_out.R1 = curr_presig.R1;
      ((MemberCtx*)ctx)->rf_ctr = curr_presig.rf_ctr;
      commit_out.R2 = curr_presig.R2;
      *rnd_bsn = curr_presig.rnd_bsn;
    }

    commit_out.T = curr_presig.T;

    sts = HashSignCommitment(Fp, ctx->hash_alg, &ctx->pub_key, &commit_out, msg,
                             msg_len, &c_str);
    BREAK_ON_EPID_ERROR(sts);

    digest_size = EpidGetHashSize(ctx->hash_alg);
    digest = (uint8_t*)SAFE_ALLOC(digest_size);
    if (!digest) {
      sts = kEpidNoMemErr;
      break;
    }
    memcpy_S(digest + digest_size - sizeof(c_str), sizeof(c_str), &c_str,
             sizeof(c_str));

    sts = NewFfElement(Fp, &t3);
    BREAK_ON_EPID_ERROR(sts);

    sts = NewFfElement(Fp, &c);
    BREAK_ON_EPID_ERROR(sts);

    sts = ReadFfElement(Fp, &c_str, sizeof(c_str), c);
    BREAK_ON_EPID_ERROR(sts);

    // 7.  The member computes sx = (rx + c * x) mod p.
    sts = FfMul(Fp, c, x, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(Fp, rx, t3, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sx, sizeof(sig->sx));
    BREAK_ON_EPID_ERROR(sts);

    // 8.  The member computes sf = (rf + c * f) mod p.
    sts = Tpm2Sign(ctx->tpm2_ctx, digest, digest_size, *rf_ctr, NULL, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sf, sizeof(sig->sf));
    BREAK_ON_EPID_ERROR(sts);

    // 9.  The member computes sa = (ra + c * a) mod p.
    sts = FfMul(Fp, c, a, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(Fp, ra, t3, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sa, sizeof(sig->sa));
    BREAK_ON_EPID_ERROR(sts);

    // 10. The member computes sb = (rb + c * b) mod p.
    sts = FfMul(Fp, c, b, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = FfAdd(Fp, rb, t3, t3);
    BREAK_ON_EPID_ERROR(sts);
    sts = WriteFfElement(Fp, t3, &sig->sb, sizeof(sig->sb));
    BREAK_ON_EPID_ERROR(sts);

    sig->B = commit_out.B;
    sig->K = commit_out.K;
    sig->T = commit_out.T;
    sig->c = c_str;

    sts = kEpidNoErr;
  } while (0);

  if (sts != kEpidNoErr) {
    (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, (uint16_t)ctx->rf_ctr);
    (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, curr_presig.rf_ctr);
  } else if (basename) {
    (void)Tpm2ReleaseCounter(ctx->tpm2_ctx, curr_presig.rf_ctr);
  }

  EpidZeroMemory(&curr_presig, sizeof(curr_presig));

  DeleteEcPoint(&B);
  DeleteEcPoint(&k);
  DeleteEcPoint(&t);
  DeleteEcPoint(&e);
  DeleteFfElement(&R2);
  DeleteFfElement(&p2y);
  DeleteFfElement(&t1);
  DeleteFfElement(&t2);

  DeleteFfElement(&a);
  DeleteFfElement(&b);
  DeleteFfElement(&rx);
  DeleteFfElement(&ra);
  DeleteFfElement(&rb);

  SAFE_FREE(p2x);

  DeleteFfElement(&t3);
  DeleteFfElement(&c);
  SAFE_FREE(digest);

  return sts;
}
예제 #8
0
파일: matnull.c 프로젝트: momtx/meataxe
MTX_DEFINE_FILE_INFO

/// @addtogroup mat
/// @{

////////////////////////////////////////////////////////////////////////////////////////////////////
/// Null space.
/// This function calculates the null-space of a matrix. The matrix is passed
/// as first argument, |nor| is the number of rows, |piv| must be a pointer
/// to an array of at least $|nor|+1$ integers, and |nsp| must be a pointer to
/// a square matrix of size |nor|.
///
/// If the function is successfull (non-negative return value),
/// - |matrix| is reduced to echelon form,
/// - |nsp| contains the null-space in echelon form, and
/// - |piv| contains a pivot table for the null space.
/// If |flags| is nonzero, the null-space is not reduced to echelon form,
/// and the contents of |piv| are undefined.
///
/// @return The dimension of the null-space, or -1 on error.

static long znullsp(PTR matrix, long nor, int *piv, PTR nsp, int flags)
{
   PTR x, y, a, b;
   int i;
   long noc = FfNoc;
   long dim;
   FEL f;

   // initialize result with identity
   if (FfSetNoc(nor) != 0) {
      return -1;
   }
   x = nsp;
   for (i = 0; i < nor; ++i) {
      piv[i] = -1;
      FfMulRow(x,FF_ZERO);
      FfInsert(x,i,FF_ONE);
      FfStepPtr(&x);
   }

   // gaussian elimination
   x = matrix;
   y = nsp;
   for (i = 0; i < nor; ++i) {
      PTR xx = matrix, yy = nsp;
      long k, p;

      for (k = 0; k < i; ++k) {
         FfSetNoc(noc); // not checked since we know noc is valid
         if (((p = piv[k]) >= 0) && ((f = FfExtract(x,p)) != FF_ZERO)) {
            f = FfNeg(FfDiv(f,FfExtract(xx,p)));
            FfSetNoc(noc);
            FfAddMulRow(x,xx,f);
            FfSetNoc(nor);
            FfAddMulRow(y,yy,f);
         }
         FfSetNoc(noc);
         FfStepPtr(&xx);
         FfSetNoc(nor);
         FfStepPtr(&yy);
      }
      FfSetNoc(noc);
      piv[i] = p = FfFindPivot(x,&f);
      FfSetNoc(noc);
      FfStepPtr(&x);
      FfSetNoc(nor);
      FfStepPtr(&y);
   }

   // step 2: reduce the null space to echelon form.
   dim = 0;
   x = y = nsp;
   a = b = matrix;
   for (i = 0; i < nor; ++i) {
      if (piv[i] == -1) {
         FfSetNoc(nor);
         if (y != x) { FfCopyRow(y,x); }
         if (flags) {
            ++dim;
         } else {
            FfCleanRow(y,nsp,dim,piv);
            piv[dim++] = FfFindPivot(y,&f);
         }
         FfStepPtr(&y);
      } else {
         FfSetNoc(noc);
         if (b != a) { FfCopyRow(b,a); }
         FfStepPtr(&b);
      }
      FfSetNoc(nor);
      FfStepPtr(&x);
      FfSetNoc(noc);
      FfStepPtr(&a);
   }

   return dim;
}
예제 #9
0
파일: zor.c 프로젝트: momtx/meataxe
static int ordmat()

{   PTR m1, v;
    PTR base, bend;
    int dim;
    int *piv;
    char *ispiv;
    int ord, i;

    FfSetField(ifile->Field); 
    FfSetNoc(ifile->Noc); 
    if (ifile->Nor != ifile->Noc) 
    {
	MTX_ERROR2("%s: %E",iname,MTX_ERR_NOTSQUARE);
	return 1;
    }
    m1 = FfAlloc(FfNoc);
    base = FfAlloc(FfNoc+1);
    piv = NALLOC(int,FfNoc);
    ispiv = NALLOC(char,FfNoc);
    memset(ispiv,0,FfNoc);
    v = FfAlloc(1);
    if (MfReadRows(ifile,m1,FfNoc) != FfNoc)
    {
	MTX_ERROR("Error reading input file");
	return -1;
    }
    ord = 1;
    bend = base;

    for (dim = 0; dim < FfNoc; )
    {	
	PTR start = bend;
	int tord = 0;
	int closed = 0;

	/* Find the next seed vector
	   ------------------------- */
	for (i = 0; i < FfNoc && ispiv[i]; ++i);
	MTX_ASSERT(i < FfNoc);
	FfMulRow(bend,FF_ZERO);
	FfInsert(bend,i,FF_ONE);

	/* Calculate order on the cyclic subspace
	   -------------------------------------- */
	do
	{   PTR b;
	    FEL f;
	    int pv;

	    /* Save the vector and extend the basis,
	       if the vector is linearly independent.
	       -------------------------------------- */
	    FfCopyRow(v,bend);
	    if (!closed)
	    {	b = base;
	    	for (i = 0; i < dim; ++i)
	    	{   
		    f = FfExtract(bend,piv[i]);
		    if (f != FF_ZERO)
		    {	
			FfAddMulRow(bend,b,FfNeg(FfDiv(f,FfExtract(b,piv[i]))));
		    }
		    FfStepPtr(&b);
		}
		pv = FfFindPivot(bend,&f);
		if (pv >= 0)
		{   piv[dim++] = pv;
		    ispiv[pv] = 1;
		    FfStepPtr(&bend);
		}
		else
		    closed = 1;
	    }

	    /* Apply the matrix.
	       ----------------- */
	    if (++tord > MAXORDER_C)
	    {  
		MTX_ERROR1("zor: Partial order is over %d",MAXORDER_C);
		return 1;
	    }
	    FfMapRow(v,m1,FfNoc,bend);
	}
	while (FfCmpRows(bend,start));

	/* Calculate l.c.m. of all tord's
	   ------------------------------ */
	for (i = ord; ord % tord != 0; ord += i);
	if (ord > MAXORDER)
	{
	    MTX_ERROR1("zor: Order is over %d",MAXORDER);
	    return 1;
	}
	if (opt_q && dim > FfNoc/10) break;
	if (maxord > 1)
	{   if (ord > maxord)
	    {
	    	fprintf(stderr,"zor: Order is over %d\n",maxord);
	    	exit(1);
	    }
	    if (ord == maxord) break;
	}
    }

    if (opt_q && ord != maxord)
	MESSAGE(0,("ORDER IS A MULTIPLE OF %d\n",ord));
    else
    {
	if (opt_G)
	    printf("MeatAxe.Order := %d;\n",ord);
	else
	    printf("ORDER IS %d\n",ord);
    }
    return 0;
}
예제 #10
0
파일: presig.c 프로젝트: axelexic/linux-sgx
EpidStatus EpidComputePreSig(MemberCtx const* ctx,
                             PreComputedSignature* precompsig) {
  EpidStatus res = kEpidNotImpl;

  EcPoint* B = NULL;
  EcPoint* K = NULL;
  EcPoint* T = NULL;
  EcPoint* R1 = NULL;

  FfElement* R2 = NULL;

  FfElement* a = NULL;
  FfElement* b = NULL;
  FfElement* rx = NULL;
  FfElement* rf = NULL;
  FfElement* ra = NULL;
  FfElement* rb = NULL;
  FfElement* t1 = NULL;
  FfElement* t2 = NULL;
  FfElement* f = NULL;

  if (!ctx || !precompsig) return kEpidBadArgErr;
  if (!ctx->epid2_params || !ctx->pub_key || !ctx->priv_key)
    return kEpidBadArgErr;

  do {
    // handy shorthands:
    EcGroup* G1 = ctx->epid2_params->G1;
    FiniteField* GT = ctx->epid2_params->GT;
    FiniteField* Fp = ctx->epid2_params->Fp;
    EcPoint* h2 = ctx->pub_key->h2;
    EcPoint* A = ctx->priv_key->A;
    FfElement* x = ctx->priv_key->x;
    BigNumStr f_str = {0};
    BigNumStr a_str = {0};
    BigNumStr t1_str = {0};
    BigNumStr rf_str = {0};
    BigNumStr t2_str = {0};
    BigNumStr ra_str = {0};
    static const BigNumStr one = {
        {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}};

    if (!G1 || !GT || !Fp || !h2 || !A || !x || !ctx->priv_key->f ||
        !ctx->e12 || !ctx->e22 || !ctx->e2w || !ctx->ea2) {
      res = kEpidBadArgErr;
      BREAK_ON_EPID_ERROR(res);
    }
    f = ctx->priv_key->f;
    // The following variables B, K, T, R1 (elements of G1), R2
    // (elements of GT), a, b, rx, rf, ra, rb, t1, t2 (256-bit
    // integers) are used.
    res = NewEcPoint(G1, &B);
    BREAK_ON_EPID_ERROR(res);
    res = NewEcPoint(G1, &K);
    BREAK_ON_EPID_ERROR(res);
    res = NewEcPoint(G1, &T);
    BREAK_ON_EPID_ERROR(res);
    res = NewEcPoint(G1, &R1);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(GT, &R2);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &a);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &b);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &rx);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &rf);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &ra);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &rb);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &t1);
    BREAK_ON_EPID_ERROR(res);
    res = NewFfElement(Fp, &t2);
    BREAK_ON_EPID_ERROR(res);
    // 1. The member expects the pre-computation is done (e12, e22, e2w,
    //    ea2). Refer to Section 3.5 for the computation of these
    //    values.

    // 2. The member verifies gid in public key matches gid in private
    //    key.
    // 3. The member computes B = G1.getRandom().
    res = EcGetRandom(G1, ctx->rnd_func, ctx->rnd_param, B);
    BREAK_ON_EPID_ERROR(res);
    // 4. The member computes K = G1.sscmExp(B, f).
    res = WriteFfElement(Fp, f, &f_str, sizeof(f_str));
    BREAK_ON_EPID_ERROR(res);
    res = EcExp(G1, B, &f_str, K);
    BREAK_ON_EPID_ERROR(res);
    // 5. The member chooses randomly an integers a from [1, p-1].
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, a);
    BREAK_ON_EPID_ERROR(res);
    // 6. The member computes T = G1.sscmExp(h2, a).
    res = WriteFfElement(Fp, a, &a_str, sizeof(a_str));
    BREAK_ON_EPID_ERROR(res);
    res = EcExp(G1, h2, &a_str, T);
    BREAK_ON_EPID_ERROR(res);
    // 7. The member computes T = G1.mul(T, A).
    res = EcMul(G1, T, A, T);
    BREAK_ON_EPID_ERROR(res);
    // 8. The member computes b = (a * x) mod p.
    res = FfMul(Fp, a, x, b);
    BREAK_ON_EPID_ERROR(res);
    // 9. The member chooses rx, rf, ra, rb randomly from [1, p-1].
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rx);
    BREAK_ON_EPID_ERROR(res);
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rf);
    BREAK_ON_EPID_ERROR(res);
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, ra);
    BREAK_ON_EPID_ERROR(res);
    res = FfGetRandom(Fp, &one, ctx->rnd_func, ctx->rnd_param, rb);
    BREAK_ON_EPID_ERROR(res);
    // 10. The member computes t1 = (- rx) mod p.
    res = FfNeg(Fp, rx, t1);
    BREAK_ON_EPID_ERROR(res);
    // 11. The member computes t2 = (rb - a * rx) mod p.
    res = FfMul(Fp, a, rx, t2);
    BREAK_ON_EPID_ERROR(res);
    res = FfNeg(Fp, t2, t2);
    BREAK_ON_EPID_ERROR(res);
    res = FfAdd(Fp, rb, t2, t2);
    BREAK_ON_EPID_ERROR(res);
    // 12. The member computes R1 = G1.sscmExp(B, rf).
    res = WriteFfElement(Fp, rf, &rf_str, sizeof(rf_str));
    BREAK_ON_EPID_ERROR(res);
    res = EcExp(G1, B, &rf_str, R1);
    BREAK_ON_EPID_ERROR(res);
    // 13. The member computes R2 = GT.sscmMultiExp(ea2, t1, e12, rf,
    //     e22, t2, e2w, ra).
    res = WriteFfElement(Fp, t1, &t1_str, sizeof(t1_str));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, t2, &t2_str, sizeof(t2_str));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, ra, &ra_str, sizeof(ra_str));
    BREAK_ON_EPID_ERROR(res);
    {
      FfElement const* points[4];
      BigNumStr const* exponents[4];
      points[0] = ctx->ea2;
      points[1] = ctx->e12;
      points[2] = ctx->e22;
      points[3] = ctx->e2w;
      exponents[0] = &t1_str;
      exponents[1] = &rf_str;
      exponents[2] = &t2_str;
      exponents[3] = &ra_str;
      res = FfMultiExp(GT, points, exponents, COUNT_OF(points), R2);
      BREAK_ON_EPID_ERROR(res);
    }
    // 14. The member sets and outputs pre-sigma = (B, K, T, a, b, rx,
    //     rf, ra, rb, R1, R2).
    res = WriteEcPoint(G1, B, &precompsig->B, sizeof(precompsig->B));
    BREAK_ON_EPID_ERROR(res);
    res = WriteEcPoint(G1, K, &precompsig->K, sizeof(precompsig->K));
    BREAK_ON_EPID_ERROR(res);
    res = WriteEcPoint(G1, T, &precompsig->T, sizeof(precompsig->T));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, a, &precompsig->a, sizeof(precompsig->a));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, b, &precompsig->b, sizeof(precompsig->b));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, rx, &precompsig->rx, sizeof(precompsig->rx));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, rf, &precompsig->rf, sizeof(precompsig->rf));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, ra, &precompsig->ra, sizeof(precompsig->ra));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(Fp, rb, &precompsig->rb, sizeof(precompsig->rb));
    BREAK_ON_EPID_ERROR(res);
    res = WriteEcPoint(G1, R1, &precompsig->R1, sizeof(precompsig->R1));
    BREAK_ON_EPID_ERROR(res);
    res = WriteFfElement(GT, R2, &precompsig->R2, sizeof(precompsig->R2));
    BREAK_ON_EPID_ERROR(res);
    // 15. The member stores pre-sigma in the secure storage of the
    //     member.
    res = kEpidNoErr;
  } while (0);

  f = NULL;
  DeleteEcPoint(&B);
  DeleteEcPoint(&K);
  DeleteEcPoint(&T);
  DeleteEcPoint(&R1);
  DeleteFfElement(&R2);
  DeleteFfElement(&a);
  DeleteFfElement(&b);
  DeleteFfElement(&rx);
  DeleteFfElement(&rf);
  DeleteFfElement(&ra);
  DeleteFfElement(&rb);
  DeleteFfElement(&t1);
  DeleteFfElement(&t2);

  return (res);
}