/*************************************************************************** * 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 Chinese Remainder Thereom routines (for use with small moduli) * mrscrt.c */ #include #include "miracl.h" #ifdef MR_FP #include #endif static mr_utype in_range(mr_utype x,mr_utype y) { /* x=x%y, and positive */ mr_utype r; #ifdef MR_FP mr_small dres; #endif r=MR_REMAIN(x,y); if (r<0) r+=y; return r; } #ifndef MR_STATIC BOOL scrt_init(_MIPD_ small_chinese *c,int r,mr_utype *moduli) { /* calculate CRT constants - returns FALSE if there is a problem */ int i,j,k; if (r<1) return FALSE; if (r==1) { c->NP=1; c->M=(mr_utype *)mr_alloc(_MIPP_ r,sizeof(mr_utype)); if (c->M==NULL) return FALSE; c->M[0]=moduli[0]; return TRUE; } for (i=0;iM=(mr_utype *)mr_alloc(_MIPP_ r,sizeof(mr_utype)); if (c->M==NULL) return FALSE; c->C=(mr_utype *)mr_alloc(_MIPP_ r*(r-1)/2,sizeof(mr_utype)); if (c->C==NULL) { /* no room */ mr_free(c->M); return FALSE; } c->V=(mr_utype *)mr_alloc(_MIPP_ r,sizeof(mr_utype)); if (c->V==NULL) { /* no room */ mr_free(c->M); mr_free(c->C); return FALSE; } for (k=0,i=0;iM[i]=moduli[i]; for (j=0;jC[k]=invers(c->M[j],c->M[i]); } c->NP=r; return TRUE; } void scrt_end(small_chinese *c) { /* clean up after CRT */ if (c->NP<1) { c->NP=0; return; } if (c->NP==1) { mr_free(c->M); c->NP=0; return; } mr_free(c->M); mr_free(c->V); mr_free(c->C); c->NP=0; } #endif void scrt(_MIPD_ small_chinese *c,mr_utype *u,big x) { /* Chinese Remainder Thereom * * Calculate x given remainders u[i] mod M[i] */ int i,j,k,len; mr_utype *V,*C,*M; mr_small t; #ifdef MR_OS_THREADS miracl *mr_mip=get_mip(); #endif #ifdef MR_FP_ROUNDING mr_large im; #endif V=c->V; C=c->C; M=c->M; len=c->NP; if (len<1) return; if (len==1) { t=smul(1,in_range(u[0],M[0]),M[0]); convert(_MIPP_ 1,mr_mip->w5); mr_pmul(_MIPP_ mr_mip->w5,t,x); return; } V[0]=u[0]; k=0; for (i=1;iw5); for (j=1;jw5,(mr_small)(M[j-1]),mr_mip->w5); mr_pmul(_MIPP_ mr_mip->w5,(mr_small)(V[j]),mr_mip->w0); mr_padd(_MIPP_ x,mr_mip->w0,x); } }