Exemple #1
0
/**
 * calculate the result = A mod n.
 * n is the order of the eliptic curve.
 * A and result could point to the same value
 *
 * A: input value (max size * 4 bytes)
 * result: result of modulo calculation (max 36 bytes)
 * size: size of A
 *
 * This uses the Barrett modular reduction as described in the Handbook 
 * of Applied Cryptography 14.42 Algorithm Barrett modular reduction, 
 * see http://cacr.uwaterloo.ca/hac/about/chap14.pdf and 
 * http://everything2.com/title/Barrett+Reduction
 *
 * b = 32 (bite size of the processor architecture)
 * mu (ecc_order_mu) was precomputed in a java program
 */
static void fieldModO(const uint32_t *A, uint32_t *result, uint8_t length) {
	// This is used for value q1 and q3
	uint32_t q1_q3[9];
	// This is used for q2 and a temp var
	uint32_t q2_tmp[18];

	// return if the given value is smaller than the modulus
	if (length == arrayLength && isGreater(A, ecc_order_m, arrayLength) <= 0) {
		if (A != result)
		        copy(A, result, length);
		return;
	}

	rshiftby(A, length, q1_q3, 9, ecc_order_k - 1);

	fieldMult(ecc_order_mu, q1_q3, q2_tmp, 9);

	rshiftby(q2_tmp, 18, q1_q3, 8, ecc_order_k + 1);

	// r1 = first 9 blocks of A

	fieldMult(q1_q3, ecc_order_m, q2_tmp, 8);

	// r2 = first 9 blocks of q2_tmp

	sub(A, q2_tmp, result, 9);

	while (isGreater(result, ecc_order_m, 9) >= 0)
		sub(result, ecc_order_m, result, 9);
}
Exemple #2
0
/**
 * How to make this not so inefficient:
 * LinkedLists aren't the best data structure
 * for this, a tree would allow log(n) insertions.
 * Or, with a simple array, binary searches could
 * be used to also acheive log(n) insertion.
 * Using a linked list locks you in to O(n), but
 * some level of caching may improve real world
 * performance.  For example, knowing the size of the
 * list and storing pointers to midpoints would
 * improve performance at the expense of memory.
 * When using this on very large real world text,
 * it would be useful to store pointers to the most
 * popular words (the, and, a, etc.) because access
 * to these words in constant time would significantly
 * improve performance in a text with enough unique
 * words.  Even with all this magic, a tree will
 * outperform the linkedlist.
 */
