includes/clientside/static/crypto.js
changeset 1227 bdac73ed481e
parent 843 4415e50e4e84
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
   186 mr_x1=t; mr_r=t; mr_a=t;                                      //used in millerRabin()
   186 mr_x1=t; mr_r=t; mr_a=t;                                      //used in millerRabin()
   187 eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t;               //used in eGCD_(), inverseMod_()
   187 eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t;               //used in eGCD_(), inverseMod_()
   188 md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
   188 md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
   189 
   189 
   190 primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t; 
   190 primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t; 
   191   s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_()
   191 	s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_()
   192 
   192 
   193 ////////////////////////////////////////////////////////////////////////////////////////
   193 ////////////////////////////////////////////////////////////////////////////////////////
   194 
   194 
   195 //return array of all primes less than integer n
   195 //return array of all primes less than integer n
   196 function findPrimes(n) {
   196 function findPrimes(n) {
   197   var i,s,p,ans;
   197 	var i,s,p,ans;
   198   s=new Array(n);
   198 	s=new Array(n);
   199   for (i=0;i<n;i++)
   199 	for (i=0;i<n;i++)
   200     s[i]=0;
   200 		s[i]=0;
   201   s[0]=2;
   201 	s[0]=2;
   202   p=0;    //first p elements of s are primes, the rest are a sieve
   202 	p=0;    //first p elements of s are primes, the rest are a sieve
   203   for(;s[p]<n;) {                  //s[p] is the pth prime
   203 	for(;s[p]<n;) {                  //s[p] is the pth prime
   204     for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
   204 		for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
   205       s[i]=1;
   205 			s[i]=1;
   206     p++;
   206 		p++;
   207     s[p]=s[p-1]+1;
   207 		s[p]=s[p-1]+1;
   208     for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
   208 		for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
   209   }
   209 	}
   210   ans=new Array(p);
   210 	ans=new Array(p);
   211   for(i=0;i<p;i++)
   211 	for(i=0;i<p;i++)
   212     ans[i]=s[i];
   212 		ans[i]=s[i];
   213   return ans;
   213 	return ans;
   214 }
   214 }
   215 
   215 
   216 //does a single round of Miller-Rabin base b consider x to be a possible prime?
   216 //does a single round of Miller-Rabin base b consider x to be a possible prime?
   217 //x is a bigInt, and b is an integer
   217 //x is a bigInt, and b is an integer
   218 function millerRabin(x,b) {
   218 function millerRabin(x,b) {
   219   var i,j,k,s;
   219 	var i,j,k,s;
   220 
   220 
   221   if (mr_x1.length!=x.length) {
   221 	if (mr_x1.length!=x.length) {
   222     mr_x1=dup(x);
   222 		mr_x1=dup(x);
   223     mr_r=dup(x);
   223 		mr_r=dup(x);
   224     mr_a=dup(x);
   224 		mr_a=dup(x);
   225   }
   225 	}
   226 
   226 
   227   copyInt_(mr_a,b);
   227 	copyInt_(mr_a,b);
   228   copy_(mr_r,x);
   228 	copy_(mr_r,x);
   229   copy_(mr_x1,x);
   229 	copy_(mr_x1,x);
   230 
   230 
   231   addInt_(mr_r,-1);
   231 	addInt_(mr_r,-1);
   232   addInt_(mr_x1,-1);
   232 	addInt_(mr_x1,-1);
   233 
   233 
   234   //s=the highest power of two that divides mr_r
   234 	//s=the highest power of two that divides mr_r
   235   k=0;
   235 	k=0;
   236   for (i=0;i<mr_r.length;i++)
   236 	for (i=0;i<mr_r.length;i++)
   237     for (j=1;j<mask;j<<=1)
   237 		for (j=1;j<mask;j<<=1)
   238       if (x[i] & j) {
   238 			if (x[i] & j) {
   239         s=(k<mr_r.length+bpe ? k : 0); 
   239 				s=(k<mr_r.length+bpe ? k : 0); 
   240          i=mr_r.length;
   240  				i=mr_r.length;
   241          j=mask;
   241  				j=mask;
   242       } else
   242 			} else
   243         k++;
   243 				k++;
   244 
   244 
   245   if (s)                
   245 	if (s)                
   246     rightShift_(mr_r,s);
   246 		rightShift_(mr_r,s);
   247 
   247 
   248   powMod_(mr_a,mr_r,x);
   248 	powMod_(mr_a,mr_r,x);
   249 
   249 
   250   if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
   250 	if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
   251     j=1;
   251 		j=1;
   252     while (j<=s-1 && !equals(mr_a,mr_x1)) {
   252 		while (j<=s-1 && !equals(mr_a,mr_x1)) {
   253       squareMod_(mr_a,x);
   253 			squareMod_(mr_a,x);
   254       if (equalsInt(mr_a,1)) {
   254 			if (equalsInt(mr_a,1)) {
   255         return 0;
   255 				return 0;
   256       }
   256 			}
   257       j++;
   257 			j++;
   258     }
   258 		}
   259     if (!equals(mr_a,mr_x1)) {
   259 		if (!equals(mr_a,mr_x1)) {
   260       return 0;
   260 			return 0;
   261     }
   261 		}
   262   }
   262 	}
   263   return 1;  
   263 	return 1;  
   264 }
   264 }
   265 
   265 
   266 //returns how many bits long the bigInt is, not counting leading zeros.
   266 //returns how many bits long the bigInt is, not counting leading zeros.
   267 function bitSize(x) {
   267 function bitSize(x) {
   268   var j,z,w;
   268 	var j,z,w;
   269   for (j=x.length-1; (x[j]==0) && (j>0); j--);
   269 	for (j=x.length-1; (x[j]==0) && (j>0); j--);
   270   for (z=0,w=x[j]; w; (w>>=1),z++);
   270 	for (z=0,w=x[j]; w; (w>>=1),z++);
   271   z+=bpe*j;
   271 	z+=bpe*j;
   272   return z;
   272 	return z;
   273 }
   273 }
   274 
   274 
   275 //return a copy of x with at least n elements, adding leading zeros if needed
   275 //return a copy of x with at least n elements, adding leading zeros if needed
   276 function expand(x,n) {
   276 function expand(x,n) {
   277   var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
   277 	var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
   278   copy_(ans,x);
   278 	copy_(ans,x);
   279   return ans;
   279 	return ans;
   280 }
   280 }
   281 
   281 
   282 //return a k-bit true random prime using Maurer's algorithm.
   282 //return a k-bit true random prime using Maurer's algorithm.
   283 function randTruePrime(k) {
   283 function randTruePrime(k) {
   284   var ans=int2bigInt(0,k,0);
   284 	var ans=int2bigInt(0,k,0);
   285   randTruePrime_(ans,k);
   285 	randTruePrime_(ans,k);
   286   return bigint_trim(ans,1);
   286 	return bigint_trim(ans,1);
   287 }
   287 }
   288 
   288 
   289 //return a new bigInt equal to (x mod n) for bigInts x and n.
   289 //return a new bigInt equal to (x mod n) for bigInts x and n.
   290 function mod(x,n) {
   290 function mod(x,n) {
   291   var ans=dup(x);
   291 	var ans=dup(x);
   292   mod_(ans,n);
   292 	mod_(ans,n);
   293   return bigint_trim(ans,1);
   293 	return bigint_trim(ans,1);
   294 }
   294 }
   295 
   295 
   296 //return (x+n) where x is a bigInt and n is an integer.
   296 //return (x+n) where x is a bigInt and n is an integer.
   297 function addInt(x,n) {
   297 function addInt(x,n) {
   298   var ans=expand(x,x.length+1);
   298 	var ans=expand(x,x.length+1);
   299   addInt_(ans,n);
   299 	addInt_(ans,n);
   300   return bigint_trim(ans,1);
   300 	return bigint_trim(ans,1);
   301 }
   301 }
   302 
   302 
   303 //return x*y for bigInts x and y. This is faster when y<x.
   303 //return x*y for bigInts x and y. This is faster when y<x.
   304 function mult(x,y) {
   304 function mult(x,y) {
   305   var ans=expand(x,x.length+y.length);
   305 	var ans=expand(x,x.length+y.length);
   306   mult_(ans,y);
   306 	mult_(ans,y);
   307   return bigint_trim(ans,1);
   307 	return bigint_trim(ans,1);
   308 }
   308 }
   309 
   309 
   310 //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation.  0**0=1. Faster for odd n.
   310 //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation.  0**0=1. Faster for odd n.
   311 function powMod(x,y,n) {
   311 function powMod(x,y,n) {
   312   var ans=expand(x,n.length);  
   312 	var ans=expand(x,n.length);  
   313   powMod_(ans,bigint_trim(y,2),bigint_trim(n,2),0);  //this should work without the trim, but doesn't
   313 	powMod_(ans,bigint_trim(y,2),bigint_trim(n,2),0);  //this should work without the trim, but doesn't
   314   return bigint_trim(ans,1);
   314 	return bigint_trim(ans,1);
   315 }
   315 }
   316 
   316 
   317 //return (x-y) for bigInts x and y.  Negative answers will be 2s complement
   317 //return (x-y) for bigInts x and y.  Negative answers will be 2s complement
   318 function sub(x,y) {
   318 function sub(x,y) {
   319   var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); 
   319 	var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); 
   320   sub_(ans,y);
   320 	sub_(ans,y);
   321   return bigint_trim(ans,1);
   321 	return bigint_trim(ans,1);
   322 }
   322 }
   323 
   323 
   324 //return (x+y) for bigInts x and y.  
   324 //return (x+y) for bigInts x and y.  
   325 function add(x,y) {
   325 function add(x,y) {
   326   var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); 
   326 	var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1)); 
   327   add_(ans,y);
   327 	add_(ans,y);
   328   return bigint_trim(ans,1);
   328 	return bigint_trim(ans,1);
   329 }
   329 }
   330 
   330 
   331 //return (x**(-1) mod n) for bigInts x and n.  If no inverse exists, it returns null
   331 //return (x**(-1) mod n) for bigInts x and n.  If no inverse exists, it returns null
   332 function inverseMod(x,n) {
   332 function inverseMod(x,n) {
   333   var ans=expand(x,n.length); 
   333 	var ans=expand(x,n.length); 
   334   var s;
   334 	var s;
   335   s=inverseMod_(ans,n);
   335 	s=inverseMod_(ans,n);
   336   return s ? bigint_trim(ans,1) : null;
   336 	return s ? bigint_trim(ans,1) : null;
   337 }
   337 }
   338 
   338 
   339 //return (x*y mod n) for bigInts x,y,n.  For greater speed, let y<x.
   339 //return (x*y mod n) for bigInts x,y,n.  For greater speed, let y<x.
   340 function multMod(x,y,n) {
   340 function multMod(x,y,n) {
   341   var ans=expand(x,n.length);
   341 	var ans=expand(x,n.length);
   342   multMod_(ans,y,n);
   342 	multMod_(ans,y,n);
   343   return bigint_trim(ans,1);
   343 	return bigint_trim(ans,1);
   344 }
   344 }
   345 
   345 
   346 //generate a k-bit true random prime using Maurer's algorithm,
   346 //generate a k-bit true random prime using Maurer's algorithm,
   347 //and put it into ans.  The bigInt ans must be large enough to hold it.
   347 //and put it into ans.  The bigInt ans must be large enough to hold it.
   348 function randTruePrime_(ans,k) {
   348 function randTruePrime_(ans,k) {
   349   var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
   349 	var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
   350 
   350 
   351   if (primes.length==0)
   351 	if (primes.length==0)
   352     primes=findPrimes(30000);  //check for divisibility by primes <=30000
   352 		primes=findPrimes(30000);  //check for divisibility by primes <=30000
   353 
   353 
   354   if (pows.length==0) {
   354 	if (pows.length==0) {
   355     pows=new Array(512);
   355 		pows=new Array(512);
   356     for (j=0;j<512;j++) {
   356 		for (j=0;j<512;j++) {
   357       pows[j]=Math.pow(2,j/511.-1.);
   357 			pows[j]=Math.pow(2,j/511.-1.);
   358     }
   358 		}
   359   }
   359 	}
   360 
   360 
   361   //c and m should be tuned for a particular machine and value of k, to maximize speed
   361 	//c and m should be tuned for a particular machine and value of k, to maximize speed
   362   c=0.1;  //c=0.1 in HAC
   362 	c=0.1;  //c=0.1 in HAC
   363   m=20;   //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
   363 	m=20;   //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
   364   recLimit=20; //stop recursion when k <=recLimit.  Must have recLimit >= 2
   364 	recLimit=20; //stop recursion when k <=recLimit.  Must have recLimit >= 2
   365 
   365 
   366   if (s_i2.length!=ans.length) {
   366 	if (s_i2.length!=ans.length) {
   367     s_i2=dup(ans);
   367 		s_i2=dup(ans);
   368     s_R =dup(ans);
   368 		s_R =dup(ans);
   369     s_n1=dup(ans);
   369 		s_n1=dup(ans);
   370     s_r2=dup(ans);
   370 		s_r2=dup(ans);
   371     s_d =dup(ans);
   371 		s_d =dup(ans);
   372     s_x1=dup(ans);
   372 		s_x1=dup(ans);
   373     s_x2=dup(ans);
   373 		s_x2=dup(ans);
   374     s_b =dup(ans);
   374 		s_b =dup(ans);
   375     s_n =dup(ans);
   375 		s_n =dup(ans);
   376     s_i =dup(ans);
   376 		s_i =dup(ans);
   377     s_rm=dup(ans);
   377 		s_rm=dup(ans);
   378     s_q =dup(ans);
   378 		s_q =dup(ans);
   379     s_a =dup(ans);
   379 		s_a =dup(ans);
   380     s_aa=dup(ans);
   380 		s_aa=dup(ans);
   381   }
   381 	}
   382 
   382 
   383   if (k <= recLimit) {  //generate small random primes by trial division up to its square root
   383 	if (k <= recLimit) {  //generate small random primes by trial division up to its square root
   384     pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
   384 		pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
   385     copyInt_(ans,0);
   385 		copyInt_(ans,0);
   386     for (dd=1;dd;) {
   386 		for (dd=1;dd;) {
   387       dd=0;
   387 			dd=0;
   388       ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k));  //random, k-bit, odd integer, with msb 1
   388 			ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k));  //random, k-bit, odd integer, with msb 1
   389       for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
   389 			for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
   390         if (0==(ans[0]%primes[j])) {
   390 				if (0==(ans[0]%primes[j])) {
   391           dd=1;
   391 					dd=1;
   392           break;
   392 					break;
   393         }
   393 				}
   394       }
   394 			}
   395     }
   395 		}
   396     carry_(ans);
   396 		carry_(ans);
   397     return;
   397 		return;
   398   }
   398 	}
   399 
   399 
   400   B=c*k*k;    //try small primes up to B (or all the primes[] array if the largest is less than B).
   400 	B=c*k*k;    //try small primes up to B (or all the primes[] array if the largest is less than B).
   401   if (k>2*m)  //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
   401 	if (k>2*m)  //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
   402     for (r=1; k-k*r<=m; )
   402 		for (r=1; k-k*r<=m; )
   403       r=pows[Math.floor(Math.random()*512)];   //r=Math.pow(2,Math.random()-1);
   403 			r=pows[Math.floor(Math.random()*512)];   //r=Math.pow(2,Math.random()-1);
   404   else
   404 	else
   405     r=.5;
   405 		r=.5;
   406 
   406 
   407   //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
   407 	//simulation suggests the more complex algorithm using r=.333 is only slightly faster.
   408 
   408 
   409   recSize=Math.floor(r*k)+1;
   409 	recSize=Math.floor(r*k)+1;
   410 
   410 
   411   randTruePrime_(s_q,recSize);
   411 	randTruePrime_(s_q,recSize);
   412   copyInt_(s_i2,0);
   412 	copyInt_(s_i2,0);
   413   s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe));   //s_i2=2^(k-2)
   413 	s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe));   //s_i2=2^(k-2)
   414   divide_(s_i2,s_q,s_i,s_rm);                        //s_i=floor((2^(k-1))/(2q))
   414 	divide_(s_i2,s_q,s_i,s_rm);                        //s_i=floor((2^(k-1))/(2q))
   415 
   415 
   416   z=bitSize(s_i);
   416 	z=bitSize(s_i);
   417 
   417 
   418   for (;;) {
   418 	for (;;) {
   419     for (;;) {  //generate z-bit numbers until one falls in the range [0,s_i-1]
   419 		for (;;) {  //generate z-bit numbers until one falls in the range [0,s_i-1]
   420       randBigInt_(s_R,z,0);
   420 			randBigInt_(s_R,z,0);
   421       if (greater(s_i,s_R))
   421 			if (greater(s_i,s_R))
   422         break;
   422 				break;
   423     }                //now s_R is in the range [0,s_i-1]
   423 		}                //now s_R is in the range [0,s_i-1]
   424     addInt_(s_R,1);  //now s_R is in the range [1,s_i]
   424 		addInt_(s_R,1);  //now s_R is in the range [1,s_i]
   425     add_(s_R,s_i);   //now s_R is in the range [s_i+1,2*s_i]
   425 		add_(s_R,s_i);   //now s_R is in the range [s_i+1,2*s_i]
   426 
   426 
   427     copy_(s_n,s_q);
   427 		copy_(s_n,s_q);
   428     mult_(s_n,s_R); 
   428 		mult_(s_n,s_R); 
   429     multInt_(s_n,2);
   429 		multInt_(s_n,2);
   430     addInt_(s_n,1);    //s_n=2*s_R*s_q+1
   430 		addInt_(s_n,1);    //s_n=2*s_R*s_q+1
   431     
   431 		
   432     copy_(s_r2,s_R);
   432 		copy_(s_r2,s_R);
   433     multInt_(s_r2,2);  //s_r2=2*s_R
   433 		multInt_(s_r2,2);  //s_r2=2*s_R
   434 
   434 
   435     //check s_n for divisibility by small primes up to B
   435 		//check s_n for divisibility by small primes up to B
   436     for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
   436 		for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
   437       if (modInt(s_n,primes[j])==0) {
   437 			if (modInt(s_n,primes[j])==0) {
   438         divisible=1;
   438 				divisible=1;
   439         break;
   439 				break;
   440       }      
   440 			}      
   441 
   441 
   442     if (!divisible)    //if it passes small primes check, then try a single Miller-Rabin base 2
   442 		if (!divisible)    //if it passes small primes check, then try a single Miller-Rabin base 2
   443       if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_ 
   443 			if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_ 
   444         divisible=1;
   444 				divisible=1;
   445 
   445 
   446     if (!divisible) {  //if it passes that test, continue checking s_n
   446 		if (!divisible) {  //if it passes that test, continue checking s_n
   447       addInt_(s_n,-3);
   447 			addInt_(s_n,-3);
   448       for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--);  //strip leading zeros
   448 			for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--);  //strip leading zeros
   449       for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
   449 			for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
   450       zz+=bpe*j;                             //zz=number of bits in s_n, ignoring leading zeros
   450 			zz+=bpe*j;                             //zz=number of bits in s_n, ignoring leading zeros
   451       for (;;) {  //generate z-bit numbers until one falls in the range [0,s_n-1]
   451 			for (;;) {  //generate z-bit numbers until one falls in the range [0,s_n-1]
   452         randBigInt_(s_a,zz,0);
   452 				randBigInt_(s_a,zz,0);
   453         if (greater(s_n,s_a))
   453 				if (greater(s_n,s_a))
   454           break;
   454 					break;
   455       }                //now s_a is in the range [0,s_n-1]
   455 			}                //now s_a is in the range [0,s_n-1]
   456       addInt_(s_n,3);  //now s_a is in the range [0,s_n-4]
   456 			addInt_(s_n,3);  //now s_a is in the range [0,s_n-4]
   457       addInt_(s_a,2);  //now s_a is in the range [2,s_n-2]
   457 			addInt_(s_a,2);  //now s_a is in the range [2,s_n-2]
   458       copy_(s_b,s_a);
   458 			copy_(s_b,s_a);
   459       copy_(s_n1,s_n);
   459 			copy_(s_n1,s_n);
   460       addInt_(s_n1,-1);
   460 			addInt_(s_n1,-1);
   461       powMod_(s_b,s_n1,s_n);   //s_b=s_a^(s_n-1) modulo s_n
   461 			powMod_(s_b,s_n1,s_n);   //s_b=s_a^(s_n-1) modulo s_n
   462       addInt_(s_b,-1);
   462 			addInt_(s_b,-1);
   463       if (isZero(s_b)) {
   463 			if (isZero(s_b)) {
   464         copy_(s_b,s_a);
   464 				copy_(s_b,s_a);
   465         powMod_(s_b,s_r2,s_n);
   465 				powMod_(s_b,s_r2,s_n);
   466         addInt_(s_b,-1);
   466 				addInt_(s_b,-1);
   467         copy_(s_aa,s_n);
   467 				copy_(s_aa,s_n);
   468         copy_(s_d,s_b);
   468 				copy_(s_d,s_b);
   469         GCD_(s_d,s_n);  //if s_b and s_n are relatively prime, then s_n is a prime
   469 				GCD_(s_d,s_n);  //if s_b and s_n are relatively prime, then s_n is a prime
   470         if (equalsInt(s_d,1)) {
   470 				if (equalsInt(s_d,1)) {
   471           copy_(ans,s_aa);
   471 					copy_(ans,s_aa);
   472           return;     //if we've made it this far, then s_n is absolutely guaranteed to be prime
   472 					return;     //if we've made it this far, then s_n is absolutely guaranteed to be prime
   473         }
   473 				}
   474       }
   474 			}
   475     }
   475 		}
   476   }
   476 	}
   477 }
   477 }
   478 
   478 
   479 //Return an n-bit random BigInt (n>=1).  If s=1, then the most significant of those n bits is set to 1.
   479 //Return an n-bit random BigInt (n>=1).  If s=1, then the most significant of those n bits is set to 1.
   480 function randBigInt(n,s) {
   480 function randBigInt(n,s) {
   481   var a,b;
   481 	var a,b;
   482   a=Math.floor((n-1)/bpe)+2; //# array elements to hold the BigInt with a leading 0 element
   482 	a=Math.floor((n-1)/bpe)+2; //# array elements to hold the BigInt with a leading 0 element
   483   b=int2bigInt(0,0,a);
   483 	b=int2bigInt(0,0,a);
   484   randBigInt_(b,n,s);
   484 	randBigInt_(b,n,s);
   485   return b;
   485 	return b;
   486 }
   486 }
   487 
   487 
   488 //Set b to an n-bit random BigInt.  If s=1, then the most significant of those n bits is set to 1.
   488 //Set b to an n-bit random BigInt.  If s=1, then the most significant of those n bits is set to 1.
   489 //Array b must be big enough to hold the result. Must have n>=1
   489 //Array b must be big enough to hold the result. Must have n>=1
   490 function randBigInt_(b,n,s) {
   490 function randBigInt_(b,n,s) {
   491   var i,a;
   491 	var i,a;
   492   for (i=0;i<b.length;i++)
   492 	for (i=0;i<b.length;i++)
   493     b[i]=0;
   493 		b[i]=0;
   494   a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
   494 	a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
   495   for (i=0;i<a;i++) {
   495 	for (i=0;i<a;i++) {
   496     b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
   496 		b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
   497   }
   497 	}
   498   b[a-1] &= (2<<((n-1)%bpe))-1;
   498 	b[a-1] &= (2<<((n-1)%bpe))-1;
   499   if (s==1)
   499 	if (s==1)
   500     b[a-1] |= (1<<((n-1)%bpe));
   500 		b[a-1] |= (1<<((n-1)%bpe));
   501 }
   501 }
   502 
   502 
   503 //Return the greatest common divisor of bigInts x and y (each with same number of elements).
   503 //Return the greatest common divisor of bigInts x and y (each with same number of elements).
   504 function GCD(x,y) {
   504 function GCD(x,y) {
   505   var xc,yc;
   505 	var xc,yc;
   506   xc=dup(x);
   506 	xc=dup(x);
   507   yc=dup(y);
   507 	yc=dup(y);
   508   GCD_(xc,yc);
   508 	GCD_(xc,yc);
   509   return xc;
   509 	return xc;
   510 }
   510 }
   511 
   511 
   512 //set x to the greatest common divisor of bigInts x and y (each with same number of elements).
   512 //set x to the greatest common divisor of bigInts x and y (each with same number of elements).
   513 //y is destroyed.
   513 //y is destroyed.
   514 function GCD_(x,y) {
   514 function GCD_(x,y) {
   515   var i,xp,yp,A,B,C,D,q,sing;
   515 	var i,xp,yp,A,B,C,D,q,sing;
   516   if (T.length!=x.length)
   516 	if (T.length!=x.length)
   517     T=dup(x);
   517 		T=dup(x);
   518 
   518 
   519   sing=1;
   519 	sing=1;
   520   while (sing) { //while y has nonzero elements other than y[0]
   520 	while (sing) { //while y has nonzero elements other than y[0]
   521     sing=0;
   521 		sing=0;
   522     for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
   522 		for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
   523       if (y[i]) {
   523 			if (y[i]) {
   524         sing=1;
   524 				sing=1;
   525         break;
   525 				break;
   526       }
   526 			}
   527     if (!sing) break; //quit when y all zero elements except possibly y[0]
   527 		if (!sing) break; //quit when y all zero elements except possibly y[0]
   528 
   528 
   529     for (i=x.length;!x[i] && i>=0;i--);  //find most significant element of x
   529 		for (i=x.length;!x[i] && i>=0;i--);  //find most significant element of x
   530     xp=x[i];
   530 		xp=x[i];
   531     yp=y[i];
   531 		yp=y[i];
   532     A=1; B=0; C=0; D=1;
   532 		A=1; B=0; C=0; D=1;
   533     while ((yp+C) && (yp+D)) {
   533 		while ((yp+C) && (yp+D)) {
   534       q =Math.floor((xp+A)/(yp+C));
   534 			q =Math.floor((xp+A)/(yp+C));
   535       qp=Math.floor((xp+B)/(yp+D));
   535 			qp=Math.floor((xp+B)/(yp+D));
   536       if (q!=qp)
   536 			if (q!=qp)
   537         break;
   537 				break;
   538       t= A-q*C;   A=C;   C=t;    //  do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp)      
   538 			t= A-q*C;   A=C;   C=t;    //  do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp)      
   539       t= B-q*D;   B=D;   D=t;
   539 			t= B-q*D;   B=D;   D=t;
   540       t=xp-q*yp; xp=yp; yp=t;
   540 			t=xp-q*yp; xp=yp; yp=t;
   541     }
   541 		}
   542     if (B) {
   542 		if (B) {
   543       copy_(T,x);
   543 			copy_(T,x);
   544       linComb_(x,y,A,B); //x=A*x+B*y
   544 			linComb_(x,y,A,B); //x=A*x+B*y
   545       linComb_(y,T,D,C); //y=D*y+C*T
   545 			linComb_(y,T,D,C); //y=D*y+C*T
   546     } else {
   546 		} else {
   547       mod_(x,y);
   547 			mod_(x,y);
   548       copy_(T,x);
   548 			copy_(T,x);
   549       copy_(x,y);
   549 			copy_(x,y);
   550       copy_(y,T);
   550 			copy_(y,T);
   551     } 
   551 		} 
   552   }
   552 	}
   553   if (y[0]==0)
   553 	if (y[0]==0)
   554     return;
   554 		return;
   555   t=modInt(x,y[0]);
   555 	t=modInt(x,y[0]);
   556   copyInt_(x,y[0]);
   556 	copyInt_(x,y[0]);
   557   y[0]=t;
   557 	y[0]=t;
   558   while (y[0]) {
   558 	while (y[0]) {
   559     x[0]%=y[0];
   559 		x[0]%=y[0];
   560     t=x[0]; x[0]=y[0]; y[0]=t;
   560 		t=x[0]; x[0]=y[0]; y[0]=t;
   561   }
   561 	}
   562 }
   562 }
   563 
   563 
   564 //do x=x**(-1) mod n, for bigInts x and n.
   564 //do x=x**(-1) mod n, for bigInts x and n.
   565 //If no inverse exists, it sets x to zero and returns 0, else it returns 1.
   565 //If no inverse exists, it sets x to zero and returns 0, else it returns 1.
   566 //The x array must be at least as large as the n array.
   566 //The x array must be at least as large as the n array.
   567 function inverseMod_(x,n) {
   567 function inverseMod_(x,n) {
   568   var k=1+2*Math.max(x.length,n.length);
   568 	var k=1+2*Math.max(x.length,n.length);
   569 
   569 
   570   if(!(x[0]&1)  && !(n[0]&1)) {  //if both inputs are even, then inverse doesn't exist
   570 	if(!(x[0]&1)  && !(n[0]&1)) {  //if both inputs are even, then inverse doesn't exist
   571     copyInt_(x,0);
   571 		copyInt_(x,0);
   572     return 0;
   572 		return 0;
   573   }
   573 	}
   574 
   574 
   575   if (eg_u.length!=k) {
   575 	if (eg_u.length!=k) {
   576     eg_u=new Array(k);
   576 		eg_u=new Array(k);
   577     eg_v=new Array(k);
   577 		eg_v=new Array(k);
   578     eg_A=new Array(k);
   578 		eg_A=new Array(k);
   579     eg_B=new Array(k);
   579 		eg_B=new Array(k);
   580     eg_C=new Array(k);
   580 		eg_C=new Array(k);
   581     eg_D=new Array(k);
   581 		eg_D=new Array(k);
   582   }
   582 	}
   583 
   583 
   584   copy_(eg_u,x);
   584 	copy_(eg_u,x);
   585   copy_(eg_v,n);
   585 	copy_(eg_v,n);
   586   copyInt_(eg_A,1);
   586 	copyInt_(eg_A,1);
   587   copyInt_(eg_B,0);
   587 	copyInt_(eg_B,0);
   588   copyInt_(eg_C,0);
   588 	copyInt_(eg_C,0);
   589   copyInt_(eg_D,1);
   589 	copyInt_(eg_D,1);
   590   for (;;) {
   590 	for (;;) {
   591     while(!(eg_u[0]&1)) {  //while eg_u is even
   591 		while(!(eg_u[0]&1)) {  //while eg_u is even
   592       halve_(eg_u);
   592 			halve_(eg_u);
   593       if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
   593 			if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
   594         halve_(eg_A);
   594 				halve_(eg_A);
   595         halve_(eg_B);      
   595 				halve_(eg_B);      
   596       } else {
   596 			} else {
   597         add_(eg_A,n);  halve_(eg_A);
   597 				add_(eg_A,n);  halve_(eg_A);
   598         sub_(eg_B,x);  halve_(eg_B);
   598 				sub_(eg_B,x);  halve_(eg_B);
   599       }
   599 			}
   600     }
   600 		}
   601 
   601 
   602     while (!(eg_v[0]&1)) {  //while eg_v is even
   602 		while (!(eg_v[0]&1)) {  //while eg_v is even
   603       halve_(eg_v);
   603 			halve_(eg_v);
   604       if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
   604 			if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
   605         halve_(eg_C);
   605 				halve_(eg_C);
   606         halve_(eg_D);      
   606 				halve_(eg_D);      
   607       } else {
   607 			} else {
   608         add_(eg_C,n);  halve_(eg_C);
   608 				add_(eg_C,n);  halve_(eg_C);
   609         sub_(eg_D,x);  halve_(eg_D);
   609 				sub_(eg_D,x);  halve_(eg_D);
   610       }
   610 			}
   611     }
   611 		}
   612 
   612 
   613     if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
   613 		if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
   614       sub_(eg_u,eg_v);
   614 			sub_(eg_u,eg_v);
   615       sub_(eg_A,eg_C);
   615 			sub_(eg_A,eg_C);
   616       sub_(eg_B,eg_D);
   616 			sub_(eg_B,eg_D);
   617     } else {                   //eg_v > eg_u
   617 		} else {                   //eg_v > eg_u
   618       sub_(eg_v,eg_u);
   618 			sub_(eg_v,eg_u);
   619       sub_(eg_C,eg_A);
   619 			sub_(eg_C,eg_A);
   620       sub_(eg_D,eg_B);
   620 			sub_(eg_D,eg_B);
   621     }
   621 		}
   622   
   622 	
   623     if (equalsInt(eg_u,0)) {
   623 		if (equalsInt(eg_u,0)) {
   624       if (negative(eg_C)) //make sure answer is nonnegative
   624 			if (negative(eg_C)) //make sure answer is nonnegative
   625         add_(eg_C,n);
   625 				add_(eg_C,n);
   626       copy_(x,eg_C);
   626 			copy_(x,eg_C);
   627 
   627 
   628       if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
   628 			if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
   629         copyInt_(x,0);
   629 				copyInt_(x,0);
   630         return 0;
   630 				return 0;
   631       }
   631 			}
   632       return 1;
   632 			return 1;
   633     }
   633 		}
   634   }
   634 	}
   635 }
   635 }
   636 
   636 
   637 //return x**(-1) mod n, for integers x and n.  Return 0 if there is no inverse
   637 //return x**(-1) mod n, for integers x and n.  Return 0 if there is no inverse
   638 function inverseModInt(x,n) {
   638 function inverseModInt(x,n) {
   639   var a=1,b=0,t;
   639 	var a=1,b=0,t;
   640   for (;;) {
   640 	for (;;) {
   641     if (x==1) return a;
   641 		if (x==1) return a;
   642     if (x==0) return 0;
   642 		if (x==0) return 0;
   643     b-=a*Math.floor(n/x);
   643 		b-=a*Math.floor(n/x);
   644     n%=x;
   644 		n%=x;
   645 
   645 
   646     if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
   646 		if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
   647     if (n==0) return 0;
   647 		if (n==0) return 0;
   648     a-=b*Math.floor(x/n);
   648 		a-=b*Math.floor(x/n);
   649     x%=n;
   649 		x%=n;
   650   }
   650 	}
   651 }
   651 }
   652 
   652 
   653 //this deprecated function is for backward compatibility only. 
   653 //this deprecated function is for backward compatibility only. 
   654 function inverseModInt_(x,n) {
   654 function inverseModInt_(x,n) {
   655    return inverseModInt(x,n);
   655  	return inverseModInt(x,n);
   656 }
   656 }
   657 
   657 
   658 
   658 
   659 //Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
   659 //Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
   660 //     v = GCD_(x,y) = a*x-b*y
   660 //     v = GCD_(x,y) = a*x-b*y
   661 //The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
   661 //The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
   662 function eGCD_(x,y,v,a,b) {
   662 function eGCD_(x,y,v,a,b) {
   663   var g=0;
   663 	var g=0;
   664   var k=Math.max(x.length,y.length);
   664 	var k=Math.max(x.length,y.length);
   665   if (eg_u.length!=k) {
   665 	if (eg_u.length!=k) {
   666     eg_u=new Array(k);
   666 		eg_u=new Array(k);
   667     eg_A=new Array(k);
   667 		eg_A=new Array(k);
   668     eg_B=new Array(k);
   668 		eg_B=new Array(k);
   669     eg_C=new Array(k);
   669 		eg_C=new Array(k);
   670     eg_D=new Array(k);
   670 		eg_D=new Array(k);
   671   }
   671 	}
   672   while(!(x[0]&1)  && !(y[0]&1)) {  //while x and y both even
   672 	while(!(x[0]&1)  && !(y[0]&1)) {  //while x and y both even
   673     halve_(x);
   673 		halve_(x);
   674     halve_(y);
   674 		halve_(y);
   675     g++;
   675 		g++;
   676   }
   676 	}
   677   copy_(eg_u,x);
   677 	copy_(eg_u,x);
   678   copy_(v,y);
   678 	copy_(v,y);
   679   copyInt_(eg_A,1);
   679 	copyInt_(eg_A,1);
   680   copyInt_(eg_B,0);
   680 	copyInt_(eg_B,0);
   681   copyInt_(eg_C,0);
   681 	copyInt_(eg_C,0);
   682   copyInt_(eg_D,1);
   682 	copyInt_(eg_D,1);
   683   for (;;) {
   683 	for (;;) {
   684     while(!(eg_u[0]&1)) {  //while u is even
   684 		while(!(eg_u[0]&1)) {  //while u is even
   685       halve_(eg_u);
   685 			halve_(eg_u);
   686       if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
   686 			if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
   687         halve_(eg_A);
   687 				halve_(eg_A);
   688         halve_(eg_B);      
   688 				halve_(eg_B);      
   689       } else {
   689 			} else {
   690         add_(eg_A,y);  halve_(eg_A);
   690 				add_(eg_A,y);  halve_(eg_A);
   691         sub_(eg_B,x);  halve_(eg_B);
   691 				sub_(eg_B,x);  halve_(eg_B);
   692       }
   692 			}
   693     }
   693 		}
   694 
   694 
   695     while (!(v[0]&1)) {  //while v is even
   695 		while (!(v[0]&1)) {  //while v is even
   696       halve_(v);
   696 			halve_(v);
   697       if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
   697 			if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
   698         halve_(eg_C);
   698 				halve_(eg_C);
   699         halve_(eg_D);      
   699 				halve_(eg_D);      
   700       } else {
   700 			} else {
   701         add_(eg_C,y);  halve_(eg_C);
   701 				add_(eg_C,y);  halve_(eg_C);
   702         sub_(eg_D,x);  halve_(eg_D);
   702 				sub_(eg_D,x);  halve_(eg_D);
   703       }
   703 			}
   704     }
   704 		}
   705 
   705 
   706     if (!greater(v,eg_u)) { //v<=u
   706 		if (!greater(v,eg_u)) { //v<=u
   707       sub_(eg_u,v);
   707 			sub_(eg_u,v);
   708       sub_(eg_A,eg_C);
   708 			sub_(eg_A,eg_C);
   709       sub_(eg_B,eg_D);
   709 			sub_(eg_B,eg_D);
   710     } else {                //v>u
   710 		} else {                //v>u
   711       sub_(v,eg_u);
   711 			sub_(v,eg_u);
   712       sub_(eg_C,eg_A);
   712 			sub_(eg_C,eg_A);
   713       sub_(eg_D,eg_B);
   713 			sub_(eg_D,eg_B);
   714     }
   714 		}
   715     if (equalsInt(eg_u,0)) {
   715 		if (equalsInt(eg_u,0)) {
   716       if (negative(eg_C)) {   //make sure a (C)is nonnegative
   716 			if (negative(eg_C)) {   //make sure a (C)is nonnegative
   717         add_(eg_C,y);
   717 				add_(eg_C,y);
   718         sub_(eg_D,x);
   718 				sub_(eg_D,x);
   719       }
   719 			}
   720       multInt_(eg_D,-1);  ///make sure b (D) is nonnegative
   720 			multInt_(eg_D,-1);  ///make sure b (D) is nonnegative
   721       copy_(a,eg_C);
   721 			copy_(a,eg_C);
   722       copy_(b,eg_D);
   722 			copy_(b,eg_D);
   723       leftShift_(v,g);
   723 			leftShift_(v,g);
   724       return;
   724 			return;
   725     }
   725 		}
   726   }
   726 	}
   727 }
   727 }
   728 
   728 
   729 
   729 
   730 //is bigInt x negative?
   730 //is bigInt x negative?
   731 function negative(x) {
   731 function negative(x) {
   732   return ((x[x.length-1]>>(bpe-1))&1);
   732 	return ((x[x.length-1]>>(bpe-1))&1);
   733 }
   733 }
   734 
   734 
   735 
   735 
   736 //is (x << (shift*bpe)) > y?
   736 //is (x << (shift*bpe)) > y?
   737 //x and y are nonnegative bigInts
   737 //x and y are nonnegative bigInts
   738 //shift is a nonnegative integer
   738 //shift is a nonnegative integer
   739 function greaterShift(x,y,shift) {
   739 function greaterShift(x,y,shift) {
   740   var kx=x.length, ky=y.length;
   740 	var kx=x.length, ky=y.length;
   741   k=((kx+shift)<ky) ? (kx+shift) : ky;
   741 	k=((kx+shift)<ky) ? (kx+shift) : ky;
   742   for (i=ky-1-shift; i<kx && i>=0; i++) 
   742 	for (i=ky-1-shift; i<kx && i>=0; i++) 
   743     if (x[i]>0)
   743 		if (x[i]>0)
   744       return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
   744 			return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
   745   for (i=kx-1+shift; i<ky; i++)
   745 	for (i=kx-1+shift; i<ky; i++)
   746     if (y[i]>0)
   746 		if (y[i]>0)
   747       return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
   747 			return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
   748   for (i=k-1; i>=shift; i--)
   748 	for (i=k-1; i>=shift; i--)
   749     if      (x[i-shift]>y[i]) return 1;
   749 		if      (x[i-shift]>y[i]) return 1;
   750     else if (x[i-shift]<y[i]) return 0;
   750 		else if (x[i-shift]<y[i]) return 0;
   751   return 0;
   751 	return 0;
   752 }
   752 }
   753 
   753 
   754 //is x > y? (x and y both nonnegative)
   754 //is x > y? (x and y both nonnegative)
   755 function greater(x,y) {
   755 function greater(x,y) {
   756   var i;
   756 	var i;
   757   var k=(x.length<y.length) ? x.length : y.length;
   757 	var k=(x.length<y.length) ? x.length : y.length;
   758 
   758 
   759   for (i=x.length;i<y.length;i++)
   759 	for (i=x.length;i<y.length;i++)
   760     if (y[i])
   760 		if (y[i])
   761       return 0;  //y has more digits
   761 			return 0;  //y has more digits
   762 
   762 
   763   for (i=y.length;i<x.length;i++)
   763 	for (i=y.length;i<x.length;i++)
   764     if (x[i])
   764 		if (x[i])
   765       return 1;  //x has more digits
   765 			return 1;  //x has more digits
   766 
   766 
   767   for (i=k-1;i>=0;i--)
   767 	for (i=k-1;i>=0;i--)
   768     if (x[i]>y[i])
   768 		if (x[i]>y[i])
   769       return 1;
   769 			return 1;
   770     else if (x[i]<y[i])
   770 		else if (x[i]<y[i])
   771       return 0;
   771 			return 0;
   772   return 0;
   772 	return 0;
   773 }
   773 }
   774 
   774 
   775 //divide x by y giving quotient q and remainder r.  (q=floor(x/y),  r=x mod y).  All 4 are bigints.
   775 //divide x by y giving quotient q and remainder r.  (q=floor(x/y),  r=x mod y).  All 4 are bigints.
   776 //x must have at least one leading zero element.
   776 //x must have at least one leading zero element.
   777 //y must be nonzero.
   777 //y must be nonzero.
   778 //q and r must be arrays that are exactly the same length as x. (Or q can have more).
   778 //q and r must be arrays that are exactly the same length as x. (Or q can have more).
   779 //Must have x.length >= y.length >= 2.
   779 //Must have x.length >= y.length >= 2.
   780 function divide_(x,y,q,r) {
   780 function divide_(x,y,q,r) {
   781   var kx, ky;
   781 	var kx, ky;
   782   var i,j,y1,y2,c,a,b;
   782 	var i,j,y1,y2,c,a,b;
   783   copy_(r,x);
   783 	copy_(r,x);
   784   for (ky=y.length;y[ky-1]==0;ky--); //ky is number of elements in y, not including leading zeros
   784 	for (ky=y.length;y[ky-1]==0;ky--); //ky is number of elements in y, not including leading zeros
   785 
   785 
   786   //normalize: ensure the most significant element of y has its highest bit set  
   786 	//normalize: ensure the most significant element of y has its highest bit set  
   787   b=y[ky-1];
   787 	b=y[ky-1];
   788   for (a=0; b; a++)
   788 	for (a=0; b; a++)
   789     b>>=1;  
   789 		b>>=1;  
   790   a=bpe-a;  //a is how many bits to shift so that the high order bit of y is leftmost in its array element
   790 	a=bpe-a;  //a is how many bits to shift so that the high order bit of y is leftmost in its array element
   791   leftShift_(y,a);  //multiply both by 1<<a now, then divide both by that at the end
   791 	leftShift_(y,a);  //multiply both by 1<<a now, then divide both by that at the end
   792   leftShift_(r,a);
   792 	leftShift_(r,a);
   793 
   793 
   794   //Rob Visser discovered a bug: the following line was originally just before the normalization.
   794 	//Rob Visser discovered a bug: the following line was originally just before the normalization.
   795   for (kx=r.length;r[kx-1]==0 && kx>ky;kx--); //kx is number of elements in normalized x, not including leading zeros
   795 	for (kx=r.length;r[kx-1]==0 && kx>ky;kx--); //kx is number of elements in normalized x, not including leading zeros
   796 
   796 
   797   copyInt_(q,0);                      // q=0
   797 	copyInt_(q,0);                      // q=0
   798   while (!greaterShift(y,r,kx-ky)) {  // while (leftShift_(y,kx-ky) <= r) {
   798 	while (!greaterShift(y,r,kx-ky)) {  // while (leftShift_(y,kx-ky) <= r) {
   799     subShift_(r,y,kx-ky);             //   r=r-leftShift_(y,kx-ky)
   799 		subShift_(r,y,kx-ky);             //   r=r-leftShift_(y,kx-ky)
   800     q[kx-ky]++;                       //   q[kx-ky]++;
   800 		q[kx-ky]++;                       //   q[kx-ky]++;
   801   }                                   // }
   801 	}                                   // }
   802 
   802 
   803   for (i=kx-1; i>=ky; i--) {
   803 	for (i=kx-1; i>=ky; i--) {
   804     if (r[i]==y[ky-1])
   804 		if (r[i]==y[ky-1])
   805       q[i-ky]=mask;
   805 			q[i-ky]=mask;
   806     else
   806 		else
   807       q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);	
   807 			q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);	
   808 
   808 
   809     //The following for(;;) loop is equivalent to the commented while loop, 
   809 		//The following for(;;) loop is equivalent to the commented while loop, 
   810     //except that the uncommented version avoids overflow.
   810 		//except that the uncommented version avoids overflow.
   811     //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
   811 		//The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
   812     //  while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
   812 		//  while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
   813     //    q[i-ky]--;    
   813 		//    q[i-ky]--;    
   814     for (;;) {
   814 		for (;;) {
   815       y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
   815 			y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
   816       c=y2>>bpe;
   816 			c=y2>>bpe;
   817       y2=y2 & mask;
   817 			y2=y2 & mask;
   818       y1=c+q[i-ky]*y[ky-1];
   818 			y1=c+q[i-ky]*y[ky-1];
   819       c=y1>>bpe;
   819 			c=y1>>bpe;
   820       y1=y1 & mask;
   820 			y1=y1 & mask;
   821 
   821 
   822       if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i]) 
   822 			if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i]) 
   823         q[i-ky]--;
   823 				q[i-ky]--;
   824       else
   824 			else
   825         break;
   825 				break;
   826     }
   826 		}
   827 
   827 
   828     linCombShift_(r,y,-q[i-ky],i-ky);    //r=r-q[i-ky]*leftShift_(y,i-ky)
   828 		linCombShift_(r,y,-q[i-ky],i-ky);    //r=r-q[i-ky]*leftShift_(y,i-ky)
   829     if (negative(r)) {
   829 		if (negative(r)) {
   830       addShift_(r,y,i-ky);         //r=r+leftShift_(y,i-ky)
   830 			addShift_(r,y,i-ky);         //r=r+leftShift_(y,i-ky)
   831       q[i-ky]--;
   831 			q[i-ky]--;
   832     }
   832 		}
   833   }
   833 	}
   834 
   834 
   835   rightShift_(y,a);  //undo the normalization step
   835 	rightShift_(y,a);  //undo the normalization step
   836   rightShift_(r,a);  //undo the normalization step
   836 	rightShift_(r,a);  //undo the normalization step
   837 }
   837 }
   838 
   838 
   839 //do carries and borrows so each element of the bigInt x fits in bpe bits.
   839 //do carries and borrows so each element of the bigInt x fits in bpe bits.
   840 function carry_(x) {
   840 function carry_(x) {
   841   var i,k,c,b;
   841 	var i,k,c,b;
   842   k=x.length;
   842 	k=x.length;
   843   c=0;
   843 	c=0;
   844   for (i=0;i<k;i++) {
   844 	for (i=0;i<k;i++) {
   845     c+=x[i];
   845 		c+=x[i];
   846     b=0;
   846 		b=0;
   847     if (c<0) {
   847 		if (c<0) {
   848       b=-(c>>bpe);
   848 			b=-(c>>bpe);
   849       c+=b*radix;
   849 			c+=b*radix;
   850     }
   850 		}
   851     x[i]=c & mask;
   851 		x[i]=c & mask;
   852     c=(c>>bpe)-b;
   852 		c=(c>>bpe)-b;
   853   }
   853 	}
   854 }
   854 }
   855 
   855 
   856 //return x mod n for bigInt x and integer n.
   856 //return x mod n for bigInt x and integer n.
   857 function modInt(x,n) {
   857 function modInt(x,n) {
   858   var i,c=0;
   858 	var i,c=0;
   859   for (i=x.length-1; i>=0; i--)
   859 	for (i=x.length-1; i>=0; i--)
   860     c=(c*radix+x[i])%n;
   860 		c=(c*radix+x[i])%n;
   861   return c;
   861 	return c;
   862 }
   862 }
   863 
   863 
   864 //convert the integer t into a bigInt with at least the given number of bits.
   864 //convert the integer t into a bigInt with at least the given number of bits.
   865 //the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
   865 //the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
   866 //Pad the array with leading zeros so that it has at least minSize elements.
   866 //Pad the array with leading zeros so that it has at least minSize elements.
   867 //There will always be at least one leading 0 element.
   867 //There will always be at least one leading 0 element.
   868 function int2bigInt(t,bits,minSize) {   
   868 function int2bigInt(t,bits,minSize) {   
   869   var i,k;
   869 	var i,k;
   870   k=Math.ceil(bits/bpe)+1;
   870 	k=Math.ceil(bits/bpe)+1;
   871   k=minSize>k ? minSize : k;
   871 	k=minSize>k ? minSize : k;
   872   buff=new Array(k);
   872 	buff=new Array(k);
   873   copyInt_(buff,t);
   873 	copyInt_(buff,t);
   874   return buff;
   874 	return buff;
   875 }
   875 }
   876 
   876 
   877 //return the bigInt given a string representation in a given base.  
   877 //return the bigInt given a string representation in a given base.  
   878 //Pad the array with leading zeros so that it has at least minSize elements.
   878 //Pad the array with leading zeros so that it has at least minSize elements.
   879 //If base=-1, then it reads in a space-separated list of array elements in decimal.
   879 //If base=-1, then it reads in a space-separated list of array elements in decimal.
   880 //The array will always have at least one leading zero, unless base=-1.
   880 //The array will always have at least one leading zero, unless base=-1.
   881 function str2bigInt(s,base,minSize) {
   881 function str2bigInt(s,base,minSize) {
   882   var d, i, j, x, y, kk;
   882 	var d, i, j, x, y, kk;
   883   var k=s.length;
   883 	var k=s.length;
   884   if (base==-1) { //comma-separated list of array elements in decimal
   884 	if (base==-1) { //comma-separated list of array elements in decimal
   885     x=new Array(0);
   885 		x=new Array(0);
   886     for (;;) {
   886 		for (;;) {
   887       y=new Array(x.length+1);
   887 			y=new Array(x.length+1);
   888       for (i=0;i<x.length;i++)
   888 			for (i=0;i<x.length;i++)
   889         y[i+1]=x[i];
   889 				y[i+1]=x[i];
   890       y[0]=parseInt(s,10);
   890 			y[0]=parseInt(s,10);
   891       x=y;
   891 			x=y;
   892       d=s.indexOf(',',0);
   892 			d=s.indexOf(',',0);
   893       if (d<1) 
   893 			if (d<1) 
   894         break;
   894 				break;
   895       s=s.substring(d+1);
   895 			s=s.substring(d+1);
   896       if (s.length==0)
   896 			if (s.length==0)
   897         break;
   897 				break;
   898     }
   898 		}
   899     if (x.length<minSize) {
   899 		if (x.length<minSize) {
   900       y=new Array(minSize);
   900 			y=new Array(minSize);
   901       copy_(y,x);
   901 			copy_(y,x);
   902       return y;
   902 			return y;
   903     }
   903 		}
   904     return x;
   904 		return x;
   905   }
   905 	}
   906 
   906 
   907   x=int2bigInt(0,base*k,0);
   907 	x=int2bigInt(0,base*k,0);
   908   for (i=0;i<k;i++) {
   908 	for (i=0;i<k;i++) {
   909     d=digitsStr.indexOf(s.substring(i,i+1),0);
   909 		d=digitsStr.indexOf(s.substring(i,i+1),0);
   910     if (base<=36 && d>=36)  //convert lowercase to uppercase if base<=36
   910 		if (base<=36 && d>=36)  //convert lowercase to uppercase if base<=36
   911       d-=26;
   911 			d-=26;
   912     if (d<base && d>=0) {   //ignore illegal characters
   912 		if (d<base && d>=0) {   //ignore illegal characters
   913       multInt_(x,base);
   913 			multInt_(x,base);
   914       addInt_(x,d);
   914 			addInt_(x,d);
   915     }
   915 		}
   916   }
   916 	}
   917 
   917 
   918   for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
   918 	for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
   919   k=minSize>k+1 ? minSize : k+1;
   919 	k=minSize>k+1 ? minSize : k+1;
   920   y=new Array(k);
   920 	y=new Array(k);
   921   kk=k<x.length ? k : x.length;
   921 	kk=k<x.length ? k : x.length;
   922   for (i=0;i<kk;i++)
   922 	for (i=0;i<kk;i++)
   923     y[i]=x[i];
   923 		y[i]=x[i];
   924   for (;i<k;i++)
   924 	for (;i<k;i++)
   925     y[i]=0;
   925 		y[i]=0;
   926   return y;
   926 	return y;
   927 }
   927 }
   928 
   928 
   929 //is bigint x equal to integer y?
   929 //is bigint x equal to integer y?
   930 //y must have less than bpe bits
   930 //y must have less than bpe bits
   931 function equalsInt(x,y) {
   931 function equalsInt(x,y) {
   932   var i;
   932 	var i;
   933   if (x[0]!=y)
   933 	if (x[0]!=y)
   934     return 0;
   934 		return 0;
   935   for (i=1;i<x.length;i++)
   935 	for (i=1;i<x.length;i++)
   936     if (x[i])
   936 		if (x[i])
   937       return 0;
   937 			return 0;
   938   return 1;
   938 	return 1;
   939 }
   939 }
   940 
   940 
   941 //are bigints x and y equal?
   941 //are bigints x and y equal?
   942 //this works even if x and y are different lengths and have arbitrarily many leading zeros
   942 //this works even if x and y are different lengths and have arbitrarily many leading zeros
   943 function equals(x,y) {
   943 function equals(x,y) {
   944   var i;
   944 	var i;
   945   var k=x.length<y.length ? x.length : y.length;
   945 	var k=x.length<y.length ? x.length : y.length;
   946   for (i=0;i<k;i++)
   946 	for (i=0;i<k;i++)
   947     if (x[i]!=y[i])
   947 		if (x[i]!=y[i])
   948       return 0;
   948 			return 0;
   949   if (x.length>y.length) {
   949 	if (x.length>y.length) {
   950     for (;i<x.length;i++)
   950 		for (;i<x.length;i++)
   951       if (x[i])
   951 			if (x[i])
   952         return 0;
   952 				return 0;
   953   } else {
   953 	} else {
   954     for (;i<y.length;i++)
   954 		for (;i<y.length;i++)
   955       if (y[i])
   955 			if (y[i])
   956         return 0;
   956 				return 0;
   957   }
   957 	}
   958   return 1;
   958 	return 1;
   959 }
   959 }
   960 
   960 
   961 //is the bigInt x equal to zero?
   961 //is the bigInt x equal to zero?
   962 function isZero(x) {
   962 function isZero(x) {
   963   var i;
   963 	var i;
   964   for (i=0;i<x.length;i++)
   964 	for (i=0;i<x.length;i++)
   965     if (x[i])
   965 		if (x[i])
   966       return 0;
   966 			return 0;
   967   return 1;
   967 	return 1;
   968 }
   968 }
   969 
   969 
   970 //convert a bigInt into a string in a given base, from base 2 up to base 95.
   970 //convert a bigInt into a string in a given base, from base 2 up to base 95.
   971 //Base -1 prints the contents of the array representing the number.
   971 //Base -1 prints the contents of the array representing the number.
   972 function bigInt2str(x,base) {
   972 function bigInt2str(x,base) {
   973   var i,t,s="";
   973 	var i,t,s="";
   974 
   974 
   975   if (s6.length!=x.length) 
   975 	if (s6.length!=x.length) 
   976     s6=dup(x);
   976 		s6=dup(x);
   977   else
   977 	else
   978     copy_(s6,x);
   978 		copy_(s6,x);
   979 
   979 
   980   if (base==-1) { //return the list of array contents
   980 	if (base==-1) { //return the list of array contents
   981     for (i=x.length-1;i>0;i--)
   981 		for (i=x.length-1;i>0;i--)
   982       s+=x[i]+',';
   982 			s+=x[i]+',';
   983     s+=x[0];
   983 		s+=x[0];
   984   }
   984 	}
   985   else { //return it in the given base
   985 	else { //return it in the given base
   986     while (!isZero(s6)) {
   986 		while (!isZero(s6)) {
   987       t=divInt_(s6,base);  //t=s6 % base; s6=floor(s6/base);
   987 			t=divInt_(s6,base);  //t=s6 % base; s6=floor(s6/base);
   988       s=digitsStr.substring(t,t+1)+s;
   988 			s=digitsStr.substring(t,t+1)+s;
   989     }
   989 		}
   990   }
   990 	}
   991   if (s.length==0)
   991 	if (s.length==0)
   992     s="0";
   992 		s="0";
   993   return s;
   993 	return s;
   994 }
   994 }
   995 
   995 
   996 //returns a duplicate of bigInt x
   996 //returns a duplicate of bigInt x
   997 function dup(x) {
   997 function dup(x) {
   998   var i;
   998 	var i;
   999   buff=new Array(x.length);
   999 	buff=new Array(x.length);
  1000   copy_(buff,x);
  1000 	copy_(buff,x);
  1001   return buff;
  1001 	return buff;
  1002 }
  1002 }
  1003 
  1003 
  1004 //do x=y on bigInts x and y.  x must be an array at least as big as y (not counting the leading zeros in y).
  1004 //do x=y on bigInts x and y.  x must be an array at least as big as y (not counting the leading zeros in y).
  1005 function copy_(x,y) {
  1005 function copy_(x,y) {
  1006   var i;
  1006 	var i;
  1007   var k=x.length<y.length ? x.length : y.length;
  1007 	var k=x.length<y.length ? x.length : y.length;
  1008   for (i=0;i<k;i++)
  1008 	for (i=0;i<k;i++)
  1009     x[i]=y[i];
  1009 		x[i]=y[i];
  1010   for (i=k;i<x.length;i++)
  1010 	for (i=k;i<x.length;i++)
  1011     x[i]=0;
  1011 		x[i]=0;
  1012 }
  1012 }
  1013 
  1013 
  1014 //do x=y on bigInt x and integer y.  
  1014 //do x=y on bigInt x and integer y.  
  1015 function copyInt_(x,n) {
  1015 function copyInt_(x,n) {
  1016   var i,c;
  1016 	var i,c;
  1017   for (c=n,i=0;i<x.length;i++) {
  1017 	for (c=n,i=0;i<x.length;i++) {
  1018     x[i]=c & mask;
  1018 		x[i]=c & mask;
  1019     c>>=bpe;
  1019 		c>>=bpe;
  1020   }
  1020 	}
  1021 }
  1021 }
  1022 
  1022 
  1023 //do x=x+n where x is a bigInt and n is an integer.
  1023 //do x=x+n where x is a bigInt and n is an integer.
  1024 //x must be large enough to hold the result.
  1024 //x must be large enough to hold the result.
  1025 function addInt_(x,n) {
  1025 function addInt_(x,n) {
  1026   var i,k,c,b;
  1026 	var i,k,c,b;
  1027   x[0]+=n;
  1027 	x[0]+=n;
  1028   k=x.length;
  1028 	k=x.length;
  1029   c=0;
  1029 	c=0;
  1030   for (i=0;i<k;i++) {
  1030 	for (i=0;i<k;i++) {
  1031     c+=x[i];
  1031 		c+=x[i];
  1032     b=0;
  1032 		b=0;
  1033     if (c<0) {
  1033 		if (c<0) {
  1034       b=-(c>>bpe);
  1034 			b=-(c>>bpe);
  1035       c+=b*radix;
  1035 			c+=b*radix;
  1036     }
  1036 		}
  1037     x[i]=c & mask;
  1037 		x[i]=c & mask;
  1038     c=(c>>bpe)-b;
  1038 		c=(c>>bpe)-b;
  1039     if (!c) return; //stop carrying as soon as the carry_ is zero
  1039 		if (!c) return; //stop carrying as soon as the carry_ is zero
  1040   }
  1040 	}
  1041 }
  1041 }
  1042 
  1042 
  1043 //right shift bigInt x by n bits.  0 <= n < bpe.
  1043 //right shift bigInt x by n bits.  0 <= n < bpe.
  1044 function rightShift_(x,n) {
  1044 function rightShift_(x,n) {
  1045   var i;
  1045 	var i;
  1046   var k=Math.floor(n/bpe);
  1046 	var k=Math.floor(n/bpe);
  1047   if (k) {
  1047 	if (k) {
  1048     for (i=0;i<x.length-k;i++) //right shift x by k elements
  1048 		for (i=0;i<x.length-k;i++) //right shift x by k elements
  1049       x[i]=x[i+k];
  1049 			x[i]=x[i+k];
  1050     for (;i<x.length;i++)
  1050 		for (;i<x.length;i++)
  1051       x[i]=0;
  1051 			x[i]=0;
  1052     n%=bpe;
  1052 		n%=bpe;
  1053   }
  1053 	}
  1054   for (i=0;i<x.length-1;i++) {
  1054 	for (i=0;i<x.length-1;i++) {
  1055     x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
  1055 		x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
  1056   }
  1056 	}
  1057   x[i]>>=n;
  1057 	x[i]>>=n;
  1058 }
  1058 }
  1059 
  1059 
  1060 //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
  1060 //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
  1061 function halve_(x) {
  1061 function halve_(x) {
  1062   var i;
  1062 	var i;
  1063   for (i=0;i<x.length-1;i++) {
  1063 	for (i=0;i<x.length-1;i++) {
  1064     x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
  1064 		x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
  1065   }
  1065 	}
  1066   x[i]=(x[i]>>1) | (x[i] & (radix>>1));  //most significant bit stays the same
  1066 	x[i]=(x[i]>>1) | (x[i] & (radix>>1));  //most significant bit stays the same
  1067 }
  1067 }
  1068 
  1068 
  1069 //left shift bigInt x by n bits.
  1069 //left shift bigInt x by n bits.
  1070 function leftShift_(x,n) {
  1070 function leftShift_(x,n) {
  1071   var i;
  1071 	var i;
  1072   var k=Math.floor(n/bpe);
  1072 	var k=Math.floor(n/bpe);
  1073   if (k) {
  1073 	if (k) {
  1074     for (i=x.length; i>=k; i--) //left shift x by k elements
  1074 		for (i=x.length; i>=k; i--) //left shift x by k elements
  1075       x[i]=x[i-k];
  1075 			x[i]=x[i-k];
  1076     for (;i>=0;i--)
  1076 		for (;i>=0;i--)
  1077       x[i]=0;  
  1077 			x[i]=0;  
  1078     n%=bpe;
  1078 		n%=bpe;
  1079   }
  1079 	}
  1080   if (!n)
  1080 	if (!n)
  1081     return;
  1081 		return;
  1082   for (i=x.length-1;i>0;i--) {
  1082 	for (i=x.length-1;i>0;i--) {
  1083     x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
  1083 		x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
  1084   }
  1084 	}
  1085   x[i]=mask & (x[i]<<n);
  1085 	x[i]=mask & (x[i]<<n);
  1086 }
  1086 }
  1087 
  1087 
  1088 //do x=x*n where x is a bigInt and n is an integer.
  1088 //do x=x*n where x is a bigInt and n is an integer.
  1089 //x must be large enough to hold the result.
  1089 //x must be large enough to hold the result.
  1090 function multInt_(x,n) {
  1090 function multInt_(x,n) {
  1091   var i,k,c,b;
  1091 	var i,k,c,b;
  1092   if (!n)
  1092 	if (!n)
  1093     return;
  1093 		return;
  1094   k=x.length;
  1094 	k=x.length;
  1095   c=0;
  1095 	c=0;
  1096   for (i=0;i<k;i++) {
  1096 	for (i=0;i<k;i++) {
  1097     c+=x[i]*n;
  1097 		c+=x[i]*n;
  1098     b=0;
  1098 		b=0;
  1099     if (c<0) {
  1099 		if (c<0) {
  1100       b=-(c>>bpe);
  1100 			b=-(c>>bpe);
  1101       c+=b*radix;
  1101 			c+=b*radix;
  1102     }
  1102 		}
  1103     x[i]=c & mask;
  1103 		x[i]=c & mask;
  1104     c=(c>>bpe)-b;
  1104 		c=(c>>bpe)-b;
  1105   }
  1105 	}
  1106 }
  1106 }
  1107 
  1107 
  1108 //do x=floor(x/n) for bigInt x and integer n, and return the remainder
  1108 //do x=floor(x/n) for bigInt x and integer n, and return the remainder
  1109 function divInt_(x,n) {
  1109 function divInt_(x,n) {
  1110   var i,r=0,s;
  1110 	var i,r=0,s;
  1111   for (i=x.length-1;i>=0;i--) {
  1111 	for (i=x.length-1;i>=0;i--) {
  1112     s=r*radix+x[i];
  1112 		s=r*radix+x[i];
  1113     x[i]=Math.floor(s/n);
  1113 		x[i]=Math.floor(s/n);
  1114     r=s%n;
  1114 		r=s%n;
  1115   }
  1115 	}
  1116   return r;
  1116 	return r;
  1117 }
  1117 }
  1118 
  1118 
  1119 //do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
  1119 //do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
  1120 //x must be large enough to hold the answer.
  1120 //x must be large enough to hold the answer.
  1121 function linComb_(x,y,a,b) {
  1121 function linComb_(x,y,a,b) {
  1122   var i,c,k,kk;
  1122 	var i,c,k,kk;
  1123   k=x.length<y.length ? x.length : y.length;
  1123 	k=x.length<y.length ? x.length : y.length;
  1124   kk=x.length;
  1124 	kk=x.length;
  1125   for (c=0,i=0;i<k;i++) {
  1125 	for (c=0,i=0;i<k;i++) {
  1126     c+=a*x[i]+b*y[i];
  1126 		c+=a*x[i]+b*y[i];
  1127     x[i]=c & mask;
  1127 		x[i]=c & mask;
  1128     c>>=bpe;
  1128 		c>>=bpe;
  1129   }
  1129 	}
  1130   for (i=k;i<kk;i++) {
  1130 	for (i=k;i<kk;i++) {
  1131     c+=a*x[i];
  1131 		c+=a*x[i];
  1132     x[i]=c & mask;
  1132 		x[i]=c & mask;
  1133     c>>=bpe;
  1133 		c>>=bpe;
  1134   }
  1134 	}
  1135 }
  1135 }
  1136 
  1136 
  1137 //do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
  1137 //do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
  1138 //x must be large enough to hold the answer.
  1138 //x must be large enough to hold the answer.
  1139 function linCombShift_(x,y,b,ys) {
  1139 function linCombShift_(x,y,b,ys) {
  1140   var i,c,k,kk;
  1140 	var i,c,k,kk;
  1141   k=x.length<ys+y.length ? x.length : ys+y.length;
  1141 	k=x.length<ys+y.length ? x.length : ys+y.length;
  1142   kk=x.length;
  1142 	kk=x.length;
  1143   for (c=0,i=ys;i<k;i++) {
  1143 	for (c=0,i=ys;i<k;i++) {
  1144     c+=x[i]+b*y[i-ys];
  1144 		c+=x[i]+b*y[i-ys];
  1145     x[i]=c & mask;
  1145 		x[i]=c & mask;
  1146     c>>=bpe;
  1146 		c>>=bpe;
  1147   }
  1147 	}
  1148   for (i=k;c && i<kk;i++) {
  1148 	for (i=k;c && i<kk;i++) {
  1149     c+=x[i];
  1149 		c+=x[i];
  1150     x[i]=c & mask;
  1150 		x[i]=c & mask;
  1151     c>>=bpe;
  1151 		c>>=bpe;
  1152   }
  1152 	}
  1153 }
  1153 }
  1154 
  1154 
  1155 //do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
  1155 //do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
  1156 //x must be large enough to hold the answer.
  1156 //x must be large enough to hold the answer.
  1157 function addShift_(x,y,ys) {
  1157 function addShift_(x,y,ys) {
  1158   var i,c,k,kk;
  1158 	var i,c,k,kk;
  1159   k=x.length<ys+y.length ? x.length : ys+y.length;
  1159 	k=x.length<ys+y.length ? x.length : ys+y.length;
  1160   kk=x.length;
  1160 	kk=x.length;
  1161   for (c=0,i=ys;i<k;i++) {
  1161 	for (c=0,i=ys;i<k;i++) {
  1162     c+=x[i]+y[i-ys];
  1162 		c+=x[i]+y[i-ys];
  1163     x[i]=c & mask;
  1163 		x[i]=c & mask;
  1164     c>>=bpe;
  1164 		c>>=bpe;
  1165   }
  1165 	}
  1166   for (i=k;c && i<kk;i++) {
  1166 	for (i=k;c && i<kk;i++) {
  1167     c+=x[i];
  1167 		c+=x[i];
  1168     x[i]=c & mask;
  1168 		x[i]=c & mask;
  1169     c>>=bpe;
  1169 		c>>=bpe;
  1170   }
  1170 	}
  1171 }
  1171 }
  1172 
  1172 
  1173 //do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
  1173 //do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
  1174 //x must be large enough to hold the answer.
  1174 //x must be large enough to hold the answer.
  1175 function subShift_(x,y,ys) {
  1175 function subShift_(x,y,ys) {
  1176   var i,c,k,kk;
  1176 	var i,c,k,kk;
  1177   k=x.length<ys+y.length ? x.length : ys+y.length;
  1177 	k=x.length<ys+y.length ? x.length : ys+y.length;
  1178   kk=x.length;
  1178 	kk=x.length;
  1179   for (c=0,i=ys;i<k;i++) {
  1179 	for (c=0,i=ys;i<k;i++) {
  1180     c+=x[i]-y[i-ys];
  1180 		c+=x[i]-y[i-ys];
  1181     x[i]=c & mask;
  1181 		x[i]=c & mask;
  1182     c>>=bpe;
  1182 		c>>=bpe;
  1183   }
  1183 	}
  1184   for (i=k;c && i<kk;i++) {
  1184 	for (i=k;c && i<kk;i++) {
  1185     c+=x[i];
  1185 		c+=x[i];
  1186     x[i]=c & mask;
  1186 		x[i]=c & mask;
  1187     c>>=bpe;
  1187 		c>>=bpe;
  1188   }
  1188 	}
  1189 }
  1189 }
  1190 
  1190 
  1191 //do x=x-y for bigInts x and y.
  1191 //do x=x-y for bigInts x and y.
  1192 //x must be large enough to hold the answer.
  1192 //x must be large enough to hold the answer.
  1193 //negative answers will be 2s complement
  1193 //negative answers will be 2s complement
  1194 function sub_(x,y) {
  1194 function sub_(x,y) {
  1195   var i,c,k,kk;
  1195 	var i,c,k,kk;
  1196   k=x.length<y.length ? x.length : y.length;
  1196 	k=x.length<y.length ? x.length : y.length;
  1197   for (c=0,i=0;i<k;i++) {
  1197 	for (c=0,i=0;i<k;i++) {
  1198     c+=x[i]-y[i];
  1198 		c+=x[i]-y[i];
  1199     x[i]=c & mask;
  1199 		x[i]=c & mask;
  1200     c>>=bpe;
  1200 		c>>=bpe;
  1201   }
  1201 	}
  1202   for (i=k;c && i<x.length;i++) {
  1202 	for (i=k;c && i<x.length;i++) {
  1203     c+=x[i];
  1203 		c+=x[i];
  1204     x[i]=c & mask;
  1204 		x[i]=c & mask;
  1205     c>>=bpe;
  1205 		c>>=bpe;
  1206   }
  1206 	}
  1207 }
  1207 }
  1208 
  1208 
  1209 //do x=x+y for bigInts x and y.
  1209 //do x=x+y for bigInts x and y.
  1210 //x must be large enough to hold the answer.
  1210 //x must be large enough to hold the answer.
  1211 function add_(x,y) {
  1211 function add_(x,y) {
  1212   var i,c,k,kk;
  1212 	var i,c,k,kk;
  1213   k=x.length<y.length ? x.length : y.length;
  1213 	k=x.length<y.length ? x.length : y.length;
  1214   for (c=0,i=0;i<k;i++) {
  1214 	for (c=0,i=0;i<k;i++) {
  1215     c+=x[i]+y[i];
  1215 		c+=x[i]+y[i];
  1216     x[i]=c & mask;
  1216 		x[i]=c & mask;
  1217     c>>=bpe;
  1217 		c>>=bpe;
  1218   }
  1218 	}
  1219   for (i=k;c && i<x.length;i++) {
  1219 	for (i=k;c && i<x.length;i++) {
  1220     c+=x[i];
  1220 		c+=x[i];
  1221     x[i]=c & mask;
  1221 		x[i]=c & mask;
  1222     c>>=bpe;
  1222 		c>>=bpe;
  1223   }
  1223 	}
  1224 }
  1224 }
  1225 
  1225 
  1226 //do x=x*y for bigInts x and y.  This is faster when y<x.
  1226 //do x=x*y for bigInts x and y.  This is faster when y<x.
  1227 function mult_(x,y) {
  1227 function mult_(x,y) {
  1228   var i;
  1228 	var i;
  1229   if (ss.length!=2*x.length)
  1229 	if (ss.length!=2*x.length)
  1230     ss=new Array(2*x.length);
  1230 		ss=new Array(2*x.length);
  1231   copyInt_(ss,0);
  1231 	copyInt_(ss,0);
  1232   for (i=0;i<y.length;i++)
  1232 	for (i=0;i<y.length;i++)
  1233     if (y[i])
  1233 		if (y[i])
  1234       linCombShift_(ss,x,y[i],i);   //ss=1*ss+y[i]*(x<<(i*bpe))
  1234 			linCombShift_(ss,x,y[i],i);   //ss=1*ss+y[i]*(x<<(i*bpe))
  1235   copy_(x,ss);
  1235 	copy_(x,ss);
  1236 }
  1236 }
  1237 
  1237 
  1238 //do x=x mod n for bigInts x and n.
  1238 //do x=x mod n for bigInts x and n.
  1239 function mod_(x,n) {
  1239 function mod_(x,n) {
  1240   if (s4.length!=x.length)
  1240 	if (s4.length!=x.length)
  1241     s4=dup(x);
  1241 		s4=dup(x);
  1242   else
  1242 	else
  1243     copy_(s4,x);
  1243 		copy_(s4,x);
  1244   if (s5.length!=x.length)
  1244 	if (s5.length!=x.length)
  1245     s5=dup(x);  
  1245 		s5=dup(x);  
  1246   divide_(s4,n,s5,x);  //x = remainder of s4 / n
  1246 	divide_(s4,n,s5,x);  //x = remainder of s4 / n
  1247 }
  1247 }
  1248 
  1248 
  1249 //do x=x*y mod n for bigInts x,y,n.
  1249 //do x=x*y mod n for bigInts x,y,n.
  1250 //for greater speed, let y<x.
  1250 //for greater speed, let y<x.
  1251 function multMod_(x,y,n) {
  1251 function multMod_(x,y,n) {
  1252   var i;
  1252 	var i;
  1253   if (s0.length!=2*x.length)
  1253 	if (s0.length!=2*x.length)
  1254     s0=new Array(2*x.length);
  1254 		s0=new Array(2*x.length);
  1255   copyInt_(s0,0);
  1255 	copyInt_(s0,0);
  1256   for (i=0;i<y.length;i++)
  1256 	for (i=0;i<y.length;i++)
  1257     if (y[i])
  1257 		if (y[i])
  1258       linCombShift_(s0,x,y[i],i);   //s0=1*s0+y[i]*(x<<(i*bpe))
  1258 			linCombShift_(s0,x,y[i],i);   //s0=1*s0+y[i]*(x<<(i*bpe))
  1259   mod_(s0,n);
  1259 	mod_(s0,n);
  1260   copy_(x,s0);
  1260 	copy_(x,s0);
  1261 }
  1261 }
  1262 
  1262 
  1263 //do x=x*x mod n for bigInts x,n.
  1263 //do x=x*x mod n for bigInts x,n.
  1264 function squareMod_(x,n) {
  1264 function squareMod_(x,n) {
  1265   var i,j,d,c,kx,kn,k;
  1265 	var i,j,d,c,kx,kn,k;
  1266   for (kx=x.length; kx>0 && !x[kx-1]; kx--);  //ignore leading zeros in x
  1266 	for (kx=x.length; kx>0 && !x[kx-1]; kx--);  //ignore leading zeros in x
  1267   k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n
  1267 	k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n
  1268   if (s0.length!=k) 
  1268 	if (s0.length!=k) 
  1269     s0=new Array(k);
  1269 		s0=new Array(k);
  1270   copyInt_(s0,0);
  1270 	copyInt_(s0,0);
  1271   for (i=0;i<kx;i++) {
  1271 	for (i=0;i<kx;i++) {
  1272     c=s0[2*i]+x[i]*x[i];
  1272 		c=s0[2*i]+x[i]*x[i];
  1273     s0[2*i]=c & mask;
  1273 		s0[2*i]=c & mask;
  1274     c>>=bpe;
  1274 		c>>=bpe;
  1275     for (j=i+1;j<kx;j++) {
  1275 		for (j=i+1;j<kx;j++) {
  1276       c=s0[i+j]+2*x[i]*x[j]+c;
  1276 			c=s0[i+j]+2*x[i]*x[j]+c;
  1277       s0[i+j]=(c & mask);
  1277 			s0[i+j]=(c & mask);
  1278       c>>=bpe;
  1278 			c>>=bpe;
  1279     }
  1279 		}
  1280     s0[i+kx]=c;
  1280 		s0[i+kx]=c;
  1281   }
  1281 	}
  1282   mod_(s0,n);
  1282 	mod_(s0,n);
  1283   copy_(x,s0);
  1283 	copy_(x,s0);
  1284 }
  1284 }
  1285 
  1285 
  1286 //return x with exactly k leading zero elements
  1286 //return x with exactly k leading zero elements
  1287 function bigint_trim(x,k) {
  1287 function bigint_trim(x,k) {
  1288   var i,y;
  1288 	var i,y;
  1289   for (i=x.length; i>0 && !x[i-1]; i--);
  1289 	for (i=x.length; i>0 && !x[i-1]; i--);
  1290   y=new Array(i+k);
  1290 	y=new Array(i+k);
  1291   copy_(y,x);
  1291 	copy_(y,x);
  1292   return y;
  1292 	return y;
  1293 }
  1293 }
  1294 
  1294 
  1295 //do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation.  0**0=1.
  1295 //do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation.  0**0=1.
  1296 //this is faster when n is odd.  x usually needs to have as many elements as n.
  1296 //this is faster when n is odd.  x usually needs to have as many elements as n.
  1297 function powMod_(x,y,n) {
  1297 function powMod_(x,y,n) {
  1298   var k1,k2,kn,np;
  1298 	var k1,k2,kn,np;
  1299   if(s7.length!=n.length)
  1299 	if(s7.length!=n.length)
  1300     s7=dup(n);
  1300 		s7=dup(n);
  1301 
  1301 
  1302   //for even modulus, use a simple square-and-multiply algorithm,
  1302 	//for even modulus, use a simple square-and-multiply algorithm,
  1303   //rather than using the more complex Montgomery algorithm.
  1303 	//rather than using the more complex Montgomery algorithm.
  1304   if ((n[0]&1)==0) {
  1304 	if ((n[0]&1)==0) {
  1305     copy_(s7,x);
  1305 		copy_(s7,x);
  1306     copyInt_(x,1);
  1306 		copyInt_(x,1);
  1307     while(!equalsInt(y,0)) {
  1307 		while(!equalsInt(y,0)) {
  1308       if (y[0]&1)
  1308 			if (y[0]&1)
  1309         multMod_(x,s7,n);
  1309 				multMod_(x,s7,n);
  1310       divInt_(y,2);
  1310 			divInt_(y,2);
  1311       squareMod_(s7,n); 
  1311 			squareMod_(s7,n); 
  1312     }
  1312 		}
  1313     return;
  1313 		return;
  1314   }
  1314 	}
  1315 
  1315 
  1316   //calculate np from n for the Montgomery multiplications
  1316 	//calculate np from n for the Montgomery multiplications
  1317   copyInt_(s7,0);
  1317 	copyInt_(s7,0);
  1318   for (kn=n.length;kn>0 && !n[kn-1];kn--);
  1318 	for (kn=n.length;kn>0 && !n[kn-1];kn--);
  1319   np=radix-inverseModInt(modInt(n,radix),radix);
  1319 	np=radix-inverseModInt(modInt(n,radix),radix);
  1320   s7[kn]=1;
  1320 	s7[kn]=1;
  1321   multMod_(x ,s7,n);   // x = x * 2**(kn*bp) mod n
  1321 	multMod_(x ,s7,n);   // x = x * 2**(kn*bp) mod n
  1322 
  1322 
  1323   if (s3.length!=x.length)
  1323 	if (s3.length!=x.length)
  1324     s3=dup(x);
  1324 		s3=dup(x);
  1325   else
  1325 	else
  1326     copy_(s3,x);
  1326 		copy_(s3,x);
  1327 
  1327 
  1328   for (k1=y.length-1;k1>0 & !y[k1]; k1--);  //k1=first nonzero element of y
  1328 	for (k1=y.length-1;k1>0 & !y[k1]; k1--);  //k1=first nonzero element of y
  1329   if (y[k1]==0) {  //anything to the 0th power is 1
  1329 	if (y[k1]==0) {  //anything to the 0th power is 1
  1330     copyInt_(x,1);
  1330 		copyInt_(x,1);
  1331     return;
  1331 		return;
  1332   }
  1332 	}
  1333   for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1);  //k2=position of first 1 bit in y[k1]
  1333 	for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1);  //k2=position of first 1 bit in y[k1]
  1334   for (;;) {
  1334 	for (;;) {
  1335     if (!(k2>>=1)) {  //look at next bit of y
  1335 		if (!(k2>>=1)) {  //look at next bit of y
  1336       k1--;
  1336 			k1--;
  1337       if (k1<0) {
  1337 			if (k1<0) {
  1338         mont_(x,one,n,np);
  1338 				mont_(x,one,n,np);
  1339         return;
  1339 				return;
  1340       }
  1340 			}
  1341       k2=1<<(bpe-1);
  1341 			k2=1<<(bpe-1);
  1342     }    
  1342 		}    
  1343     mont_(x,x,n,np);
  1343 		mont_(x,x,n,np);
  1344 
  1344 
  1345     if (k2 & y[k1]) //if next bit is a 1
  1345 		if (k2 & y[k1]) //if next bit is a 1
  1346       mont_(x,s3,n,np);
  1346 			mont_(x,s3,n,np);
  1347   }
  1347 	}
  1348 }    
  1348 }    
  1349 
  1349 
  1350 //do x=x*y*Ri mod n for bigInts x,y,n, 
  1350 //do x=x*y*Ri mod n for bigInts x,y,n, 
  1351 //  where Ri = 2**(-kn*bpe) mod n, and kn is the 
  1351 //  where Ri = 2**(-kn*bpe) mod n, and kn is the 
  1352 //  number of elements in the n array, not 
  1352 //  number of elements in the n array, not 
  1356 //must have:
  1356 //must have:
  1357 //  x,y < n
  1357 //  x,y < n
  1358 //  n is odd
  1358 //  n is odd
  1359 //  np = -(n^(-1)) mod radix
  1359 //  np = -(n^(-1)) mod radix
  1360 function mont_(x,y,n,np) {
  1360 function mont_(x,y,n,np) {
  1361   var i,j,c,ui,t;
  1361 	var i,j,c,ui,t;
  1362   var kn=n.length;
  1362 	var kn=n.length;
  1363   var ky=y.length;
  1363 	var ky=y.length;
  1364 
  1364 
  1365   if (sa.length!=kn)
  1365 	if (sa.length!=kn)
  1366     sa=new Array(kn);
  1366 		sa=new Array(kn);
  1367 
  1367 
  1368   for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
  1368 	for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
  1369   //this function sometimes gives wrong answers when the next line is uncommented
  1369 	//this function sometimes gives wrong answers when the next line is uncommented
  1370   //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
  1370 	//for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
  1371 
  1371 
  1372   copyInt_(sa,0);
  1372 	copyInt_(sa,0);
  1373 
  1373 
  1374   //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
  1374 	//the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
  1375   for (i=0; i<kn; i++) {
  1375 	for (i=0; i<kn; i++) {
  1376     t=sa[0]+x[i]*y[0];
  1376 		t=sa[0]+x[i]*y[0];
  1377     ui=((t & mask) * np) & mask;  //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
  1377 		ui=((t & mask) * np) & mask;  //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
  1378     c=(t+ui*n[0]) >> bpe;
  1378 		c=(t+ui*n[0]) >> bpe;
  1379     t=x[i];
  1379 		t=x[i];
  1380 
  1380 
  1381     //do sa=(sa+x[i]*y+ui*n)/b   where b=2**bpe
  1381 		//do sa=(sa+x[i]*y+ui*n)/b   where b=2**bpe
  1382     for (j=1;j<ky;j++) { 
  1382 		for (j=1;j<ky;j++) { 
  1383       c+=sa[j]+t*y[j]+ui*n[j];
  1383 			c+=sa[j]+t*y[j]+ui*n[j];
  1384       sa[j-1]=c & mask;
  1384 			sa[j-1]=c & mask;
  1385       c>>=bpe;
  1385 			c>>=bpe;
  1386     }    
  1386 		}    
  1387     for (;j<kn;j++) { 
  1387 		for (;j<kn;j++) { 
  1388       c+=sa[j]+ui*n[j];
  1388 			c+=sa[j]+ui*n[j];
  1389       sa[j-1]=c & mask;
  1389 			sa[j-1]=c & mask;
  1390       c>>=bpe;
  1390 			c>>=bpe;
  1391     }    
  1391 		}    
  1392     sa[j-1]=c & mask;
  1392 		sa[j-1]=c & mask;
  1393   }
  1393 	}
  1394 
  1394 
  1395   if (!greater(n,sa))
  1395 	if (!greater(n,sa))
  1396     sub_(sa,n);
  1396 		sub_(sa,n);
  1397   copy_(x,sa);
  1397 	copy_(x,sa);
  1398 }
  1398 }
  1399 
  1399 
  1400 
  1400 
  1401 /* rijndael.js      Rijndael Reference Implementation
  1401 /* rijndael.js      Rijndael Reference Implementation
  1402    Copyright (c) 2001 Fritz Schneider
  1402  	Copyright (c) 2001 Fritz Schneider
  1403  
  1403  
  1404  This software is provided as-is, without express or implied warranty.  
  1404  This software is provided as-is, without express or implied warranty.  
  1405  Permission to use, copy, modify, distribute or sell this software, with or
  1405  Permission to use, copy, modify, distribute or sell this software, with or
  1406  without fee, for any purpose and by any individual or organization, is hereby
  1406  without fee, for any purpose and by any individual or organization, is hereby
  1407  granted, provided that the above copyright notice and this paragraph appear 
  1407  granted, provided that the above copyright notice and this paragraph appear 
  1408  in all copies. Distribution as a part of an application or binary must
  1408  in all copies. Distribution as a part of an application or binary must
  1409  include the above copyright notice in the documentation and/or other materials
  1409  include the above copyright notice in the documentation and/or other materials
  1410  provided with the application or distribution.
  1410  provided with the application or distribution.
  1411 
  1411 
  1412 
  1412 
  1413    As the above disclaimer notes, you are free to use this code however you
  1413  	As the above disclaimer notes, you are free to use this code however you
  1414    want. However, I would request that you send me an email 
  1414  	want. However, I would request that you send me an email 
  1415    (fritz /at/ cs /dot/ ucsd /dot/ edu) to say hi if you find this code useful
  1415  	(fritz /at/ cs /dot/ ucsd /dot/ edu) to say hi if you find this code useful
  1416    or instructional. Seeing that people are using the code acts as 
  1416  	or instructional. Seeing that people are using the code acts as 
  1417    encouragement for me to continue development. If you *really* want to thank
  1417  	encouragement for me to continue development. If you *really* want to thank
  1418    me you can buy the book I wrote with Thomas Powell, _JavaScript:
  1418  	me you can buy the book I wrote with Thomas Powell, _JavaScript:
  1419    _The_Complete_Reference_ :)
  1419  	_The_Complete_Reference_ :)
  1420 
  1420 
  1421    This code is an UNOPTIMIZED REFERENCE implementation of Rijndael. 
  1421  	This code is an UNOPTIMIZED REFERENCE implementation of Rijndael. 
  1422    If there is sufficient interest I can write an optimized (word-based, 
  1422  	If there is sufficient interest I can write an optimized (word-based, 
  1423    table-driven) version, although you might want to consider using a 
  1423  	table-driven) version, although you might want to consider using a 
  1424    compiled language if speed is critical to your application. As it stands,
  1424  	compiled language if speed is critical to your application. As it stands,
  1425    one run of the monte carlo test (10,000 encryptions) can take up to 
  1425  	one run of the monte carlo test (10,000 encryptions) can take up to 
  1426    several minutes, depending upon your processor. You shouldn't expect more
  1426  	several minutes, depending upon your processor. You shouldn't expect more
  1427    than a few kilobytes per second in throughput.
  1427  	than a few kilobytes per second in throughput.
  1428 
  1428 
  1429    Also note that there is very little error checking in these functions. 
  1429  	Also note that there is very little error checking in these functions. 
  1430    Doing proper error checking is always a good idea, but the ideal 
  1430  	Doing proper error checking is always a good idea, but the ideal 
  1431    implementation (using the instanceof operator and exceptions) requires
  1431  	implementation (using the instanceof operator and exceptions) requires
  1432    IE5+/NS6+, and I've chosen to implement this code so that it is compatible
  1432  	IE5+/NS6+, and I've chosen to implement this code so that it is compatible
  1433    with IE4/NS4. 
  1433  	with IE4/NS4. 
  1434 
  1434 
  1435    And finally, because JavaScript doesn't have an explicit byte/char data 
  1435  	And finally, because JavaScript doesn't have an explicit byte/char data 
  1436    type (although JavaScript 2.0 most likely will), when I refer to "byte" 
  1436  	type (although JavaScript 2.0 most likely will), when I refer to "byte" 
  1437    in this code I generally mean "32 bit integer with value in the interval 
  1437  	in this code I generally mean "32 bit integer with value in the interval 
  1438    [0,255]" which I treat as a byte.
  1438  	[0,255]" which I treat as a byte.
  1439 
  1439 
  1440    See http://www-cse.ucsd.edu/~fritz/rijndael.html for more documentation
  1440  	See http://www-cse.ucsd.edu/~fritz/rijndael.html for more documentation
  1441    of the (very simple) API provided by this code.
  1441  	of the (very simple) API provided by this code.
  1442 
  1442 
  1443                                                Fritz Schneider
  1443  																							Fritz Schneider
  1444                                                fritz at cs.ucsd.edu
  1444  																							fritz at cs.ucsd.edu
  1445  
  1445  
  1446 */
  1446 */
  1447 
  1447 
  1448 // Rijndael parameters --  Valid values are 128, 192, or 256
  1448 // Rijndael parameters --  Valid values are 128, 192, or 256
  1449 
  1449 
  1458 //       are 2d arrays of the form state[4][Nb].
  1458 //       are 2d arrays of the form state[4][Nb].
  1459 
  1459 
  1460 
  1460 
  1461 // The number of rounds for the cipher, indexed by [Nk][Nb]
  1461 // The number of rounds for the cipher, indexed by [Nk][Nb]
  1462 var roundsArray = [ ,,,,[,,,,10,, 12,, 14],, 
  1462 var roundsArray = [ ,,,,[,,,,10,, 12,, 14],, 
  1463                         [,,,,12,, 12,, 14],, 
  1463 												[,,,,12,, 12,, 14],, 
  1464                         [,,,,14,, 14,, 14] ];
  1464 												[,,,,14,, 14,, 14] ];
  1465 
  1465 
  1466 // The number of bytes to shift by in shiftRow, indexed by [Nb][row]
  1466 // The number of bytes to shift by in shiftRow, indexed by [Nb][row]
  1467 var shiftOffsets = [ ,,,,[,1, 2, 3],,[,1, 2, 3],,[,1, 3, 4] ];
  1467 var shiftOffsets = [ ,,,,[,1, 2, 3],,[,1, 2, 3],,[,1, 3, 4] ];
  1468 
  1468 
  1469 // The round constants used in subkey expansion
  1469 // The round constants used in subkey expansion
  1485 190,  57,  74,  76,  88, 207, 208, 239, 170, 251,  67,  77,  51, 133,  69, 
  1485 190,  57,  74,  76,  88, 207, 208, 239, 170, 251,  67,  77,  51, 133,  69, 
  1486 249,   2, 127,  80,  60, 159, 168,  81, 163,  64, 143, 146, 157,  56, 245, 
  1486 249,   2, 127,  80,  60, 159, 168,  81, 163,  64, 143, 146, 157,  56, 245, 
  1487 188, 182, 218,  33,  16, 255, 243, 210, 205,  12,  19, 236,  95, 151,  68,  
  1487 188, 182, 218,  33,  16, 255, 243, 210, 205,  12,  19, 236,  95, 151,  68,  
  1488 23,  196, 167, 126,  61, 100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 
  1488 23,  196, 167, 126,  61, 100,  93,  25, 115,  96, 129,  79, 220,  34,  42, 
  1489 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 224,  50,  58,  10,  73,
  1489 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 224,  50,  58,  10,  73,
  1490   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 
  1490 	6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 
  1491 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,  
  1491 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,  
  1492  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 112,  62, 
  1492  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 112,  62, 
  1493 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 225,
  1493 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 225,
  1494 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223,
  1494 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223,
  1495 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  
  1495 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  
  1516  23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12,
  1516  23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12,
  1517 125 ];
  1517 125 ];
  1518 
  1518 
  1519 function str_split(string, chunklen)
  1519 function str_split(string, chunklen)
  1520 {
  1520 {
  1521   if(!chunklen) chunklen = 1;
  1521 	if(!chunklen) chunklen = 1;
  1522   ret = new Array();
  1522 	ret = new Array();
  1523   for ( i = 0; i < string.length; i+=chunklen )
  1523 	for ( i = 0; i < string.length; i+=chunklen )
  1524   {
  1524 	{
  1525     ret[ret.length] = string.slice(i, i+chunklen);
  1525 		ret[ret.length] = string.slice(i, i+chunklen);
  1526   }
  1526 	}
  1527   return ret;
  1527 	return ret;
  1528 }
  1528 }
  1529 
  1529 
  1530 // This method circularly shifts the array left by the number of elements
  1530 // This method circularly shifts the array left by the number of elements
  1531 // given in its parameter. It returns the resulting array and is used for 
  1531 // given in its parameter. It returns the resulting array and is used for 
  1532 // the ShiftRow step. Note that shift() and push() could be used for a more 
  1532 // the ShiftRow step. Note that shift() and push() could be used for a more 
  1533 // elegant solution, but they require IE5.5+, so I chose to do it manually. 
  1533 // elegant solution, but they require IE5.5+, so I chose to do it manually. 
  1534 
  1534 
  1535 function cyclicShiftLeft(theArray, positions) {
  1535 function cyclicShiftLeft(theArray, positions) {
  1536   var temp = theArray.slice(0, positions);
  1536 	var temp = theArray.slice(0, positions);
  1537   theArray = theArray.slice(positions).concat(temp);
  1537 	theArray = theArray.slice(positions).concat(temp);
  1538   return theArray;
  1538 	return theArray;
  1539 }
  1539 }
  1540 
  1540 
  1541 // Cipher parameters ... do not change these
  1541 // Cipher parameters ... do not change these
  1542 var Nk = keySizeInBits / 32;                   
  1542 var Nk = keySizeInBits / 32;                   
  1543 var Nb = blockSizeInBits / 32;
  1543 var Nb = blockSizeInBits / 32;
  1544 var Nr = roundsArray[Nk][Nb];
  1544 var Nr = roundsArray[Nk][Nb];
  1545 
  1545 
  1546 // Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.
  1546 // Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.
  1547 
  1547 
  1548 function xtime(poly) {
  1548 function xtime(poly) {
  1549   poly <<= 1;
  1549 	poly <<= 1;
  1550   return ((poly & 0x100) ? (poly ^ 0x11B) : (poly));
  1550 	return ((poly & 0x100) ? (poly ^ 0x11B) : (poly));
  1551 }
  1551 }
  1552 
  1552 
  1553 // Multiplies the two elements of GF(2^8) together and returns the result.
  1553 // Multiplies the two elements of GF(2^8) together and returns the result.
  1554 // See the Rijndael spec, but should be straightforward: for each power of
  1554 // See the Rijndael spec, but should be straightforward: for each power of
  1555 // the indeterminant that has a 1 coefficient in x, add y times that power
  1555 // the indeterminant that has a 1 coefficient in x, add y times that power
  1556 // to the result. x and y should be bytes representing elements of GF(2^8)
  1556 // to the result. x and y should be bytes representing elements of GF(2^8)
  1557 
  1557 
  1558 function mult_GF256(x, y) {
  1558 function mult_GF256(x, y) {
  1559   var bit, result = 0;
  1559 	var bit, result = 0;
  1560   
  1560 	
  1561   for (bit = 1; bit < 256; bit *= 2, y = xtime(y)) {
  1561 	for (bit = 1; bit < 256; bit *= 2, y = xtime(y)) {
  1562     if (x & bit) 
  1562 		if (x & bit) 
  1563       result ^= y;
  1563 			result ^= y;
  1564   }
  1564 	}
  1565   return result;
  1565 	return result;
  1566 }
  1566 }
  1567 
  1567 
  1568 // Performs the substitution step of the cipher. State is the 2d array of
  1568 // Performs the substitution step of the cipher. State is the 2d array of
  1569 // state information (see spec) and direction is string indicating whether
  1569 // state information (see spec) and direction is string indicating whether
  1570 // we are performing the forward substitution ("encrypt") or inverse 
  1570 // we are performing the forward substitution ("encrypt") or inverse 
  1571 // substitution (anything else)
  1571 // substitution (anything else)
  1572 
  1572 
  1573 function byteSub(state, direction) {
  1573 function byteSub(state, direction) {
  1574   var S;
  1574 	var S;
  1575   if (direction == "encrypt")           // Point S to the SBox we're using
  1575 	if (direction == "encrypt")           // Point S to the SBox we're using
  1576     S = SBox;
  1576 		S = SBox;
  1577   else
  1577 	else
  1578     S = SBoxInverse;
  1578 		S = SBoxInverse;
  1579   for (var i = 0; i < 4; i++)           // Substitute for every byte in state
  1579 	for (var i = 0; i < 4; i++)           // Substitute for every byte in state
  1580     for (var j = 0; j < Nb; j++)
  1580 		for (var j = 0; j < Nb; j++)
  1581        state[i][j] = S[state[i][j]];
  1581  			state[i][j] = S[state[i][j]];
  1582 }
  1582 }
  1583 
  1583 
  1584 // Performs the row shifting step of the cipher.
  1584 // Performs the row shifting step of the cipher.
  1585 
  1585 
  1586 function shiftRow(state, direction) {
  1586 function shiftRow(state, direction) {
  1587   for (var i=1; i<4; i++)               // Row 0 never shifts
  1587 	for (var i=1; i<4; i++)               // Row 0 never shifts
  1588     if (direction == "encrypt")
  1588 		if (direction == "encrypt")
  1589        state[i] = cyclicShiftLeft(state[i], shiftOffsets[Nb][i]);
  1589  			state[i] = cyclicShiftLeft(state[i], shiftOffsets[Nb][i]);
  1590     else
  1590 		else
  1591        state[i] = cyclicShiftLeft(state[i], Nb - shiftOffsets[Nb][i]);
  1591  			state[i] = cyclicShiftLeft(state[i], Nb - shiftOffsets[Nb][i]);
  1592 
  1592 
  1593 }
  1593 }
  1594 
  1594 
  1595 // Performs the column mixing step of the cipher. Most of these steps can
  1595 // Performs the column mixing step of the cipher. Most of these steps can
  1596 // be combined into table lookups on 32bit values (at least for encryption)
  1596 // be combined into table lookups on 32bit values (at least for encryption)
  1597 // to greatly increase the speed. 
  1597 // to greatly increase the speed. 
  1598 
  1598 
  1599 function mixColumn(state, direction) {
  1599 function mixColumn(state, direction) {
  1600   var b = [];                            // Result of matrix multiplications
  1600 	var b = [];                            // Result of matrix multiplications
  1601   for (var j = 0; j < Nb; j++) {         // Go through each column...
  1601 	for (var j = 0; j < Nb; j++) {         // Go through each column...
  1602     for (var i = 0; i < 4; i++) {        // and for each row in the column...
  1602 		for (var i = 0; i < 4; i++) {        // and for each row in the column...
  1603       if (direction == "encrypt")
  1603 			if (direction == "encrypt")
  1604         b[i] = mult_GF256(state[i][j], 2) ^          // perform mixing
  1604 				b[i] = mult_GF256(state[i][j], 2) ^          // perform mixing
  1605                mult_GF256(state[(i+1)%4][j], 3) ^ 
  1605  							mult_GF256(state[(i+1)%4][j], 3) ^ 
  1606                state[(i+2)%4][j] ^ 
  1606  							state[(i+2)%4][j] ^ 
  1607                state[(i+3)%4][j];
  1607  							state[(i+3)%4][j];
  1608       else 
  1608 			else 
  1609         b[i] = mult_GF256(state[i][j], 0xE) ^ 
  1609 				b[i] = mult_GF256(state[i][j], 0xE) ^ 
  1610                mult_GF256(state[(i+1)%4][j], 0xB) ^
  1610  							mult_GF256(state[(i+1)%4][j], 0xB) ^
  1611                mult_GF256(state[(i+2)%4][j], 0xD) ^
  1611  							mult_GF256(state[(i+2)%4][j], 0xD) ^
  1612                mult_GF256(state[(i+3)%4][j], 9);
  1612  							mult_GF256(state[(i+3)%4][j], 9);
  1613     }
  1613 		}
  1614     for (var i = 0; i < 4; i++)          // Place result back into column
  1614 		for (var i = 0; i < 4; i++)          // Place result back into column
  1615       state[i][j] = b[i];
  1615 			state[i][j] = b[i];
  1616   }
  1616 	}
  1617 }
  1617 }
  1618 
  1618 
  1619 // Adds the current round key to the state information. Straightforward.
  1619 // Adds the current round key to the state information. Straightforward.
  1620 
  1620 
  1621 function addRoundKey(state, roundKey) {
  1621 function addRoundKey(state, roundKey) {
  1622   for (var j = 0; j < Nb; j++) {                 // Step through columns...
  1622 	for (var j = 0; j < Nb; j++) {                 // Step through columns...
  1623     state[0][j] ^= (roundKey[j] & 0xFF);         // and XOR
  1623 		state[0][j] ^= (roundKey[j] & 0xFF);         // and XOR
  1624     state[1][j] ^= ((roundKey[j]>>8) & 0xFF);
  1624 		state[1][j] ^= ((roundKey[j]>>8) & 0xFF);
  1625     state[2][j] ^= ((roundKey[j]>>16) & 0xFF);
  1625 		state[2][j] ^= ((roundKey[j]>>16) & 0xFF);
  1626     state[3][j] ^= ((roundKey[j]>>24) & 0xFF);
  1626 		state[3][j] ^= ((roundKey[j]>>24) & 0xFF);
  1627   }
  1627 	}
  1628 }
  1628 }
  1629 
  1629 
  1630 // This function creates the expanded key from the input (128/192/256-bit)
  1630 // This function creates the expanded key from the input (128/192/256-bit)
  1631 // key. The parameter key is an array of bytes holding the value of the key.
  1631 // key. The parameter key is an array of bytes holding the value of the key.
  1632 // The returned value is an array whose elements are the 32-bit words that 
  1632 // The returned value is an array whose elements are the 32-bit words that 
  1633 // make up the expanded key.
  1633 // make up the expanded key.
  1634 
  1634 
  1635 function keyExpansion(key) {
  1635 function keyExpansion(key) {
  1636   var expandedKey = new Array();
  1636 	var expandedKey = new Array();
  1637   var temp;
  1637 	var temp;
  1638 
  1638 
  1639   // in case the key size or parameters were changed...
  1639 	// in case the key size or parameters were changed...
  1640   Nk = keySizeInBits / 32;                   
  1640 	Nk = keySizeInBits / 32;                   
  1641   Nb = blockSizeInBits / 32;
  1641 	Nb = blockSizeInBits / 32;
  1642   Nr = roundsArray[Nk][Nb];
  1642 	Nr = roundsArray[Nk][Nb];
  1643 
  1643 
  1644   for (var j=0; j < Nk; j++)     // Fill in input key first
  1644 	for (var j=0; j < Nk; j++)     // Fill in input key first
  1645     expandedKey[j] = 
  1645 		expandedKey[j] = 
  1646       (key[4*j]) | (key[4*j+1]<<8) | (key[4*j+2]<<16) | (key[4*j+3]<<24);
  1646 			(key[4*j]) | (key[4*j+1]<<8) | (key[4*j+2]<<16) | (key[4*j+3]<<24);
  1647 
  1647 
  1648   // Now walk down the rest of the array filling in expanded key bytes as
  1648 	// Now walk down the rest of the array filling in expanded key bytes as
  1649   // per Rijndael's spec
  1649 	// per Rijndael's spec
  1650   for (j = Nk; j < Nb * (Nr + 1); j++) {    // For each word of expanded key
  1650 	for (j = Nk; j < Nb * (Nr + 1); j++) {    // For each word of expanded key
  1651     temp = expandedKey[j - 1];
  1651 		temp = expandedKey[j - 1];
  1652     if (j % Nk == 0) 
  1652 		if (j % Nk == 0) 
  1653       temp = ( (SBox[(temp>>8) & 0xFF]) |
  1653 			temp = ( (SBox[(temp>>8) & 0xFF]) |
  1654                (SBox[(temp>>16) & 0xFF]<<8) |
  1654  							(SBox[(temp>>16) & 0xFF]<<8) |
  1655                (SBox[(temp>>24) & 0xFF]<<16) |
  1655  							(SBox[(temp>>24) & 0xFF]<<16) |
  1656                (SBox[temp & 0xFF]<<24) ) ^ Rcon[Math.floor(j / Nk) - 1];
  1656  							(SBox[temp & 0xFF]<<24) ) ^ Rcon[Math.floor(j / Nk) - 1];
  1657     else if (Nk > 6 && j % Nk == 4)
  1657 		else if (Nk > 6 && j % Nk == 4)
  1658       temp = (SBox[(temp>>24) & 0xFF]<<24) |
  1658 			temp = (SBox[(temp>>24) & 0xFF]<<24) |
  1659              (SBox[(temp>>16) & 0xFF]<<16) |
  1659  						(SBox[(temp>>16) & 0xFF]<<16) |
  1660              (SBox[(temp>>8) & 0xFF]<<8) |
  1660  						(SBox[(temp>>8) & 0xFF]<<8) |
  1661              (SBox[temp & 0xFF]);
  1661  						(SBox[temp & 0xFF]);
  1662     expandedKey[j] = expandedKey[j-Nk] ^ temp;
  1662 		expandedKey[j] = expandedKey[j-Nk] ^ temp;
  1663   }
  1663 	}
  1664   return expandedKey;
  1664 	return expandedKey;
  1665 }
  1665 }
  1666 
  1666 
  1667 // Rijndael's round functions... 
  1667 // Rijndael's round functions... 
  1668 
  1668 
  1669 function Round(state, roundKey) {
  1669 function Round(state, roundKey) {
  1670   byteSub(state, "encrypt");
  1670 	byteSub(state, "encrypt");
  1671   shiftRow(state, "encrypt");
  1671 	shiftRow(state, "encrypt");
  1672   mixColumn(state, "encrypt");
  1672 	mixColumn(state, "encrypt");
  1673   addRoundKey(state, roundKey);
  1673 	addRoundKey(state, roundKey);
  1674 }
  1674 }
  1675 
  1675 
  1676 function InverseRound(state, roundKey) {
  1676 function InverseRound(state, roundKey) {
  1677   addRoundKey(state, roundKey);
  1677 	addRoundKey(state, roundKey);
  1678   mixColumn(state, "decrypt");
  1678 	mixColumn(state, "decrypt");
  1679   shiftRow(state, "decrypt");
  1679 	shiftRow(state, "decrypt");
  1680   byteSub(state, "decrypt");
  1680 	byteSub(state, "decrypt");
  1681 }
  1681 }
  1682 
  1682 
  1683 function FinalRound(state, roundKey) {
  1683 function FinalRound(state, roundKey) {
  1684   byteSub(state, "encrypt");
  1684 	byteSub(state, "encrypt");
  1685   shiftRow(state, "encrypt");
  1685 	shiftRow(state, "encrypt");
  1686   addRoundKey(state, roundKey);
  1686 	addRoundKey(state, roundKey);
  1687 }
  1687 }
  1688 
  1688 
  1689 function InverseFinalRound(state, roundKey){
  1689 function InverseFinalRound(state, roundKey){
  1690   addRoundKey(state, roundKey);
  1690 	addRoundKey(state, roundKey);
  1691   shiftRow(state, "decrypt");
  1691 	shiftRow(state, "decrypt");
  1692   byteSub(state, "decrypt");  
  1692 	byteSub(state, "decrypt");  
  1693 }
  1693 }
  1694 
  1694 
  1695 // encrypt is the basic encryption function. It takes parameters
  1695 // encrypt is the basic encryption function. It takes parameters
  1696 // block, an array of bytes representing a plaintext block, and expandedKey,
  1696 // block, an array of bytes representing a plaintext block, and expandedKey,
  1697 // an array of words representing the expanded key previously returned by
  1697 // an array of words representing the expanded key previously returned by
  1698 // keyExpansion(). The ciphertext block is returned as an array of bytes.
  1698 // keyExpansion(). The ciphertext block is returned as an array of bytes.
  1699 
  1699 
  1700 function encrypt(block, expandedKey) {
  1700 function encrypt(block, expandedKey) {
  1701   var i;  
  1701 	var i;  
  1702   if (!block || block.length*8 != blockSizeInBits)
  1702 	if (!block || block.length*8 != blockSizeInBits)
  1703      return; 
  1703  		return; 
  1704   if (!expandedKey)
  1704 	if (!expandedKey)
  1705      return;
  1705  		return;
  1706 
  1706 
  1707   block = packBytes(block);
  1707 	block = packBytes(block);
  1708   addRoundKey(block, expandedKey);
  1708 	addRoundKey(block, expandedKey);
  1709   for (i=1; i<Nr; i++) 
  1709 	for (i=1; i<Nr; i++) 
  1710     Round(block, expandedKey.slice(Nb*i, Nb*(i+1)));
  1710 		Round(block, expandedKey.slice(Nb*i, Nb*(i+1)));
  1711   FinalRound(block, expandedKey.slice(Nb*Nr)); 
  1711 	FinalRound(block, expandedKey.slice(Nb*Nr)); 
  1712   return unpackBytes(block);
  1712 	return unpackBytes(block);
  1713 }
  1713 }
  1714 
  1714 
  1715 // decrypt is the basic decryption function. It takes parameters
  1715 // decrypt is the basic decryption function. It takes parameters
  1716 // block, an array of bytes representing a ciphertext block, and expandedKey,
  1716 // block, an array of bytes representing a ciphertext block, and expandedKey,
  1717 // an array of words representing the expanded key previously returned by
  1717 // an array of words representing the expanded key previously returned by
  1718 // keyExpansion(). The decrypted block is returned as an array of bytes.
  1718 // keyExpansion(). The decrypted block is returned as an array of bytes.
  1719 
  1719 
  1720 function decrypt(block, expandedKey) {
  1720 function decrypt(block, expandedKey) {
  1721   var i;
  1721 	var i;
  1722   if (!block || block.length*8 != blockSizeInBits)
  1722 	if (!block || block.length*8 != blockSizeInBits)
  1723      return;
  1723  		return;
  1724   if (!expandedKey)
  1724 	if (!expandedKey)
  1725      return;
  1725  		return;
  1726 
  1726 
  1727   block = packBytes(block);
  1727 	block = packBytes(block);
  1728   InverseFinalRound(block, expandedKey.slice(Nb*Nr)); 
  1728 	InverseFinalRound(block, expandedKey.slice(Nb*Nr)); 
  1729   for (i = Nr - 1; i>0; i--) 
  1729 	for (i = Nr - 1; i>0; i--) 
  1730     InverseRound(block, expandedKey.slice(Nb*i, Nb*(i+1)));
  1730 		InverseRound(block, expandedKey.slice(Nb*i, Nb*(i+1)));
  1731   addRoundKey(block, expandedKey);
  1731 	addRoundKey(block, expandedKey);
  1732   return unpackBytes(block);
  1732 	return unpackBytes(block);
  1733 }
  1733 }
  1734 
  1734 
  1735 // This function packs an array of bytes into the four row form defined by
  1735 // This function packs an array of bytes into the four row form defined by
  1736 // Rijndael. It assumes the length of the array of bytes is divisible by
  1736 // Rijndael. It assumes the length of the array of bytes is divisible by
  1737 // four. Bytes are filled in according to the Rijndael spec (starting with
  1737 // four. Bytes are filled in according to the Rijndael spec (starting with
  1738 // column 0, row 0 to 3). This function returns a 2d array.
  1738 // column 0, row 0 to 3). This function returns a 2d array.
  1739 
  1739 
  1740 function packBytes(octets) {
  1740 function packBytes(octets) {
  1741   var state = new Array();
  1741 	var state = new Array();
  1742   if (!octets || octets.length % 4)
  1742 	if (!octets || octets.length % 4)
  1743     return;
  1743 		return;
  1744 
  1744 
  1745   state[0] = new Array();  state[1] = new Array(); 
  1745 	state[0] = new Array();  state[1] = new Array(); 
  1746   state[2] = new Array();  state[3] = new Array();
  1746 	state[2] = new Array();  state[3] = new Array();
  1747   for (var j=0; j<octets.length; j+= 4) {
  1747 	for (var j=0; j<octets.length; j+= 4) {
  1748      state[0][j/4] = octets[j];
  1748  		state[0][j/4] = octets[j];
  1749      state[1][j/4] = octets[j+1];
  1749  		state[1][j/4] = octets[j+1];
  1750      state[2][j/4] = octets[j+2];
  1750  		state[2][j/4] = octets[j+2];
  1751      state[3][j/4] = octets[j+3];
  1751  		state[3][j/4] = octets[j+3];
  1752   }
  1752 	}
  1753   return state;  
  1753 	return state;  
  1754 }
  1754 }
  1755 
  1755 
  1756 // This function unpacks an array of bytes from the four row format preferred
  1756 // This function unpacks an array of bytes from the four row format preferred
  1757 // by Rijndael into a single 1d array of bytes. It assumes the input "packed"
  1757 // by Rijndael into a single 1d array of bytes. It assumes the input "packed"
  1758 // is a packed array. Bytes are filled in according to the Rijndael spec. 
  1758 // is a packed array. Bytes are filled in according to the Rijndael spec. 
  1759 // This function returns a 1d array of bytes.
  1759 // This function returns a 1d array of bytes.
  1760 
  1760 
  1761 function unpackBytes(packed) {
  1761 function unpackBytes(packed) {
  1762   var result = new Array();
  1762 	var result = new Array();
  1763   for (var j=0; j<packed[0].length; j++) {
  1763 	for (var j=0; j<packed[0].length; j++) {
  1764     result[result.length] = packed[0][j];
  1764 		result[result.length] = packed[0][j];
  1765     result[result.length] = packed[1][j];
  1765 		result[result.length] = packed[1][j];
  1766     result[result.length] = packed[2][j];
  1766 		result[result.length] = packed[2][j];
  1767     result[result.length] = packed[3][j];
  1767 		result[result.length] = packed[3][j];
  1768   }
  1768 	}
  1769   return result;
  1769 	return result;
  1770 }
  1770 }
  1771 
  1771 
  1772 // This function takes a prospective plaintext (string or array of bytes)
  1772 // This function takes a prospective plaintext (string or array of bytes)
  1773 // and pads it with zero bytes if its length is not a multiple of the block 
  1773 // and pads it with zero bytes if its length is not a multiple of the block 
  1774 // size. If plaintext is a string, it is converted to an array of bytes
  1774 // size. If plaintext is a string, it is converted to an array of bytes
  1775 // in the process. The type checking can be made much nicer using the 
  1775 // in the process. The type checking can be made much nicer using the 
  1776 // instanceof operator, but this operator is not available until IE5.0 so I 
  1776 // instanceof operator, but this operator is not available until IE5.0 so I 
  1777 // chose to use the heuristic below. 
  1777 // chose to use the heuristic below. 
  1778 
  1778 
  1779 function formatPlaintext(plaintext) {
  1779 function formatPlaintext(plaintext) {
  1780   var bpb = blockSizeInBits / 8;               // bytes per block
  1780 	var bpb = blockSizeInBits / 8;               // bytes per block
  1781   var i;
  1781 	var i;
  1782 
  1782 
  1783   // if primitive string or String instance
  1783 	// if primitive string or String instance
  1784   if (typeof plaintext == "string" || plaintext.split) {
  1784 	if (typeof plaintext == "string" || plaintext.split) {
  1785     // alert('AUUGH you idiot it\'s NOT A STRING ITS A '+typeof(plaintext)+'!!!');
  1785 		// alert('AUUGH you idiot it\'s NOT A STRING ITS A '+typeof(plaintext)+'!!!');
  1786     // return false;
  1786 		// return false;
  1787     plaintext = plaintext.split("");
  1787 		plaintext = plaintext.split("");
  1788     // Unicode issues here (ignoring high byte)
  1788 		// Unicode issues here (ignoring high byte)
  1789     for (i=0; i<plaintext.length; i++)
  1789 		for (i=0; i<plaintext.length; i++)
  1790       plaintext[i] = plaintext[i].charCodeAt(0) & 0xFF;
  1790 			plaintext[i] = plaintext[i].charCodeAt(0) & 0xFF;
  1791   } 
  1791 	} 
  1792 
  1792 
  1793   for (i = bpb - (plaintext.length % bpb); i > 0 && i < bpb; i--) 
  1793 	for (i = bpb - (plaintext.length % bpb); i > 0 && i < bpb; i--) 
  1794     plaintext[plaintext.length] = 0;
  1794 		plaintext[plaintext.length] = 0;
  1795   
  1795 	
  1796   return plaintext;
  1796 	return plaintext;
  1797 }
  1797 }
  1798 
  1798 
  1799 // Returns an array containing "howMany" random bytes. YOU SHOULD CHANGE THIS
  1799 // Returns an array containing "howMany" random bytes. YOU SHOULD CHANGE THIS
  1800 // TO RETURN HIGHER QUALITY RANDOM BYTES IF YOU ARE USING THIS FOR A "REAL"
  1800 // TO RETURN HIGHER QUALITY RANDOM BYTES IF YOU ARE USING THIS FOR A "REAL"
  1801 // APPLICATION.
  1801 // APPLICATION.
  1802 
  1802 
  1803 function getRandomBytes(howMany) {
  1803 function getRandomBytes(howMany) {
  1804   var i;
  1804 	var i;
  1805   var bytes = new Array();
  1805 	var bytes = new Array();
  1806   for (i=0; i<howMany; i++)
  1806 	for (i=0; i<howMany; i++)
  1807     bytes[i] = Math.round(Math.random()*255);
  1807 		bytes[i] = Math.round(Math.random()*255);
  1808   return bytes;
  1808 	return bytes;
  1809 }
  1809 }
  1810 
  1810 
  1811 // rijndaelEncrypt(plaintext, key, mode)
  1811 // rijndaelEncrypt(plaintext, key, mode)
  1812 // Encrypts the plaintext using the given key and in the given mode. 
  1812 // Encrypts the plaintext using the given key and in the given mode. 
  1813 // The parameter "plaintext" can either be a string or an array of bytes. 
  1813 // The parameter "plaintext" can either be a string or an array of bytes. 
  1821 // this array to hex, invoke byteArrayToHex() on it. If you are using this 
  1821 // this array to hex, invoke byteArrayToHex() on it. If you are using this 
  1822 // "for real" it is a good idea to change the function getRandomBytes() to 
  1822 // "for real" it is a good idea to change the function getRandomBytes() to 
  1823 // something that returns truly random bits.
  1823 // something that returns truly random bits.
  1824 
  1824 
  1825 function rijndaelEncrypt(plaintext, key, mode) {
  1825 function rijndaelEncrypt(plaintext, key, mode) {
  1826   var expandedKey, i, aBlock;
  1826 	var expandedKey, i, aBlock;
  1827   var bpb = blockSizeInBits / 8;          // bytes per block
  1827 	var bpb = blockSizeInBits / 8;          // bytes per block
  1828   var ct;                                 // ciphertext
  1828 	var ct;                                 // ciphertext
  1829 
  1829 
  1830   if (typeof plaintext != 'object' || typeof key != 'object')
  1830 	if (typeof plaintext != 'object' || typeof key != 'object')
  1831   {
  1831 	{
  1832     alert( 'Invalid params\nplaintext: '+typeof(plaintext)+'\nkey: '+typeof(key) );
  1832 		alert( 'Invalid params\nplaintext: '+typeof(plaintext)+'\nkey: '+typeof(key) );
  1833     return false;
  1833 		return false;
  1834   }
  1834 	}
  1835   if (key.length*8 == keySizeInBits+8)
  1835 	if (key.length*8 == keySizeInBits+8)
  1836     key.length = keySizeInBits / 8;
  1836 		key.length = keySizeInBits / 8;
  1837   if (key.length*8 != keySizeInBits)
  1837 	if (key.length*8 != keySizeInBits)
  1838   {
  1838 	{
  1839     alert( 'Key length is bad!\nLength: '+key.length+'\nExpected: '+keySizeInBits / 8 );
  1839 		alert( 'Key length is bad!\nLength: '+key.length+'\nExpected: '+keySizeInBits / 8 );
  1840     return false;
  1840 		return false;
  1841   }
  1841 	}
  1842   if (mode == "CBC")
  1842 	if (mode == "CBC")
  1843     ct = getRandomBytes(bpb);             // get IV
  1843 		ct = getRandomBytes(bpb);             // get IV
  1844   else {
  1844 	else {
  1845     mode = "ECB";
  1845 		mode = "ECB";
  1846     ct = new Array();
  1846 		ct = new Array();
  1847   }
  1847 	}
  1848 
  1848 
  1849   // convert plaintext to byte array and pad with zeros if necessary. 
  1849 	// convert plaintext to byte array and pad with zeros if necessary. 
  1850   plaintext = formatPlaintext(plaintext);
  1850 	plaintext = formatPlaintext(plaintext);
  1851 
  1851 
  1852   expandedKey = keyExpansion(key);
  1852 	expandedKey = keyExpansion(key);
  1853   
  1853 	
  1854   for (var block=0; block<plaintext.length / bpb; block++) {
  1854 	for (var block=0; block<plaintext.length / bpb; block++) {
  1855     aBlock = plaintext.slice(block*bpb, (block+1)*bpb);
  1855 		aBlock = plaintext.slice(block*bpb, (block+1)*bpb);
  1856     if (mode == "CBC")
  1856 		if (mode == "CBC")
  1857       for (var i=0; i<bpb; i++) 
  1857 			for (var i=0; i<bpb; i++) 
  1858         aBlock[i] ^= ct[block*bpb + i];
  1858 				aBlock[i] ^= ct[block*bpb + i];
  1859     ct = ct.concat(encrypt(aBlock, expandedKey));
  1859 		ct = ct.concat(encrypt(aBlock, expandedKey));
  1860   }
  1860 	}
  1861 
  1861 
  1862   return ct;
  1862 	return ct;
  1863 }
  1863 }
  1864 
  1864 
  1865 // rijndaelDecrypt(ciphertext, key, mode)
  1865 // rijndaelDecrypt(ciphertext, key, mode)
  1866 // Decrypts the using the given key and mode. The parameter "ciphertext" 
  1866 // Decrypts the using the given key and mode. The parameter "ciphertext" 
  1867 // must be an array of bytes. The parameter "key" must be an array of key 
  1867 // must be an array of bytes. The parameter "key" must be an array of key 
  1872 // An array of bytes representing the plaintext is returned. To convert 
  1872 // An array of bytes representing the plaintext is returned. To convert 
  1873 // this array to a hex string, invoke byteArrayToHex() on it. To convert it 
  1873 // this array to a hex string, invoke byteArrayToHex() on it. To convert it 
  1874 // to a string of characters, you can use byteArrayToString().
  1874 // to a string of characters, you can use byteArrayToString().
  1875 
  1875 
  1876 function rijndaelDecrypt(ciphertext, key, mode) {
  1876 function rijndaelDecrypt(ciphertext, key, mode) {
  1877   var expandedKey;
  1877 	var expandedKey;
  1878   var bpb = blockSizeInBits / 8;          // bytes per block
  1878 	var bpb = blockSizeInBits / 8;          // bytes per block
  1879   var pt = new Array();                   // plaintext array
  1879 	var pt = new Array();                   // plaintext array
  1880   var aBlock;                             // a decrypted block
  1880 	var aBlock;                             // a decrypted block
  1881   var block;                              // current block number
  1881 	var block;                              // current block number
  1882 
  1882 
  1883   if (!ciphertext || !key || typeof ciphertext == "string")
  1883 	if (!ciphertext || !key || typeof ciphertext == "string")
  1884     return;
  1884 		return;
  1885   if (key.length*8 != keySizeInBits)
  1885 	if (key.length*8 != keySizeInBits)
  1886     return; 
  1886 		return; 
  1887   if (!mode)
  1887 	if (!mode)
  1888     mode = "ECB";                         // assume ECB if mode omitted
  1888 		mode = "ECB";                         // assume ECB if mode omitted
  1889 
  1889 
  1890   expandedKey = keyExpansion(key);
  1890 	expandedKey = keyExpansion(key);
  1891  
  1891  
  1892   // work backwards to accomodate CBC mode 
  1892 	// work backwards to accomodate CBC mode 
  1893   for (block=(ciphertext.length / bpb)-1; block>0; block--) {
  1893 	for (block=(ciphertext.length / bpb)-1; block>0; block--) {
  1894     aBlock = 
  1894 		aBlock = 
  1895      decrypt(ciphertext.slice(block*bpb,(block+1)*bpb), expandedKey);
  1895  		decrypt(ciphertext.slice(block*bpb,(block+1)*bpb), expandedKey);
  1896     if (mode == "CBC") 
  1896 		if (mode == "CBC") 
  1897       for (var i=0; i<bpb; i++) 
  1897 			for (var i=0; i<bpb; i++) 
  1898         pt[(block-1)*bpb + i] = aBlock[i] ^ ciphertext[(block-1)*bpb + i];
  1898 				pt[(block-1)*bpb + i] = aBlock[i] ^ ciphertext[(block-1)*bpb + i];
  1899     else 
  1899 		else 
  1900       pt = aBlock.concat(pt);
  1900 			pt = aBlock.concat(pt);
  1901   }
  1901 	}
  1902 
  1902 
  1903   // do last block if ECB (skips the IV in CBC)
  1903 	// do last block if ECB (skips the IV in CBC)
  1904   if (mode == "ECB")
  1904 	if (mode == "ECB")
  1905     pt = decrypt(ciphertext.slice(0, bpb), expandedKey).concat(pt);
  1905 		pt = decrypt(ciphertext.slice(0, bpb), expandedKey).concat(pt);
  1906 
  1906 
  1907   return pt;
  1907 	return pt;
  1908 }
  1908 }
  1909 
  1909 
  1910 // This method takes a byte array (byteArray) and converts it to a string by
  1910 // This method takes a byte array (byteArray) and converts it to a string by
  1911 // applying String.fromCharCode() to each value and concatenating the result.
  1911 // applying String.fromCharCode() to each value and concatenating the result.
  1912 // The resulting string is returned. Note that this function SKIPS zero bytes
  1912 // The resulting string is returned. Note that this function SKIPS zero bytes
  1914 // Obviously, do not invoke this method on raw data that can contain zero
  1914 // Obviously, do not invoke this method on raw data that can contain zero
  1915 // bytes. It is really only appropriate for printable ASCII/Latin-1 
  1915 // bytes. It is really only appropriate for printable ASCII/Latin-1 
  1916 // values. Roll your own function for more robust functionality :)
  1916 // values. Roll your own function for more robust functionality :)
  1917 
  1917 
  1918 function byteArrayToString(byteArray) {
  1918 function byteArrayToString(byteArray) {
  1919   var result = "";
  1919 	var result = "";
  1920   for ( var i=0; i < byteArray.length; i++ )
  1920 	for ( var i=0; i < byteArray.length; i++ )
  1921     if (byteArray[i] != 0) 
  1921 		if (byteArray[i] != 0) 
  1922       result += '%' + byteArray[i].toString(16);
  1922 			result += '%' + byteArray[i].toString(16);
  1923   return decodeURIComponent(result);
  1923 	return decodeURIComponent(result);
  1924 }
  1924 }
  1925 
  1925 
  1926 // This function takes an array of bytes (byteArray) and converts them
  1926 // This function takes an array of bytes (byteArray) and converts them
  1927 // to a hexadecimal string. Array element 0 is found at the beginning of 
  1927 // to a hexadecimal string. Array element 0 is found at the beginning of 
  1928 // the resulting string, high nibble first. Consecutive elements follow
  1928 // the resulting string, high nibble first. Consecutive elements follow
  1929 // similarly, for example [16, 255] --> "10ff". The function returns a 
  1929 // similarly, for example [16, 255] --> "10ff". The function returns a 
  1930 // string.
  1930 // string.
  1931 
  1931 
  1932 function byteArrayToHex(byteArray) {
  1932 function byteArrayToHex(byteArray) {
  1933   var result = "";
  1933 	var result = "";
  1934   if (!byteArray)
  1934 	if (!byteArray)
  1935     return;
  1935 		return;
  1936   for (var i=0; i<byteArray.length; i++)
  1936 	for (var i=0; i<byteArray.length; i++)
  1937     result += ((byteArray[i]<16) ? "0" : "") + byteArray[i].toString(16);
  1937 		result += ((byteArray[i]<16) ? "0" : "") + byteArray[i].toString(16);
  1938 
  1938 
  1939   return result;
  1939 	return result;
  1940 }
  1940 }
  1941 
  1941 
  1942 // This function converts a string containing hexadecimal digits to an 
  1942 // This function converts a string containing hexadecimal digits to an 
  1943 // array of bytes. The resulting byte array is filled in the order the
  1943 // array of bytes. The resulting byte array is filled in the order the
  1944 // values occur in the string, for example "10FF" --> [16, 255]. This
  1944 // values occur in the string, for example "10FF" --> [16, 255]. This
  1945 // function returns an array. 
  1945 // function returns an array. 
  1946 
  1946 
  1947 function hexToByteArray(hexString) {
  1947 function hexToByteArray(hexString) {
  1948   /*
  1948 	/*
  1949   var byteArray = [];
  1949 	var byteArray = [];
  1950   if (hexString.length % 2)             // must have even length
  1950 	if (hexString.length % 2)             // must have even length
  1951     return;
  1951 		return;
  1952   if (hexString.indexOf("0x") == 0 || hexString.indexOf("0X") == 0)
  1952 	if (hexString.indexOf("0x") == 0 || hexString.indexOf("0X") == 0)
  1953     hexString = hexString.substring(2);
  1953 		hexString = hexString.substring(2);
  1954   for (var i = 0; i<hexString.length; i += 2) 
  1954 	for (var i = 0; i<hexString.length; i += 2) 
  1955     byteArray[Math.floor(i/2)] = parseInt(hexString.slice(i, i+2), 16);
  1955 		byteArray[Math.floor(i/2)] = parseInt(hexString.slice(i, i+2), 16);
  1956   return byteArray;
  1956 	return byteArray;
  1957   */
  1957 	*/
  1958   var bytes = new Array();
  1958 	var bytes = new Array();
  1959   hexString = str_split(hexString, 2);
  1959 	hexString = str_split(hexString, 2);
  1960   //alert(hexString.toString());
  1960 	//alert(hexString.toString());
  1961   //return false;
  1961 	//return false;
  1962   for( var i in hexString )
  1962 	for( var i in hexString )
  1963   {
  1963 	{
  1964     bytes[bytes.length] = parseInt(hexString[i], 16);
  1964 		bytes[bytes.length] = parseInt(hexString[i], 16);
  1965   }
  1965 	}
  1966   //alert(bytes.toString());
  1966 	//alert(bytes.toString());
  1967   return bytes;
  1967 	return bytes;
  1968 }
  1968 }
  1969 
  1969 
  1970 function stringToByteArray(text)
  1970 function stringToByteArray(text)
  1971 {
  1971 {
  1972   // Modified for Enano 2009-02-16 to be Unicode-safe
  1972 	// Modified for Enano 2009-02-16 to be Unicode-safe
  1973   var result = new Array();
  1973 	var result = new Array();
  1974   text = encodeURIComponent(text);
  1974 	text = encodeURIComponent(text);
  1975   for ( var i = 0; i < text.length; i++ )
  1975 	for ( var i = 0; i < text.length; i++ )
  1976   {
  1976 	{
  1977     var ch = text.charCodeAt(i);
  1977 		var ch = text.charCodeAt(i);
  1978     var a = false;
  1978 		var a = false;
  1979     if ( ch == 37 ) // "%"
  1979 		if ( ch == 37 ) // "%"
  1980     {
  1980 		{
  1981       var hexch = text.substr(i, 3);
  1981 			var hexch = text.substr(i, 3);
  1982       if ( hexch.match(/^%[a-f0-9][a-f0-9]$/i) )
  1982 			if ( hexch.match(/^%[a-f0-9][a-f0-9]$/i) )
  1983       {
  1983 			{
  1984         result[result.length] = (unescape(hexch)).charCodeAt(0);
  1984 				result[result.length] = (unescape(hexch)).charCodeAt(0);
  1985         a = true;
  1985 				a = true;
  1986         i += 2;
  1986 				i += 2;
  1987       }
  1987 			}
  1988     }
  1988 		}
  1989     if ( !a )
  1989 		if ( !a )
  1990     {
  1990 		{
  1991       result[result.length] = ch;
  1991 			result[result.length] = ch;
  1992     }
  1992 		}
  1993   }
  1993 	}
  1994   return result;
  1994 	return result;
  1995 }
  1995 }
  1996 
  1996 
  1997 function aes_self_test()
  1997 function aes_self_test()
  1998 {
  1998 {
  1999   //
  1999 	//
  2000   // Encryption test
  2000 	// Encryption test
  2001   //
  2001 	//
  2002   
  2002 	
  2003   var str = '';
  2003 	var str = '';
  2004   for(i=0;i<keySizeInBits/4;i++)
  2004 	for(i=0;i<keySizeInBits/4;i++)
  2005   {
  2005 	{
  2006     str+='0';
  2006 		str+='0';
  2007   }
  2007 	}
  2008   str = hexToByteArray(str);
  2008 	str = hexToByteArray(str);
  2009   var ct  = rijndaelEncrypt(str, str, 'ECB');
  2009 	var ct  = rijndaelEncrypt(str, str, 'ECB');
  2010   ct      = byteArrayToHex(ct);
  2010 	ct      = byteArrayToHex(ct);
  2011   var v;
  2011 	var v;
  2012   switch(keySizeInBits)
  2012 	switch(keySizeInBits)
  2013   {
  2013 	{
  2014     // These test vectors are for 128-bit block size.
  2014 		// These test vectors are for 128-bit block size.
  2015     case 128:
  2015 		case 128:
  2016       v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
  2016 			v = '66e94bd4ef8a2c3b884cfa59ca342b2e';
  2017       break;
  2017 			break;
  2018     case 192:
  2018 		case 192:
  2019       v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
  2019 			v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7';
  2020       break;
  2020 			break;
  2021     case 256:
  2021 		case 256:
  2022       v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
  2022 			v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087';
  2023       break;
  2023 			break;
  2024   }
  2024 	}
  2025   return ( ct == v && md5_vm_test() );
  2025 	return ( ct == v && md5_vm_test() );
  2026 }
  2026 }
  2027 
  2027 
  2028 /*
  2028 /*
  2029  * EnanoMath, an abstraction layer for big-integer (arbitrary precision)
  2029  * EnanoMath, an abstraction layer for big-integer (arbitrary precision)
  2030  * mathematics.
  2030  * mathematics.
  2033 var EnanoMathLayers = {};
  2033 var EnanoMathLayers = {};
  2034 
  2034 
  2035 // EnanoMath layer: Leemon (frontend to BigInt library by Leemon Baird)
  2035 // EnanoMath layer: Leemon (frontend to BigInt library by Leemon Baird)
  2036 
  2036 
  2037 EnanoMathLayers.Leemon = {
  2037 EnanoMathLayers.Leemon = {
  2038   Base: 10,
  2038 	Base: 10,
  2039   PowMod: function(a, b, c)
  2039 	PowMod: function(a, b, c)
  2040   {
  2040 	{
  2041     a = str2bigInt(a, this.Base);
  2041 		a = str2bigInt(a, this.Base);
  2042     b = str2bigInt(b, this.Base);
  2042 		b = str2bigInt(b, this.Base);
  2043     c = str2bigInt(c, this.Base);
  2043 		c = str2bigInt(c, this.Base);
  2044     var result = powMod(a, b, c);
  2044 		var result = powMod(a, b, c);
  2045     result = bigInt2str(result, this.Base);
  2045 		result = bigInt2str(result, this.Base);
  2046     return result;
  2046 		return result;
  2047   },
  2047 	},
  2048   RandomInt: function(bits)
  2048 	RandomInt: function(bits)
  2049   {
  2049 	{
  2050     var result = randBigInt(bits);
  2050 		var result = randBigInt(bits);
  2051     return bigInt2str(result, this.Base);
  2051 		return bigInt2str(result, this.Base);
  2052   }
  2052 	}
  2053 }
  2053 }
  2054 
  2054 
  2055 var EnanoMath = EnanoMathLayers.Leemon;
  2055 var EnanoMath = EnanoMathLayers.Leemon;
  2056 
  2056 
  2057 /*
  2057 /*
  2070  * @return string(BigInt)
  2070  * @return string(BigInt)
  2071  */
  2071  */
  2072 
  2072 
  2073 function dh_gen_private()
  2073 function dh_gen_private()
  2074 {
  2074 {
  2075   return EnanoMath.RandomInt(256);
  2075 	return EnanoMath.RandomInt(256);
  2076 }
  2076 }
  2077 
  2077 
  2078 /**
  2078 /**
  2079  * Calculates the public key from the private key
  2079  * Calculates the public key from the private key
  2080  * @param string(BigInt)
  2080  * @param string(BigInt)
  2081  * @return string(BigInt)
  2081  * @return string(BigInt)
  2082  */
  2082  */
  2083 
  2083 
  2084 function dh_gen_public(b)
  2084 function dh_gen_public(b)
  2085 {
  2085 {
  2086   return EnanoMath.PowMod(dh_g, b, dh_prime);
  2086 	return EnanoMath.PowMod(dh_g, b, dh_prime);
  2087 }
  2087 }
  2088 
  2088 
  2089 /**
  2089 /**
  2090  * Calculates the shared secret.
  2090  * Calculates the shared secret.
  2091  * @param string(BigInt) Our private key
  2091  * @param string(BigInt) Our private key
  2093  * @return string(BigInt)
  2093  * @return string(BigInt)
  2094  */
  2094  */
  2095 
  2095 
  2096 function dh_gen_shared_secret(b, A)
  2096 function dh_gen_shared_secret(b, A)
  2097 {
  2097 {
  2098   return EnanoMath.PowMod(A, b, dh_prime);
  2098 	return EnanoMath.PowMod(A, b, dh_prime);
  2099 }
  2099 }
  2100 
  2100 
  2101 /* A JavaScript implementation of the Secure Hash Algorithm, SHA-256
  2101 /* A JavaScript implementation of the Secure Hash Algorithm, SHA-256
  2102  * Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
  2102  * Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
  2103  * Distributed under the BSD License
  2103  * Distributed under the BSD License
  2109 
  2109 
  2110 Redistribution and use in source and binary forms, with or without modification,
  2110 Redistribution and use in source and binary forms, with or without modification,
  2111 are permitted provided that the following conditions are met:
  2111 are permitted provided that the following conditions are met:
  2112 
  2112 
  2113  * Redistributions of source code must retain the above copyright notice, this
  2113  * Redistributions of source code must retain the above copyright notice, this
  2114    list of conditions and the following disclaimer.
  2114  	list of conditions and the following disclaimer.
  2115  * Redistributions in binary form must reproduce the above copyright notice,
  2115  * Redistributions in binary form must reproduce the above copyright notice,
  2116    this list of conditions and the following disclaimer in the documentation
  2116  	this list of conditions and the following disclaimer in the documentation
  2117    and/or other materials provided with the distribution.
  2117  	and/or other materials provided with the distribution.
  2118  * Neither the name of the <ORGANIZATION> nor the names of its contributors may
  2118  * Neither the name of the <ORGANIZATION> nor the names of its contributors may
  2119    be used to endorse or promote products derived from this software without
  2119  	be used to endorse or promote products derived from this software without
  2120    specific prior written permission.
  2120  	specific prior written permission.
  2121 
  2121 
  2122 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  2122 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  2123 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  2123 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  2124 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2124 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2125 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  2125 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  2130 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  2130 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  2131 OF THE POSSIBILITY OF SUCH DAMAGE.
  2131 OF THE POSSIBILITY OF SUCH DAMAGE.
  2132 */
  2132 */
  2133 var chrsz = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode  */
  2133 var chrsz = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode  */
  2134 function safe_add (x, y) {
  2134 function safe_add (x, y) {
  2135   var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  2135 	var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  2136   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  2136 	var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  2137   return (msw << 16) | (lsw & 0xFFFF);
  2137 	return (msw << 16) | (lsw & 0xFFFF);
  2138 }
  2138 }
  2139 function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
  2139 function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
  2140 function R (X, n) {return ( X >>> n );}
  2140 function R (X, n) {return ( X >>> n );}
  2141 function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
  2141 function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
  2142 function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
  2142 function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
  2143 function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
  2143 function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
  2144 function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
  2144 function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
  2145 function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
  2145 function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
  2146 function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
  2146 function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
  2147 function core_sha256 (m, l) {
  2147 function core_sha256 (m, l) {
  2148     var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
  2148 		var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
  2149     var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
  2149 		var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
  2150     var W = new Array(64);
  2150 		var W = new Array(64);
  2151     var a, b, c, d, e, f, g, h, i, j;
  2151 		var a, b, c, d, e, f, g, h, i, j;
  2152     var T1, T2;
  2152 		var T1, T2;
  2153     /* append padding */
  2153 		/* append padding */
  2154     m[l >> 5] |= 0x80 << (24 - l % 32);
  2154 		m[l >> 5] |= 0x80 << (24 - l % 32);
  2155     m[((l + 64 >> 9) << 4) + 15] = l;
  2155 		m[((l + 64 >> 9) << 4) + 15] = l;
  2156     for ( var i = 0; i<m.length; i+=16 ) {
  2156 		for ( var i = 0; i<m.length; i+=16 ) {
  2157         a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
  2157 				a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
  2158         for ( var j = 0; j<64; j++) {
  2158 				for ( var j = 0; j<64; j++) {
  2159             if (j < 16) W[j] = m[j + i];
  2159 						if (j < 16) W[j] = m[j + i];
  2160             else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
  2160 						else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
  2161             T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
  2161 						T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
  2162             T2 = safe_add(Sigma0256(a), Maj(a, b, c));
  2162 						T2 = safe_add(Sigma0256(a), Maj(a, b, c));
  2163             h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2);
  2163 						h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2);
  2164         }
  2164 				}
  2165         HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]);
  2165 				HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]);
  2166     }
  2166 		}
  2167     return HASH;
  2167 		return HASH;
  2168 }
  2168 }
  2169 function str2binb (str) {
  2169 function str2binb (str) {
  2170   var bin = Array();
  2170 	var bin = Array();
  2171   var mask = (1 << chrsz) - 1;
  2171 	var mask = (1 << chrsz) - 1;
  2172   for(var i = 0; i < str.length * chrsz; i += chrsz)
  2172 	for(var i = 0; i < str.length * chrsz; i += chrsz)
  2173     bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
  2173 		bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
  2174   return bin;
  2174 	return bin;
  2175 }
  2175 }
  2176 function binb2hex (binarray) {
  2176 function binb2hex (binarray) {
  2177   var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
  2177 	var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
  2178   var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  2178 	var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  2179   var str = "";
  2179 	var str = "";
  2180   for (var i = 0; i < binarray.length * 4; i++) {
  2180 	for (var i = 0; i < binarray.length * 4; i++) {
  2181     str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  2181 		str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
  2182   }
  2182 	}
  2183   return str;
  2183 	return str;
  2184 }
  2184 }
  2185 function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));}
  2185 function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));}
  2186 
  2186 
  2187 // Javascript implementation of the and SHA1 hash algorithms - both written by Paul Johnston, licensed under the BSD license
  2187 // Javascript implementation of the and SHA1 hash algorithms - both written by Paul Johnston, licensed under the BSD license
  2188 
  2188 
  2194 function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
  2194 function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
  2195 function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
  2195 function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
  2196 function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
  2196 function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
  2197 function md5_vm_test() { return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; }
  2197 function md5_vm_test() { return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; }
  2198 function core_md5(x, len) { x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a =  1732584193; var b = -271733879; var c = -1732584194; var d =  271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
  2198 function core_md5(x, len) { x[len >> 5] |= 0x80 << ((len) % 32); x[(((len + 64) >>> 9) << 4) + 14] = len; var a =  1732584193; var b = -271733879; var c = -1732584194; var d =  271733878; for(var i = 0; i < x.length; i += 16) { var olda = a; var oldb = b; var oldc = c; var oldd = d; a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
  2199          a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);c = md5_ff(c, d, a, b, x[i+10], 17, -42063);b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
  2199  				a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);c = md5_ff(c, d, a, b, x[i+10], 17, -42063);b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
  2200          c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
  2200  				c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
  2201          a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
  2201  				a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
  2202          c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
  2202  				c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
  2203          a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
  2203  				a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
  2204          c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
  2204  				c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
  2205          a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); }
  2205  				a = safe_add(a, olda); b = safe_add(b, oldb); c = safe_add(c, oldc); d = safe_add(d, oldd); } return Array(a, b, c, d); }
  2206 function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); }
  2206 function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); }
  2207 function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); }
  2207 function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); }
  2208 function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); }
  2208 function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); }
  2209 function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); }
  2209 function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); }
  2210 function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); }
  2210 function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); }