/*************************************************************************** * Copyright 2013 CertiVox UK Ltd. * * This file is part of CertiVox MIRACL Crypto SDK. * * The CertiVox MIRACL Crypto SDK provides developers with an * extensive and efficient set of cryptographic functions. * For further information about its features and functionalities please * refer to http://www.certivox.com * * * The CertiVox MIRACL Crypto SDK is free software: you can * redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the * Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * * The CertiVox MIRACL Crypto SDK is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * * You should have received a copy of the GNU Affero General Public * License along with CertiVox MIRACL Crypto SDK. * If not, see . * * You can be released from the requirements of the license by purchasing * a commercial license. Buying such a license is mandatory as soon as you * develop commercial activities involving the CertiVox MIRACL Crypto SDK * without disclosing the source code of your own applications, or shipping * the CertiVox MIRACL Crypto SDK with a closed source product. * * ***************************************************************************/ /* * MIRACL C++ Implementation file ecn4.cpp * * AUTHOR : M. Scott * * PURPOSE : Implementation of class ECn4 (Elliptic curves over n^4) * * WARNING: This class has been cobbled together for a specific use with * the MIRACL library. It is not complete, and may not work in other * applications * */ #include "ecn4.h" using namespace std; void ECn4::get(ZZn4& a,ZZn4& b) const {a=x;b=y;} void ECn4::get(ZZn4& a) const {a=x;} BOOL ECn4::iszero(void) const {if (marker==MR_EPOINT_INFINITY) return TRUE; return FALSE;} BOOL ECn4::set(const ZZn4& xx,const ZZn4& yy) { if (yy*yy!=rhs(xx)) return FALSE; x=xx; y=yy; marker=MR_EPOINT_NORMALIZED; return TRUE; } BOOL ECn4::set(const ZZn4& xx) { ZZn4 w=rhs(xx); if (!w.iszero()) { w=sqrt(w); if (w.iszero()) return FALSE; } x=xx; y=w; marker=MR_EPOINT_NORMALIZED; return TRUE; } ECn4 operator-(const ECn4& a) {ECn4 w; if (a.marker!=MR_EPOINT_INFINITY) {w.x=a.x; w.y=-a.y; w.marker=a.marker;} return w; } ECn4& ECn4::operator*=(const Big& k) { int i,j,n,nb,nbs,nzs; ECn4 p2,pt,t[11]; Big h,kk; if (k==0) { clear(); return *this; } if (k==1) { return (*this); } pt=*this; kk=k; if (kk<0) { pt=-pt; kk=-k; } h=3*kk; p2=pt+pt; t[0]=pt; for (i=1;i<=10;i++) t[i]=t[i-1]+p2; // Left to Right method nb=bits(h); for (i=nb-2;i>=1;) { n=naf_window(kk,h,i,&nbs,&nzs,11); for (j=0;j0) pt+=t[n/2]; if (n<0) pt-=t[(-n)/2]; i-=nbs; if (nzs) { for (j=0;jTWIST; if (marker==MR_EPOINT_INFINITY) { *this=z; return FALSE; } if (z.marker==MR_EPOINT_INFINITY) { return FALSE; } if (x!=z.x) { ZZn4 t=y; t-=z.y; ZZn4 t2=x; t2-=z.x; lam=t; lam/=t2; x+=z.x; t=lam; t*=t; t-=x; x=t; y=z.x; y-=x; y*=lam; y-=z.y; } else { if (y!=z.y || y.iszero()) { clear(); lam=(ZZn4)1; return TRUE; // any non-zero value } ZZn4 t=x; ZZn4 t2=x; // lam=(3*(x*x)+getA())/(y+y); lam=x; lam*=lam; lam*=3; if (twist==MR_QUADRATIC) { // ZZn4 a4; // ZZn2 x((ZZn)0,getA()); // a4.set(x,(ZZn2)0); // A*i^4 lam+=txx( (ZZn2)getA() ); // lam+=a4; } else lam+=getA(); lam/=(y+y); t2+=x; x=lam; x*=x; x-=t2; t-=x; t*=lam; t-=y; y=t; } marker=MR_EPOINT_GENERAL; return TRUE; } #ifndef MR_NO_ECC_MULTIADD #ifndef MR_STATIC ECn4 mul(int n,ECn4* P,const Big* b) { int k,j,i,m,nb,ea; ECn4 *G; ECn4 R; m=1<nb) nb=k; for (i=nb-1;i>=0;i--) { ea=0; k=1; for (j=0;j