lnode insertWord(char * word, lnode head) {
	/* Your code to insert a word in the linked list goes here */
    if(!head) return makeLnode(word);
    lnode node = head;
    lnode prev = node;
    if(isGreater(word, node->value) == -1) {
        head = makeLnode(word);
        head->next = node;
        return head;
    }
    while(node) {
        if(isGreater(word, node->value) == -1) {
            prev->next = makeLnode(word);
            prev->next->next = node;
            return head;
        }
        if(isGreater(word, node->value) == 0) {
            node->count++;
            return head;
        }
        if(isGreater(word, node->value) == 1) {
            prev = node;
            node = node->next;
        }
    }
    prev->next = makeLnode(word);
    return head;
}
Exemple #3
0
unsigned *cannon_detect_collisions(CANNON *c,
				   OBJECT_POSITION *asteroids,
				   unsigned asteroids_size) {
  unsigned i, j, k, aNext, removedI;
  float minX, maxX, minY, maxY;
  unsigned *remove;

  if (!c)
    return NULL;

  remove = malloc(sizeof(unsigned) * asteroids_size);
  if (!remove)
    return NULL;
  removedI = 0;
  for (i = 0; i < asteroids_size; i++)
    remove[i] = UINT_MAX;

  for (i = 0; i < asteroids_size; i++) {
    for (j = 0; j < asteroids[i].points_size; j++) {
      aNext = j + 1;
      if (aNext == asteroids[i].points_size)
	aNext = 0;

      minX = fminf(asteroids[i].points[j].x, asteroids[i].points[aNext].x);
      maxX = fmaxf(asteroids[i].points[j].x, asteroids[i].points[aNext].x);
      minY = fminf(asteroids[i].points[j].y, asteroids[i].points[aNext].y);
      maxY = fmaxf(asteroids[i].points[j].y, asteroids[i].points[aNext].y);

      for (k = 0; k < MAX_LASERS_AT_ONCE; k++) {
	if (!c->lasers[k].valid)
	  continue;
	if ((isGreater(c->lasers[k].pos->points[0].x, minX)
	     && isLess(c->lasers[k].pos->points[0].x, maxX)
	     && isGreater(c->lasers[k].pos->points[0].y, minY)
	     && isLess(c->lasers[k].pos->points[0].y, maxY))
	    ||
	    (isGreater(c->lasers[k].pos->points[1].x, minX)
	     && isLess(c->lasers[k].pos->points[1].x, maxX)
	     && isGreater(c->lasers[k].pos->points[1].y, minY)
	     && isLess(c->lasers[k].pos->points[1].y, maxY))) {
	  c->lasers[k].valid = false;
	  c->totalLasers--;
	  remove[removedI++] = asteroids[i].id;
	}
      }
    }
  }
  return remove;
}
Exemple #4
0
  bool sub (bignum one, bignum two, bignum* result) {
    //Return true if one is greater than two otherwise false
    bool temp_bool = isGreater(one, two);
    if (!temp_bool) {
      sub(two, one, result);
      return false;
    }
    assert(isGreater(one, two));
    int diff = 0, borrow = 0, i = one.length - 1, j = two.length - 1, last = MAXLEN - 1;
    char temp[MAXLEN];

    while (j >= 0) {
      diff = int(one.data[i--]) - int(two.data[j--]) + borrow;
      borrow = 0;
      while (diff < 0) {
        borrow--;
        diff += 10;
      }
      temp[last--] = diff + '0';
    }
    while (i >=0) {
      diff = int(one.data[i--]) - int('0') + borrow;
      borrow = 0;
      while(diff < 0) {
        borrow--;
        diff += 10;
        }
      temp[last--] = diff + '0';
    }
    /*working fine, need to check case of borrow>0??
    * removing all the preceding zeros except the case 
    * when answer is 0, thus MAXLEN - 2.
    */ 
    while ((last < MAXLEN-2) && (temp[last+1]) == '0') {
      last++;
    }
    
    result->length = MAXLEN - 1 - last;
    for (int i = 0; i< result->length; i++) {
      result->data[i] = temp[i+last+1];
    }
     return true;
  }
