177 lines
6.8 KiB
C
177 lines
6.8 KiB
C
|
|
/***************************************************************************
|
|
*
|
|
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 <http://www.gnu.org/licenses/>. *
|
|
*
|
|
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 flash number builder: uses generator of
|
|
* regular continued fraction expansion to create
|
|
* a flash number, rounded if necessary.
|
|
* mrbuild.c
|
|
*/
|
|
|
|
#include "miracl.h"
|
|
|
|
#ifdef MR_FLASH
|
|
|
|
void build(_MIPD_ flash x,int (*gen)(_MIPT_ big,int))
|
|
{ /* Build x from its regular c.f. *
|
|
* generated by gen() */
|
|
mr_small ex1,ex2,ex,st,sr;
|
|
int a,b,c,d,rm,q,n,prc,lw2,lw4,lz;
|
|
BOOL finoff,last;
|
|
big t;
|
|
#ifdef MR_OS_THREADS
|
|
miracl *mr_mip=get_mip();
|
|
#endif
|
|
if (mr_mip->ERNUM) return;
|
|
|
|
MR_IN(48)
|
|
|
|
zero(mr_mip->w1);
|
|
convert(_MIPP_ 1,mr_mip->w2);
|
|
convert(_MIPP_ 1,mr_mip->w3);
|
|
zero(mr_mip->w4);
|
|
finoff=FALSE;
|
|
last=FALSE;
|
|
n=0;
|
|
q=(*gen)(_MIPP_ x,n); /* Note - first quotient may be zero */
|
|
ex=mr_mip->base-1;
|
|
if (mr_mip->nib==mr_mip->workprec) prc=mr_mip->nib;
|
|
else prc=mr_mip->workprec+1;
|
|
while (!mr_mip->ERNUM && q>=0)
|
|
{
|
|
if (q==MR_TOOBIG || n==0 || finoff)
|
|
{
|
|
if (q!=MR_TOOBIG) convert(_MIPP_ q,x);
|
|
else last=FALSE;
|
|
mr_mip->check=OFF;
|
|
multiply(_MIPP_ mr_mip->w2,x,mr_mip->w0);
|
|
subtract(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w7);
|
|
mr_mip->check=ON;
|
|
if ((int)(mr_mip->w7->len&MR_OBITS)>mr_mip->nib) break;
|
|
copy(mr_mip->w7,mr_mip->w1);
|
|
t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t; /* swap(w1,w2) */
|
|
mr_mip->check=OFF;
|
|
multiply(_MIPP_ mr_mip->w4,x,mr_mip->w0);
|
|
subtract(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w7);
|
|
mr_mip->check=ON;
|
|
if ((int)(mr_mip->w7->len&MR_OBITS)>mr_mip->nib)
|
|
{ /* oops! */
|
|
fpack(_MIPP_ mr_mip->w1,mr_mip->w4,x);
|
|
negify(x,x);
|
|
mr_mip->EXACT=FALSE;
|
|
MR_OUT
|
|
return;
|
|
}
|
|
copy(mr_mip->w7,mr_mip->w3);
|
|
t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t; /* swap(w3,w4) */
|
|
n++;
|
|
}
|
|
lw2=(int)(mr_mip->w2->len&MR_OBITS);
|
|
lw4=(int)(mr_mip->w4->len&MR_OBITS);
|
|
lz=lw2+lw4;
|
|
if (lz > prc) break; /* too big - exit */
|
|
if (last)
|
|
{
|
|
if (finoff) break;
|
|
finoff=TRUE;
|
|
q=(*gen)(_MIPP_ x,n);
|
|
continue;
|
|
}
|
|
if (lz>=prc-1)
|
|
{ /* nearly finished - so be careful not to overshoot */
|
|
if (mr_mip->base==0)
|
|
{
|
|
#ifndef MR_NOFULLWIDTH
|
|
st=mr_mip->w2->w[lw2-1]+1;
|
|
if (st==0) ex1=1;
|
|
else ex1=muldvm((mr_small)1,(mr_small)0,st,&sr);
|
|
st=mr_mip->w4->w[lw4-1]+1;
|
|
if (st==0) ex2=1;
|
|
else ex2=muldvm((mr_small)1,(mr_small)0,st,&sr);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
ex1=mr_mip->base/(mr_mip->w2->w[lw2-1]+1);
|
|
ex2=mr_mip->base/(mr_mip->w4->w[lw4-1]+1);
|
|
}
|
|
if (ex2>ex1) ex=ex1,ex1=ex2,ex2=ex;
|
|
if (lz==prc) ex=ex2;
|
|
else ex=ex1;
|
|
last=TRUE;
|
|
}
|
|
a=1;
|
|
b=0;
|
|
c=0;
|
|
d=1;
|
|
forever
|
|
{
|
|
q=(*gen)(_MIPP_ x,n);
|
|
if (q<0 || q>=MR_TOOBIG/mr_abs(d))
|
|
{ /* there could be more.... *** V3.21 mod *** */
|
|
last=FALSE;
|
|
break;
|
|
}
|
|
rm=b-q*d;
|
|
b=d;
|
|
d=rm;
|
|
rm=a-q*c;
|
|
a=c;
|
|
c=rm;
|
|
n++;
|
|
if ((mr_small)(mr_abs(c-d))>ex) break;
|
|
}
|
|
premult(_MIPP_ mr_mip->w1,c,mr_mip->w7);
|
|
premult(_MIPP_ mr_mip->w1,a,mr_mip->w1);
|
|
premult(_MIPP_ mr_mip->w2,b,mr_mip->w0);
|
|
premult(_MIPP_ mr_mip->w2,d,mr_mip->w2);
|
|
add(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1);
|
|
add(_MIPP_ mr_mip->w2,mr_mip->w7,mr_mip->w2);
|
|
premult(_MIPP_ mr_mip->w3,c,mr_mip->w7);
|
|
premult(_MIPP_ mr_mip->w3,a,mr_mip->w3);
|
|
premult(_MIPP_ mr_mip->w4,b,mr_mip->w0);
|
|
premult(_MIPP_ mr_mip->w4,d,mr_mip->w4);
|
|
add(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3);
|
|
add(_MIPP_ mr_mip->w4,mr_mip->w7,mr_mip->w4);
|
|
}
|
|
if (fit(mr_mip->w2,mr_mip->w4,mr_mip->nib)) fpack(_MIPP_ mr_mip->w2,mr_mip->w4,x);
|
|
else fpack(_MIPP_ mr_mip->w1,mr_mip->w3,x);
|
|
negify (x,x);
|
|
if (q!=(-1)) mr_mip->EXACT=FALSE;
|
|
MR_OUT
|
|
}
|
|
|
|
#endif
|
|
|