bn_mont.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:10k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* crypto/bn/bn_mont.c */
  2. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  3.  * All rights reserved.
  4.  *
  5.  * This package is an SSL implementation written
  6.  * by Eric Young (eay@cryptsoft.com).
  7.  * The implementation was written so as to conform with Netscapes SSL.
  8.  * 
  9.  * This library is free for commercial and non-commercial use as long as
  10.  * the following conditions are aheared to.  The following conditions
  11.  * apply to all code found in this distribution, be it the RC4, RSA,
  12.  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  13.  * included with this distribution is covered by the same copyright terms
  14.  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  15.  * 
  16.  * Copyright remains Eric Young's, and as such any Copyright notices in
  17.  * the code are not to be removed.
  18.  * If this package is used in a product, Eric Young should be given attribution
  19.  * as the author of the parts of the library used.
  20.  * This can be in the form of a textual message at program startup or
  21.  * in documentation (online or textual) provided with the package.
  22.  * 
  23.  * Redistribution and use in source and binary forms, with or without
  24.  * modification, are permitted provided that the following conditions
  25.  * are met:
  26.  * 1. Redistributions of source code must retain the copyright
  27.  *    notice, this list of conditions and the following disclaimer.
  28.  * 2. Redistributions in binary form must reproduce the above copyright
  29.  *    notice, this list of conditions and the following disclaimer in the
  30.  *    documentation and/or other materials provided with the distribution.
  31.  * 3. All advertising materials mentioning features or use of this software
  32.  *    must display the following acknowledgement:
  33.  *    "This product includes cryptographic software written by
  34.  *     Eric Young (eay@cryptsoft.com)"
  35.  *    The word 'cryptographic' can be left out if the rouines from the library
  36.  *    being used are not cryptographic related :-).
  37.  * 4. If you include any Windows specific code (or a derivative thereof) from 
  38.  *    the apps directory (application code) you must include an acknowledgement:
  39.  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  40.  * 
  41.  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  42.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  43.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  45.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  47.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  48.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  49.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  50.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51.  * SUCH DAMAGE.
  52.  * 
  53.  * The licence and distribution terms for any publically available version or
  54.  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  55.  * copied and put under another distribution licence
  56.  * [including the GNU Public Licence.]
  57.  */
  58. /*
  59.  * Details about Montgomery multiplication algorithms can be found at
  60.  * http://security.ece.orst.edu/publications.html, e.g.
  61.  * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
  62.  * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
  63.  */
  64. #include <stdio.h>
  65. #include "cryptlib.h"
  66. #include "bn_lcl.h"
  67. #define MONT_WORD /* use the faster word-based algorithm */
  68. int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
  69.   BN_MONT_CTX *mont, BN_CTX *ctx)
  70. {
  71. BIGNUM *tmp;
  72. int ret=0;
  73. BN_CTX_start(ctx);
  74. tmp = BN_CTX_get(ctx);
  75. if (tmp == NULL) goto err;
  76. bn_check_top(tmp);
  77. if (a == b)
  78. {
  79. if (!BN_sqr(tmp,a,ctx)) goto err;
  80. }
  81. else
  82. {
  83. if (!BN_mul(tmp,a,b,ctx)) goto err;
  84. }
  85. /* reduce from aRR to aR */
  86. if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err;
  87. bn_check_top(r);
  88. ret=1;
  89. err:
  90. BN_CTX_end(ctx);
  91. return(ret);
  92. }
  93. int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
  94.      BN_CTX *ctx)
  95. {
  96. int retn=0;
  97. #ifdef MONT_WORD
  98. BIGNUM *n,*r;
  99. BN_ULONG *ap,*np,*rp,n0,v,*nrp;
  100. int al,nl,max,i,x,ri;
  101. BN_CTX_start(ctx);
  102. if ((r = BN_CTX_get(ctx)) == NULL) goto err;
  103. if (!BN_copy(r,a)) goto err;
  104. n= &(mont->N);
  105. ap=a->d;
  106. /* mont->ri is the size of mont->N in bits (rounded up
  107.    to the word size) */
  108. al=ri=mont->ri/BN_BITS2;
  109. nl=n->top;
  110. if ((al == 0) || (nl == 0)) { r->top=0; return(1); }
  111. max=(nl+al+1); /* allow for overflow (no?) XXX */
  112. if (bn_wexpand(r,max) == NULL) goto err;
  113. if (bn_wexpand(ret,max) == NULL) goto err;
  114. r->neg=a->neg^n->neg;
  115. np=n->d;
  116. rp=r->d;
  117. nrp= &(r->d[nl]);
  118. /* clear the top words of T */
  119. #if 1
  120. for (i=r->top; i<max; i++) /* memset? XXX */
  121. r->d[i]=0;
  122. #else
  123. memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
  124. #endif
  125. r->top=max;
  126. n0=mont->n0;
  127. #ifdef BN_COUNT
  128. fprintf(stderr,"word BN_from_montgomery %d * %dn",nl,nl);
  129. #endif
  130. for (i=0; i<nl; i++)
  131. {
  132. #ifdef __TANDEM
  133.                 {
  134.                    long long t1;
  135.                    long long t2;
  136.                    long long t3;
  137.                    t1 = rp[0] * (n0 & 0177777);
  138.                    t2 = 037777600000l;
  139.                    t2 = n0 & t2;
  140.                    t3 = rp[0] & 0177777;
  141.                    t2 = (t3 * t2) & BN_MASK2;
  142.                    t1 = t1 + t2;
  143.                    v=bn_mul_add_words(rp,np,nl,(BN_ULONG) t1);
  144.                 }
  145. #else
  146. v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
  147. #endif
  148. nrp++;
  149. rp++;
  150. if (((nrp[-1]+=v)&BN_MASK2) >= v)
  151. continue;
  152. else
  153. {
  154. if (((++nrp[0])&BN_MASK2) != 0) continue;
  155. if (((++nrp[1])&BN_MASK2) != 0) continue;
  156. for (x=2; (((++nrp[x])&BN_MASK2) == 0); x++) ;
  157. }
  158. }
  159. bn_correct_top(r);
  160. /* mont->ri will be a multiple of the word size */
  161. #if 0
  162. BN_rshift(ret,r,mont->ri);
  163. #else
  164. ret->neg = r->neg;
  165. x=ri;
  166. rp=ret->d;
  167. ap= &(r->d[x]);
  168. if (r->top < x)
  169. al=0;
  170. else
  171. al=r->top-x;
  172. ret->top=al;
  173. al-=4;
  174. for (i=0; i<al; i+=4)
  175. {
  176. BN_ULONG t1,t2,t3,t4;
  177. t1=ap[i+0];
  178. t2=ap[i+1];
  179. t3=ap[i+2];
  180. t4=ap[i+3];
  181. rp[i+0]=t1;
  182. rp[i+1]=t2;
  183. rp[i+2]=t3;
  184. rp[i+3]=t4;
  185. }
  186. al+=4;
  187. for (; i<al; i++)
  188. rp[i]=ap[i];
  189. #endif
  190. #else /* !MONT_WORD */ 
  191. BIGNUM *t1,*t2;
  192. BN_CTX_start(ctx);
  193. t1 = BN_CTX_get(ctx);
  194. t2 = BN_CTX_get(ctx);
  195. if (t1 == NULL || t2 == NULL) goto err;
  196. if (!BN_copy(t1,a)) goto err;
  197. BN_mask_bits(t1,mont->ri);
  198. if (!BN_mul(t2,t1,&mont->Ni,ctx)) goto err;
  199. BN_mask_bits(t2,mont->ri);
  200. if (!BN_mul(t1,t2,&mont->N,ctx)) goto err;
  201. if (!BN_add(t2,a,t1)) goto err;
  202. if (!BN_rshift(ret,t2,mont->ri)) goto err;
  203. #endif /* MONT_WORD */
  204. if (BN_ucmp(ret, &(mont->N)) >= 0)
  205. {
  206. if (!BN_usub(ret,ret,&(mont->N))) goto err;
  207. }
  208. retn=1;
  209. bn_check_top(ret);
  210.  err:
  211. BN_CTX_end(ctx);
  212. return(retn);
  213. }
  214. BN_MONT_CTX *BN_MONT_CTX_new(void)
  215. {
  216. BN_MONT_CTX *ret;
  217. if ((ret=(BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL)
  218. return(NULL);
  219. BN_MONT_CTX_init(ret);
  220. ret->flags=BN_FLG_MALLOCED;
  221. return(ret);
  222. }
  223. void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
  224. {
  225. ctx->ri=0;
  226. BN_init(&(ctx->RR));
  227. BN_init(&(ctx->N));
  228. BN_init(&(ctx->Ni));
  229. ctx->flags=0;
  230. }
  231. void BN_MONT_CTX_free(BN_MONT_CTX *mont)
  232. {
  233. if(mont == NULL)
  234.     return;
  235. BN_free(&(mont->RR));
  236. BN_free(&(mont->N));
  237. BN_free(&(mont->Ni));
  238. if (mont->flags & BN_FLG_MALLOCED)
  239. OPENSSL_free(mont);
  240. }
  241. int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
  242. {
  243. int ret = 0;
  244. BIGNUM *Ri,*R;
  245. BN_CTX_start(ctx);
  246. if((Ri = BN_CTX_get(ctx)) == NULL) goto err;
  247. R= &(mont->RR); /* grab RR as a temp */
  248. if (!BN_copy(&(mont->N),mod)) goto err; /* Set N */
  249. mont->N.neg = 0;
  250. #ifdef MONT_WORD
  251. {
  252. BIGNUM tmod;
  253. BN_ULONG buf[2];
  254. mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2;
  255. BN_zero(R);
  256. if (!(BN_set_bit(R,BN_BITS2))) goto err; /* R */
  257. buf[0]=mod->d[0]; /* tmod = N mod word size */
  258. buf[1]=0;
  259. tmod.d=buf;
  260. tmod.top = buf[0] != 0 ? 1 : 0;
  261. tmod.dmax=2;
  262. tmod.neg=0;
  263. /* Ri = R^-1 mod N*/
  264. if ((BN_mod_inverse(Ri,R,&tmod,ctx)) == NULL)
  265. goto err;
  266. if (!BN_lshift(Ri,Ri,BN_BITS2)) goto err; /* R*Ri */
  267. if (!BN_is_zero(Ri))
  268. {
  269. if (!BN_sub_word(Ri,1)) goto err;
  270. }
  271. else /* if N mod word size == 1 */
  272. {
  273. if (!BN_set_word(Ri,BN_MASK2)) goto err;  /* Ri-- (mod word size) */
  274. }
  275. if (!BN_div(Ri,NULL,Ri,&tmod,ctx)) goto err;
  276. /* Ni = (R*Ri-1)/N,
  277.  * keep only least significant word: */
  278. mont->n0 = (Ri->top > 0) ? Ri->d[0] : 0;
  279. }
  280. #else /* !MONT_WORD */
  281. { /* bignum version */
  282. mont->ri=BN_num_bits(&mont->N);
  283. BN_zero(R);
  284. if (!BN_set_bit(R,mont->ri)) goto err;  /* R = 2^ri */
  285.                                         /* Ri = R^-1 mod N*/
  286. if ((BN_mod_inverse(Ri,R,&mont->N,ctx)) == NULL)
  287. goto err;
  288. if (!BN_lshift(Ri,Ri,mont->ri)) goto err; /* R*Ri */
  289. if (!BN_sub_word(Ri,1)) goto err;
  290. /* Ni = (R*Ri-1) / N */
  291. if (!BN_div(&(mont->Ni),NULL,Ri,&mont->N,ctx)) goto err;
  292. }
  293. #endif
  294. /* setup RR for conversions */
  295. BN_zero(&(mont->RR));
  296. if (!BN_set_bit(&(mont->RR),mont->ri*2)) goto err;
  297. if (!BN_mod(&(mont->RR),&(mont->RR),&(mont->N),ctx)) goto err;
  298. ret = 1;
  299. err:
  300. BN_CTX_end(ctx);
  301. return ret;
  302. }
  303. BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
  304. {
  305. if (to == from) return(to);
  306. if (!BN_copy(&(to->RR),&(from->RR))) return NULL;
  307. if (!BN_copy(&(to->N),&(from->N))) return NULL;
  308. if (!BN_copy(&(to->Ni),&(from->Ni))) return NULL;
  309. to->ri=from->ri;
  310. to->n0=from->n0;
  311. return(to);
  312. }
  313. BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
  314. const BIGNUM *mod, BN_CTX *ctx)
  315. {
  316. if (*pmont)
  317. return *pmont;
  318. CRYPTO_w_lock(lock);
  319. if (!*pmont)
  320. {
  321. BN_MONT_CTX *mtmp;
  322. mtmp = BN_MONT_CTX_new();
  323. if (mtmp && !BN_MONT_CTX_set(mtmp, mod, ctx))
  324. BN_MONT_CTX_free(mtmp);
  325. else
  326. *pmont = mtmp;
  327. }
  328. CRYPTO_w_unlock(lock);
  329. return *pmont;
  330. }