int itemCompare (void const* ap, void const* bp)
{
  StatsItem const* a = (StatsItem const*) ap;
  StatsItem const* b = (StatsItem const*) bp;
  int res = isGreater (a, b);
  if (res == 0)
    res = a->curpos - b->curpos;
  if (sortUp)
    res = -res;
  return res;
}
Exemple #6
0
Result validate(const SampledDimension &sampled_dim) {
    return validator({
        must(sampled_dim, &SampledDimension::index, notSmaller(1), "index is not set to valid value (size_t > 0)!"),
        must(sampled_dim, &SampledDimension::samplingInterval, isGreater(0), "samplingInterval is not set to valid value (> 0)!"),
        must(sampled_dim, &SampledDimension::dimensionType, isEqual<DimensionType>(DimensionType::Sample), "dimension type is not correct!"),
        could(sampled_dim, &SampledDimension::offset, notFalse(), {
            should(sampled_dim, &SampledDimension::unit, isAtomicUnit(), "offset is set, but no valid unit set!") }),
        could(sampled_dim, &SampledDimension::unit, notFalse(), {
            must(sampled_dim, &SampledDimension::unit, isAtomicUnit(), "Unit is set but not an atomic SI. Note: So far composite units are not supported!") })
    });
}
void bubbleSort(DBrecord *A[], int num, Field f)
{
    int i,j;
    for(i = 0; i < num-1; i++)
    {
        for(j = 0; j < num-i-1; j++)
        {
            if( isGreater(A[j],A[j+1],f) )
                swap (A,j,j+1);
        }
    }
}
int search_element(struct transaction *arr, char *key, int len, int low, int high)
{
	//if(key<arr[low] || key>arr[high])
	int temp1, temp2;
	temp1 = isGreater(key, arr[low].date);
	temp2 = isGreater(key, arr[high-1].date);
	//printf("%d,%d",temp1,temp2);
	if (temp1 == -1 || temp2 == 1)
		return -1;
	if (high >= low)
	{
		//printf("high=%d\nlow=%d",high,low);
		int mid = (low + high) / 2;
		temp1 = isGreater(arr[mid + 1].date, key);
		temp2 = isGreater(arr[mid].date, key);
		if ((mid == 0 || temp1 == 1) && temp2 == 0)
			return mid;
		else if (temp2 == 1)
			search_element(arr, key, len, low, mid-1);
		else
			search_element(arr, key, len, mid+1, high);
	}
}
Exemple #9
0
static int fieldAddAndDivide(const uint32_t *x, const uint32_t *modulus, const uint32_t *reducer, uint32_t* result){
	uint32_t n = add(x, modulus, result, arrayLength);
	rshift(result);
	if(n){ //add prime if carry is still set!
		result[7] |= 0x80000000;//add the carry
		if (isGreater(result, modulus, arrayLength) == 1)
		{
			uint32_t tempas[8];
			setZero(tempas, 8);
			add(result, reducer, tempas, 8);
			copy(tempas, result, arrayLength);
		}
		
	}
	return 0;
}
void asteroids_coordinator_move_asteroids(ASTEROIDS_COORDINATOR *ac) {
  unsigned i;

  if (!ac)
    return;

  for (i = 0; i < MAX_ASTEROIDS; i++) {
    if (!ac->asteroids[i].valid) {
      ac->asteroids[i].valid = true;
      ac->asteroids[i].x_speed = (rand() % MAX_ASTEROID_SPEED) +
	(double)MAX_ASTEROID_SPEED/4;
      ac->asteroids[i].y_speed = (rand() % MAX_ASTEROID_SPEED) +
	(double)MAX_ASTEROID_SPEED/4;
      if (rand() % 2) {
	if (rand() % 2)
	  ac->asteroids[i].pos->center.x = 0.0f;
	else
	  ac->asteroids[i].pos->center.x = ac->display.x;

	ac->asteroids[i].pos->center.y = rand() % (int)ac->display.y;
      } else {
	ac->asteroids[i].pos->center.x = rand() % (int)ac->display.x;
	if (rand() % 2)
	  ac->asteroids[i].pos->center.y = 0.0f;
	else
	  ac->asteroids[i].pos->center.y = ac->display.y;
      }
      ac->asteroids[i].pos->rotation = 0.0f;
      ac->asteroids[i].rotation_step = (rand() % 2) * (M_PI / 50.0f) + 0.05;

      if ((int)ac->asteroids[i].x_speed % 2)
	ac->asteroids[i].rotation_step *= -1;
    }

    ac->asteroids[i].pos->rotation += ac->asteroids[i].rotation_step;
    if (isGreater(fabs(ac->asteroids[i].pos->rotation), M_DOUBLE_PI))
      ac->asteroids[i].pos->rotation = 0.0;

    ac->asteroids[i].pos->center.x += ac->asteroids[i].x_speed;

    ac->asteroids[i].pos->center.y += ac->asteroids[i].y_speed;

    ac->asteroids[i].valid = _set_asteroid_position(&ac->asteroids[i],
						    ac->display);
  }
}
struct transaction * sortedArraysCommonElements(struct transaction *A, int ALen, struct transaction *B, int BLen) {
	int i, j, m = 0;
	struct transaction common[10];
	if ((A == NULL) || (B == NULL) || (ALen<1) || (BLen<1))
		return NULL;
	for (i = 0; i < ALen; i++)
	{
		for (j = 0; j < BLen; j++)
		{
			if (isGreater(A[i].date, B[j].date) == 0)
				common[m++] = A[i];
		}
	}
	if (m == 0)
		return NULL;
	return common;
}
Exemple #12
0
   // intersection segment((p - 1erpoint vector)/segment(2e et 3e point du vecteur)
  static int inter(gml::Point3D const & p,
                   std::vector< gml::Point3D > const &points,
                   double* t1, double* t2)
  {
    double one = 1;
    double null_value = 0;
    
    int i;
    double d, a[3], b[3], c[3];
    std::vector< gml::Point3D > allPoints;
     
    allPoints.push_back(p);
    allPoints.push_back(points[0]);
    allPoints.push_back(points[1]);
    allPoints.push_back(points[2]);

    //define if all the points are on the plane
    if( ! onPlane(allPoints[0], allPoints) )
    {
      return 0;
    }

    if( ! onPlane(allPoints[1], allPoints) )
    {
      return 0;
    }

    if( ! onPlane(allPoints[2], allPoints) )
    {
      return 0;
    }

    if( ! onPlane(allPoints[3], allPoints) )
    {
      return 0;
    }


    for(i=0; i<3; i++)
    {
      a[i]= allPoints[1][i] - allPoints[0][i];
      b[i]= -allPoints[3][i] + allPoints[2][i];
      c[i]= allPoints[0][i] - allPoints[2][i];
    }
    
    for(i=0; i<3; i++)
    {
      int j, j_nxt;
      
      j=i;
      j_nxt=(i==2)?0:i+1;

      d= a[j]*b[j_nxt] - b[j]*a[j_nxt];
      
      if( ! isEqual(d, 0.0) )
      {
        *t1= (-c[j]*b[j_nxt] + b[j]*c[j_nxt])/d;
        *t2= (-a[j]*c[j_nxt] + c[j]*a[j_nxt])/d;
	
//        if( *t1 < -tolerance || *t1 > 1.+tolerance )
        if( isLesser(*t1, null_value) || isGreater(*t1, one) ) 
        {
          return 2;
        }
        
//        if( *t2 < -tolerance || *t2 > 1.+tolerance )
        if( isLesser(*t2, null_value) || isGreater(*t2, one) ) 
        {
          return 2;
        }
        return 1;
      }
    }
    
    return 0;
    
  } //end of method inter
