void PFC::add_to_hash(const GT& x) { ZZn4 u; ZZn12 v=x.g; ZZn2 h,l; Big a; ZZn xx[6]; int i,j,m; v.get(u); u.get(l,h); l.get(xx[0],xx[1]); h.get(xx[2],xx[3]); for (i=0;i<4;i++) { a=(Big)xx[i]; while (a>0) { m=a%256; shs256_process(&SH,m); a/=256; } } }
Big H2(ZZn12 x) { // Compress and hash an Fp12 to a big number sha256 sh; ZZn4 u; ZZn2 h,l; Big a,hash,p,xx[4]; char s[HASH_LEN]; int i,j,m; shs256_init(&sh); x.get(u); // compress to single ZZn4 u.get(l,h); xx[0]=real(l); xx[1]=imaginary(l); xx[2]=real(h); xx[3]=imaginary(h); for (i=0;i<4;i++) { a=xx[i]; while (a>0) { m=a%256; shs256_process(&sh,m); a/=256; } } shs256_hash(&sh,s); hash=from_binary(HASH_LEN,s); return hash; }
ZZn4 sqrt(const ZZn4& x) { // sqrt(a+xb) = sqrt((a+sqrt(a*a-n*b*b))/2)+x.b/(2*sqrt((a+sqrt(a*a-n*b*b))/2)) // sqrt(a) = x.sqrt(a/n) // where x*x=n ZZn4 w; ZZn2 a,s,t; if (x.iszero()) return w; x.get(a,s); if (s.iszero()) { if (qr(a)) { s=sqrt(a); w.set(s,0); } else { s=sqrt(txd(a)); w.set(0,s); } return w; } s*=s; a*=a; a-=txx(s); s=sqrt(a); if (s.iszero()) return w; x.get(t); if (qr((ZZn2)((t+s)/2))) { a=sqrt((t+s)/2); } else { a=sqrt((t-s)/2); if (a.iszero()) return w; } x.geth(t); w.set(a,t/(2*a)); return w; }
ZZn4 txd(const ZZn4& x) { ZZn2 u,v; x.get(u,v); u=txd(u); ZZn4 w(v,u); return w; }
Big H4(ZZn4 x) { // Hash an Fp2 to a big number sha sh; Big a,u,v; ZZn2 X,Y; char s[HASH_LEN]; int m; shs_init(&sh); x.get(X,Y); X.get(u,v); a=u; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } a=v; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } Y.get(u,v); a=u; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } a=v; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } shs_hash(&sh,s); a=from_binary(HASH_LEN,s); return a; }
BOOL qr(const ZZn4& x) { ZZn2 a,s; if (x.iszero()) return TRUE; x.get(a,s); if (s.iszero()) return TRUE; s*=s; a*=a; a-=txx(s); if (!qr(a)) return FALSE; return TRUE; // s=sqrt(a); // if (qr((x.a+s)/2) || qr((x.a-s)/2)) return TRUE; // return FALSE; }
ZZn2 real(const ZZn4 &x) { ZZn2 r; x.get(r); return r; }