Network wrapper protocol as part of the practical master thesis
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.
 
 

476 lines
11 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^2 functions */
/* SU=m, m is Stack Usage (no lazy )*/
/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
#include "fp2_FP256BN.h"
/* test x==0 ? */
/* SU= 8 */
int FP2_FP256BN_iszilch(FP2_FP256BN *x)
{
FP2_FP256BN_reduce(x);
if (FP_FP256BN_iszilch(&(x->a)) && FP_FP256BN_iszilch(&(x->b))) return 1;
return 0;
}
/* Move b to a if d=1 */
void FP2_FP256BN_cmove(FP2_FP256BN *f,FP2_FP256BN *g,int d)
{
FP_FP256BN_cmove(&(f->a),&(g->a),d);
FP_FP256BN_cmove(&(f->b),&(g->b),d);
}
/* test x==1 ? */
/* SU= 48 */
int FP2_FP256BN_isunity(FP2_FP256BN *x)
{
FP_FP256BN one;
FP_FP256BN_one(&one);
FP2_FP256BN_reduce(x);
if (FP_FP256BN_equals(&(x->a),&one) && FP_FP256BN_iszilch(&(x->b))) return 1;
return 0;
}
/* SU= 8 */
/* Fully reduce a and b mod Modulus */
void FP2_FP256BN_reduce(FP2_FP256BN *w)
{
FP_FP256BN_reduce(&(w->a));
FP_FP256BN_reduce(&(w->b));
}
/* return 1 if x==y, else 0 */
/* SU= 16 */
int FP2_FP256BN_equals(FP2_FP256BN *x,FP2_FP256BN *y)
{
FP2_FP256BN_reduce(x);
FP2_FP256BN_reduce(y);
if (FP_FP256BN_equals(&(x->a),&(y->a)) && FP_FP256BN_equals(&(x->b),&(y->b)))
return 1;
return 0;
}
/* Create FP2 from two FPs */
/* SU= 16 */
void FP2_FP256BN_from_FPs(FP2_FP256BN *w,FP_FP256BN *x,FP_FP256BN *y)
{
FP_FP256BN_copy(&(w->a),x);
FP_FP256BN_copy(&(w->b),y);
}
/* Create FP2 from two BIGS */
/* SU= 16 */
void FP2_FP256BN_from_BIGs(FP2_FP256BN *w,BIG_256_56 x,BIG_256_56 y)
{
FP_FP256BN_nres(&(w->a),x);
FP_FP256BN_nres(&(w->b),y);
}
/* Create FP2 from FP */
/* SU= 8 */
void FP2_FP256BN_from_FP(FP2_FP256BN *w,FP_FP256BN *x)
{
FP_FP256BN_copy(&(w->a),x);
FP_FP256BN_zero(&(w->b));
}
/* Create FP2 from BIG */
/* SU= 8 */
void FP2_FP256BN_from_BIG(FP2_FP256BN *w,BIG_256_56 x)
{
FP_FP256BN_nres(&(w->a),x);
FP_FP256BN_zero(&(w->b));
}
/* FP2 copy w=x */
/* SU= 16 */
void FP2_FP256BN_copy(FP2_FP256BN *w,FP2_FP256BN *x)
{
if (w==x) return;
FP_FP256BN_copy(&(w->a),&(x->a));
FP_FP256BN_copy(&(w->b),&(x->b));
}
/* FP2 set w=0 */
/* SU= 8 */
void FP2_FP256BN_zero(FP2_FP256BN *w)
{
FP_FP256BN_zero(&(w->a));
FP_FP256BN_zero(&(w->b));
}
/* FP2 set w=1 */
/* SU= 48 */
void FP2_FP256BN_one(FP2_FP256BN *w)
{
FP_FP256BN one;
FP_FP256BN_one(&one);
FP2_FP256BN_from_FP(w,&one);
}
/* Set w=-x */
/* SU= 88 */
void FP2_FP256BN_neg(FP2_FP256BN *w,FP2_FP256BN *x)
{
/* Just one neg! */
FP_FP256BN m,t;
// FP2_FP256BN_norm(x);
FP_FP256BN_add(&m,&(x->a),&(x->b));
FP_FP256BN_neg(&m,&m);
FP_FP256BN_add(&t,&m,&(x->b));
FP_FP256BN_add(&(w->b),&m,&(x->a));
FP_FP256BN_copy(&(w->a),&t);
}
/* Set w=conj(x) */
/* SU= 16 */
void FP2_FP256BN_conj(FP2_FP256BN *w,FP2_FP256BN *x)
{
FP_FP256BN_copy(&(w->a),&(x->a));
// BIG_256_56_norm(x->b);
FP_FP256BN_neg(&(w->b),&(x->b));
FP_FP256BN_norm(&(w->b));
}
/* Set w=x+y */
/* SU= 16 */
void FP2_FP256BN_add(FP2_FP256BN *w,FP2_FP256BN *x,FP2_FP256BN *y)
{
FP_FP256BN_add(&(w->a),&(x->a),&(y->a));
FP_FP256BN_add(&(w->b),&(x->b),&(y->b));
}
/* Set w=x-y */
/* Input y MUST be normed */
void FP2_FP256BN_sub(FP2_FP256BN *w,FP2_FP256BN *x,FP2_FP256BN *y)
{
FP2_FP256BN m;
FP2_FP256BN_neg(&m,y);
FP2_FP256BN_add(w,x,&m);
}
/* Set w=s*x, where s is FP */
/* SU= 16 */
void FP2_FP256BN_pmul(FP2_FP256BN *w,FP2_FP256BN *x,FP_FP256BN *s)
{
FP_FP256BN_mul(&(w->a),&(x->a),s);
FP_FP256BN_mul(&(w->b),&(x->b),s);
}
/* SU= 16 */
/* Set w=s*x, where s is int */
void FP2_FP256BN_imul(FP2_FP256BN *w,FP2_FP256BN *x,int s)
{
FP_FP256BN_imul(&(w->a),&(x->a),s);
FP_FP256BN_imul(&(w->b),&(x->b),s);
}
/* Set w=x^2 */
/* SU= 128 */
void FP2_FP256BN_sqr(FP2_FP256BN *w,FP2_FP256BN *x)
{
FP_FP256BN w1,w3,mb;
FP_FP256BN_add(&w1,&(x->a),&(x->b));
FP_FP256BN_neg(&mb,&(x->b));
FP_FP256BN_add(&w3,&(x->a),&(x->a));
FP_FP256BN_norm(&w3);
FP_FP256BN_mul(&(w->b),&w3,&(x->b));
FP_FP256BN_add(&(w->a),&(x->a),&mb);
FP_FP256BN_norm(&w1);
FP_FP256BN_norm(&(w->a));
FP_FP256BN_mul(&(w->a),&w1,&(w->a)); /* w->a#2 w->a=1 w1&w2=6 w1*w2=2 */
}
/* Set w=x*y */
/* Inputs MUST be normed */
/* Now uses Lazy reduction */
void FP2_FP256BN_mul(FP2_FP256BN *w,FP2_FP256BN *x,FP2_FP256BN *y)
{
DBIG_256_56 A,B,E,F,pR;
BIG_256_56 C,D,p;
BIG_256_56_rcopy(p,Modulus_FP256BN);
BIG_256_56_dsucopy(pR,p);
// reduce excesses of a and b as required (so product < pR)
if ((sign64)(x->a.XES+x->b.XES)*(y->a.XES+y->b.XES)>(sign64)FEXCESS_FP256BN)
{
#ifdef DEBUG_REDUCE
printf("FP2 Product too large - reducing it\n");
#endif
if (x->a.XES>1) FP_FP256BN_reduce(&(x->a));
if (x->b.XES>1) FP_FP256BN_reduce(&(x->b));
}
BIG_256_56_mul(A,x->a.g,y->a.g);
BIG_256_56_mul(B,x->b.g,y->b.g);
BIG_256_56_add(C,x->a.g,x->b.g);
BIG_256_56_norm(C);
BIG_256_56_add(D,y->a.g,y->b.g);
BIG_256_56_norm(D);
BIG_256_56_mul(E,C,D);
BIG_256_56_dadd(F,A,B);
BIG_256_56_dsub(B,pR,B); //
BIG_256_56_dadd(A,A,B); // A<pR? Not necessarily, but <2pR
BIG_256_56_dsub(E,E,F); // E<pR ? Yes
BIG_256_56_dnorm(A);
FP_FP256BN_mod(w->a.g,A);
w->a.XES=3;// may drift above 2p...
BIG_256_56_dnorm(E);
FP_FP256BN_mod(w->b.g,E);
w->b.XES=2;
}
/* output FP2 in hex format [a,b] */
/* SU= 16 */
void FP2_FP256BN_output(FP2_FP256BN *w)
{
BIG_256_56 bx,by;
FP2_FP256BN_reduce(w);
FP_FP256BN_redc(bx,&(w->a));
FP_FP256BN_redc(by,&(w->b));
printf("[");
BIG_256_56_output(bx);
printf(",");
BIG_256_56_output(by);
printf("]");
FP_FP256BN_nres(&(w->a),bx);
FP_FP256BN_nres(&(w->b),by);
}
/* SU= 8 */
void FP2_FP256BN_rawoutput(FP2_FP256BN *w)
{
printf("[");
BIG_256_56_rawoutput(w->a.g);
printf(",");
BIG_256_56_rawoutput(w->b.g);
printf("]");
}
/* Set w=1/x */
/* SU= 128 */
void FP2_FP256BN_inv(FP2_FP256BN *w,FP2_FP256BN *x)
{
BIG_256_56 m,b;
FP_FP256BN w1,w2;
BIG_256_56_rcopy(m,Modulus_FP256BN);
FP2_FP256BN_norm(x);
FP_FP256BN_sqr(&w1,&(x->a));
FP_FP256BN_sqr(&w2,&(x->b));
FP_FP256BN_add(&w1,&w1,&w2);
FP_FP256BN_redc(b,&w1);
BIG_256_56_invmodp(b,b,m);
FP_FP256BN_nres(&w1,b);
FP_FP256BN_mul(&(w->a),&(x->a),&w1);
FP_FP256BN_neg(&w1,&w1);
FP_FP256BN_norm(&w1);
FP_FP256BN_mul(&(w->b),&(x->b),&w1);
// FP2_FP256BN_norm(w);
}
/* Set w=x/2 */
/* SU= 16 */
void FP2_FP256BN_div2(FP2_FP256BN *w,FP2_FP256BN *x)
{
FP_FP256BN_div2(&(w->a),&(x->a));
FP_FP256BN_div2(&(w->b),&(x->b));
}
/* Set w*=(1+sqrt(-1)) */
/* where X^2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
/* Input MUST be normed */
void FP2_FP256BN_mul_ip(FP2_FP256BN *w)
{
FP_FP256BN z;
FP2_FP256BN t;
// FP2_FP256BN_norm(w);
FP2_FP256BN_copy(&t,w);
FP_FP256BN_copy(&z,&(w->a));
FP_FP256BN_neg(&(w->a),&(w->b));
FP_FP256BN_copy(&(w->b),&z);
FP2_FP256BN_add(w,&t,w);
// Output NOT normed, so use with care
}
void FP2_FP256BN_div_ip2(FP2_FP256BN *w)
{
FP2_FP256BN t;
FP_FP256BN_add(&(t.a),&(w->a),&(w->b));
FP_FP256BN_sub(&(t.b),&(w->b),&(w->a));
FP2_FP256BN_copy(w,&t);
}
/* Set w/=(1+sqrt(-1)) */
/* SU= 88 */
void FP2_FP256BN_div_ip(FP2_FP256BN *w)
{
FP2_FP256BN t;
FP2_FP256BN_norm(w);
FP_FP256BN_add(&t.a,&(w->a),&(w->b));
FP_FP256BN_sub(&t.b,&(w->b),&(w->a));
FP2_FP256BN_norm(&t);
FP2_FP256BN_div2(w,&t);
}
/* SU= 8 */
/* normalise a and b components of w */
void FP2_FP256BN_norm(FP2_FP256BN *w)
{
FP_FP256BN_norm(&(w->a));
FP_FP256BN_norm(&(w->b));
}
/* Set w=a^b mod m */
/* SU= 208 */
void FP2_FP256BN_pow(FP2_FP256BN *r,FP2_FP256BN* a,BIG_256_56 b)
{
FP2_FP256BN w;
FP_FP256BN one;
BIG_256_56 z,zilch;
int bt;
BIG_256_56_norm(b);
BIG_256_56_copy(z,b);
FP2_FP256BN_copy(&w,a);
FP_FP256BN_one(&one);
BIG_256_56_zero(zilch);
FP2_FP256BN_from_FP(r,&one);
while(1)
{
bt=BIG_256_56_parity(z);
BIG_256_56_shr(z,1);
if (bt) FP2_FP256BN_mul(r,r,&w);
if (BIG_256_56_comp(z,zilch)==0) break;
FP2_FP256BN_sqr(&w,&w);
}
FP2_FP256BN_reduce(r);
}
/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
/* returns true if u is QR */
int FP2_FP256BN_sqrt(FP2_FP256BN *w,FP2_FP256BN *u)
{
BIG_256_56 b,q;
FP_FP256BN w1,w2;
FP2_FP256BN_copy(w,u);
if (FP2_FP256BN_iszilch(w)) return 1;
BIG_256_56_rcopy(q,Modulus_FP256BN);
FP_FP256BN_sqr(&w1,&(w->b));
FP_FP256BN_sqr(&w2,&(w->a));
FP_FP256BN_add(&w1,&w1,&w2);
if (!FP_FP256BN_qr(&w1))
{
FP2_FP256BN_zero(w);
return 0;
}
FP_FP256BN_sqrt(&w1,&w1);
FP_FP256BN_add(&w2,&(w->a),&w1);
FP_FP256BN_norm(&w2);
FP_FP256BN_div2(&w2,&w2);
if (!FP_FP256BN_qr(&w2))
{
FP_FP256BN_sub(&w2,&(w->a),&w1);
FP_FP256BN_norm(&w2);
FP_FP256BN_div2(&w2,&w2);
if (!FP_FP256BN_qr(&w2))
{
FP2_FP256BN_zero(w);
return 0;
}
}
FP_FP256BN_sqrt(&w2,&w2);
FP_FP256BN_copy(&(w->a),&w2);
FP_FP256BN_add(&w2,&w2,&w2);
FP_FP256BN_redc(b,&w2);
BIG_256_56_invmodp(b,b,q);
FP_FP256BN_nres(&w2,b);
FP_FP256BN_mul(&(w->b),&(w->b),&w2);
return 1;
}
/*
int main()
{
int i;
FP2_FP256BN w,z;
BIG_256_56 a,b,e;
BIG_256_56 pp1,pm1;
BIG_256_56_unity(a); BIG_256_56_unity(b);
FP2_FP256BN_from_BIGs(&w,a,b);
// for (i=0;i<100;i++)
// {
// BIG_256_56_randomnum(a); BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus_FP256BN); BIG_256_56_mod(b,Modulus_FP256BN);
// FP2_FP256BN_from_FPs(&w,a,b);
// FP2_FP256BN_output(&w);
// FP2_FP256BN_inv(&z,&w);
// FP2_FP256BN_output(&z);
// FP2_FP256BN_inv(&z,&z);
// FP2_FP256BN_output(&z);
// FP2_FP256BN_output(&w);
// if (FP2_FP256BN_comp(&w,&z)!=1) printf("error \n");
// else printf("OK \n");
// }
//exit(0);
printf("w= "); FP2_FP256BN_output(&w); printf("\n");
BIG_256_56_zero(e); BIG_256_56_inc(e,27);
FP2_FP256BN_pow(&w,&w,e);
FP2_FP256BN_output(&w);
exit(0);
BIG_256_56_rcopy(pp1,Modulus_FP256BN);
BIG_256_56_rcopy(pm1,Modulus_FP256BN);
BIG_256_56_inc(pp1,1);
BIG_256_56_dec(pm1,1);
BIG_256_56_norm(pp1);
BIG_256_56_norm(pm1);
FP2_FP256BN_pow(&w,&w,pp1);
FP2_FP256BN_pow(&w,&w,pm1);
FP2_FP256BN_output(&w);
}
*/