Beispiel #1
0
    Sequence::SimData neutral_sample( uniform_generator & uni,
				      uniform01_generator & uni01,
				      exponential_generator & expo,
				      poisson_generator & poiss,
				      const double & theta,
				      const double & rho,
				      const int & nsites,
				      const int & nsam,
				      std::vector<chromosome> * sample,
				      arg * sample_history,
				      unsigned * max_chromosomes = NULL,
				      const unsigned & max_chromosomes_inc = 0)
    /*!
      @brief A simple function to generate samples under a neutral equilibrium model.

      A simple function to generate samples under a neutral equilibrium model
      with infinite-sites mutation and a constant recombination rate accross the region.

      \param uni a function/object capable of returning a random double uniformly from [0,k)
      \param uni01 a function/object capable of returning a random probability uniformly from [0,1)
      \param expo a function/object capable of returning an exponentially distributed random variable. 
      The function must take a single double as an argument, which is the mean of the exponential 
      distribution
      \param poiss a function/object capable of returning an poisson distributed random variable. 
      The function must take a single double as an argument, which is the mean of the poisson 
      distribution
      \param theta 4Nu, the coalescent-scaled mutation rate
      \param rho 4Nr, the recombination rate for the whole region
      \param nsites the number of mutational sites to simulate.  Recombination is equally likely
      between any two sites.
      \param nsites the total sample size. (There is no population structure in this routine)
      \param sample A pointer to the sample of chromosomes you wish to simulate.  
      This must be properly initialized, for example using the function init_sample in 
      <Sequence/Coalescent/Initialize.hpp>
      \param sample_history a pointer to the ancestral recombination graph.  This must be
      initialized in the calling enviroment.  In general, you can use init_marginal in 
      <Sequence/Coalescent/Initialize.hpp>
      \param max_chromosomes  This is a pointer to an integer in the calling environment which you
      can use to reserve memory in the array containing the sample of chromosomes.  If the size of \a sample
      ever gets larger than this, max_chromosomes is incremented by \a max_chromosomes_inc
      \param max_chromosomes_inc the amount by which to increment \a max_chromosomes
      \note This function does require a bit of work to use, although not much.  Please see the example
      code that comes with the library, in particular ms--.cc
      \ingroup coalescent
    */
    {
      int NSAM = nsam;

      //this is rho = 4Nr/site
      double littler = rho/(double(nsites-1));

      //a chromosome with nsites sites has nsites-1 positions ("links")
      //at which crossovers can occur, so the total number of
      //links at the start of the simulation is:
      int nlinks = nsam*(nsites-1);
      double t = 0.;
      while(NSAM>1)
	{
	  double rcoal = double(NSAM*(NSAM-1));
	  double rrec = (rho>0.) ? littler*double(nlinks) : 0.;

	  //note--the function calls below scale time in units of 4Ne
	  double tcoal = expo(1./rcoal);
	  double trec = expo(1./rrec);
	  if ( trec < tcoal ) //crossover event
	    {
	      t+=trec;
	      std::pair<int,int> pos_rec = pick_uniform_spot(uni01(),
							     nlinks,
							     sample->begin(),NSAM);
	      assert( pos_rec.second >= 0 );
	      assert( pos_rec.second >= (sample->begin()+pos_rec.first)->first() );
	      assert( pos_rec.second <= ((sample->begin()+pos_rec.first)->last() ) ); 
				       
	      assert( (sample->begin()+pos_rec.first)->links()>0 );
	      nlinks -= crossover(NSAM,pos_rec.first,pos_rec.second,
				  sample,sample_history);
	      NSAM++;
	    }
	  else //common ancestor event
	    {
	      t+=tcoal;
	      std::pair<int,int> two = pick2(uni,NSAM);
	      NSAM -= coalesce(t,nsam,NSAM,two.first,two.second,nsites,
			       &nlinks,sample,sample_history);
	    }
	  if (unsigned(NSAM) < sample->size()/5)
	    {
	      sample->erase(sample->begin()+NSAM+1,sample->end());
	    }
	}
      if (max_chromosomes != NULL && sample->size() > *max_chromosomes)
	*max_chromosomes  += max_chromosomes_inc;

      //As we have scaled time in units of 4Nr generations, we pass theta
      //to the mutation function.  If we had used the following code to
      //generate times:
      //	double tcoal = expo(2./rcoal);
      //	double trec = expo(2./rrec);
      //Then time would be scaled in units of 2Ne generations, 
      //and if our simulation considers theta=4Neu, we'd pass theta/2
      //to the infinite_sites routine

      SimData gametes_obj = infinite_sites_sim_data(poiss,uni,
						    nsites,*sample_history,theta);
      return gametes_obj;
    }