Exemple #13
0
int
MeshEdgeElementTable::calcLineIntersections(int elem_index, short elem_dir,
                                            Point3& lstart, Point3& ldir, Point3* isec_points)
{
  meshElementCode elem_code = getElementCode(elem_index);

  if (elem_code <  MEC_202 || elem_code >= 303)
    return 0;

  const int* nodeIds = getNodeIds(elem_index, elem_dir);

  Point3& p0 = meshNodes[nodeIds[0]];
  Point3& p1 = meshNodes[nodeIds[1]];
  
  Point3& normal = normals[elem_index];
  if (elem_dir == -1)
    scalarmult(-1, normal, normal);

  // Check end-point cases
  if ( samepoint(p0, lstart) ){
    copy3(p0, *isec_points);
    return 1;
  }
  if ( samepoint(p1, lstart) ){
    copy3(p1, *isec_points);
    return 1;
  }


  Point3 edge_dir, l_delta0, tmp;
 
  // Edge direction vector (normalized)
  edge_dir[0] = normal[1];
  edge_dir[1] = -1 * normal[0];
  edge_dir[2] = 0.0;

  // Edge length
  diff3(p1, p0, tmp);
  double edge_len = dot3(edge_dir, tmp);

  // Vector l_delta0 = lstart - p0
  diff3(lstart, p0, l_delta0);

  // Check that intersection is "within" the edge
  // project the intersection point to the edge
  double t = dot3(edge_dir, l_delta0);
  if ( isLess(t, 0.0) ||
       isGreater(t, edge_len)
     )
    return 0;

  // Check that intersection distance from the edge is ok
  // project intersection point to the edge normal
  double d = dot3(normal, l_delta0);
  if (d < 0)
    d *= -1;
  if ( isGreater(d, MeshEdgeElementTable::pickingTolerance) )
    return 0;

  // Intersection point is: p0 + t * (p1 - p0)
  scalarmult(t, edge_dir, tmp);
  add3(p0, tmp, *isec_points);

  return 1;
}
Exemple #14
0
// NOTE: This should work for all triangle elments (303 - 306), but only
// if mid-edge and middle nodes are after "corner" nodes in the node list!
// Return nof intersections
//
int
MeshFaceElementTable::calcTriangleLineIntersections(int elem_index, short direction,
                                                    Point3& lstart, Point3& ldir, Point3* isec_points)
{
  // Ccw ordered nodes (if elem_dir is -1, it is from the parent2
  // and nodes are cw oriented and must me reordered
  Point3& p0 = meshNodes[nodeIds[elem_index][0]];
  Point3& p1 = meshNodes[nodeIds[elem_index][1]];
  Point3& p2 = meshNodes[nodeIds[elem_index][2]];
  Point3& normal = normals[elem_index];

  static Point3* points[3];

  points[0] = (direction >= 0)? &p0 : &p1;
  points[1] = (direction >= 0)? &p1 : &p0;
  points[2] = &p2;

#if 0
  // If element is looking into wrong direction
  //
  // NOTE: This makes picking much faster, so wew have to use it (unless some better
  // method is found), although it means that elements cannot be selected from 'inside',
  // which would be quite convenient in some cases!
  //
  if ( direction == 1 ) {
    if ( !isLess(dot3(normal, ldir), 0) ) {
      return 0;
    }

  } else if ( direction == -1 ) {
    if ( !isGreater(dot3(normal, ldir), 0) ) {
      return 0;
    }
  }
#endif

  // Plane equation for the normal and a point in the plane is;
  // (r) dot (normal) = (r0) dot (normal) = d
  // So for the form Ax + By + Cz + D = 0, we have
  // A = normal[0], B = normal[1], C = normal[2], D = -d

  double D = -1 * dot3(p0, normal);

  double numer = dot3(normal, lstart) + D;
  double denom = dot3(normal, ldir);

  double t;

  // Intersection
  if (denom != 0) {
    t = - numer / denom;

  // Line is on the plane
  } else if (numer == 0) {
    t = 0.0;

  // Line is parallel,but not in the plane
  } else {
    return 0;
  }


  //-Calc intersection point from the line equation
  Point3 tmp;
  scalarmult(t, ldir, tmp);
  Point3 isec_point;
  add3(lstart, tmp, isec_point);

  // Finally check if intersection point
  // is inside the element (triangle)
  if ( pointInsideTriangle(isec_point, points, centers[elem_index], rSquares[elem_index]) ) {

    copy3(isec_point, *isec_points);
    return 1;

  } else {
    return 0;
  }

}
Exemple #15
0
int ecc_isGreater(const uint32_t *A, const uint32_t *B, uint8_t length)
{
	return isGreater(A, B , length);
}
Exemple #16
0
int ecc_is_valid_key(const uint32_t * priv_key)
{
	return isGreater(ecc_order_m, priv_key, arrayLength) == 1;
}
Exemple #17
0
bool isInvisible(POINT p, POINT display) {
  return isGreater(p.x, display.x) || isGreater(p.y, display.y) ||
    isLess(p.x, 0.0) || isLess(p.y, 0.0);
}
Exemple #18
0
//Returns wheter or not the segment [ a , b]
// intersect he plane defined by the points in the vector
// Valeurs retournées :
// -1 : problème dans la definition du plan
// 0 : le segment n'intersecte pas la face
// 1 : le segment intersecte la face de façon incorrecte
// 2 : le segment intersecte la face de façon correcte
  static int interPlan(gml::Point3D & a, gml::Point3D & b, 
                        std::vector < gml::Point3D > const & points,
                        double *t)
  {
    std::vector<double> plane;
    double null_value = 0.0;
    double one = 1.0;

    // 1) If the normal of the plan and the vector of the 
    //edge are perpendicular, then there is no verification
    double vectorEdgeX = a[0] - b[0];
    double vectorEdgeY = a[1] - b[1];
    double vectorEdgeZ = a[2] - b[2];

    plane = definePlane(points);
    if( plane.empty() )
    {
      return -1;
    }


    // Premiere verification, on regarde si le segment est parallèle au plan 
    // Il y a alors deux cas :
    // - le segment est en dehors du plan
    // - le segment est sur le plan
    if(isEqual((plane[0]*vectorEdgeX + plane[1]*vectorEdgeY + plane[2]*vectorEdgeZ), null_value))
    {
      // Si le segment ne se trouve pas sur le plan, alors on retourne 0
      if (!onPlane(a, points) && !onPlane(b, points)) {
	return 0;
      }

      // Cas ou le segment se trouve sur le plan
      else {

	/*if (onPlane(a, points) && !onPlane(b, points)) {
	   std::cout << "a est sur le plan mais pas b" << std::endl;
	 }

	  if (!onPlane(a, points) && onPlane(b, points)) {
	    std::cout << "b est sur le plan mais pas a" << std::endl;
	    }*/

	// Recherche si les points du segment ne correspondent pas aux points de la face
	bool founda = false;
	bool foundb = false;
	int i=0;
	int j=0;
	while ((!founda || !foundb ) && i<points.size()) {
	  
	  // Si le premier point a est un point de la face
	  if (isTheSame(a, points[i])) {
	    
	    founda = true;
	    
	    
	    // Gestion des indices
	    if (i+1 == points.size()) {
	      j=0;
	    }
	    else {
	      j=i+1;
	    }
	    
	    // Si le segment est une arrete de la face on stoppe l'execution
	    if (isTheSame(b, points[j])) {
	      return 2;
	    }
	  }

	  // Si le premier point b est un point de la face
	  if (isTheSame(b, points[i])) {
	    
	    foundb = true;


	    // Gestion des indices
	    if (i+1 == points.size()) {
	      j=0;
	    }
	    else {
	      j=i+1;
	    }

	    // Si le segment est une arrete de la face on stoppe l'execution
	    if (isTheSame(a, points[j])) {
		return 2;
	    }
	  }

	  i++;
	    
	}
	    
	 
	// Si les deux points du segment sont des points de la face mais pas des points successifs 
	if (founda && foundb) {
	  *t=0.0;
	  return 1;
	}
	else {
	  // Le point b est un point de la face mais pas le point a
	  if (!founda && foundb) {
	    // Cependant le point a est un point sur la face
	    if (onFace(a, points)) {
	      *t=0.0;
	      return 1;
	    }
	    // Sinon
	    else {
	      return 2;
	    }
	  }
	  else {
	    // Le point a est un point de la face mais pas le point b
	    if (founda && !foundb) {
	      // Cependant le point b est un point sur la face
	      if (onFace(b, points)) {
		*t=1.0;
		return 1;
	      }
	      else {
		return 2;
	      }
	    }
	    // Aucun des points a ou b n'est un point de la face
	    else {
	      // Si le point a est sur la face
	      if (onFace(a, points)) {
		*t=0.0;
		return 1;
	      }
	      // Si le point b est sur la face
	      if (onFace(b, points)) {
		*t=1.0;
		return 1;
	      }
	      return 0;
	    }
	  }
	}

	// Probleme de valeur
	return -1;

      }
    }

    // 3) Compute of t
    *t = (-plane[0] * a[0] - plane[1] * a[1] - plane[2] * a[2] - plane[3]) /
      (plane[0]*vectorEdgeX + plane[1]*vectorEdgeY + plane[2]*vectorEdgeZ);

    //Intersection avec la droite mais PAS le segment
    if ( isLesser(*t, null_value) || isGreater(*t ,one) )
    {
      return 0;
    }
    else
    {
#ifndef CORE_LEVEL
      gml::Point3D interPoint = a.collinear(b, *t);
#else
      //TODO : check more accurately
      gml::Point3D interPoint = a.collinear(b, (*t).doubleValue() );
#endif
      if (! onFace(interPoint, points))
	{
	  return 0;
	}
      else
	{
	  return 1;
	}
    }
  }
