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.
 
 

849 lines
22 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^12 functions */
/* SU=m, m is Stack Usage (no lazy )*/
/* FP12 elements are of the form a+i.b+i^2.c */
#include "fp12_FP256BN.h"
/* test x==0 ? */
/* SU= 8 */
int FP12_FP256BN_iszilch(FP12_FP256BN *x)
{
if (FP4_FP256BN_iszilch(&(x->a)) && FP4_FP256BN_iszilch(&(x->b)) && FP4_FP256BN_iszilch(&(x->c))) return 1;
return 0;
}
/* test x==1 ? */
/* SU= 8 */
int FP12_FP256BN_isunity(FP12_FP256BN *x)
{
if (FP4_FP256BN_isunity(&(x->a)) && FP4_FP256BN_iszilch(&(x->b)) && FP4_FP256BN_iszilch(&(x->c))) return 1;
return 0;
}
/* FP12 copy w=x */
/* SU= 16 */
void FP12_FP256BN_copy(FP12_FP256BN *w,FP12_FP256BN *x)
{
if (x==w) return;
FP4_FP256BN_copy(&(w->a),&(x->a));
FP4_FP256BN_copy(&(w->b),&(x->b));
FP4_FP256BN_copy(&(w->c),&(x->c));
}
/* FP12 w=1 */
/* SU= 8 */
void FP12_FP256BN_one(FP12_FP256BN *w)
{
FP4_FP256BN_one(&(w->a));
FP4_FP256BN_zero(&(w->b));
FP4_FP256BN_zero(&(w->c));
}
/* return 1 if x==y, else 0 */
/* SU= 16 */
int FP12_FP256BN_equals(FP12_FP256BN *x,FP12_FP256BN *y)
{
if (FP4_FP256BN_equals(&(x->a),&(y->a)) && FP4_FP256BN_equals(&(x->b),&(y->b)) && FP4_FP256BN_equals(&(x->b),&(y->b)))
return 1;
return 0;
}
/* Set w=conj(x) */
/* SU= 8 */
void FP12_FP256BN_conj(FP12_FP256BN *w,FP12_FP256BN *x)
{
FP12_FP256BN_copy(w,x);
FP4_FP256BN_conj(&(w->a),&(w->a));
FP4_FP256BN_nconj(&(w->b),&(w->b));
FP4_FP256BN_conj(&(w->c),&(w->c));
}
/* Create FP12 from FP4 */
/* SU= 8 */
void FP12_FP256BN_from_FP4(FP12_FP256BN *w,FP4_FP256BN *a)
{
FP4_FP256BN_copy(&(w->a),a);
FP4_FP256BN_zero(&(w->b));
FP4_FP256BN_zero(&(w->c));
}
/* Create FP12 from 3 FP4's */
/* SU= 16 */
void FP12_FP256BN_from_FP4s(FP12_FP256BN *w,FP4_FP256BN *a,FP4_FP256BN *b,FP4_FP256BN *c)
{
FP4_FP256BN_copy(&(w->a),a);
FP4_FP256BN_copy(&(w->b),b);
FP4_FP256BN_copy(&(w->c),c);
}
/* Granger-Scott Unitary Squaring. This does not benefit from lazy reduction */
/* SU= 600 */
void FP12_FP256BN_usqr(FP12_FP256BN *w,FP12_FP256BN *x)
{
FP4_FP256BN A,B,C,D;
FP4_FP256BN_copy(&A,&(x->a));
FP4_FP256BN_sqr(&(w->a),&(x->a));
FP4_FP256BN_add(&D,&(w->a),&(w->a));
FP4_FP256BN_add(&(w->a),&D,&(w->a));
FP4_FP256BN_norm(&(w->a));
FP4_FP256BN_nconj(&A,&A);
FP4_FP256BN_add(&A,&A,&A);
FP4_FP256BN_add(&(w->a),&(w->a),&A);
FP4_FP256BN_sqr(&B,&(x->c));
FP4_FP256BN_times_i(&B);
FP4_FP256BN_add(&D,&B,&B);
FP4_FP256BN_add(&B,&B,&D);
FP4_FP256BN_norm(&B);
FP4_FP256BN_sqr(&C,&(x->b));
FP4_FP256BN_add(&D,&C,&C);
FP4_FP256BN_add(&C,&C,&D);
FP4_FP256BN_norm(&C);
FP4_FP256BN_conj(&(w->b),&(x->b));
FP4_FP256BN_add(&(w->b),&(w->b),&(w->b));
FP4_FP256BN_nconj(&(w->c),&(x->c));
FP4_FP256BN_add(&(w->c),&(w->c),&(w->c));
FP4_FP256BN_add(&(w->b),&B,&(w->b));
FP4_FP256BN_add(&(w->c),&C,&(w->c));
FP12_FP256BN_reduce(w); /* reduce here as in pow function repeated squarings would trigger multiple reductions */
}
/* FP12 squaring w=x^2 */
/* SU= 600 */
void FP12_FP256BN_sqr(FP12_FP256BN *w,FP12_FP256BN *x)
{
/* Use Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
FP4_FP256BN A,B,C,D;
FP4_FP256BN_sqr(&A,&(x->a));
FP4_FP256BN_mul(&B,&(x->b),&(x->c));
FP4_FP256BN_add(&B,&B,&B);
FP4_FP256BN_norm(&B);
FP4_FP256BN_sqr(&C,&(x->c));
FP4_FP256BN_mul(&D,&(x->a),&(x->b));
FP4_FP256BN_add(&D,&D,&D);
FP4_FP256BN_add(&(w->c),&(x->a),&(x->c));
FP4_FP256BN_add(&(w->c),&(x->b),&(w->c));
FP4_FP256BN_norm(&(w->c));
FP4_FP256BN_sqr(&(w->c),&(w->c));
FP4_FP256BN_copy(&(w->a),&A);
FP4_FP256BN_add(&A,&A,&B);
FP4_FP256BN_norm(&A);
FP4_FP256BN_add(&A,&A,&C);
FP4_FP256BN_add(&A,&A,&D);
FP4_FP256BN_norm(&A);
FP4_FP256BN_neg(&A,&A);
FP4_FP256BN_times_i(&B);
FP4_FP256BN_times_i(&C);
FP4_FP256BN_add(&(w->a),&(w->a),&B);
FP4_FP256BN_add(&(w->b),&C,&D);
FP4_FP256BN_add(&(w->c),&(w->c),&A);
FP12_FP256BN_norm(w);
}
/* FP12 full multiplication w=w*y */
/* SU= 896 */
/* FP12 full multiplication w=w*y */
void FP12_FP256BN_mul(FP12_FP256BN *w,FP12_FP256BN *y)
{
FP4_FP256BN z0,z1,z2,z3,t0,t1;
FP4_FP256BN_mul(&z0,&(w->a),&(y->a));
FP4_FP256BN_mul(&z2,&(w->b),&(y->b)); //
FP4_FP256BN_add(&t0,&(w->a),&(w->b));
FP4_FP256BN_add(&t1,&(y->a),&(y->b)); //
FP4_FP256BN_norm(&t0);
FP4_FP256BN_norm(&t1);
FP4_FP256BN_mul(&z1,&t0,&t1);
FP4_FP256BN_add(&t0,&(w->b),&(w->c));
FP4_FP256BN_add(&t1,&(y->b),&(y->c)); //
FP4_FP256BN_norm(&t0);
FP4_FP256BN_norm(&t1);
FP4_FP256BN_mul(&z3,&t0,&t1);
FP4_FP256BN_neg(&t0,&z0);
FP4_FP256BN_neg(&t1,&z2);
FP4_FP256BN_add(&z1,&z1,&t0); // z1=z1-z0
// FP4_FP256BN_norm(&z1);
FP4_FP256BN_add(&(w->b),&z1,&t1);
// z1=z1-z2
FP4_FP256BN_add(&z3,&z3,&t1); // z3=z3-z2
FP4_FP256BN_add(&z2,&z2,&t0); // z2=z2-z0
FP4_FP256BN_add(&t0,&(w->a),&(w->c));
FP4_FP256BN_add(&t1,&(y->a),&(y->c));
FP4_FP256BN_norm(&t0);
FP4_FP256BN_norm(&t1);
FP4_FP256BN_mul(&t0,&t1,&t0);
FP4_FP256BN_add(&z2,&z2,&t0);
FP4_FP256BN_mul(&t0,&(w->c),&(y->c));
FP4_FP256BN_neg(&t1,&t0);
FP4_FP256BN_add(&(w->c),&z2,&t1);
FP4_FP256BN_add(&z3,&z3,&t1);
FP4_FP256BN_times_i(&t0);
FP4_FP256BN_add(&(w->b),&(w->b),&t0);
FP4_FP256BN_norm(&z3);
FP4_FP256BN_times_i(&z3);
FP4_FP256BN_add(&(w->a),&z0,&z3);
FP12_FP256BN_norm(w);
}
/* FP12 multiplication w=w*y */
/* SU= 744 */
/* catering for special case that arises from special form of ATE pairing line function */
void FP12_FP256BN_smul(FP12_FP256BN *w,FP12_FP256BN *y,int type)
{
FP4_FP256BN z0,z1,z2,z3,t0,t1;
if (type==D_TYPE)
{
// y->c is 0
FP4_FP256BN_copy(&z3,&(w->b));
FP4_FP256BN_mul(&z0,&(w->a),&(y->a));
FP4_FP256BN_pmul(&z2,&(w->b),&(y->b).a);
FP4_FP256BN_add(&(w->b),&(w->a),&(w->b));
FP4_FP256BN_copy(&t1,&(y->a));
FP2_FP256BN_add(&t1.a,&t1.a,&(y->b).a);
FP4_FP256BN_norm(&t1);
FP4_FP256BN_norm(&(w->b));
FP4_FP256BN_mul(&(w->b),&(w->b),&t1);
FP4_FP256BN_add(&z3,&z3,&(w->c));
FP4_FP256BN_norm(&z3);
FP4_FP256BN_pmul(&z3,&z3,&(y->b).a);
FP4_FP256BN_neg(&t0,&z0);
FP4_FP256BN_neg(&t1,&z2);
FP4_FP256BN_add(&(w->b),&(w->b),&t0); // z1=z1-z0
// FP4_FP256BN_norm(&(w->b));
FP4_FP256BN_add(&(w->b),&(w->b),&t1); // z1=z1-z2
FP4_FP256BN_add(&z3,&z3,&t1); // z3=z3-z2
FP4_FP256BN_add(&z2,&z2,&t0); // z2=z2-z0
FP4_FP256BN_add(&t0,&(w->a),&(w->c));
FP4_FP256BN_norm(&t0);
FP4_FP256BN_norm(&z3);
FP4_FP256BN_mul(&t0,&(y->a),&t0);
FP4_FP256BN_add(&(w->c),&z2,&t0);
FP4_FP256BN_times_i(&z3);
FP4_FP256BN_add(&(w->a),&z0,&z3);
}
if (type==M_TYPE)
{
// y->b is zero
FP4_FP256BN_mul(&z0,&(w->a),&(y->a));
FP4_FP256BN_add(&t0,&(w->a),&(w->b));
FP4_FP256BN_norm(&t0);
FP4_FP256BN_mul(&z1,&t0,&(y->a));
FP4_FP256BN_add(&t0,&(w->b),&(w->c));
FP4_FP256BN_norm(&t0);
FP4_FP256BN_pmul(&z3,&t0,&(y->c).b);
FP4_FP256BN_times_i(&z3);
FP4_FP256BN_neg(&t0,&z0);
FP4_FP256BN_add(&z1,&z1,&t0); // z1=z1-z0
FP4_FP256BN_copy(&(w->b),&z1);
FP4_FP256BN_copy(&z2,&t0);
FP4_FP256BN_add(&t0,&(w->a),&(w->c));
FP4_FP256BN_add(&t1,&(y->a),&(y->c));
FP4_FP256BN_norm(&t0);
FP4_FP256BN_norm(&t1);
FP4_FP256BN_mul(&t0,&t1,&t0);
FP4_FP256BN_add(&z2,&z2,&t0);
FP4_FP256BN_pmul(&t0,&(w->c),&(y->c).b);
FP4_FP256BN_times_i(&t0);
FP4_FP256BN_neg(&t1,&t0);
FP4_FP256BN_times_i(&t0);
FP4_FP256BN_add(&(w->c),&z2,&t1);
FP4_FP256BN_add(&z3,&z3,&t1);
FP4_FP256BN_add(&(w->b),&(w->b),&t0);
FP4_FP256BN_norm(&z3);
FP4_FP256BN_times_i(&z3);
FP4_FP256BN_add(&(w->a),&z0,&z3);
}
FP12_FP256BN_norm(w);
}
/* Set w=1/x */
/* SU= 600 */
void FP12_FP256BN_inv(FP12_FP256BN *w,FP12_FP256BN *x)
{
FP4_FP256BN f0,f1,f2,f3;
// FP12_FP256BN_norm(x);
FP4_FP256BN_sqr(&f0,&(x->a));
FP4_FP256BN_mul(&f1,&(x->b),&(x->c));
FP4_FP256BN_times_i(&f1);
FP4_FP256BN_sub(&f0,&f0,&f1); /* y.a */
FP4_FP256BN_norm(&f0);
FP4_FP256BN_sqr(&f1,&(x->c));
FP4_FP256BN_times_i(&f1);
FP4_FP256BN_mul(&f2,&(x->a),&(x->b));
FP4_FP256BN_sub(&f1,&f1,&f2); /* y.b */
FP4_FP256BN_norm(&f1);
FP4_FP256BN_sqr(&f2,&(x->b));
FP4_FP256BN_mul(&f3,&(x->a),&(x->c));
FP4_FP256BN_sub(&f2,&f2,&f3); /* y.c */
FP4_FP256BN_norm(&f2);
FP4_FP256BN_mul(&f3,&(x->b),&f2);
FP4_FP256BN_times_i(&f3);
FP4_FP256BN_mul(&(w->a),&f0,&(x->a));
FP4_FP256BN_add(&f3,&(w->a),&f3);
FP4_FP256BN_mul(&(w->c),&f1,&(x->c));
FP4_FP256BN_times_i(&(w->c));
FP4_FP256BN_add(&f3,&(w->c),&f3);
FP4_FP256BN_norm(&f3);
FP4_FP256BN_inv(&f3,&f3);
FP4_FP256BN_mul(&(w->a),&f0,&f3);
FP4_FP256BN_mul(&(w->b),&f1,&f3);
FP4_FP256BN_mul(&(w->c),&f2,&f3);
}
/* constant time powering by small integer of max length bts */
void FP12_FP256BN_pinpow(FP12_FP256BN *r,int e,int bts)
{
int i,b;
FP12_FP256BN R[2];
FP12_FP256BN_one(&R[0]);
FP12_FP256BN_copy(&R[1],r);
for (i=bts-1; i>=0; i--)
{
b=(e>>i)&1;
FP12_FP256BN_mul(&R[1-b],&R[b]);
FP12_FP256BN_usqr(&R[b],&R[b]);
}
FP12_FP256BN_copy(r,&R[0]);
}
/* Compressed powering of unitary elements y=x^(e mod r) */
void FP12_FP256BN_compow(FP4_FP256BN *c,FP12_FP256BN *x,BIG_256_56 e,BIG_256_56 r)
{
FP12_FP256BN g1,g2;
FP4_FP256BN cp,cpm1,cpm2;
FP2_FP256BN f;
BIG_256_56 q,a,b,m;
BIG_256_56_rcopy(a,Fra_FP256BN);
BIG_256_56_rcopy(b,Frb_FP256BN);
FP2_FP256BN_from_BIGs(&f,a,b);
BIG_256_56_rcopy(q,Modulus_FP256BN);
FP12_FP256BN_copy(&g1,x);
FP12_FP256BN_copy(&g2,x);
BIG_256_56_copy(m,q);
BIG_256_56_mod(m,r);
BIG_256_56_copy(a,e);
BIG_256_56_mod(a,m);
BIG_256_56_copy(b,e);
BIG_256_56_sdiv(b,m);
FP12_FP256BN_trace(c,&g1);
if (BIG_256_56_iszilch(b))
{
FP4_FP256BN_xtr_pow(c,c,e);
return;
}
FP12_FP256BN_frob(&g2,&f);
FP12_FP256BN_trace(&cp,&g2);
FP12_FP256BN_conj(&g1,&g1);
FP12_FP256BN_mul(&g2,&g1);
FP12_FP256BN_trace(&cpm1,&g2);
FP12_FP256BN_mul(&g2,&g1);
FP12_FP256BN_trace(&cpm2,&g2);
FP4_FP256BN_xtr_pow2(c,&cp,c,&cpm1,&cpm2,a,b);
}
/* SU= 528 */
/* set r=a^b */
/* Note this is simple square and multiply, so not side-channel safe */
void FP12_FP256BN_pow(FP12_FP256BN *r,FP12_FP256BN *a,BIG_256_56 b)
{
FP12_FP256BN w;
BIG_256_56 b3;
int i,nb,bt;
BIG_256_56_norm(b);
BIG_256_56_pmul(b3,b,3);
BIG_256_56_norm(b3);
FP12_FP256BN_copy(&w,a);
nb=BIG_256_56_nbits(b3);
for (i=nb-2; i>=1; i--)
{
FP12_FP256BN_usqr(&w,&w);
bt=BIG_256_56_bit(b3,i)-BIG_256_56_bit(b,i);
if (bt==1)
FP12_FP256BN_mul(&w,a);
if (bt==-1)
{
FP12_FP256BN_conj(a,a);
FP12_FP256BN_mul(&w,a);
FP12_FP256BN_conj(a,a);
}
}
FP12_FP256BN_copy(r,&w);
FP12_FP256BN_reduce(r);
/*
while(1)
{
bt=BIG_256_56_parity(z);
BIG_256_56_shr(z,1);
if (bt)
FP12_FP256BN_mul(r,&w);
if (BIG_256_56_comp(z,zilch)==0) break;
FP12_FP256BN_usqr(&w,&w);
}
FP12_FP256BN_reduce(r); */
}
/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
/* Timing attack secure, but not cache attack secure */
void FP12_FP256BN_pow4(FP12_FP256BN *p,FP12_FP256BN *q,BIG_256_56 u[4])
{
int i,j,a[4],nb,m;
FP12_FP256BN g[8],c,s[2];
BIG_256_56 t[4],mt;
sign8 w[NLEN_256_56*BASEBITS_256_56+1];
for (i=0; i<4; i++)
BIG_256_56_copy(t[i],u[i]);
FP12_FP256BN_copy(&g[0],&q[0]);
FP12_FP256BN_conj(&s[0],&q[1]);
FP12_FP256BN_mul(&g[0],&s[0]); /* P/Q */
FP12_FP256BN_copy(&g[1],&g[0]);
FP12_FP256BN_copy(&g[2],&g[0]);
FP12_FP256BN_copy(&g[3],&g[0]);
FP12_FP256BN_copy(&g[4],&q[0]);
FP12_FP256BN_mul(&g[4],&q[1]); /* P*Q */
FP12_FP256BN_copy(&g[5],&g[4]);
FP12_FP256BN_copy(&g[6],&g[4]);
FP12_FP256BN_copy(&g[7],&g[4]);
FP12_FP256BN_copy(&s[1],&q[2]);
FP12_FP256BN_conj(&s[0],&q[3]);
FP12_FP256BN_mul(&s[1],&s[0]); /* R/S */
FP12_FP256BN_conj(&s[0],&s[1]);
FP12_FP256BN_mul(&g[1],&s[0]);
FP12_FP256BN_mul(&g[2],&s[1]);
FP12_FP256BN_mul(&g[5],&s[0]);
FP12_FP256BN_mul(&g[6],&s[1]);
FP12_FP256BN_copy(&s[1],&q[2]);
FP12_FP256BN_mul(&s[1],&q[3]); /* R*S */
FP12_FP256BN_conj(&s[0],&s[1]);
FP12_FP256BN_mul(&g[0],&s[0]);
FP12_FP256BN_mul(&g[3],&s[1]);
FP12_FP256BN_mul(&g[4],&s[0]);
FP12_FP256BN_mul(&g[7],&s[1]);
/* if power is even add 1 to power, and add q to correction */
FP12_FP256BN_one(&c);
BIG_256_56_zero(mt);
for (i=0; i<4; i++)
{
if (BIG_256_56_parity(t[i])==0)
{
BIG_256_56_inc(t[i],1);
BIG_256_56_norm(t[i]);
FP12_FP256BN_mul(&c,&q[i]);
}
BIG_256_56_add(mt,mt,t[i]);
BIG_256_56_norm(mt);
}
FP12_FP256BN_conj(&c,&c);
nb=1+BIG_256_56_nbits(mt);
/* convert exponent to signed 1-bit window */
for (j=0; j<nb; j++)
{
for (i=0; i<4; i++)
{
a[i]=BIG_256_56_lastbits(t[i],2)-2;
BIG_256_56_dec(t[i],a[i]);
BIG_256_56_norm(t[i]);
BIG_256_56_fshr(t[i],1);
}
w[j]=8*a[0]+4*a[1]+2*a[2]+a[3];
}
w[nb]=8*BIG_256_56_lastbits(t[0],2)+4*BIG_256_56_lastbits(t[1],2)+2*BIG_256_56_lastbits(t[2],2)+BIG_256_56_lastbits(t[3],2);
FP12_FP256BN_copy(p,&g[(w[nb]-1)/2]);
for (i=nb-1; i>=0; i--)
{
m=w[i]>>7;
j=(w[i]^m)-m; /* j=abs(w[i]) */
j=(j-1)/2;
FP12_FP256BN_copy(&s[0],&g[j]);
FP12_FP256BN_conj(&s[1],&g[j]);
FP12_FP256BN_usqr(p,p);
FP12_FP256BN_mul(p,&s[m&1]);
}
FP12_FP256BN_mul(p,&c); /* apply correction */
FP12_FP256BN_reduce(p);
}
/* Set w=w^p using Frobenius */
/* SU= 160 */
void FP12_FP256BN_frob(FP12_FP256BN *w,FP2_FP256BN *f)
{
FP2_FP256BN f2,f3;
FP2_FP256BN_sqr(&f2,f); /* f2=f^2 */
FP2_FP256BN_mul(&f3,&f2,f); /* f3=f^3 */
FP4_FP256BN_frob(&(w->a),&f3);
FP4_FP256BN_frob(&(w->b),&f3);
FP4_FP256BN_frob(&(w->c),&f3);
FP4_FP256BN_pmul(&(w->b),&(w->b),f);
FP4_FP256BN_pmul(&(w->c),&(w->c),&f2);
}
/* SU= 8 */
/* normalise all components of w */
void FP12_FP256BN_norm(FP12_FP256BN *w)
{
FP4_FP256BN_norm(&(w->a));
FP4_FP256BN_norm(&(w->b));
FP4_FP256BN_norm(&(w->c));
}
/* SU= 8 */
/* reduce all components of w */
void FP12_FP256BN_reduce(FP12_FP256BN *w)
{
FP4_FP256BN_reduce(&(w->a));
FP4_FP256BN_reduce(&(w->b));
FP4_FP256BN_reduce(&(w->c));
}
/* trace function w=trace(x) */
/* SU= 8 */
void FP12_FP256BN_trace(FP4_FP256BN *w,FP12_FP256BN *x)
{
FP4_FP256BN_imul(w,&(x->a),3);
FP4_FP256BN_reduce(w);
}
/* SU= 8 */
/* Output w in hex */
void FP12_FP256BN_output(FP12_FP256BN *w)
{
printf("[");
FP4_FP256BN_output(&(w->a));
printf(",");
FP4_FP256BN_output(&(w->b));
printf(",");
FP4_FP256BN_output(&(w->c));
printf("]");
}
/* SU= 64 */
/* Convert g to octet string w */
void FP12_FP256BN_toOctet(octet *W,FP12_FP256BN *g)
{
BIG_256_56 a;
W->len=12*MODBYTES_256_56;
FP_FP256BN_redc(a,&(g->a.a.a));
BIG_256_56_toBytes(&(W->val[0]),a);
FP_FP256BN_redc(a,&(g->a.a.b));
BIG_256_56_toBytes(&(W->val[MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->a.b.a));
BIG_256_56_toBytes(&(W->val[2*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->a.b.b));
BIG_256_56_toBytes(&(W->val[3*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->b.a.a));
BIG_256_56_toBytes(&(W->val[4*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->b.a.b));
BIG_256_56_toBytes(&(W->val[5*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->b.b.a));
BIG_256_56_toBytes(&(W->val[6*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->b.b.b));
BIG_256_56_toBytes(&(W->val[7*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->c.a.a));
BIG_256_56_toBytes(&(W->val[8*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->c.a.b));
BIG_256_56_toBytes(&(W->val[9*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->c.b.a));
BIG_256_56_toBytes(&(W->val[10*MODBYTES_256_56]),a);
FP_FP256BN_redc(a,&(g->c.b.b));
BIG_256_56_toBytes(&(W->val[11*MODBYTES_256_56]),a);
}
/* SU= 24 */
/* Restore g from octet string w */
void FP12_FP256BN_fromOctet(FP12_FP256BN *g,octet *W)
{
BIG_256_56 b;
BIG_256_56_fromBytes(b,&W->val[0]);
FP_FP256BN_nres(&(g->a.a.a),b);
BIG_256_56_fromBytes(b,&W->val[MODBYTES_256_56]);
FP_FP256BN_nres(&(g->a.a.b),b);
BIG_256_56_fromBytes(b,&W->val[2*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->a.b.a),b);
BIG_256_56_fromBytes(b,&W->val[3*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->a.b.b),b);
BIG_256_56_fromBytes(b,&W->val[4*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->b.a.a),b);
BIG_256_56_fromBytes(b,&W->val[5*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->b.a.b),b);
BIG_256_56_fromBytes(b,&W->val[6*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->b.b.a),b);
BIG_256_56_fromBytes(b,&W->val[7*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->b.b.b),b);
BIG_256_56_fromBytes(b,&W->val[8*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->c.a.a),b);
BIG_256_56_fromBytes(b,&W->val[9*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->c.a.b),b);
BIG_256_56_fromBytes(b,&W->val[10*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->c.b.a),b);
BIG_256_56_fromBytes(b,&W->val[11*MODBYTES_256_56]);
FP_FP256BN_nres(&(g->c.b.b),b);
}
/*
int main(){
FP2_FP256BN f,w0,w1;
FP4_FP256BN t0,t1,t2;
FP12_FP256BN w,t,lv;
BIG_256_56 a,b;
BIG_256_56 p;
//Test w^(P^4) = w mod p^2
// BIG_256_56_randomnum(a);
// BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus); BIG_256_56_mod(b,Modulus);
BIG_256_56_zero(a); BIG_256_56_zero(b); BIG_256_56_inc(a,1); BIG_256_56_inc(b,2); FP_FP256BN_nres(a); FP_FP256BN_nres(b);
FP2_FP256BN_from_zps(&w0,a,b);
// BIG_256_56_randomnum(a); BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus); BIG_256_56_mod(b,Modulus);
BIG_256_56_zero(a); BIG_256_56_zero(b); BIG_256_56_inc(a,3); BIG_256_56_inc(b,4); FP_FP256BN_nres(a); FP_FP256BN_nres(b);
FP2_FP256BN_from_zps(&w1,a,b);
FP4_FP256BN_from_FP2s(&t0,&w0,&w1);
FP4_FP256BN_reduce(&t0);
// BIG_256_56_randomnum(a);
// BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus); BIG_256_56_mod(b,Modulus);
BIG_256_56_zero(a); BIG_256_56_zero(b); BIG_256_56_inc(a,5); BIG_256_56_inc(b,6); FP_FP256BN_nres(a); FP_FP256BN_nres(b);
FP2_FP256BN_from_zps(&w0,a,b);
// BIG_256_56_randomnum(a); BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus); BIG_256_56_mod(b,Modulus);
BIG_256_56_zero(a); BIG_256_56_zero(b); BIG_256_56_inc(a,7); BIG_256_56_inc(b,8); FP_FP256BN_nres(a); FP_FP256BN_nres(b);
FP2_FP256BN_from_zps(&w1,a,b);
FP4_FP256BN_from_FP2s(&t1,&w0,&w1);
FP4_FP256BN_reduce(&t1);
// BIG_256_56_randomnum(a);
// BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus); BIG_256_56_mod(b,Modulus);
BIG_256_56_zero(a); BIG_256_56_zero(b); BIG_256_56_inc(a,9); BIG_256_56_inc(b,10); FP_FP256BN_nres(a); FP_FP256BN_nres(b);
FP2_FP256BN_from_zps(&w0,a,b);
// BIG_256_56_randomnum(a); BIG_256_56_randomnum(b);
// BIG_256_56_mod(a,Modulus); BIG_256_56_mod(b,Modulus);
BIG_256_56_zero(a); BIG_256_56_zero(b); BIG_256_56_inc(a,11); BIG_256_56_inc(b,12); FP_FP256BN_nres(a); FP_FP256BN_nres(b);
FP2_FP256BN_from_zps(&w1,a,b);
FP4_FP256BN_from_FP2s(&t2,&w0,&w1);
FP4_FP256BN_reduce(&t2);
FP12_FP256BN_from_FP4s(&w,&t0,&t1,&t2);
FP12_FP256BN_copy(&t,&w);
printf("w= ");
FP12_FP256BN_output(&w);
printf("\n");
BIG_256_56_rcopy(p,Modulus);
//BIG_256_56_zero(p); BIG_256_56_inc(p,7);
FP12_FP256BN_pow(&w,&w,p);
printf("w^p= ");
FP12_FP256BN_output(&w);
printf("\n");
FP2_FP256BN_gfc(&f,12);
FP12_FP256BN_frob(&t,&f);
printf("w^p= ");
FP12_FP256BN_output(&t);
printf("\n");
//exit(0);
FP12_FP256BN_pow(&w,&w,p);
//printf("w^p^2= ");
//FP12_FP256BN_output(&w);
//printf("\n");
FP12_FP256BN_pow(&w,&w,p);
//printf("w^p^3= ");
//FP12_FP256BN_output(&w);
//printf("\n");
FP12_FP256BN_pow(&w,&w,p);
FP12_FP256BN_pow(&w,&w,p);
FP12_FP256BN_pow(&w,&w,p);
printf("w^p^6= ");
FP12_FP256BN_output(&w);
printf("\n");
FP12_FP256BN_pow(&w,&w,p);
FP12_FP256BN_pow(&w,&w,p);
printf("w^p^8= ");
FP12_FP256BN_output(&w);
printf("\n");
FP12_FP256BN_pow(&w,&w,p);
FP12_FP256BN_pow(&w,&w,p);
FP12_FP256BN_pow(&w,&w,p);
printf("w^p^11= ");
FP12_FP256BN_output(&w);
printf("\n");
// BIG_256_56_zero(p); BIG_256_56_inc(p,7); BIG_256_56_norm(p);
FP12_FP256BN_pow(&w,&w,p);
printf("w^p12= ");
FP12_FP256BN_output(&w);
printf("\n");
//exit(0);
FP12_FP256BN_inv(&t,&w);
printf("1/w mod p^4 = ");
FP12_FP256BN_output(&t);
printf("\n");
FP12_FP256BN_inv(&w,&t);
printf("1/(1/w) mod p^4 = ");
FP12_FP256BN_output(&w);
printf("\n");
FP12_FP256BN_inv(&lv,&w);
//printf("w= "); FP12_FP256BN_output(&w); printf("\n");
FP12_FP256BN_conj(&w,&w);
//printf("w= "); FP12_FP256BN_output(&w); printf("\n");
//exit(0);
FP12_FP256BN_mul(&w,&w,&lv);
//printf("w= "); FP12_FP256BN_output(&w); printf("\n");
FP12_FP256BN_copy(&lv,&w);
FP12_FP256BN_frob(&w,&f);
FP12_FP256BN_frob(&w,&f);
FP12_FP256BN_mul(&w,&w,&lv);
//printf("w= "); FP12_FP256BN_output(&w); printf("\n");
//exit(0);
w.unitary=0;
FP12_FP256BN_conj(&lv,&w);
printf("rx= "); FP12_FP256BN_output(&lv); printf("\n");
FP12_FP256BN_inv(&lv,&w);
printf("ry= "); FP12_FP256BN_output(&lv); printf("\n");
return 0;
}
*/