예제 #1
0
/* Line function */
static void PAIR_line(FP12 *v,ECP2 *A,ECP2 *B,BIG Qx,BIG Qy)
{
	ECP2 P;
	FP2 Z3,X,Y,ZZ,T,NY;
	FP4 a,b,c;
	int D;
	ECP2_copy(&P,A);
	if (A==B)
		D=ECP2_dbl(A);  // check these return numbers...
	else
		D=ECP2_add(A,B);
	if (D<0)
	{ /* Infinity */
		FP12_one(v);
		return;
	}

	FP2_copy(&Z3,&(A->z));
	FP4_zero(&c);
	FP2_sqr(&ZZ,&(P.z));    /* ZZ=Z^2 */
	if (D==0)
	{ /* addition */
		ECP2_get(&X,&Y,B);
		FP2_mul(&T,&(P.z),&Y);  /* T=Z*Y2 */

		FP2_mul(&ZZ,&ZZ,&T);

		FP2_neg(&NY,&(P.y));
		FP2_add(&ZZ,&ZZ,&NY); /* ZZ=Z^3*Y2-Y (slope numerator) */
		FP2_pmul(&Z3,&Z3,Qy);    /* Z3*Qy */
		FP2_mul(&T,&T,&(P.x));
		FP2_mul(&X,&X,&NY);
		FP2_add(&T,&T,&X);       /* Z*Y2*X-X2*Y */
		FP4_from_FP2s(&a,&Z3,&T); /* a=[Z3*Qy,Z*Y2*X-X2*Y] */
		FP2_neg(&ZZ,&ZZ);
		FP2_pmul(&ZZ,&ZZ,Qx);
		FP4_from_FP2(&b,&ZZ);    /* b=-slope*Qx */
	}
	else
	{ /* doubling */
		FP2_sqr(&T,&(P.x));
		FP2_imul(&T,&T,3);   /* T=3X^2 (slope numerator) */
		FP2_sqr(&Y,&(P.y));

		FP2_add(&Y,&Y,&Y);   /* Y=2Y^2 */
		FP2_mul(&Z3,&Z3,&ZZ);   /* Z3=Z3*ZZ */
		FP2_pmul(&Z3,&Z3,Qy);   /* Z3=Z3*ZZ*Qy */

		FP2_mul(&X,&(P.x),&T);
		FP2_sub(&X,&X,&Y);      /* X=X*slope-2Y^2 */
		FP4_from_FP2s(&a,&Z3,&X); /* a=[Z3*ZZ*Qy , X*slope-2Y^2] */
		FP2_neg(&T,&T);
		FP2_mul(&ZZ,&ZZ,&T);
		FP2_pmul(&ZZ,&ZZ,Qx);
		FP4_from_FP2(&b,&ZZ);    /* b=-slope*ZZ*Qx */
	}

	FP12_from_FP4s(v,&a,&b,&c);
}
예제 #2
0
/* SU= 160 */
void FP4_neg(FP4 *w,FP4 *x)
{ /* Just one field neg */
	FP2 m,t;
	FP2_add(&m,&(x->a),&(x->b));
	FP2_neg(&m,&m);
	FP2_norm(&m);
	FP2_add(&t,&m,&(x->b));
	FP2_add(&(w->b),&m,&(x->a));
	FP2_copy(&(w->a),&t);
}
예제 #3
0
int FP6_add(const PAIRING_GROUP *group, FP6 *r, const FP6 *a, const FP6 *b) {
	if (!FP2_add(group, &r->f[0], &a->f[0], &b->f[0])) {
		return 0;
	}
	if (!FP2_add(group, &r->f[1], &a->f[1], &b->f[1])) {
		return 0;
	}
	if (!FP2_add(group, &r->f[2], &a->f[2], &b->f[2])) {
		return 0;
	}
	return 1;
}
예제 #4
0
/* SU= 312 */
void FP4_mul(FP4 *w,FP4 *x,FP4 *y)
{

	FP2 t1,t2,t3,t4;
	FP2_mul(&t1,&(x->a),&(y->a)); /* norms x */
	FP2_mul(&t2,&(x->b),&(y->b)); /* and y */
	FP2_add(&t3,&(y->b),&(y->a)); 
	FP2_add(&t4,&(x->b),&(x->a)); 


	FP2_mul(&t4,&t4,&t3); /* (xa+xb)(ya+yb) */
	FP2_sub(&t4,&t4,&t1);    
#if CHUNK<64
	FP2_norm(&t4);
#endif
	FP2_sub(&(w->b),&t4,&t2); 
	FP2_mul_ip(&t2);
	FP2_add(&(w->a),&t2,&t1);

	FP4_norm(w);
}
예제 #5
0
/* SU= 232 */
void FP4_sqr(FP4 *w,FP4 *x)
{
	FP2 t1,t2,t3;
 
	FP2_mul(&t3,&(x->a),&(x->b)); /* norms x */
	FP2_copy(&t2,&(x->b));
	FP2_add(&t1,&(x->a),&(x->b)); 
	FP2_mul_ip(&t2); 

	FP2_add(&t2,&(x->a),&t2); 

	FP2_mul(&(w->a),&t1,&t2);

	FP2_copy(&t2,&t3);   
	FP2_mul_ip(&t2);         

	FP2_add(&t2,&t2,&t3); 

	FP2_neg(&t2,&t2);         
	FP2_add(&(w->a),&(w->a),&t2);  /* a=(a+b)(a+i^2.b)-i^2.ab-ab = a*a+ib*ib */
	FP2_add(&(w->b),&t3,&t3);  /* b=2ab */

	FP4_norm(w);
}
예제 #6
0
/* SU= 200 */
void FP4_times_i(FP4 *w)
{
	BIG z;
	FP2 s,t;
#if CHUNK<64
	FP4_norm(w);
#endif
	FP2_copy(&t,&(w->b));

	FP2_copy(&s,&t);

	BIG_copy(z,s.a);
	FP_neg(s.a,s.b);
	BIG_copy(s.b,z);

	FP2_add(&t,&t,&s);
#if CHUNK<64
	FP2_norm(&t);
#endif
	FP2_copy(&(w->b),&(w->a));
	FP2_copy(&(w->a),&t);
}
예제 #7
0
파일: fp12.c 프로젝트: gitter-badger/MiotCL
/* catering for special case that arises from special form of ATE pairing line function */
void FP12_smul(FP12 *w,FP12 *y)
{
	FP4 z0,z2,z3,t0,t1;

	FP4_copy(&z3,&(w->b));
	FP4_mul(&z0,&(w->a),&(y->a));
	FP4_pmul(&z2,&(w->b),&(y->b).a);
	FP4_add(&(w->b),&(w->a),&(w->b));
	FP4_copy(&t1,&(y->a));
	FP2_add(&t1.a,&t1.a,&(y->b).a);

	FP4_mul(&(w->b),&(w->b),&t1);  
	FP4_add(&z3,&z3,&(w->c));
	FP4_pmul(&z3,&z3,&(y->b).a);
	FP4_neg(&t0,&z0);
	FP4_neg(&t1,&z2);

	FP4_add(&(w->b),&(w->b),&t0);   // z1=z1-z0
#if CHUNK<64	
	FP4_norm(&(w->b));
#endif
	FP4_add(&(w->b),&(w->b),&t1);   // z1=z1-z2

	FP4_add(&z3,&z3,&t1);        // z3=z3-z2
	FP4_add(&z2,&z2,&t0);        // z2=z2-z0

	FP4_add(&t0,&(w->a),&(w->c));
	
	FP4_mul(&t0,&(y->a),&t0);
	FP4_add(&(w->c),&z2,&t0);

	FP4_times_i(&z3);
	FP4_add(&(w->a),&z0,&z3);

	FP12_norm(w);
}
예제 #8
0
int FP6_inv(const PAIRING_GROUP *group, FP6 *r, const FP6 *a, BN_CTX *ctx) {
	FP2 v0, v1, v2, t0;
	int ret;

	FP2_init(&v0);
	FP2_init(&v1);
	FP2_init(&v2);
	FP2_init(&t0);

	/* v0 = a_0^2 - E * a_1 * a_2. */
	if (!FP2_sqr(group, &t0, &a->f[0], ctx)) {
		goto err;
	}
	if (!FP2_mul(group, &v0, &a->f[1], &a->f[2], ctx)) {
		goto err;
	}
	if (!FP2_mul_nor(group, &v2, &v0, ctx)) {
		goto err;
	}
	if (!FP2_sub(group, &v0, &t0, &v2)) {
		goto err;
	}

	/* v1 = E * a_2^2 - a_0 * a_1. */
	if (!FP2_sqr(group, &t0, &a->f[2], ctx)) {
		goto err;
	}
	if (!FP2_mul_nor(group, &v2, &t0, ctx)) {
		goto err;
	}
	if (!FP2_mul(group, &v1, &a->f[0], &a->f[1], ctx)) {
		goto err;
	}
	if (!FP2_sub(group, &v1, &v2, &v1)) {
		goto err;
	}

	/* v2 = a_1^2 - a_0 * a_2. */
	if (!FP2_sqr(group, &t0, &a->f[1], ctx)) {
		goto err;
	}
	if (!FP2_mul(group, &v2, &a->f[0], &a->f[2], ctx)) {
		goto err;
	}
	if (!FP2_sub(group, &v2, &t0, &v2)) {
		goto err;
	}

	if (!FP2_mul(group, &t0, &a->f[1], &v2, ctx)) {
		goto err;
	}
	if (!FP2_mul_nor(group, &r->f[1], &t0, ctx)) {
		goto err;
	}

	if (!FP2_mul(group, &r->f[0], &a->f[0], &v0, ctx)) {
		goto err;
	}

	if (!FP2_mul(group, &t0, &a->f[2], &v1, ctx)) {
		goto err;
	}
	if (!FP2_mul_nor(group, &r->f[2], &t0, ctx)) {
		goto err;
	}

	if (!FP2_add(group, &t0, &r->f[0], &r->f[1])) {
		goto err;
	}
	if (!FP2_add(group, &t0, &t0, &r->f[2])) {
		goto err;
	}
	if (!FP2_inv(group, &t0, &t0, ctx)) {
		goto err;
	}

	if (!FP2_mul(group, &r->f[0], &v0, &t0, ctx)) {
		goto err;
	}
	if (!FP2_mul(group, &r->f[1], &v1, &t0, ctx)) {
		goto err;
	}
	if (!FP2_mul(group, &r->f[2], &v2, &t0, ctx)) {
		goto err;
	}

	ret = 1;
err:
	FP2_free(&v0);
	FP2_free(&v1);
	FP2_free(&v2);
	FP2_free(&t0);
	return ret;
}
예제 #9
0
int FP6_sqr2(const PAIRING_GROUP *group, FP6 *r, const FP6 *a, BN_CTX *ctx) {
	FP2 t0, t1, t2, t3, t4;
	int ret = 0;

	FP2_init(&t0);
	FP2_init(&t1);
	FP2_init(&t2);
	FP2_init(&t3);
	FP2_init(&t4);

	/* t0 = a_0^2 */
	if (!FP2_sqr(group, &t0, &a->f[0], ctx)) {
		goto err;
	}

	/* t1 = 2 * a_0 * a_1 */
	if (!FP2_mul(group, &t1, &a->f[0], &a->f[1], ctx)) {
		goto err;
	}
	if (!FP2_add(group, &t1, &t1, &t1)) {
		goto err;
	}

	/* t2 = (a_0 - a_1 + a_2)^2 */
	if (!FP2_sub(group, &t2, &a->f[0], &a->f[1])) {
		goto err;
	}
	if (!FP2_add(group, &t2, &t2, &a->f[2])) {
		goto err;
	}
	if (!FP2_sqr(group, &t2, &t2, ctx)) {
		goto err;
	}

	/* t3 = 2 * a_1 * a_2 */
	if (!FP2_mul(group, &t3, &a->f[1], &a->f[2], ctx)) {
		goto err;
	}
	if (!FP2_add(group, &t3, &t3, &t3)) {
		goto err;
	}

	/* t4 = a_2^2 */
	if (!FP2_sqr(group, &t4, &a->f[2], ctx)) {
		goto err;
	}

	/* c_0 = t0 + E * t3 */
	if (!FP2_mul_nor(group, &r->f[0], &t3, ctx)) {
		goto err;
	}
	if (!FP2_add(group, &r->f[0], &r->f[0], &t0)) {
		goto err;
	}

	/* c_1 = t1 + E * t4 */
	if (!FP2_mul_nor(group, &r->f[1], &t4, ctx)) {
		goto err;
	}
	if (!FP2_add(group, &r->f[1], &r->f[1], &t1)) {
		goto err;
	}

	/* c_2 = t1 + t2 + t3 - t0 - t4 */
	if (!FP2_add(group, &r->f[2], &t1, &t2)) {
		goto err;
	}
	if (!FP2_add(group, &r->f[2], &r->f[2], &t3)) {
		goto err;
	}
	if (!FP2_sub(group, &r->f[2], &r->f[2], &t0)) {
		goto err;
	}
	if (!FP2_sub(group, &r->f[2], &r->f[2], &t4)) {
		goto err;
	}

	ret = 1;

err:
	FP2_free(&t0);
	FP2_free(&t1);
	FP2_free(&t2);
	FP2_free(&t3);
	FP2_free(&t4);
	return ret;
}
예제 #10
0
int FP6_sqr(const PAIRING_GROUP *group, FP6 *r, const FP6 *a, BN_CTX *ctx) {
	FP2 t0, t1, t2, t3, t4;
	int ret = 0;

	FP2_init(&t0);
	FP2_init(&t1);
	FP2_init(&t2);
	FP2_init(&t3);
	FP2_init(&t4);

	/* t0 = a_0^2 */
	if (!FP2_sqr(group, &t0, &a->f[0], ctx)) {
		goto err;
	}

	/* t1 = 2 * a_1 * a_2 */
	if (!FP2_mul(group, &t1, &a->f[1], &a->f[2], ctx)) {
		goto err;
	}
	if (!FP2_add(group, &t1, &t1, &t1)) {
		goto err;
	}

	/* t2 = a_2^2. */
	if (!FP2_sqr(group, &t2, &a->f[2], ctx)) {
		goto err;
	}

	/* c2 = a_0 + a_2. */
	if (!FP2_add(group, &r->f[2], &a->f[0], &a->f[2])) {
		goto err;
	}

	/* t3 = (a_0 + a_2 + a_1)^2. */
	if (!FP2_add(group, &t3, &r->f[2], &a->f[1])) {
		goto err;
	}
	if (!FP2_sqr(group, &t3, &t3, ctx)) {
		goto err;
	}

	/* c2 = (a_0 + a_2 - a_1)^2. */
	if (!FP2_sub(group, &r->f[2], &r->f[2], &a->f[1])) {
		goto err;
	}
	if (!FP2_sqr(group, &r->f[2], &r->f[2], ctx)) {
		goto err;
	}

	/* c2 = (c2 + t3)/2. */
	if (!FP2_add(group, &r->f[2], &r->f[2], &t3)) {
		goto err;
	}
	if (BN_is_bit_set(&r->f[2].f[0], 0)) {
		if (!BN_add(&r->f[2].f[0], &r->f[2].f[0], group->field)) {
			goto err;
		}
	}
	if (!BN_rshift1(&r->f[2].f[0], &r->f[2].f[0])) {
		goto err;
	}
	if (BN_is_bit_set(&r->f[2].f[1], 0)) {
		if (!BN_add(&r->f[2].f[1], &r->f[2].f[1], group->field)) {
			goto err;
		}
	}
	if (!BN_rshift1(&r->f[2].f[1], &r->f[2].f[1])) {
		goto err;
	}

	/* t3 = t3 - c2 - t1. */
	if (!FP2_sub(group, &t3, &t3, &r->f[2])) {
		goto err;
	}
	if (!FP2_sub(group, &t3, &t3, &t1)) {
		goto err;
	}

	/* c2 = c2 - t0 - t2. */
	if (!FP2_sub(group, &r->f[2], &r->f[2], &t0)) {
		goto err;
	}
	if (!FP2_sub(group, &r->f[2], &r->f[2], &t2)) {
		goto err;
	}

	/* c0 = t0 + t1 * E. */
	if (!FP2_mul_nor(group, &t4, &t1, ctx)) {
		goto err;
	}
	if (!FP2_add(group, &r->f[0], &t0, &t4)) {
		goto err;
	}

	/* c1 = t3 + t2 * E. */
	if (!FP2_mul_nor(group, &t4, &t2, ctx)) {
		goto err;
	}
	if (!FP2_add(group, &r->f[1], &t3, &t4)) {
		goto err;
	}

	ret = 1;
err:
	FP2_free(&t0);
	FP2_free(&t1);
	FP2_free(&t2);
	FP2_free(&t3);
	FP2_free(&t4);
	return ret;
}
예제 #11
0
int FP6_mul_dxs(const PAIRING_GROUP *group, FP6 *r, const FP6 *a, const FP6 *b, BN_CTX *ctx) {
	FP2 v0, v1, v2, t0, t1, t2;
	int ret = 0;

	FP2_init(&v0);
	FP2_init(&v1);
	FP2_init(&v2);
	FP2_init(&t0);
	FP2_init(&t1);
	FP2_init(&t2);

	/* v0 = a_0b_0 */
	if (!FP2_mul(group, &v0, &a->f[0], &b->f[0], ctx)) {
		goto err;
	}

	/* v1 = a_1b_1 */
	if (!FP2_mul(group, &v1, &a->f[1], &b->f[1], ctx)) {
		goto err;
	}

	/* v2 = a_2b_2 */

	/* t2 (c_0) = v0 + E((a_1 + a_2)(b_1 + b_2) - v1 - v2) */
	if (!FP2_add(group, &t0, &a->f[1], &a->f[2])) {
		goto err;
	}
	if (!FP2_mul(group, &t0, &t0, &b->f[1], ctx)) {
		goto err;
	}
	if (!FP2_sub(group, &t0, &t0, &v1)) {
		goto err;
	}
	if (!FP2_mul_nor(group, &t2, &t0, ctx)) {
		goto err;
	}
	if (!FP2_add(group, &t2, &t2, &v0)) {
		goto err;
	}

	/* c_1 = (a_0 + a_1)(b_0 + b_1) - v0 - v1 + Ev2 */
	if (!FP2_add(group, &t0, &a->f[0], &a->f[1])) {
		goto err;
	}
	if (!FP2_add(group, &t1, &b->f[0], &b->f[1])) {
		goto err;
	}
	if (!FP2_mul(group, &r->f[1], &t0, &t1, ctx)) {
		goto err;
	}
	if (!FP2_sub(group, &r->f[1], &r->f[1], &v0)) {
		goto err;
	}
	if (!FP2_sub(group, &r->f[1], &r->f[1], &v1)) {
		goto err;
	}

	/* c_2 = (a_0 + a_2)(b_0 + b_2) - v0 + v1 - v2 */
	if (!FP2_add(group, &t0, &a->f[0], &a->f[2])) {
		goto err;
	}
	if (!FP2_mul(group, &r->f[2], &t0, &b->f[0], ctx)) {
		goto err;
	}
	if (!FP2_sub(group, &r->f[2], &r->f[2], &v0)) {
		goto err;
	}
	if (!FP2_add(group, &r->f[2], &r->f[2], &v1)) {
		goto err;
	}

	/* c_0 = t2 */
	FP2_copy(&r->f[0], &t2);

	ret = 1;

err:
	FP2_free(&t2);
	FP2_free(&t1);
	FP2_free(&t0);
	FP2_free(&v2);
	FP2_free(&v1);
	FP2_free(&v0);
	return ret;
}
예제 #12
0
/* SU= 16 */
void FP4_add(FP4 *w,FP4 *x,FP4 *y)
{
	FP2_add(&(w->a), &(x->a), &(y->a)); 
	FP2_add(&(w->b), &(x->b), &(y->b)); 
}