Exemple #19
0
//TODO: maximum:
//fffffffe00000002fffffffe0000000100000001fffffffe00000001fffffffe00000001fffffffefffffffffffffffffffffffe000000000000000000000001_16
static void fieldModP(uint32_t *A, const uint32_t *B)
{
	uint32_t tempm[8];
	uint32_t tempm2[8];
	uint8_t n;
	setZero(tempm, 8);
	setZero(tempm2, 8);
	/* A = T */ 
	copy(B,A,arrayLength);

	/* Form S1 */ 
	for(n=0;n<3;n++) tempm[n]=0; 
	for(n=3;n<8;n++) tempm[n]=B[n+8];

	/* tempm2=T+S1 */ 
	fieldAdd(A,tempm,ecc_prime_r,tempm2);
	/* A=T+S1+S1 */ 
	fieldAdd(tempm2,tempm,ecc_prime_r,A);
	/* Form S2 */ 
	for(n=0;n<3;n++) tempm[n]=0; 
	for(n=3;n<7;n++) tempm[n]=B[n+9]; 
	for(n=7;n<8;n++) tempm[n]=0;
	/* tempm2=T+S1+S1+S2 */ 
	fieldAdd(A,tempm,ecc_prime_r,tempm2);
	/* A=T+S1+S1+S2+S2 */ 
	fieldAdd(tempm2,tempm,ecc_prime_r,A);
	/* Form S3 */ 
	for(n=0;n<3;n++) tempm[n]=B[n+8]; 
	for(n=3;n<6;n++) tempm[n]=0; 
	for(n=6;n<8;n++) tempm[n]=B[n+8];
	/* tempm2=T+S1+S1+S2+S2+S3 */ 
	fieldAdd(A,tempm,ecc_prime_r,tempm2);
	/* Form S4 */ 
	for(n=0;n<3;n++) tempm[n]=B[n+9]; 
	for(n=3;n<6;n++) tempm[n]=B[n+10]; 
	for(n=6;n<7;n++) tempm[n]=B[n+7]; 
	for(n=7;n<8;n++) tempm[n]=B[n+1];
	/* A=T+S1+S1+S2+S2+S3+S4 */ 
	fieldAdd(tempm2,tempm,ecc_prime_r,A);
	/* Form D1 */ 
	for(n=0;n<3;n++) tempm[n]=B[n+11]; 
	for(n=3;n<6;n++) tempm[n]=0; 
	for(n=6;n<7;n++) tempm[n]=B[n+2]; 
	for(n=7;n<8;n++) tempm[n]=B[n+3];
	/* tempm2=T+S1+S1+S2+S2+S3+S4-D1 */ 
	fieldSub(A,tempm,ecc_prime_m,tempm2);
	/* Form D2 */ 
	for(n=0;n<4;n++) tempm[n]=B[n+12]; 
	for(n=4;n<6;n++) tempm[n]=0; 
	for(n=6;n<7;n++) tempm[n]=B[n+3]; 
	for(n=7;n<8;n++) tempm[n]=B[n+4];
	/* A=T+S1+S1+S2+S2+S3+S4-D1-D2 */ 
	fieldSub(tempm2,tempm,ecc_prime_m,A);
	/* Form D3 */ 
	for(n=0;n<3;n++) tempm[n]=B[n+13]; 
	for(n=3;n<6;n++) tempm[n]=B[n+5]; 
	for(n=6;n<7;n++) tempm[n]=0; 
	for(n=7;n<8;n++) tempm[n]=B[n+5];
	/* tempm2=T+S1+S1+S2+S2+S3+S4-D1-D2-D3 */ 
	fieldSub(A,tempm,ecc_prime_m,tempm2);
	/* Form D4 */ 
	for(n=0;n<2;n++) tempm[n]=B[n+14]; 
	for(n=2;n<3;n++) tempm[n]=0; 
	for(n=3;n<6;n++) tempm[n]=B[n+6]; 
	for(n=6;n<7;n++) tempm[n]=0; 
	for(n=7;n<8;n++) tempm[n]=B[n+6];
	/* A=T+S1+S1+S2+S2+S3+S4-D1-D2-D3-D4 */ 
	fieldSub(tempm2,tempm,ecc_prime_m,A);
	if(isGreater(A, ecc_prime_m, arrayLength) >= 0){
		fieldSub(A, ecc_prime_m, ecc_prime_m, tempm);
		copy(tempm, A, arrayLength);
	}
}