Beispiel #2
0
SigNat sign(PublicKey group, RogueKey rogue, Secret secret, Cert cert, Message msg)
{
  char bsn[MAX_CHAR_ARRAY_LENGTH], m[MAX_CHAR_ARRAY_LENGTH];
  char error[MAX_CHAR_ARRAY_LENGTH],c_h[MAX_CHAR_ARRAY_LENGTH];
  char hash[MAX_CHAR_ARRAY_LENGTH], inner[MAX_CHAR_ARRAY_LENGTH];
  BigInt n_v, c, sv, sf0, sf1, se, see, sew, sr, ser, sw;
  Origin b;
  BigInt n,gPrime,g,h,r0,r1,s;
  BigInt biga,e, p2;
  BigInt f0,f1,v;
  Tuple wr,rf0rf1,rwrr,rewrer;
  BigInt bigt1, bigt2, temp1, temp2, temp3, temp4, temp5, temp6, temp7, w, r;
  BigInt zeta,bign_V,rf0,rf1, rv, bigt2inv, tilde_TPrime2,n_t;
  BigInt tilde_T1t, tilde_rf, tilde_N_V,rw,rr,re,ree,rew, rer,hinv, tilde_T1, tilde_T2;
  Hash hashPub, hashHost ,hashTpm1, hashTpm2;
  Responses ss;
  SigNat signat;

  strcpy(bsn,msg.bsn); strcpy(m,msg.m);
  b = msg.b; n_v = msg.n_v;
  if(noOfBits(n_v) > hash_bits){
    strcpy(error,"n_v out of bounds");
    Abort(error);
  }
  n=group.n; gPrime=group.gPrime; g=group.g; h=group.h;
  r0=group.r0; r1=group.r1; s=group.s;
  
  biga = cert.biga; e = cert.e;
  f0 = secret.f; f1=secret.s; v=secret.t;
  wr = pick2(rsa_modulus_bits+distribution_bits);
  w = wr.r; r = wr.m;
  bigt1 = BImodMult(biga,BImodPower(h,wr.r,n),n);
  
  temp1 = BIpower(g,w); temp2 = BIpower(h,e); temp3 = BIpower(gPrime,r);
  temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3);
  bigt2 = BImod(temp5,n);
  
  zeta = base(bsn,rogue);
  bign_V = tag(rogue,zeta,f0,f1);

  rv = pick(random_bits+distribution_bits+hash_bits);
  rf0rf1 = pick2(halfkeyBits+distribution_bits+hash_bits);
  rf0 = rf0rf1.r; rf1 = rf0rf1.m;
  
  temp1 = BIpower(r0,rf0); temp2 = BIpower(r1,rf1); temp3 = BIpower(s,rv);
  temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3);
  tilde_T1t = BImod(temp5,n);

  temp1 = BIshiftLeft(rf1,halfkeyBits);
  temp2 = BIadd(rf0, temp1);
  tilde_rf = BImod(temp2,rogue.rho);
  tilde_N_V = BImodPower(zeta,tilde_rf,rogue.bigGamma);
  
  re = pick(prime_random_bits+distribution_bits+hash_bits);
  ree = pick(2*prime_total_bits+distribution_bits+hash_bits+1);
  rwrr = pick2(rsa_modulus_bits+2*distribution_bits+hash_bits);
  rw = rwrr.r; rr = rwrr.m;
  rewrer = pick2(prime_total_bits+rsa_modulus_bits+2*distribution_bits+hash_bits+1);
  rew = rewrer.r; rer = rewrer.m;
  hinv = BImodInv(h,n);

  temp1 = tilde_T1t; temp2 = BIpower(bigt1,re); temp3 = BIpower(hinv,rew);
  temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3);
  tilde_T1 = BImod(temp5,n);

  temp1 = BIpower(g,rw); temp2 = BIpower(h,re); temp3 = BIpower(gPrime,rr);
  temp4 = BImul(temp1, temp2); temp5 = BImul(temp4, temp3);
  tilde_T2 = BImod(temp5,n);
  
  bigt2inv = BImodInv(bigt2,n);
  temp1 = BIpower(bigt2inv,re); temp2 = BIpower(g,rew); temp3 = BIpower(h,ree); temp4 = BIpower(gPrime,rer);
  temp5 = BImul(temp1, temp2); temp6 = BImul(temp5, temp3); temp7 = BImul(temp6, temp4);
  tilde_TPrime2 = BImod(temp7,n);

  //hash public inputs
  hashPub = getSha1Hash();
  addBI(&hashPub,group.n); addBI(&hashPub,group.g); addBI(&hashPub,group.gPrime); addBI(&hashPub,group.h);
  addBI(&hashPub,group.r0); addBI(&hashPub,group.r1); addBI(&hashPub,group.s); addBI(&hashPub,group.z);
  addBI(&hashPub,rogue.gamma); addBI(&hashPub,rogue.bigGamma); addBI(&hashPub,rogue.rho);
  addBI(&hashPub,zeta); addBI(&hashPub,bigt1); addBI(&hashPub,bigt2); addBI(&hashPub,bign_V);
  strcpy(hash,hashResult(hashPub));

  //hash host inputs
  hashHost = getSha1Hash();
  addBI(&hashHost,tilde_T1); addBI(&hashHost,tilde_T2); addBI(&hashHost,tilde_TPrime2);
  addBI(&hashHost,tilde_N_V); addBI(&hashHost,n_v);
  strcpy(c_h,hashResult(hashHost));

  n_t = pick(distribution_bits);
  
  hashTpm1 = getSha1Hash();
  addBytes(&hashTpm1,c_h); 
  addBI(&hashTpm1,n_t); 
  strcpy(inner,hashResult(hashTpm1));
  hashTpm2 = getSha1Hash();
  addBytes(&hashTpm2,inner); 
  if(b == Card)
    addByte(&hashTpm2,0);
  else if (b == Verifier)
    addByte(&hashTpm2,1);
  else
    ;
  addBytes(&hashTpm2, m);
  c = BItoNumber(hashResult(hashTpm2));
  sv = rval(rv,v,c);
  sf0 = rval(rf0,f0,c);
  sf1 = rval(rf1,f1,c);
  p2 = BIshiftLeft(BItoNumber("1"),prime_total_bits-1);
  se = rval(re,BIsub(e, p2),c);
  see = rval(ree,BImul(e,e),c);
  sw = rval(rw,w,c);
  sew = rval(rew,BImul(e,w),c);
  sr = rval(rr,r,c);
  ser = rval(rer,BImul(e,r),c);

  ss.sv = sv; 
  ss.sf0 = sf0; 
  ss.sf1 = sf1; 
  ss.se = se; 
  ss.see = see; 
  ss.sw = sw; 
  ss.sew = sew; 
  ss.sr = sr; 
  ss.ser = ser;
  
  signat.zeta = zeta;
  signat.bigt1 = bigt1;
  signat.bigt2 = bigt2;
  signat.bign_V = bign_V;
  signat.c = c;
  signat.n_t = n_t;
  signat.ss = ss;

  return signat;
}