github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric-amcl/amcl/FP256BN/ECP.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  package FP256BN
    21  
    22  
    23  const WEIERSTRASS int=0
    24  const EDWARDS int=1
    25  const MONTGOMERY int=2
    26  const NOT int=0
    27  const BN int=1
    28  const BLS int=2
    29  const D_TYPE int=0
    30  const M_TYPE int=1
    31  const POSITIVEX int=0
    32  const NEGATIVEX int=1
    33  
    34  const CURVETYPE int=WEIERSTRASS
    35  const CURVE_PAIRING_TYPE int=BN
    36  const SEXTIC_TWIST int=M_TYPE
    37  const SIGN_OF_X int=NEGATIVEX
    38  
    39  const HASH_TYPE int=32
    40  const AESKEY int=16
    41  
    42  /* Elliptic Curve Point Structure */
    43  
    44  type ECP struct {
    45  	x *FP
    46  	y *FP
    47  	z *FP
    48  //	INF bool
    49  }
    50  
    51  /* Constructors */
    52  func NewECP() *ECP {
    53  	E:=new(ECP)
    54  	E.x=NewFPint(0)
    55  	E.y=NewFPint(1)
    56  	if CURVETYPE==EDWARDS {
    57  		E.z=NewFPint(1)
    58  	} else {
    59  		E.z=NewFPint(0)
    60  	}
    61  //	E.INF=true
    62  	return E
    63  }
    64  
    65  /* set (x,y) from two BIGs */
    66  func NewECPbigs(ix *BIG,iy *BIG) *ECP {
    67  	E:=new(ECP)
    68  	E.x=NewFPbig(ix)
    69  	E.y=NewFPbig(iy)
    70  	E.z=NewFPint(1)
    71  	rhs:=RHS(E.x)
    72  
    73  	if CURVETYPE==MONTGOMERY {
    74  		if rhs.jacobi()!=1 {
    75  			E.inf()
    76  		}
    77  	} else {
    78  		y2:=NewFPcopy(E.y)
    79  		y2.sqr()
    80  		if !y2.Equals(rhs) {
    81  			E.inf()
    82  		}
    83  	}
    84  	return E
    85  }
    86  
    87  /* set (x,y) from BIG and a bit */
    88  func NewECPbigint(ix *BIG,s int) *ECP {
    89  	E:=new(ECP)
    90  	E.x=NewFPbig(ix)
    91  	E.y=NewFPint(0)
    92  	rhs:=RHS(E.x)
    93  	E.z=NewFPint(1)
    94  	if rhs.jacobi()==1 {
    95  		ny:=rhs.sqrt()
    96  		if ny.redc().parity()!=s {ny.neg()}
    97  		E.y.copy(ny)
    98  		//E.INF=false
    99  	} else {E.inf()}
   100  	return E;
   101  }
   102  
   103  /* set from x - calculate y from curve equation */
   104  func NewECPbig(ix *BIG) *ECP {
   105  	E:=new(ECP)	
   106  	E.x=NewFPbig(ix)
   107  	E.y=NewFPint(0)
   108  	rhs:=RHS(E.x)
   109  	E.z=NewFPint(1)
   110  	if rhs.jacobi()==1 {
   111  		if CURVETYPE!=MONTGOMERY {E.y.copy(rhs.sqrt())}
   112  		//E.INF=false
   113  	} else {E.inf()}
   114  	return E
   115  }
   116  
   117  /* test for O point-at-infinity */
   118  func (E *ECP) Is_infinity() bool {
   119  //	if E.INF {return true}
   120  	E.x.reduce(); E.z.reduce()
   121  	if CURVETYPE==EDWARDS {
   122  		E.y.reduce();
   123  		return (E.x.iszilch() && E.y.Equals(E.z))
   124  	} 
   125  	if CURVETYPE==WEIERSTRASS {
   126  		E.y.reduce();
   127  		return (E.x.iszilch() && E.z.iszilch())
   128  	}
   129  	if CURVETYPE==MONTGOMERY {
   130  		return E.z.iszilch()
   131  	}
   132  	return true
   133  }
   134  
   135  /* Conditional swap of P and Q dependant on d */
   136  func (E *ECP) cswap(Q *ECP,d int) {
   137  	E.x.cswap(Q.x,d)
   138  	if CURVETYPE!=MONTGOMERY {E.y.cswap(Q.y,d)}
   139  	E.z.cswap(Q.z,d)
   140  /*
   141  	bd:=true
   142  	if d==0 {bd=false}
   143  	bd=bd&&(E.INF!=Q.INF)
   144  	E.INF=(bd!=E.INF)
   145  	Q.INF=(bd!=Q.INF)
   146  */
   147  }
   148  
   149  /* Conditional move of Q to P dependant on d */
   150  func (E *ECP) cmove(Q *ECP,d int) {
   151  	E.x.cmove(Q.x,d)
   152  	if CURVETYPE!=MONTGOMERY {E.y.cmove(Q.y,d)}
   153  	E.z.cmove(Q.z,d);
   154  /*
   155  	bd:=true
   156  	if d==0 {bd=false}
   157  	E.INF=(E.INF!=((E.INF!=Q.INF)&&bd))
   158  */
   159  }
   160  
   161  /* return 1 if b==c, no branching */
   162  func teq(b int32,c int32) int {
   163  	x:=b^c
   164  	x-=1  // if x=0, x now -1
   165  	return int((x>>31)&1)
   166  }
   167  
   168  /* this=P */
   169  func (E *ECP) Copy(P *ECP) {
   170  	E.x.copy(P.x);
   171  	if CURVETYPE!=MONTGOMERY {E.y.copy(P.y)}
   172  	E.z.copy(P.z);
   173  //	E.INF=P.INF;
   174  }
   175  
   176  /* this=-this */
   177  func (E *ECP) neg() {
   178  //	if E.Is_infinity() {return}
   179  	if CURVETYPE==WEIERSTRASS {
   180  		E.y.neg(); E.y.norm()
   181  	}
   182  	if CURVETYPE==EDWARDS {
   183  		E.x.neg(); E.x.norm()
   184  	}
   185  	return;
   186  }
   187  
   188  /* Constant time select from pre-computed table */
   189  func (E *ECP) selector(W []*ECP,b int32) {
   190  	MP:=NewECP()
   191  	m:=b>>31;
   192  	babs:=(b^m)-m;
   193  
   194  	babs=(babs-1)/2
   195  
   196  	E.cmove(W[0],teq(babs,0))  // conditional move
   197  	E.cmove(W[1],teq(babs,1))
   198  	E.cmove(W[2],teq(babs,2))
   199  	E.cmove(W[3],teq(babs,3))
   200  	E.cmove(W[4],teq(babs,4))
   201  	E.cmove(W[5],teq(babs,5))
   202  	E.cmove(W[6],teq(babs,6))
   203  	E.cmove(W[7],teq(babs,7))
   204   
   205  	MP.Copy(E);
   206  	MP.neg()
   207  	E.cmove(MP,int(m&1));
   208  }
   209  
   210  /* set this=O */
   211  func (E *ECP) inf() {
   212  //	E.INF=true;
   213  	E.x.zero()
   214  	if CURVETYPE!=MONTGOMERY {E.y.one()}
   215  	if CURVETYPE!=EDWARDS {
   216  		E.z.zero()
   217  	} else {E.z.one()}
   218  }
   219  
   220  /* Test P == Q */
   221  func( E *ECP) Equals(Q *ECP) bool {
   222  //	if E.Is_infinity() && Q.Is_infinity() {return true}
   223  //	if E.Is_infinity() || Q.Is_infinity() {return false}
   224  
   225  	a:=NewFPint(0)
   226  	b:=NewFPint(0)
   227  	a.copy(E.x); a.mul(Q.z); a.reduce()
   228  	b.copy(Q.x); b.mul(E.z); b.reduce()
   229  	if !a.Equals(b) {return false}
   230  	if CURVETYPE!=MONTGOMERY {
   231  		a.copy(E.y); a.mul(Q.z); a.reduce()
   232  		b.copy(Q.y); b.mul(E.z); b.reduce()
   233  		if !a.Equals(b) {return false}
   234  	}
   235  
   236  	return true
   237  }
   238  
   239  /* Calculate RHS of curve equation */
   240  func RHS(x *FP) *FP {
   241  	x.norm()
   242  	r:=NewFPcopy(x)
   243  	r.sqr();
   244  
   245  	if CURVETYPE==WEIERSTRASS { // x^3+Ax+B
   246  		b:=NewFPbig(NewBIGints(CURVE_B))
   247  		r.mul(x);
   248  		if CURVE_A==-3 {
   249  			cx:=NewFPcopy(x)
   250  			cx.imul(3)
   251  			cx.neg(); cx.norm()
   252  			r.add(cx)
   253  		}
   254  		r.add(b)
   255  	}
   256  	if CURVETYPE==EDWARDS { // (Ax^2-1)/(Bx^2-1) 
   257  		b:=NewFPbig(NewBIGints(CURVE_B))
   258  
   259  		one:=NewFPint(1)
   260  		b.mul(r)
   261  		b.sub(one)
   262  		b.norm()
   263  		if CURVE_A==-1 {r.neg()}
   264  		r.sub(one); r.norm()
   265  		b.inverse()
   266  		r.mul(b)
   267  	}
   268  	if CURVETYPE==MONTGOMERY { // x^3+Ax^2+x
   269  		x3:=NewFPint(0)
   270  		x3.copy(r)
   271  		x3.mul(x)
   272  		r.imul(CURVE_A)
   273  		r.add(x3)
   274  		r.add(x)
   275  	}
   276  	r.reduce()
   277  	return r
   278  }
   279  
   280  /* set to affine - from (x,y,z) to (x,y) */
   281  func (E *ECP) Affine() {
   282  	if E.Is_infinity() {return}
   283  	one:=NewFPint(1)
   284  	if E.z.Equals(one) {return}
   285  	E.z.inverse()
   286  	E.x.mul(E.z); E.x.reduce()
   287  
   288  	if CURVETYPE!=MONTGOMERY {
   289  		E.y.mul(E.z); E.y.reduce()
   290  	}
   291  	E.z.copy(one)
   292  }
   293  
   294  /* extract x as a BIG */
   295  func (E *ECP) GetX() *BIG {
   296  	W:=NewECP(); W.Copy(E)
   297  	W.Affine()
   298  	return W.x.redc()
   299  }
   300  /* extract y as a BIG */
   301  func (E *ECP) GetY() *BIG {
   302  	W:=NewECP(); W.Copy(E)
   303  	W.Affine()
   304  	return W.y.redc()
   305  }
   306  
   307  /* get sign of Y */
   308  func (E *ECP) GetS() int {
   309  	//E.Affine()
   310  	y:=E.GetY()
   311  	return y.parity()
   312  }
   313  /* extract x as an FP */
   314  func (E *ECP) getx() *FP {
   315  	return E.x;
   316  }
   317  /* extract y as an FP */
   318  func (E *ECP) gety() *FP {
   319  	return E.y
   320  }
   321  /* extract z as an FP */
   322  func (E *ECP) getz() *FP {
   323  	return E.z
   324  }
   325  
   326  /* convert to byte array */
   327  func (E *ECP) ToBytes(b []byte,compress bool) {
   328  	var t [int(MODBYTES)]byte
   329  	MB:=int(MODBYTES)
   330  	W:=NewECP(); W.Copy(E);
   331  	W.Affine()
   332  	W.x.redc().ToBytes(t[:])
   333  	for i:=0;i<MB;i++ {b[i+1]=t[i]}
   334  
   335  	if CURVETYPE==MONTGOMERY {
   336  		b[0]=0x06
   337  		return;
   338  	} 
   339  
   340  	if compress {
   341  		b[0]=0x02
   342  		if W.y.redc().parity()==1 {b[0]=0x03}
   343  		return;
   344  	}
   345  	
   346  	b[0]=0x04
   347  
   348  	W.y.redc().ToBytes(t[:])
   349  	for i:=0;i<MB;i++ {b[i+MB+1]=t[i]}
   350  }
   351  
   352  /* convert from byte array to point */
   353  func ECP_fromBytes(b []byte) *ECP {
   354  	var t [int(MODBYTES)]byte
   355  	MB:=int(MODBYTES)
   356  	p:=NewBIGints(Modulus)
   357  
   358  	for i:=0;i<MB;i++ {t[i]=b[i+1]}
   359  	px:=FromBytes(t[:])
   360  	if comp(px,p)>=0 {return NewECP()}
   361  
   362  	if CURVETYPE==MONTGOMERY {
   363  		return NewECPbig(px)
   364  	}
   365  
   366  	if b[0]==0x04 {
   367  		for i:=0;i<MB;i++ {t[i]=b[i+MB+1]}
   368  		py:=FromBytes(t[:])
   369  		if comp(py,p)>=0 {return NewECP()}
   370  		return NewECPbigs(px,py)
   371  	}
   372  
   373  	if b[0]==0x02 || b[0]==0x03 {
   374  		return NewECPbigint(px,int(b[0]&1))
   375  	}
   376  
   377  	return NewECP()
   378  }
   379  
   380  /* convert to hex string */
   381  func (E *ECP) toString() string {
   382  	W:=NewECP(); W.Copy(E);
   383  	W.Affine()
   384  	if W.Is_infinity() {return "infinity"}
   385  	if CURVETYPE==MONTGOMERY {
   386  		return "("+W.x.redc().toString()+")"
   387  	} else {return "("+W.x.redc().toString()+","+W.y.redc().toString()+")"}
   388  }
   389  
   390  /* this*=2 */
   391  func (E *ECP) dbl() {
   392  
   393  //	if E.INF {return}
   394  	if CURVETYPE==WEIERSTRASS {
   395  		if CURVE_A==0 {
   396  			t0:=NewFPcopy(E.y)                      /*** Change ***/    // Edits made
   397  			t0.sqr()
   398  			t1:=NewFPcopy(E.y)
   399  			t1.mul(E.z)
   400  			t2:=NewFPcopy(E.z)
   401  			t2.sqr()
   402  
   403  			E.z.copy(t0)
   404  			E.z.add(t0); E.z.norm(); 
   405  			E.z.add(E.z); E.z.add(E.z); E.z.norm()
   406  			t2.imul(3*CURVE_B_I)
   407  
   408  			x3:=NewFPcopy(t2)
   409  			x3.mul(E.z)
   410  
   411  			y3:=NewFPcopy(t0)
   412  			y3.add(t2); y3.norm()
   413  			E.z.mul(t1)
   414  			t1.copy(t2); t1.add(t2); t2.add(t1)
   415  			t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3)
   416  			t1.copy(E.x); t1.mul(E.y) 
   417  			E.x.copy(t0); E.x.norm(); E.x.mul(t1); E.x.add(E.x)
   418  			E.x.norm(); 
   419  			E.y.copy(y3); E.y.norm();
   420  		} else {
   421  			t0:=NewFPcopy(E.x)
   422  			t1:=NewFPcopy(E.y)
   423  			t2:=NewFPcopy(E.z)
   424  			t3:=NewFPcopy(E.x)
   425  			z3:=NewFPcopy(E.z)
   426  			y3:=NewFPint(0)
   427  			x3:=NewFPint(0)
   428  			b:=NewFPint(0)
   429  
   430  			if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))}
   431  
   432  			t0.sqr()  //1    x^2
   433  			t1.sqr()  //2    y^2
   434  			t2.sqr()  //3
   435  
   436  			t3.mul(E.y) //4
   437  			t3.add(t3); t3.norm() //5
   438  			z3.mul(E.x);   //6
   439  			z3.add(z3);  z3.norm()//7
   440  			y3.copy(t2) 
   441  				
   442  			if CURVE_B_I==0 {
   443  				y3.mul(b)
   444  			} else {
   445  				y3.imul(CURVE_B_I)
   446  			}
   447  				
   448  			y3.sub(z3) //y3.norm(); //9  ***
   449  			x3.copy(y3); x3.add(y3); x3.norm() //10
   450  
   451  			y3.add(x3) //y3.norm();//11
   452  			x3.copy(t1); x3.sub(y3); x3.norm() //12
   453  			y3.add(t1); y3.norm() //13
   454  			y3.mul(x3)  //14
   455  			x3.mul(t3)  //15
   456  			t3.copy(t2); t3.add(t2)  //t3.norm(); //16
   457  			t2.add(t3)  //t2.norm(); //17
   458  
   459  			if CURVE_B_I==0 {
   460  				z3.mul(b)
   461  			} else {
   462  				z3.imul(CURVE_B_I)
   463  			}
   464  
   465  			z3.sub(t2) //z3.norm();//19
   466  			z3.sub(t0); z3.norm()//20  ***
   467  			t3.copy(z3); t3.add(z3) //t3.norm();//21
   468  
   469  			z3.add(t3); z3.norm()  //22
   470  			t3.copy(t0); t3.add(t0)  //t3.norm(); //23
   471  			t0.add(t3)  //t0.norm();//24
   472  			t0.sub(t2); t0.norm() //25
   473  
   474  			t0.mul(z3) //26
   475  			y3.add(t0) //y3.norm();//27
   476  			t0.copy(E.y); t0.mul(E.z)//28
   477  			t0.add(t0); t0.norm() //29
   478  			z3.mul(t0)//30
   479  			x3.sub(z3) //x3.norm();//31
   480  			t0.add(t0); t0.norm() //32
   481  			t1.add(t1); t1.norm() //33
   482  			z3.copy(t0); z3.mul(t1) //34
   483  
   484  			E.x.copy(x3); E.x.norm() 
   485  			E.y.copy(y3); E.y.norm()
   486  			E.z.copy(z3); E.z.norm()
   487  		}
   488  	}
   489  
   490  	if CURVETYPE==EDWARDS {
   491  		C:=NewFPcopy(E.x)
   492  		D:=NewFPcopy(E.y)
   493  		H:=NewFPcopy(E.z)
   494  		J:=NewFPint(0)
   495  	
   496  		E.x.mul(E.y); E.x.add(E.x); E.x.norm()
   497  		C.sqr()
   498  		D.sqr()
   499  		if CURVE_A==-1 {C.neg()}	
   500  		E.y.copy(C); E.y.add(D); E.y.norm()
   501  
   502  		H.sqr(); H.add(H)
   503  		E.z.copy(E.y)
   504  		J.copy(E.y); J.sub(H); J.norm()
   505  		E.x.mul(J)
   506  		C.sub(D); C.norm()
   507  		E.y.mul(C)
   508  		E.z.mul(J)
   509  
   510  
   511  	}
   512  	if CURVETYPE==MONTGOMERY {
   513  		A:=NewFPcopy(E.x)
   514  		B:=NewFPcopy(E.x)	
   515  		AA:=NewFPint(0)
   516  		BB:=NewFPint(0)
   517  		C:=NewFPint(0)
   518  	
   519  	//	if E.INF {return}
   520  
   521  		A.add(E.z); A.norm()
   522  		AA.copy(A); AA.sqr()
   523  		B.sub(E.z); B.norm()
   524  		BB.copy(B); BB.sqr()
   525  		C.copy(AA); C.sub(BB)
   526  		C.norm()
   527  
   528  		E.x.copy(AA); E.x.mul(BB)
   529  
   530  		A.copy(C); A.imul((CURVE_A+2)/4)
   531  
   532  		BB.add(A); BB.norm()
   533  		E.z.copy(BB); E.z.mul(C)
   534  	}
   535  	return;
   536  }
   537  
   538  /* this+=Q */
   539  func (E *ECP) Add(Q *ECP) {
   540  /*
   541  	if E.INF {
   542  		E.Copy(Q)
   543  		return
   544  	}
   545  	if Q.INF {return}
   546  */
   547  	if CURVETYPE==WEIERSTRASS {
   548  		if CURVE_A==0 {
   549  			b:=3*CURVE_B_I
   550  			t0:=NewFPcopy(E.x)
   551  			t0.mul(Q.x)
   552  			t1:=NewFPcopy(E.y)
   553  			t1.mul(Q.y)
   554  			t2:=NewFPcopy(E.z)
   555  			t2.mul(Q.z)
   556  			t3:=NewFPcopy(E.x)
   557  			t3.add(E.y); t3.norm()
   558  			t4:=NewFPcopy(Q.x)
   559  			t4.add(Q.y); t4.norm()
   560  			t3.mul(t4)
   561  			t4.copy(t0); t4.add(t1)
   562  
   563  			t3.sub(t4); t3.norm()
   564  			t4.copy(E.y)
   565  			t4.add(E.z); t4.norm()
   566  			x3:=NewFPcopy(Q.y)
   567  			x3.add(Q.z); x3.norm()
   568  
   569  			t4.mul(x3)
   570  			x3.copy(t1)
   571  			x3.add(t2)
   572  	
   573  			t4.sub(x3); t4.norm()
   574  			x3.copy(E.x); x3.add(E.z); x3.norm()
   575  			y3:=NewFPcopy(Q.x)
   576  			y3.add(Q.z); y3.norm()
   577  			x3.mul(y3)
   578  			y3.copy(t0)
   579  			y3.add(t2)
   580  			y3.rsub(x3); y3.norm()
   581  			x3.copy(t0); x3.add(t0) 
   582  			t0.add(x3); t0.norm()
   583  			t2.imul(b)
   584  
   585  			z3:=NewFPcopy(t1); z3.add(t2); z3.norm()
   586  			t1.sub(t2); t1.norm() 
   587  			y3.imul(b)
   588  	
   589  			x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2)
   590  			y3.mul(t0); t1.mul(z3); y3.add(t1)
   591  			t0.mul(t3); z3.mul(t4); z3.add(t0)
   592  
   593  			E.x.copy(x3); E.x.norm()
   594  			E.y.copy(y3); E.y.norm()
   595  			E.z.copy(z3); E.z.norm()	
   596  		} else {
   597  
   598  			t0:=NewFPcopy(E.x)
   599  			t1:=NewFPcopy(E.y)
   600  			t2:=NewFPcopy(E.z)
   601  			t3:=NewFPcopy(E.x)
   602  			t4:=NewFPcopy(Q.x)
   603  			z3:=NewFPint(0)
   604  			y3:=NewFPcopy(Q.x)
   605  			x3:=NewFPcopy(Q.y)
   606  			b:=NewFPint(0)
   607  
   608  			if CURVE_B_I==0 {b.copy(NewFPbig(NewBIGints(CURVE_B)))}
   609  
   610  			t0.mul(Q.x) //1
   611  			t1.mul(Q.y) //2
   612  			t2.mul(Q.z) //3
   613  
   614  			t3.add(E.y); t3.norm() //4
   615  			t4.add(Q.y); t4.norm() //5
   616  			t3.mul(t4) //6
   617  			t4.copy(t0); t4.add(t1) //t4.norm(); //7
   618  			t3.sub(t4); t3.norm() //8
   619  			t4.copy(E.y); t4.add(E.z); t4.norm() //9
   620  			x3.add(Q.z); x3.norm() //10
   621  			t4.mul(x3) //11
   622  			x3.copy(t1); x3.add(t2) //x3.norm();//12
   623  
   624  			t4.sub(x3); t4.norm() //13
   625  			x3.copy(E.x); x3.add(E.z); x3.norm() //14
   626  			y3.add(Q.z); y3.norm() //15
   627  
   628  			x3.mul(y3) //16
   629  			y3.copy(t0); y3.add(t2) //y3.norm();//17
   630  
   631  			y3.rsub(x3); y3.norm() //18
   632  			z3.copy(t2) 
   633  				
   634  			if CURVE_B_I==0 {
   635  				z3.mul(b)
   636  			} else {
   637  				z3.imul(CURVE_B_I)
   638  			}
   639  				
   640  			x3.copy(y3); x3.sub(z3); x3.norm() //20
   641  			z3.copy(x3); z3.add(x3) //z3.norm(); //21
   642  
   643  			x3.add(z3) //x3.norm(); //22
   644  			z3.copy(t1); z3.sub(x3); z3.norm() //23
   645  			x3.add(t1); x3.norm() //24
   646  
   647  			if CURVE_B_I==0 {
   648  				y3.mul(b)
   649  			} else {
   650  				y3.imul(CURVE_B_I)
   651  			}
   652  
   653  			t1.copy(t2); t1.add(t2); //t1.norm();//26
   654  			t2.add(t1) //t2.norm();//27
   655  
   656  			y3.sub(t2) //y3.norm(); //28
   657  
   658  			y3.sub(t0); y3.norm() //29
   659  			t1.copy(y3); t1.add(y3) //t1.norm();//30
   660  			y3.add(t1); y3.norm() //31
   661  
   662  			t1.copy(t0); t1.add(t0) //t1.norm(); //32
   663  			t0.add(t1) //t0.norm();//33
   664  			t0.sub(t2); t0.norm() //34
   665  			t1.copy(t4); t1.mul(y3) //35
   666  			t2.copy(t0); t2.mul(y3) //36
   667  			y3.copy(x3); y3.mul(z3) //37
   668  			y3.add(t2) //y3.norm();//38
   669  			x3.mul(t3) //39
   670  			x3.sub(t1) //40
   671  			z3.mul(t4) //41
   672  			t1.copy(t3); t1.mul(t0) //42
   673  			z3.add(t1) 
   674  			E.x.copy(x3); E.x.norm() 
   675  			E.y.copy(y3); E.y.norm()
   676  			E.z.copy(z3); E.z.norm()
   677  
   678  		}
   679  	}
   680  	if CURVETYPE==EDWARDS {
   681  		b:=NewFPbig(NewBIGints(CURVE_B))
   682  		A:=NewFPcopy(E.z)
   683  		B:=NewFPint(0)
   684  		C:=NewFPcopy(E.x)
   685  		D:=NewFPcopy(E.y)
   686  		EE:=NewFPint(0)
   687  		F:=NewFPint(0)
   688  		G:=NewFPint(0)
   689  	
   690  		A.mul(Q.z);
   691  		B.copy(A); B.sqr()
   692  		C.mul(Q.x)
   693  		D.mul(Q.y)
   694  
   695  		EE.copy(C); EE.mul(D); EE.mul(b)
   696  		F.copy(B); F.sub(EE)
   697  		G.copy(B); G.add(EE)
   698  
   699  		if CURVE_A==1 {
   700  			EE.copy(D); EE.sub(C)
   701  		}
   702  		C.add(D)
   703  
   704  		B.copy(E.x); B.add(E.y)
   705  		D.copy(Q.x); D.add(Q.y)
   706  		B.norm(); D.norm()
   707  		B.mul(D)
   708  		B.sub(C)
   709  		B.norm(); F.norm()
   710  		B.mul(F)
   711  		E.x.copy(A); E.x.mul(B)
   712  		G.norm()
   713  		if CURVE_A==1 {
   714  			EE.norm(); C.copy(EE); C.mul(G)
   715  		}
   716  		if CURVE_A==-1 {
   717  			C.norm(); C.mul(G)
   718  		}
   719  		E.y.copy(A); E.y.mul(C)
   720  		E.z.copy(F); E.z.mul(G)
   721  	}
   722  	return
   723  }
   724  
   725  /* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
   726  func (E *ECP) dadd(Q *ECP,W *ECP) {
   727  	A:=NewFPcopy(E.x)
   728  	B:=NewFPcopy(E.x)
   729  	C:=NewFPcopy(Q.x)
   730  	D:=NewFPcopy(Q.x)
   731  	DA:=NewFPint(0)
   732  	CB:=NewFPint(0)
   733  			
   734  	A.add(E.z)
   735  	B.sub(E.z)
   736  
   737  	C.add(Q.z)
   738  	D.sub(Q.z)
   739  	A.norm(); D.norm()
   740  
   741  	DA.copy(D); DA.mul(A)
   742  	C.norm(); B.norm()
   743  
   744  	CB.copy(C); CB.mul(B)
   745  
   746  	A.copy(DA); A.add(CB); A.norm(); A.sqr()
   747  	B.copy(DA); B.sub(CB); B.norm(); B.sqr()
   748  
   749  	E.x.copy(A)
   750  	E.z.copy(W.x); E.z.mul(B)
   751  
   752  //	if E.z.iszilch() {
   753  //		E.inf()
   754  //	} else {E.INF=false;}
   755  
   756  }
   757  
   758  /* this-=Q */
   759  func (E *ECP) Sub(Q *ECP) {
   760  	NQ:=NewECP(); NQ.Copy(Q);
   761  	NQ.neg()
   762  	E.Add(NQ)
   763  }
   764  
   765  /* constant time multiply by small integer of length bts - use ladder */
   766  func (E *ECP) pinmul(e int32,bts int32) *ECP {	
   767  	if CURVETYPE==MONTGOMERY {
   768  		return E.mul(NewBIGint(int(e)))
   769  	} else {
   770  		P:=NewECP()
   771  		R0:=NewECP()
   772  		R1:=NewECP(); R1.Copy(E)
   773  
   774  		for i:=bts-1;i>=0;i-- {
   775  			b:=int((e>>uint32(i))&1)
   776  			P.Copy(R1)
   777  			P.Add(R0)
   778  			R0.cswap(R1,b)
   779  			R1.Copy(P)
   780  			R0.dbl()
   781  			R0.cswap(R1,b)
   782  		}
   783  		P.Copy(R0)
   784  		P.Affine()
   785  		return P
   786  	}
   787  }
   788  
   789  /* return e.this */
   790  
   791  func (E *ECP) mul(e *BIG) *ECP {
   792  	if (e.iszilch() || E.Is_infinity()) {return NewECP()}
   793  	P:=NewECP()
   794  	if CURVETYPE==MONTGOMERY {
   795  /* use Ladder */
   796  		D:=NewECP();
   797  		R0:=NewECP(); R0.Copy(E)
   798  		R1:=NewECP(); R1.Copy(E)
   799  		R1.dbl()
   800  		D.Copy(E); D.Affine()
   801  		nb:=e.nbits()
   802  		for i:=nb-2;i>=0;i-- {
   803  			b:=int(e.bit(i))
   804  			P.Copy(R1)
   805  			P.dadd(R0,D)
   806  			R0.cswap(R1,b)
   807  			R1.Copy(P)
   808  			R0.dbl()
   809  			R0.cswap(R1,b)
   810  		}
   811  		P.Copy(R0)
   812  	} else {
   813  // fixed size windows 
   814  		mt:=NewBIG()
   815  		t:=NewBIG()
   816  		Q:=NewECP()
   817  		C:=NewECP()
   818  
   819  		var W []*ECP
   820  		var w [1+(NLEN*int(BASEBITS)+3)/4]int8
   821  
   822  		//E.Affine();
   823  
   824  		Q.Copy(E);
   825  		Q.dbl();
   826  
   827  		W=append(W,NewECP());
   828  		W[0].Copy(E);
   829  
   830  		for i:=1;i<8;i++ {
   831  			W=append(W,NewECP())
   832  			W[i].Copy(W[i-1])
   833  			W[i].Add(Q)
   834  		}
   835  
   836  // make exponent odd - add 2P if even, P if odd 
   837  		t.copy(e)
   838  		s:=int(t.parity())
   839  		t.inc(1); t.norm(); ns:=int(t.parity()); mt.copy(t); mt.inc(1); mt.norm()
   840  		t.cmove(mt,s)
   841  		Q.cmove(E,ns)
   842  		C.Copy(Q)
   843  
   844  		nb:=1+(t.nbits()+3)/4
   845  
   846  // convert exponent to signed 4-bit window 
   847  		for i:=0;i<nb;i++ {
   848  			w[i]=int8(t.lastbits(5)-16)
   849  			t.dec(int(w[i])); t.norm()
   850  			t.fshr(4)	
   851  		}
   852  		w[nb]=int8(t.lastbits(5))
   853  
   854  		P.Copy(W[(int(w[nb])-1)/2])  
   855  		for i:=nb-1;i>=0;i-- {
   856  			Q.selector(W,int32(w[i]))
   857  			P.dbl()
   858  			P.dbl()
   859  			P.dbl()
   860  			P.dbl()
   861  			P.Add(Q)
   862  		}
   863  		P.Sub(C) /* apply correction */
   864  	}
   865  	P.Affine()
   866  	return P
   867  }
   868  
   869  /* Public version */
   870  func (E *ECP) Mul(e *BIG) *ECP {
   871  	return E.mul(e)
   872  }
   873  
   874  /* Return e.this+f.Q */
   875  
   876  func (E *ECP) Mul2(e *BIG,Q *ECP,f *BIG) *ECP {
   877  	te:=NewBIG()
   878  	tf:=NewBIG()
   879  	mt:=NewBIG()
   880  	S:=NewECP()
   881  	T:=NewECP()
   882  	C:=NewECP()
   883  	var W [] *ECP
   884  	//ECP[] W=new ECP[8];
   885  	var w [1+(NLEN*int(BASEBITS)+1)/2]int8		
   886  
   887  	//E.Affine()
   888  	//Q.Affine()
   889  
   890  	te.copy(e)
   891  	tf.copy(f)
   892  
   893  // precompute table 
   894  	for i:=0;i<8;i++ {
   895  		W=append(W,NewECP())
   896  	}
   897  	W[1].Copy(E); W[1].Sub(Q)
   898  	W[2].Copy(E); W[2].Add(Q);
   899  	S.Copy(Q); S.dbl();
   900  	W[0].Copy(W[1]); W[0].Sub(S);
   901  	W[3].Copy(W[2]); W[3].Add(S);
   902  	T.Copy(E); T.dbl();
   903  	W[5].Copy(W[1]); W[5].Add(T);
   904  	W[6].Copy(W[2]); W[6].Add(T);
   905  	W[4].Copy(W[5]); W[4].Sub(S);
   906  	W[7].Copy(W[6]); W[7].Add(S);
   907  
   908  // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
   909  
   910  	s:=int(te.parity());
   911  	te.inc(1); te.norm(); ns:=int(te.parity()); mt.copy(te); mt.inc(1); mt.norm()
   912  	te.cmove(mt,s)
   913  	T.cmove(E,ns)
   914  	C.Copy(T)
   915  
   916  	s=int(tf.parity())
   917  	tf.inc(1); tf.norm(); ns=int(tf.parity()); mt.copy(tf); mt.inc(1); mt.norm()
   918  	tf.cmove(mt,s)
   919  	S.cmove(Q,ns)
   920  	C.Add(S)
   921  
   922  	mt.copy(te); mt.add(tf); mt.norm()
   923  	nb:=1+(mt.nbits()+1)/2
   924  
   925  // convert exponent to signed 2-bit window 
   926  	for i:=0;i<nb;i++ {
   927  		a:=(te.lastbits(3)-4)
   928  		te.dec(int(a)); te.norm()
   929  		te.fshr(2)
   930  		b:=(tf.lastbits(3)-4)
   931  		tf.dec(int(b)); tf.norm()
   932  		tf.fshr(2)
   933  		w[i]=int8(4*a+b)
   934  	}
   935  	w[nb]=int8(4*te.lastbits(3)+tf.lastbits(3))
   936  	S.Copy(W[(w[nb]-1)/2])  
   937  
   938  	for i:=nb-1;i>=0;i-- {
   939  		T.selector(W,int32(w[i]));
   940  		S.dbl()
   941  		S.dbl()
   942  		S.Add(T)
   943  	}
   944  	S.Sub(C) /* apply correction */
   945  	S.Affine()
   946  	return S
   947  }
   948  
   949  func (E *ECP) cfp() {
   950  	cf:=CURVE_Cof_I;
   951  	if cf==1 {return}
   952  	if cf==4 {
   953  		E.dbl(); E.dbl()
   954  		//E.Affine();
   955  		return;
   956  	} 
   957  	if cf==8 {
   958  		E.dbl(); E.dbl(); E.dbl()
   959  		//E.Affine();
   960  		return;
   961  	}
   962  	c:=NewBIGints(CURVE_Cof);
   963  	E.Copy(E.mul(c));
   964  }
   965  
   966  func ECP_mapit(h []byte) *ECP {
   967  	q:=NewBIGints(Modulus)
   968  	x:=FromBytes(h[:])
   969  	x.Mod(q)
   970  	var P *ECP
   971  
   972  	for true {
   973  		for true {
   974  			if CURVETYPE!=MONTGOMERY {
   975  				P=NewECPbigint(x,0)
   976  			} else {
   977  				P=NewECPbig(x)
   978  			}
   979  			x.inc(1); x.norm()
   980  			if !P.Is_infinity() {break}
   981  		}
   982  		P.cfp()
   983  		if !P.Is_infinity() {break}
   984  	}
   985  			
   986  	return P
   987  }
   988  
   989  func ECP_generator() *ECP {
   990  	var G *ECP
   991  
   992  	gx:=NewBIGints(CURVE_Gx)
   993  	if CURVETYPE!=MONTGOMERY {
   994  		gy:=NewBIGints(CURVE_Gy)
   995  		G=NewECPbigs(gx,gy)
   996  	} else {
   997  		G=NewECPbig(gx)
   998  	}
   999  	return G
  1000  }
  1001  
  1002  /*
  1003  func main() {
  1004  	Gx:=NewBIGints(CURVE_Gx);
  1005  	var Gy *BIG
  1006  	var P *ECP
  1007  
  1008  	if CURVETYPE!=MONTGOMERY {Gy=NewBIGints(CURVE_Gy)}
  1009  	r:=NewBIGints(CURVE_Order)
  1010  
  1011  	//r.dec(7);
  1012  	
  1013  	fmt.Printf("Gx= "+Gx.toString())
  1014  	fmt.Printf("\n")
  1015  
  1016  	if CURVETYPE!=MONTGOMERY {
  1017  		fmt.Printf("Gy= "+Gy.toString())
  1018  		fmt.Printf("\n")
  1019  	}	
  1020  
  1021  	if CURVETYPE!=MONTGOMERY {
  1022  		P=NewECPbigs(Gx,Gy)
  1023  	} else  {P=NewECPbig(Gx)}
  1024  
  1025  	fmt.Printf("P= "+P.toString());		
  1026  	fmt.Printf("\n")
  1027  
  1028  	R:=P.mul(r);
  1029  		//for (int i=0;i<10000;i++)
  1030  		//	R=P.mul(r);
  1031  	
  1032  	fmt.Printf("R= "+R.toString())
  1033  	fmt.Printf("\n")
  1034  }
  1035  */