github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/ECP2.go (about)

     1  /*
     2  Licensed to the Apache Software Foundation (ASF) under one
     3  or more contributor license agreements.  See the NOTICE file
     4  distributed with this work for additional information
     5  regarding copyright ownership.  The ASF licenses this file
     6  to you under the Apache License, Version 2.0 (the
     7  "License"); you may not use this file except in compliance
     8  with the License.  You may obtain a copy of the License at
     9  
    10    http://www.apache.org/licenses/LICENSE-2.0
    11  
    12  Unless required by applicable law or agreed to in writing,
    13  software distributed under the License is distributed on an
    14  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15  KIND, either express or implied.  See the License for the
    16  specific language governing permissions and limitations
    17  under the License.
    18  */
    19  
    20  /* MiotCL Weierstrass elliptic curve functions over FP2 */
    21  
    22  package FP256BN
    23  
    24  
    25  
    26  type ECP2 struct {
    27  	x *FP2
    28  	y *FP2
    29  	z *FP2
    30  //	INF bool
    31  }
    32  
    33  func NewECP2() *ECP2 {
    34  	E:=new(ECP2)
    35  	E.x=NewFP2int(0)
    36  	E.y=NewFP2int(1)
    37  	E.z=NewFP2int(0)
    38  //	E.INF=true
    39  	return E
    40  }
    41  
    42  /* Test this=O? */
    43  func (E *ECP2) Is_infinity() bool {
    44  //	if E.INF {return true}
    45  	E.x.reduce(); E.y.reduce(); E.z.reduce()
    46  	return E.x.iszilch() && E.z.iszilch()
    47  }
    48  /* copy this=P */
    49  func (E *ECP2) Copy(P *ECP2) {
    50  	E.x.copy(P.x)
    51  	E.y.copy(P.y)
    52  	E.z.copy(P.z)
    53  //	E.INF=P.INF
    54  }
    55  /* set this=O */
    56  func (E *ECP2) inf() {
    57  //	E.INF=true
    58  	E.x.zero()
    59  	E.y.one()
    60  	E.z.zero()
    61  }
    62  
    63  /* set this=-this */
    64  func (E *ECP2) neg() {
    65  //	if E.Is_infinity() {return}
    66  	E.y.norm(); E.y.neg(); E.y.norm()
    67  }
    68  
    69  /* Conditional move of Q to P dependant on d */
    70  func (E *ECP2) cmove(Q *ECP2,d int) {
    71  	E.x.cmove(Q.x,d)
    72  	E.y.cmove(Q.y,d)
    73  	E.z.cmove(Q.z,d)
    74  /*
    75  	var bd bool
    76  	if (d==0) {
    77  		bd=false
    78  	} else {bd=true}
    79  	E.INF=(E.INF!=(E.INF!=Q.INF)&&bd)
    80  */
    81  }
    82  
    83  /* Constant time select from pre-computed table */
    84  func (E *ECP2) selector(W []*ECP2,b int32) {
    85  	MP:=NewECP2() 
    86  	m:=b>>31
    87  	babs:=(b^m)-m
    88  
    89  	babs=(babs-1)/2
    90  
    91  	E.cmove(W[0],teq(babs,0))  // conditional move
    92  	E.cmove(W[1],teq(babs,1))
    93  	E.cmove(W[2],teq(babs,2))
    94  	E.cmove(W[3],teq(babs,3))
    95  	E.cmove(W[4],teq(babs,4))
    96  	E.cmove(W[5],teq(babs,5))
    97  	E.cmove(W[6],teq(babs,6))
    98  	E.cmove(W[7],teq(babs,7))
    99   
   100  	MP.Copy(E)
   101  	MP.neg()
   102  	E.cmove(MP,int(m&1))
   103  }
   104  
   105  /* Test if P == Q */
   106  func (E *ECP2) Equals(Q *ECP2) bool {
   107  //	if E.Is_infinity() && Q.Is_infinity() {return true}
   108  //	if E.Is_infinity() || Q.Is_infinity() {return false}
   109  
   110  	a:=NewFP2copy(E.x)
   111  	b:=NewFP2copy(Q.x)
   112  	a.mul(Q.z); b.mul(E.z)
   113  
   114  	if !a.Equals(b) {return false}
   115  	a.copy(E.y); b.copy(Q.y)
   116  	a.mul(Q.z); b.mul(E.z);
   117  	if !a.Equals(b) {return false}
   118  
   119  	return true
   120  }
   121  
   122  /* set to Affine - (x,y,z) to (x,y) */
   123  func (E *ECP2) Affine() {
   124  	if E.Is_infinity() {return}
   125  	one:=NewFP2int(1)
   126  	if E.z.Equals(one) {E.x.reduce(); E.y.reduce(); return}
   127  	E.z.inverse()
   128  
   129  	E.x.mul(E.z); E.x.reduce()
   130  	E.y.mul(E.z); E.y.reduce()
   131  	E.z.copy(one)
   132  }
   133  
   134  /* extract affine x as FP2 */
   135  func (E *ECP2) GetX() *FP2 {
   136  	W:=NewECP2(); W.Copy(E)
   137  	W.Affine()
   138  	return W.x
   139  }
   140  /* extract affine y as FP2 */
   141  func (E *ECP2) GetY() *FP2 {
   142  	W:=NewECP2(); W.Copy(E)
   143  	W.Affine()
   144  	return W.y;
   145  }
   146  /* extract projective x */
   147  func (E *ECP2) getx() *FP2 {
   148  	return E.x
   149  }
   150  /* extract projective y */
   151  func (E *ECP2) gety() *FP2 {
   152  	return E.y
   153  }
   154  /* extract projective z */
   155  func (E *ECP2) getz() *FP2 {
   156  	return E.z
   157  }
   158  
   159  /* convert to byte array */
   160  func (E *ECP2) ToBytes(b []byte) {
   161  	var t [int(MODBYTES)]byte
   162  	MB:=int(MODBYTES)
   163  
   164  	W:=NewECP2(); W.Copy(E);
   165  	W.Affine()
   166  
   167  	W.x.GetA().ToBytes(t[:])
   168  	for i:=0;i<MB;i++ { b[i]=t[i]}
   169  	W.x.GetB().ToBytes(t[:])
   170  	for i:=0;i<MB;i++ { b[i+MB]=t[i]}
   171  
   172  	W.y.GetA().ToBytes(t[:])
   173  	for i:=0;i<MB;i++ {b[i+2*MB]=t[i]}
   174  	W.y.GetB().ToBytes(t[:])
   175  	for i:=0;i<MB;i++ {b[i+3*MB]=t[i]}
   176  }
   177  
   178  /* convert from byte array to point */
   179  func ECP2_fromBytes(b []byte) *ECP2 {
   180  	var t [int(MODBYTES)]byte
   181  	MB:=int(MODBYTES)
   182  
   183  	for i:=0;i<MB;i++ {t[i]=b[i]}
   184  	ra:=FromBytes(t[:])
   185  	for i:=0;i<MB;i++ {t[i]=b[i+MB]}
   186  	rb:=FromBytes(t[:])
   187  	rx:=NewFP2bigs(ra,rb)
   188  
   189  	for i:=0;i<MB;i++ {t[i]=b[i+2*MB]}
   190  	ra=FromBytes(t[:])
   191  	for i:=0;i<MB;i++ {t[i]=b[i+3*MB]}
   192  	rb=FromBytes(t[:])
   193  	ry:=NewFP2bigs(ra,rb)
   194  
   195  	return NewECP2fp2s(rx,ry)
   196  }
   197  
   198  /* convert this to hex string */
   199  func (E *ECP2) toString() string {
   200  	W:=NewECP2(); W.Copy(E);
   201  	W.Affine()
   202  	if W.Is_infinity() {return "infinity"}
   203  	return "("+W.x.toString()+","+W.y.toString()+")"
   204  }
   205  
   206  /* Calculate RHS of twisted curve equation x^3+B/i */
   207  func RHS2(x *FP2) *FP2 {
   208  	x.norm()
   209  	r:=NewFP2copy(x)
   210  	r.sqr()
   211  	b:=NewFP2big(NewBIGints(CURVE_B))
   212  
   213  	if SEXTIC_TWIST == D_TYPE {
   214  		b.div_ip()
   215  	}
   216  	if SEXTIC_TWIST == M_TYPE {
   217  		b.norm()
   218  		b.mul_ip()
   219  		b.norm()
   220  	}	
   221  	r.mul(x)
   222  	r.add(b)
   223  
   224  	r.reduce()
   225  	return r
   226  }
   227  
   228  /* construct this from (x,y) - but set to O if not on curve */
   229  func NewECP2fp2s(ix *FP2,iy *FP2) *ECP2 {
   230  	E:=new(ECP2)
   231  	E.x=NewFP2copy(ix)
   232  	E.y=NewFP2copy(iy)
   233  	E.z=NewFP2int(1)
   234  	rhs:=RHS2(E.x)
   235  	y2:=NewFP2copy(E.y)
   236  	y2.sqr()
   237  	if !y2.Equals(rhs) {
   238  		E.inf()
   239  	} 
   240  	return E
   241  }
   242  
   243  /* construct this from x - but set to O if not on curve */
   244  func NewECP2fp2(ix *FP2) *ECP2 {	
   245  	E:=new(ECP2)
   246  	E.x=NewFP2copy(ix)
   247  	E.y=NewFP2int(1)
   248  	E.z=NewFP2int(1)
   249  	rhs:=RHS2(E.x)
   250  	if rhs.sqrt() {
   251  			E.y.copy(rhs)
   252  			//E.INF=false;
   253  	} else {E.inf()}
   254  	return E
   255  }
   256  
   257  /* this+=this */
   258  func (E *ECP2) dbl() int {
   259  //	if E.INF {return -1}
   260  
   261  	iy:=NewFP2copy(E.y)
   262  	if SEXTIC_TWIST == D_TYPE {
   263  		iy.mul_ip(); iy.norm()
   264  	}
   265  
   266  	t0:=NewFP2copy(E.y)                  //***** Change 
   267  	t0.sqr();  
   268  	if SEXTIC_TWIST == D_TYPE {	
   269  		t0.mul_ip()   
   270  	}
   271  	t1:=NewFP2copy(iy)  
   272  	t1.mul(E.z)
   273  	t2:=NewFP2copy(E.z)
   274  	t2.sqr()			// z^2
   275  
   276  	E.z.copy(t0)			// y^2
   277  	E.z.add(t0); E.z.norm()		// 2y^2	
   278  	E.z.add(E.z)
   279  	E.z.add(E.z)			// 8y^2
   280  	E.z.norm()  
   281  
   282  	t2.imul(3*CURVE_B_I)		// 3bz^2
   283  	if SEXTIC_TWIST == M_TYPE {
   284  		t2.mul_ip()
   285  		t2.norm()
   286  	}
   287  	x3:=NewFP2copy(t2)
   288  	x3.mul(E.z) 
   289  
   290  	y3:=NewFP2copy(t0)   
   291  
   292  	y3.add(t2); y3.norm()
   293  	E.z.mul(t1)
   294  	t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm()  
   295  	t0.sub(t2); t0.norm()                           //y^2-9bz^2
   296  	y3.mul(t0); y3.add(x3)                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
   297  	t1.copy(E.x); t1.mul(iy)						//
   298  	E.x.copy(t0); E.x.norm(); E.x.mul(t1); E.x.add(E.x)       //(y^2-9bz^2)xy2
   299  
   300  	E.x.norm()
   301  	E.y.copy(y3); E.y.norm()
   302  
   303  	return 1
   304  }
   305  
   306  /* this+=Q - return 0 for add, 1 for double, -1 for O */
   307  func (E *ECP2) Add(Q *ECP2) int {
   308  /*	if E.INF {
   309  		E.Copy(Q)
   310  		return -1
   311  	}
   312  	if Q.INF {return -1}
   313  */
   314  	b:=3*CURVE_B_I
   315  	t0:=NewFP2copy(E.x)
   316  	t0.mul(Q.x)         // x.Q.x
   317  	t1:=NewFP2copy(E.y)
   318  	t1.mul(Q.y)		 // y.Q.y
   319  
   320  	t2:=NewFP2copy(E.z)
   321  	t2.mul(Q.z)
   322  	t3:=NewFP2copy(E.x)
   323  	t3.add(E.y); t3.norm()          //t3=X1+Y1
   324  	t4:=NewFP2copy(Q.x)            
   325  	t4.add(Q.y); t4.norm()			//t4=X2+Y2
   326  	t3.mul(t4)						//t3=(X1+Y1)(X2+Y2)
   327  	t4.copy(t0); t4.add(t1)		//t4=X1.X2+Y1.Y2
   328  
   329  	t3.sub(t4); t3.norm(); 
   330  	if SEXTIC_TWIST == D_TYPE {
   331  		t3.mul_ip();  t3.norm()         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
   332  	}
   333  	t4.copy(E.y);                    
   334  	t4.add(E.z); t4.norm()			//t4=Y1+Z1
   335  	x3:=NewFP2copy(Q.y)
   336  	x3.add(Q.z); x3.norm()			//x3=Y2+Z2
   337  
   338  	t4.mul(x3)						//t4=(Y1+Z1)(Y2+Z2)
   339  	x3.copy(t1)					//
   340  	x3.add(t2)						//X3=Y1.Y2+Z1.Z2
   341  	
   342  	t4.sub(x3); t4.norm();
   343  	if SEXTIC_TWIST == D_TYPE {	
   344  		t4.mul_ip(); t4.norm()          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
   345  	}
   346  	x3.copy(E.x); x3.add(E.z); x3.norm()	// x3=X1+Z1
   347  	y3:=NewFP2copy(Q.x)				
   348  	y3.add(Q.z); y3.norm()				// y3=X2+Z2
   349  	x3.mul(y3)							// x3=(X1+Z1)(X2+Z2)
   350  	y3.copy(t0)
   351  	y3.add(t2)							// y3=X1.X2+Z1+Z2
   352  	y3.rsub(x3); y3.norm()				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
   353  
   354  	if SEXTIC_TWIST == D_TYPE {
   355  		t0.mul_ip(); t0.norm() // x.Q.x
   356  		t1.mul_ip(); t1.norm() // y.Q.y
   357  	}
   358  	x3.copy(t0); x3.add(t0) 
   359  	t0.add(x3); t0.norm()
   360  	t2.imul(b) 	
   361  	if SEXTIC_TWIST == M_TYPE {
   362  		t2.mul_ip(); t2.norm()
   363  	}
   364  	z3:=NewFP2copy(t1); z3.add(t2); z3.norm()
   365  	t1.sub(t2); t1.norm()
   366  	y3.imul(b) 
   367  	if SEXTIC_TWIST == M_TYPE {
   368  		y3.mul_ip()
   369  		y3.norm()
   370  	}
   371  	x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2)
   372  	y3.mul(t0); t1.mul(z3); y3.add(t1)
   373  	t0.mul(t3); z3.mul(t4); z3.add(t0)
   374  
   375  	E.x.copy(x3); E.x.norm() 
   376  	E.y.copy(y3); E.y.norm()
   377  	E.z.copy(z3); E.z.norm()
   378  
   379  	return 0
   380  }
   381  
   382  /* set this-=Q */
   383  func (E *ECP2) Sub(Q *ECP2) int {
   384  	NQ:=NewECP2(); NQ.Copy(Q)
   385  	NQ.neg()
   386  	D:=E.Add(NQ)
   387  	//Q.neg()
   388  	return D
   389  }
   390  /* set this*=q, where q is Modulus, using Frobenius */
   391  func (E *ECP2) frob(X *FP2) {
   392  //	if E.INF {return}
   393  	X2:=NewFP2copy(X)
   394  	X2.sqr()
   395  	E.x.conj()
   396  	E.y.conj()
   397  	E.z.conj()
   398  	E.z.reduce();
   399  	E.x.mul(X2)
   400  	E.y.mul(X2)
   401  	E.y.mul(X)
   402  }
   403  
   404  /* P*=e */
   405  func (E *ECP2) mul(e *BIG) *ECP2 {
   406  /* fixed size windows */
   407  	mt:=NewBIG()
   408  	t:=NewBIG()
   409  	P:=NewECP2()
   410  	Q:=NewECP2()
   411  	C:=NewECP2()
   412  
   413  	if E.Is_infinity() {return NewECP2()}
   414  
   415  	var W []*ECP2
   416  	var w [1+(NLEN*int(BASEBITS)+3)/4]int8
   417  
   418  	//E.Affine()
   419  
   420  /* precompute table */
   421  	Q.Copy(E)
   422  	Q.dbl()
   423  		
   424  	W=append(W,NewECP2())
   425  	W[0].Copy(E);
   426  
   427  	for i:=1;i<8;i++ {
   428  		W=append(W,NewECP2())
   429  		W[i].Copy(W[i-1])
   430  		W[i].Add(Q)
   431  	}
   432  
   433  /* make exponent odd - add 2P if even, P if odd */
   434  	t.copy(e)
   435  	s:=int(t.parity())
   436  	t.inc(1); t.norm(); ns:=int(t.parity()); mt.copy(t); mt.inc(1); mt.norm()
   437  	t.cmove(mt,s)
   438  	Q.cmove(E,ns)
   439  	C.Copy(Q)
   440  
   441  	nb:=1+(t.nbits()+3)/4
   442  /* convert exponent to signed 4-bit window */
   443  	for i:=0;i<nb;i++ {
   444  		w[i]=int8(t.lastbits(5)-16)
   445  		t.dec(int(w[i])); t.norm()
   446  		t.fshr(4)	
   447  	}
   448  	w[nb]=int8(t.lastbits(5))
   449  		
   450  	P.Copy(W[(w[nb]-1)/2])
   451  	for i:=nb-1;i>=0;i-- {
   452  		Q.selector(W,int32(w[i]))
   453  		P.dbl()
   454  		P.dbl()
   455  		P.dbl()
   456  		P.dbl()
   457  		P.Add(Q)
   458  	}
   459  	P.Sub(C)
   460  	P.Affine()
   461  	return P
   462  }
   463  
   464  /* Public version */
   465  func (E *ECP2) Mul(e *BIG) *ECP2 {
   466  	return E.mul(e)
   467  }
   468  
   469  /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
   470  // Bos & Costello https://eprint.iacr.org/2013/458.pdf
   471  // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
   472  // Side channel attack secure 
   473  func mul4(Q []*ECP2,u []*BIG) *ECP2 {
   474  	W:=NewECP2()
   475  	P:=NewECP2()
   476  	var T [] *ECP2
   477  	mt:=NewBIG()
   478  	var t [] *BIG
   479  
   480  	var w [NLEN*int(BASEBITS)+1]int8	
   481  	var s [NLEN*int(BASEBITS)+1]int8	
   482  
   483  	for i:=0;i<4;i++ {
   484  		t=append(t,NewBIGcopy(u[i]));
   485  		//Q[i].Affine();
   486  	}
   487  
   488  	T=append(T,NewECP2()); T[0].Copy(Q[0])	// Q[0]
   489  	T=append(T,NewECP2()); T[1].Copy(T[0]); T[1].Add(Q[1])	// Q[0]+Q[1]
   490  	T=append(T,NewECP2()); T[2].Copy(T[0]); T[2].Add(Q[2])	// Q[0]+Q[2]
   491  	T=append(T,NewECP2()); T[3].Copy(T[1]); T[3].Add(Q[2])	// Q[0]+Q[1]+Q[2]
   492  	T=append(T,NewECP2()); T[4].Copy(T[0]); T[4].Add(Q[3])	// Q[0]+Q[3]
   493  	T=append(T,NewECP2()); T[5].Copy(T[1]); T[5].Add(Q[3])	// Q[0]+Q[1]+Q[3]
   494  	T=append(T,NewECP2()); T[6].Copy(T[2]); T[6].Add(Q[3])	// Q[0]+Q[2]+Q[3]
   495  	T=append(T,NewECP2()); T[7].Copy(T[3]); T[7].Add(Q[3])	// Q[0]+Q[1]+Q[2]+Q[3]
   496  	
   497  // Make it odd
   498  	pb:=1-t[0].parity()
   499  	t[0].inc(pb)
   500  //	t[0].norm();
   501  
   502  // Number of bits
   503  	mt.zero()
   504  	for i:=0;i<4;i++ {
   505  		t[i].norm()
   506  		mt.or(t[i])
   507  	}
   508  
   509  	nb:=1+mt.nbits();
   510  
   511  // Sign pivot 
   512  	s[nb-1]=1
   513  	for i:=0;i<nb-1;i++ {
   514  		t[0].fshr(1)
   515  		s[i]=2*int8(t[0].parity())-1
   516  	}
   517  
   518  // Recoded exponent
   519  	for i:=0; i<nb; i++ {
   520  		w[i]=0
   521  		k:=1
   522  		for j:=1; j<4; j++ {
   523  			bt:=s[i]*int8(t[j].parity())
   524  			t[j].fshr(1)
   525  			t[j].dec(int(bt)>>1)
   526  			t[j].norm()
   527  			w[i]+=bt*int8(k)
   528  			k*=2
   529  		}
   530  	}	
   531  	
   532  // Main loop
   533  	P.selector(T,int32(2*w[nb-1]+1))  
   534  	for i:=nb-2;i>=0;i-- {
   535  		P.dbl()
   536  		W.selector(T,int32(2*w[i]+s[i]))
   537  		P.Add(W)
   538  	}
   539  
   540  // apply correction
   541  	W.Copy(P)   
   542  	W.Sub(Q[0])
   543  	P.cmove(W,pb)
   544  
   545  	P.Affine()
   546  	return P
   547  }
   548  
   549  /*
   550  func mul4(Q []*ECP2,u []*BIG) *ECP2 {
   551  	var a [4]int8
   552  	T:=NewECP2()
   553  	C:=NewECP2()
   554  	P:=NewECP2()
   555  
   556  	var W [] *ECP2
   557  
   558  	mt:=NewBIG()
   559  	var t []*BIG
   560  
   561  	var w [NLEN*int(BASEBITS)+1]int8	
   562  
   563  	for i:=0;i<4;i++ {
   564  		t=append(t,NewBIGcopy(u[i]));
   565  		Q[i].Affine();
   566  	}
   567  
   568  // precompute table 
   569  
   570  	W=append(W,NewECP2()); W[0].Copy(Q[0]); W[0].Sub(Q[1])
   571  	W=append(W,NewECP2()); W[1].Copy(W[0])
   572  	W=append(W,NewECP2()); W[2].Copy(W[0])
   573  	W=append(W,NewECP2()); W[3].Copy(W[0])
   574  	W=append(W,NewECP2()); W[4].Copy(Q[0]); W[4].Add(Q[1])
   575  	W=append(W,NewECP2()); W[5].Copy(W[4])
   576  	W=append(W,NewECP2()); W[6].Copy(W[4])
   577  	W=append(W,NewECP2()); W[7].Copy(W[4])
   578  
   579  	T.Copy(Q[2]); T.Sub(Q[3])
   580  	W[1].Sub(T)
   581  	W[2].Add(T)
   582  	W[5].Sub(T)
   583  	W[6].Add(T)
   584  	T.Copy(Q[2]); T.Add(Q[3])
   585  	W[0].Sub(T)
   586  	W[3].Add(T)
   587  	W[4].Sub(T)
   588  	W[7].Add(T)
   589  
   590  // if multiplier is even add 1 to multiplier, and add P to correction 
   591  	mt.zero(); C.inf()
   592  	for i:=0;i<4;i++ {
   593  		if t[i].parity()==0 {
   594  			t[i].inc(1); t[i].norm()
   595  			C.Add(Q[i])
   596  		}
   597  		mt.add(t[i]); mt.norm()
   598  	}
   599  
   600  	nb:=1+mt.nbits();
   601  
   602  // convert exponent to signed 1-bit window 
   603  	for j:=0;j<nb;j++ {
   604  		for i:=0;i<4;i++ {
   605  			a[i]=int8(t[i].lastbits(2)-2)
   606  			t[i].dec(int(a[i])); t[i].norm()
   607  			t[i].fshr(1)
   608  		}
   609  		w[j]=(8*a[0]+4*a[1]+2*a[2]+a[3])
   610  	}
   611  	w[nb]=int8(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2))
   612  
   613  	P.Copy(W[(w[nb]-1)/2])  
   614  	for i:=nb-1;i>=0;i-- {
   615  		T.selector(W,int32(w[i]))
   616  		P.dbl()
   617  		P.Add(T)
   618  	}
   619  	P.Sub(C) // apply correction 
   620  
   621  	P.Affine()
   622  	return P
   623  }
   624  */
   625  
   626  /* needed for SOK */
   627  func ECP2_mapit(h []byte) *ECP2 {
   628  	q:=NewBIGints(Modulus)
   629  	x:=FromBytes(h[:])
   630  	one:=NewBIGint(1)
   631  	var X *FP2
   632  	var Q,T,K,xQ,x2Q *ECP2
   633  	x.Mod(q)
   634  	for true {
   635  		X=NewFP2bigs(one,x)
   636  		Q=NewECP2fp2(X)
   637  		if !Q.Is_infinity() {break}
   638  		x.inc(1); x.norm()
   639  	}
   640  /* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
   641  	Fra:=NewBIGints(Fra)
   642  	Frb:=NewBIGints(Frb)
   643  	X=NewFP2bigs(Fra,Frb)
   644  	if SEXTIC_TWIST == M_TYPE {
   645  		X.inverse()
   646  		X.norm()
   647  	}
   648  
   649  	x=NewBIGints(CURVE_Bnx)
   650  
   651  	if CURVE_PAIRING_TYPE==BN {
   652  		T=NewECP2(); T.Copy(Q)
   653  		T=T.mul(x); 
   654  		if SIGN_OF_X==NEGATIVEX {
   655  			T.neg()
   656  		}
   657  		
   658  		K=NewECP2(); K.Copy(T)
   659  		K.dbl(); K.Add(T); //K.Affine()
   660  
   661  		K.frob(X)
   662  		Q.frob(X); Q.frob(X); Q.frob(X)
   663  		Q.Add(T); Q.Add(K)
   664  		T.frob(X); T.frob(X)
   665  		Q.Add(T)
   666  	}
   667  	if CURVE_PAIRING_TYPE==BLS {
   668  //		xQ=NewECP2()
   669  //		x2Q=NewECP2()
   670  
   671  		xQ=Q.mul(x)
   672  		x2Q=xQ.mul(x)
   673  
   674  		if SIGN_OF_X==NEGATIVEX {
   675  			xQ.neg()
   676  		}
   677  
   678  		x2Q.Sub(xQ)
   679  		x2Q.Sub(Q)
   680  
   681  		xQ.Sub(Q)
   682  		xQ.frob(X)
   683  
   684  		Q.dbl()
   685  		Q.frob(X)
   686  		Q.frob(X)
   687  
   688  		Q.Add(x2Q)
   689  		Q.Add(xQ)
   690  	}
   691  	Q.Affine()
   692  	return Q
   693  }
   694  
   695  func ECP2_generator() *ECP2 {
   696  	var G *ECP2
   697  	G=NewECP2fp2s(NewFP2bigs(NewBIGints(CURVE_Pxa),NewBIGints(CURVE_Pxb)),NewFP2bigs(NewBIGints(CURVE_Pya),NewBIGints(CURVE_Pyb)))
   698  	return G
   699  }