You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
680 lines
17 KiB
680 lines
17 KiB
/*
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
*/
|
|
|
|
/* AMCL Fp^4 functions */
|
|
/* SU=m, m is Stack Usage (no lazy )*/
|
|
|
|
/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1)) */
|
|
|
|
#include "fp4_FP256BN.h"
|
|
|
|
/* test x==0 ? */
|
|
/* SU= 8 */
|
|
int FP4_FP256BN_iszilch(FP4_FP256BN *x)
|
|
{
|
|
if (FP2_FP256BN_iszilch(&(x->a)) && FP2_FP256BN_iszilch(&(x->b))) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/* test x==1 ? */
|
|
/* SU= 8 */
|
|
int FP4_FP256BN_isunity(FP4_FP256BN *x)
|
|
{
|
|
if (FP2_FP256BN_isunity(&(x->a)) && FP2_FP256BN_iszilch(&(x->b))) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/* test is w real? That is in a+ib test b is zero */
|
|
int FP4_FP256BN_isreal(FP4_FP256BN *w)
|
|
{
|
|
return FP2_FP256BN_iszilch(&(w->b));
|
|
}
|
|
|
|
/* return 1 if x==y, else 0 */
|
|
/* SU= 16 */
|
|
int FP4_FP256BN_equals(FP4_FP256BN *x,FP4_FP256BN *y)
|
|
{
|
|
if (FP2_FP256BN_equals(&(x->a),&(y->a)) && FP2_FP256BN_equals(&(x->b),&(y->b)))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/* set FP4 from two FP2s */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_from_FP2s(FP4_FP256BN *w,FP2_FP256BN * x,FP2_FP256BN* y)
|
|
{
|
|
FP2_FP256BN_copy(&(w->a), x);
|
|
FP2_FP256BN_copy(&(w->b), y);
|
|
}
|
|
|
|
/* set FP4 from FP2 */
|
|
/* SU= 8 */
|
|
void FP4_FP256BN_from_FP2(FP4_FP256BN *w,FP2_FP256BN *x)
|
|
{
|
|
FP2_FP256BN_copy(&(w->a), x);
|
|
FP2_FP256BN_zero(&(w->b));
|
|
}
|
|
|
|
/* set high part of FP4 from FP2 */
|
|
/* SU= 8 */
|
|
void FP4_FP256BN_from_FP2H(FP4_FP256BN *w,FP2_FP256BN *x)
|
|
{
|
|
FP2_FP256BN_copy(&(w->b), x);
|
|
FP2_FP256BN_zero(&(w->a));
|
|
}
|
|
|
|
/* FP4 copy w=x */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_copy(FP4_FP256BN *w,FP4_FP256BN *x)
|
|
{
|
|
if (w==x) return;
|
|
FP2_FP256BN_copy(&(w->a), &(x->a));
|
|
FP2_FP256BN_copy(&(w->b), &(x->b));
|
|
}
|
|
|
|
/* FP4 w=0 */
|
|
/* SU= 8 */
|
|
void FP4_FP256BN_zero(FP4_FP256BN *w)
|
|
{
|
|
FP2_FP256BN_zero(&(w->a));
|
|
FP2_FP256BN_zero(&(w->b));
|
|
}
|
|
|
|
/* FP4 w=1 */
|
|
/* SU= 8 */
|
|
void FP4_FP256BN_one(FP4_FP256BN *w)
|
|
{
|
|
FP2_FP256BN_one(&(w->a));
|
|
FP2_FP256BN_zero(&(w->b));
|
|
}
|
|
|
|
/* Set w=-x */
|
|
/* SU= 160 */
|
|
void FP4_FP256BN_neg(FP4_FP256BN *w,FP4_FP256BN *x)
|
|
{
|
|
/* Just one field neg */
|
|
FP2_FP256BN m,t;
|
|
|
|
FP2_FP256BN_add(&m,&(x->a),&(x->b));
|
|
// FP2_FP256BN_norm(&m);
|
|
FP2_FP256BN_neg(&m,&m);
|
|
// FP2_FP256BN_norm(&m);
|
|
FP2_FP256BN_add(&t,&m,&(x->b));
|
|
FP2_FP256BN_add(&(w->b),&m,&(x->a));
|
|
FP2_FP256BN_copy(&(w->a),&t);
|
|
FP4_FP256BN_norm(w);
|
|
}
|
|
|
|
/* Set w=conj(x) */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_conj(FP4_FP256BN *w,FP4_FP256BN *x)
|
|
{
|
|
FP2_FP256BN_copy(&(w->a), &(x->a));
|
|
FP2_FP256BN_neg(&(w->b), &(x->b));
|
|
FP4_FP256BN_norm(w);
|
|
}
|
|
|
|
/* Set w=-conj(x) */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_nconj(FP4_FP256BN *w,FP4_FP256BN *x)
|
|
{
|
|
FP2_FP256BN_copy(&(w->b),&(x->b));
|
|
FP2_FP256BN_neg(&(w->a), &(x->a));
|
|
FP4_FP256BN_norm(w);
|
|
}
|
|
|
|
/* Set w=x+y */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_add(FP4_FP256BN *w,FP4_FP256BN *x,FP4_FP256BN *y)
|
|
{
|
|
FP2_FP256BN_add(&(w->a), &(x->a), &(y->a));
|
|
FP2_FP256BN_add(&(w->b), &(x->b), &(y->b));
|
|
}
|
|
|
|
/* Set w=x-y */
|
|
/* Input y MUST be normed */
|
|
void FP4_FP256BN_sub(FP4_FP256BN *w,FP4_FP256BN *x,FP4_FP256BN *y)
|
|
{
|
|
FP4_FP256BN my;
|
|
|
|
FP4_FP256BN_neg(&my, y);
|
|
FP4_FP256BN_add(w, x, &my);
|
|
|
|
}
|
|
/* SU= 8 */
|
|
/* reduce all components of w mod Modulus */
|
|
void FP4_FP256BN_reduce(FP4_FP256BN *w)
|
|
{
|
|
FP2_FP256BN_reduce(&(w->a));
|
|
FP2_FP256BN_reduce(&(w->b));
|
|
}
|
|
|
|
/* SU= 8 */
|
|
/* normalise all elements of w */
|
|
void FP4_FP256BN_norm(FP4_FP256BN *w)
|
|
{
|
|
FP2_FP256BN_norm(&(w->a));
|
|
FP2_FP256BN_norm(&(w->b));
|
|
}
|
|
|
|
/* Set w=s*x, where s is FP2 */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_pmul(FP4_FP256BN *w,FP4_FP256BN *x,FP2_FP256BN *s)
|
|
{
|
|
FP2_FP256BN_mul(&(w->a),&(x->a),s);
|
|
FP2_FP256BN_mul(&(w->b),&(x->b),s);
|
|
}
|
|
|
|
/* SU= 16 */
|
|
/* Set w=s*x, where s is int */
|
|
void FP4_FP256BN_imul(FP4_FP256BN *w,FP4_FP256BN *x,int s)
|
|
{
|
|
FP2_FP256BN_imul(&(w->a),&(x->a),s);
|
|
FP2_FP256BN_imul(&(w->b),&(x->b),s);
|
|
}
|
|
|
|
/* Set w=x^2 */
|
|
/* Input MUST be normed */
|
|
void FP4_FP256BN_sqr(FP4_FP256BN *w,FP4_FP256BN *x)
|
|
{
|
|
FP2_FP256BN t1,t2,t3;
|
|
|
|
FP2_FP256BN_mul(&t3,&(x->a),&(x->b)); /* norms x */
|
|
FP2_FP256BN_copy(&t2,&(x->b));
|
|
FP2_FP256BN_add(&t1,&(x->a),&(x->b));
|
|
FP2_FP256BN_mul_ip(&t2);
|
|
|
|
FP2_FP256BN_add(&t2,&(x->a),&t2);
|
|
|
|
FP2_FP256BN_norm(&t1); // 2
|
|
FP2_FP256BN_norm(&t2); // 2
|
|
|
|
FP2_FP256BN_mul(&(w->a),&t1,&t2);
|
|
|
|
FP2_FP256BN_copy(&t2,&t3);
|
|
FP2_FP256BN_mul_ip(&t2);
|
|
|
|
FP2_FP256BN_add(&t2,&t2,&t3);
|
|
|
|
FP2_FP256BN_norm(&t2); // 2
|
|
FP2_FP256BN_neg(&t2,&t2);
|
|
FP2_FP256BN_add(&(w->a),&(w->a),&t2); /* a=(a+b)(a+i^2.b)-i^2.ab-ab = a*a+ib*ib */
|
|
FP2_FP256BN_add(&(w->b),&t3,&t3); /* b=2ab */
|
|
|
|
FP4_FP256BN_norm(w);
|
|
}
|
|
|
|
/* Set w=x*y */
|
|
/* Inputs MUST be normed */
|
|
void FP4_FP256BN_mul(FP4_FP256BN *w,FP4_FP256BN *x,FP4_FP256BN *y)
|
|
{
|
|
|
|
FP2_FP256BN t1,t2,t3,t4;
|
|
FP2_FP256BN_mul(&t1,&(x->a),&(y->a));
|
|
FP2_FP256BN_mul(&t2,&(x->b),&(y->b));
|
|
|
|
FP2_FP256BN_add(&t3,&(y->b),&(y->a));
|
|
FP2_FP256BN_add(&t4,&(x->b),&(x->a));
|
|
|
|
FP2_FP256BN_norm(&t4); // 2
|
|
FP2_FP256BN_norm(&t3); // 2
|
|
|
|
FP2_FP256BN_mul(&t4,&t4,&t3); /* (xa+xb)(ya+yb) */
|
|
|
|
FP2_FP256BN_neg(&t3,&t1); // 1
|
|
FP2_FP256BN_add(&t4,&t4,&t3); //t4E=3
|
|
FP2_FP256BN_norm(&t4);
|
|
|
|
FP2_FP256BN_neg(&t3,&t2); // 1
|
|
FP2_FP256BN_add(&(w->b),&t4,&t3); //wbE=3
|
|
|
|
FP2_FP256BN_mul_ip(&t2);
|
|
FP2_FP256BN_add(&(w->a),&t2,&t1);
|
|
|
|
FP4_FP256BN_norm(w);
|
|
}
|
|
|
|
/* output FP4 in format [a,b] */
|
|
/* SU= 8 */
|
|
void FP4_FP256BN_output(FP4_FP256BN *w)
|
|
{
|
|
printf("[");
|
|
FP2_FP256BN_output(&(w->a));
|
|
printf(",");
|
|
FP2_FP256BN_output(&(w->b));
|
|
printf("]");
|
|
}
|
|
|
|
/* SU= 8 */
|
|
void FP4_FP256BN_rawoutput(FP4_FP256BN *w)
|
|
{
|
|
printf("[");
|
|
FP2_FP256BN_rawoutput(&(w->a));
|
|
printf(",");
|
|
FP2_FP256BN_rawoutput(&(w->b));
|
|
printf("]");
|
|
}
|
|
|
|
/* Set w=1/x */
|
|
/* SU= 160 */
|
|
void FP4_FP256BN_inv(FP4_FP256BN *w,FP4_FP256BN *x)
|
|
{
|
|
FP2_FP256BN t1,t2;
|
|
FP2_FP256BN_sqr(&t1,&(x->a));
|
|
FP2_FP256BN_sqr(&t2,&(x->b));
|
|
FP2_FP256BN_mul_ip(&t2);
|
|
FP2_FP256BN_norm(&t2);
|
|
FP2_FP256BN_sub(&t1,&t1,&t2);
|
|
FP2_FP256BN_inv(&t1,&t1);
|
|
FP2_FP256BN_mul(&(w->a),&t1,&(x->a));
|
|
FP2_FP256BN_neg(&t1,&t1);
|
|
FP2_FP256BN_norm(&t1);
|
|
FP2_FP256BN_mul(&(w->b),&t1,&(x->b));
|
|
}
|
|
|
|
/* w*=i where i = sqrt(-1+sqrt(-1)) */
|
|
/* SU= 200 */
|
|
void FP4_FP256BN_times_i(FP4_FP256BN *w)
|
|
{
|
|
FP_FP256BN z;
|
|
FP2_FP256BN s,t;
|
|
|
|
// FP4_FP256BN_norm(w);
|
|
FP2_FP256BN_copy(&t,&(w->b));
|
|
|
|
FP2_FP256BN_copy(&s,&t);
|
|
|
|
FP_FP256BN_copy(&z,&(s.a));
|
|
FP_FP256BN_neg(&(s.a),&(s.b));
|
|
FP_FP256BN_copy(&(s.b),&z);
|
|
|
|
FP2_FP256BN_add(&t,&t,&s);
|
|
|
|
FP2_FP256BN_copy(&(w->b),&(w->a));
|
|
FP2_FP256BN_copy(&(w->a),&t);
|
|
FP4_FP256BN_norm(w);
|
|
}
|
|
|
|
/* Set w=w^p using Frobenius */
|
|
/* SU= 16 */
|
|
void FP4_FP256BN_frob(FP4_FP256BN *w,FP2_FP256BN *f)
|
|
{
|
|
FP2_FP256BN_conj(&(w->a),&(w->a));
|
|
FP2_FP256BN_conj(&(w->b),&(w->b));
|
|
FP2_FP256BN_mul( &(w->b),f,&(w->b));
|
|
}
|
|
|
|
/* Set r=a^b mod m */
|
|
/* SU= 240 */
|
|
void FP4_FP256BN_pow(FP4_FP256BN *r,FP4_FP256BN* a,BIG_256_56 b)
|
|
{
|
|
FP4_FP256BN w;
|
|
BIG_256_56 z,zilch;
|
|
int bt;
|
|
|
|
BIG_256_56_zero(zilch);
|
|
BIG_256_56_norm(b);
|
|
BIG_256_56_copy(z,b);
|
|
FP4_FP256BN_copy(&w,a);
|
|
FP4_FP256BN_one(r);
|
|
|
|
while(1)
|
|
{
|
|
bt=BIG_256_56_parity(z);
|
|
BIG_256_56_shr(z,1);
|
|
if (bt) FP4_FP256BN_mul(r,r,&w);
|
|
if (BIG_256_56_comp(z,zilch)==0) break;
|
|
FP4_FP256BN_sqr(&w,&w);
|
|
}
|
|
FP4_FP256BN_reduce(r);
|
|
}
|
|
|
|
/* SU= 304 */
|
|
/* XTR xtr_a function */
|
|
void FP4_FP256BN_xtr_A(FP4_FP256BN *r,FP4_FP256BN *w,FP4_FP256BN *x,FP4_FP256BN *y,FP4_FP256BN *z)
|
|
{
|
|
FP4_FP256BN t1,t2;
|
|
|
|
FP4_FP256BN_copy(r,x);
|
|
//FP4_FP256BN_norm(y);
|
|
FP4_FP256BN_sub(&t1,w,y);
|
|
FP4_FP256BN_norm(&t1);
|
|
FP4_FP256BN_pmul(&t1,&t1,&(r->a));
|
|
FP4_FP256BN_add(&t2,w,y);
|
|
FP4_FP256BN_norm(&t2);
|
|
FP4_FP256BN_pmul(&t2,&t2,&(r->b));
|
|
FP4_FP256BN_times_i(&t2);
|
|
|
|
FP4_FP256BN_add(r,&t1,&t2);
|
|
FP4_FP256BN_add(r,r,z);
|
|
|
|
FP4_FP256BN_reduce(r);
|
|
}
|
|
|
|
/* SU= 152 */
|
|
/* XTR xtr_d function */
|
|
void FP4_FP256BN_xtr_D(FP4_FP256BN *r,FP4_FP256BN *x)
|
|
{
|
|
FP4_FP256BN w;
|
|
FP4_FP256BN_copy(r,x);
|
|
FP4_FP256BN_conj(&w,r);
|
|
FP4_FP256BN_add(&w,&w,&w);
|
|
FP4_FP256BN_sqr(r,r);
|
|
FP4_FP256BN_norm(&w);
|
|
FP4_FP256BN_sub(r,r,&w);
|
|
FP4_FP256BN_reduce(r); /* reduce here as multiple calls trigger automatic reductions */
|
|
}
|
|
|
|
/* SU= 728 */
|
|
/* r=x^n using XTR method on traces of FP12s */
|
|
void FP4_FP256BN_xtr_pow(FP4_FP256BN *r,FP4_FP256BN *x,BIG_256_56 n)
|
|
{
|
|
int i,par,nb;
|
|
BIG_256_56 v;
|
|
FP2_FP256BN w;
|
|
FP4_FP256BN t,a,b,c;
|
|
|
|
BIG_256_56_zero(v);
|
|
BIG_256_56_inc(v,3);
|
|
BIG_256_56_norm(v);
|
|
FP2_FP256BN_from_BIG(&w,v);
|
|
FP4_FP256BN_from_FP2(&a,&w);
|
|
|
|
FP4_FP256BN_copy(&b,x);
|
|
FP4_FP256BN_xtr_D(&c,x);
|
|
|
|
BIG_256_56_norm(n);
|
|
par=BIG_256_56_parity(n);
|
|
BIG_256_56_copy(v,n);
|
|
BIG_256_56_shr(v,1);
|
|
if (par==0)
|
|
{
|
|
BIG_256_56_dec(v,1);
|
|
BIG_256_56_norm(v);
|
|
}
|
|
|
|
nb=BIG_256_56_nbits(v);
|
|
for (i=nb-1; i>=0; i--)
|
|
{
|
|
if (!BIG_256_56_bit(v,i))
|
|
{
|
|
FP4_FP256BN_copy(&t,&b);
|
|
FP4_FP256BN_conj(x,x);
|
|
FP4_FP256BN_conj(&c,&c);
|
|
FP4_FP256BN_xtr_A(&b,&a,&b,x,&c);
|
|
FP4_FP256BN_conj(x,x);
|
|
FP4_FP256BN_xtr_D(&c,&t);
|
|
FP4_FP256BN_xtr_D(&a,&a);
|
|
}
|
|
else
|
|
{
|
|
FP4_FP256BN_conj(&t,&a);
|
|
FP4_FP256BN_xtr_D(&a,&b);
|
|
FP4_FP256BN_xtr_A(&b,&c,&b,x,&t);
|
|
FP4_FP256BN_xtr_D(&c,&c);
|
|
}
|
|
}
|
|
|
|
if (par==0) FP4_FP256BN_copy(r,&c);
|
|
else FP4_FP256BN_copy(r,&b);
|
|
FP4_FP256BN_reduce(r);
|
|
}
|
|
|
|
/* SU= 872 */
|
|
/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
|
|
void FP4_FP256BN_xtr_pow2(FP4_FP256BN *r,FP4_FP256BN *ck,FP4_FP256BN *cl,FP4_FP256BN *ckml,FP4_FP256BN *ckm2l,BIG_256_56 a,BIG_256_56 b)
|
|
{
|
|
int i,f2;
|
|
BIG_256_56 d,e,w;
|
|
FP4_FP256BN t,cu,cv,cumv,cum2v;
|
|
|
|
BIG_256_56_norm(a);
|
|
BIG_256_56_norm(b);
|
|
BIG_256_56_copy(e,a);
|
|
BIG_256_56_copy(d,b);
|
|
FP4_FP256BN_copy(&cu,ck);
|
|
FP4_FP256BN_copy(&cv,cl);
|
|
FP4_FP256BN_copy(&cumv,ckml);
|
|
FP4_FP256BN_copy(&cum2v,ckm2l);
|
|
|
|
f2=0;
|
|
while (BIG_256_56_parity(d)==0 && BIG_256_56_parity(e)==0)
|
|
{
|
|
BIG_256_56_shr(d,1);
|
|
BIG_256_56_shr(e,1);
|
|
f2++;
|
|
}
|
|
while (BIG_256_56_comp(d,e)!=0)
|
|
{
|
|
if (BIG_256_56_comp(d,e)>0)
|
|
{
|
|
BIG_256_56_imul(w,e,4);
|
|
BIG_256_56_norm(w);
|
|
if (BIG_256_56_comp(d,w)<=0)
|
|
{
|
|
BIG_256_56_copy(w,d);
|
|
BIG_256_56_copy(d,e);
|
|
BIG_256_56_sub(e,w,e);
|
|
BIG_256_56_norm(e);
|
|
FP4_FP256BN_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
|
|
FP4_FP256BN_conj(&cum2v,&cumv);
|
|
FP4_FP256BN_copy(&cumv,&cv);
|
|
FP4_FP256BN_copy(&cv,&cu);
|
|
FP4_FP256BN_copy(&cu,&t);
|
|
}
|
|
else if (BIG_256_56_parity(d)==0)
|
|
{
|
|
BIG_256_56_shr(d,1);
|
|
FP4_FP256BN_conj(r,&cum2v);
|
|
FP4_FP256BN_xtr_A(&t,&cu,&cumv,&cv,r);
|
|
FP4_FP256BN_xtr_D(&cum2v,&cumv);
|
|
FP4_FP256BN_copy(&cumv,&t);
|
|
FP4_FP256BN_xtr_D(&cu,&cu);
|
|
}
|
|
else if (BIG_256_56_parity(e)==1)
|
|
{
|
|
BIG_256_56_sub(d,d,e);
|
|
BIG_256_56_norm(d);
|
|
BIG_256_56_shr(d,1);
|
|
FP4_FP256BN_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
|
|
FP4_FP256BN_xtr_D(&cu,&cu);
|
|
FP4_FP256BN_xtr_D(&cum2v,&cv);
|
|
FP4_FP256BN_conj(&cum2v,&cum2v);
|
|
FP4_FP256BN_copy(&cv,&t);
|
|
}
|
|
else
|
|
{
|
|
BIG_256_56_copy(w,d);
|
|
BIG_256_56_copy(d,e);
|
|
BIG_256_56_shr(d,1);
|
|
BIG_256_56_copy(e,w);
|
|
FP4_FP256BN_xtr_D(&t,&cumv);
|
|
FP4_FP256BN_conj(&cumv,&cum2v);
|
|
FP4_FP256BN_conj(&cum2v,&t);
|
|
FP4_FP256BN_xtr_D(&t,&cv);
|
|
FP4_FP256BN_copy(&cv,&cu);
|
|
FP4_FP256BN_copy(&cu,&t);
|
|
}
|
|
}
|
|
if (BIG_256_56_comp(d,e)<0)
|
|
{
|
|
BIG_256_56_imul(w,d,4);
|
|
BIG_256_56_norm(w);
|
|
if (BIG_256_56_comp(e,w)<=0)
|
|
{
|
|
BIG_256_56_sub(e,e,d);
|
|
BIG_256_56_norm(e);
|
|
FP4_FP256BN_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
|
|
FP4_FP256BN_copy(&cum2v,&cumv);
|
|
FP4_FP256BN_copy(&cumv,&cu);
|
|
FP4_FP256BN_copy(&cu,&t);
|
|
}
|
|
else if (BIG_256_56_parity(e)==0)
|
|
{
|
|
BIG_256_56_copy(w,d);
|
|
BIG_256_56_copy(d,e);
|
|
BIG_256_56_shr(d,1);
|
|
BIG_256_56_copy(e,w);
|
|
FP4_FP256BN_xtr_D(&t,&cumv);
|
|
FP4_FP256BN_conj(&cumv,&cum2v);
|
|
FP4_FP256BN_conj(&cum2v,&t);
|
|
FP4_FP256BN_xtr_D(&t,&cv);
|
|
FP4_FP256BN_copy(&cv,&cu);
|
|
FP4_FP256BN_copy(&cu,&t);
|
|
}
|
|
else if (BIG_256_56_parity(d)==1)
|
|
{
|
|
BIG_256_56_copy(w,e);
|
|
BIG_256_56_copy(e,d);
|
|
BIG_256_56_sub(w,w,d);
|
|
BIG_256_56_norm(w);
|
|
BIG_256_56_copy(d,w);
|
|
BIG_256_56_shr(d,1);
|
|
FP4_FP256BN_xtr_A(&t,&cu,&cv,&cumv,&cum2v);
|
|
FP4_FP256BN_conj(&cumv,&cumv);
|
|
FP4_FP256BN_xtr_D(&cum2v,&cu);
|
|
FP4_FP256BN_conj(&cum2v,&cum2v);
|
|
FP4_FP256BN_xtr_D(&cu,&cv);
|
|
FP4_FP256BN_copy(&cv,&t);
|
|
}
|
|
else
|
|
{
|
|
BIG_256_56_shr(d,1);
|
|
FP4_FP256BN_conj(r,&cum2v);
|
|
FP4_FP256BN_xtr_A(&t,&cu,&cumv,&cv,r);
|
|
FP4_FP256BN_xtr_D(&cum2v,&cumv);
|
|
FP4_FP256BN_copy(&cumv,&t);
|
|
FP4_FP256BN_xtr_D(&cu,&cu);
|
|
}
|
|
}
|
|
}
|
|
FP4_FP256BN_xtr_A(r,&cu,&cv,&cumv,&cum2v);
|
|
for (i=0; i<f2; i++) FP4_FP256BN_xtr_D(r,r);
|
|
FP4_FP256BN_xtr_pow(r,r,d);
|
|
}
|
|
/*
|
|
int main(){
|
|
FP2_FP256BN w0,w1,f;
|
|
FP4_FP256BN w,t;
|
|
FP4_FP256BN c1,c2,c3,c4,cr;
|
|
BIG_256_56 a,b;
|
|
BIG_256_56 e,e1,e2;
|
|
BIG_256_56 p,md;
|
|
|
|
|
|
BIG_256_56_rcopy(md,Modulus);
|
|
//Test w^(P^4) = w mod p^2
|
|
BIG_256_56_zero(a); BIG_256_56_inc(a,27);
|
|
BIG_256_56_zero(b); BIG_256_56_inc(b,45);
|
|
FP2_FP256BN_from_BIGs(&w0,a,b);
|
|
|
|
BIG_256_56_zero(a); BIG_256_56_inc(a,33);
|
|
BIG_256_56_zero(b); BIG_256_56_inc(b,54);
|
|
FP2_FP256BN_from_BIGs(&w1,a,b);
|
|
|
|
FP4_FP256BN_from_FP2s(&w,&w0,&w1);
|
|
FP4_FP256BN_reduce(&w);
|
|
|
|
printf("w= ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
|
|
FP4_FP256BN_copy(&t,&w);
|
|
|
|
|
|
BIG_256_56_copy(p,md);
|
|
FP4_FP256BN_pow(&w,&w,p);
|
|
|
|
printf("w^p= ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
//exit(0);
|
|
|
|
BIG_256_56_rcopy(a,CURVE_Fra);
|
|
BIG_256_56_rcopy(b,CURVE_Frb);
|
|
FP2_FP256BN_from_BIGs(&f,a,b);
|
|
|
|
FP4_FP256BN_frob(&t,&f);
|
|
printf("w^p= ");
|
|
FP4_FP256BN_output(&t);
|
|
printf("\n");
|
|
|
|
FP4_FP256BN_pow(&w,&w,p);
|
|
FP4_FP256BN_pow(&w,&w,p);
|
|
FP4_FP256BN_pow(&w,&w,p);
|
|
printf("w^p4= ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
// Test 1/(1/x) = x mod p^4
|
|
FP4_FP256BN_from_FP2s(&w,&w0,&w1);
|
|
printf("Test Inversion \nw= ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
FP4_FP256BN_inv(&w,&w);
|
|
printf("1/w mod p^4 = ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
FP4_FP256BN_inv(&w,&w);
|
|
printf("1/(1/w) mod p^4 = ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
BIG_256_56_zero(e); BIG_256_56_inc(e,12);
|
|
|
|
|
|
|
|
// FP4_FP256BN_xtr_A(&w,&t,&w,&t,&t);
|
|
FP4_FP256BN_xtr_pow(&w,&w,e);
|
|
|
|
printf("w^e= ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
|
|
BIG_256_56_zero(a); BIG_256_56_inc(a,37);
|
|
BIG_256_56_zero(b); BIG_256_56_inc(b,17);
|
|
FP2_FP256BN_from_BIGs(&w0,a,b);
|
|
|
|
BIG_256_56_zero(a); BIG_256_56_inc(a,49);
|
|
BIG_256_56_zero(b); BIG_256_56_inc(b,31);
|
|
FP2_FP256BN_from_BIGs(&w1,a,b);
|
|
|
|
FP4_FP256BN_from_FP2s(&c1,&w0,&w1);
|
|
FP4_FP256BN_from_FP2s(&c2,&w0,&w1);
|
|
FP4_FP256BN_from_FP2s(&c3,&w0,&w1);
|
|
FP4_FP256BN_from_FP2s(&c4,&w0,&w1);
|
|
|
|
BIG_256_56_zero(e1); BIG_256_56_inc(e1,3331);
|
|
BIG_256_56_zero(e2); BIG_256_56_inc(e2,3372);
|
|
|
|
FP4_FP256BN_xtr_pow2(&w,&c1,&w,&c2,&c3,e1,e2);
|
|
|
|
printf("c^e= ");
|
|
FP4_FP256BN_output(&w);
|
|
printf("\n");
|
|
|
|
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
|