Example #1
0
/*!
 Decrypts cleartext data using EAX' mode (see ANSI Standard C12.22-2008).

 @param[in]	pN	pointer to cleartext (canonified form)
 @param[in]	pK	pointer to secret key
 @param[in,out] pC	pointer to ciphertext
 @param[in]	SizeN	byte length of cleartext (pN) buffer
 @param[in]	SizeK	byte length of secret key (pK) 
 @param[in]	SizeC	byte length of ciphertext (pC) buffer
 @param[in]	pMac	four-byte Message Authentication Code
 @param[in]	Mode	EAX_MODE_CLEARTEXT_AUTH or EAX_MODE_CIPHERTEXT_AUTH
 @return		TRUE if message has been authenticated; FALSE if not 
			authenticated, invalid Mode or error
 */
gboolean Eax_Decrypt(guint8 *pN, guint8 *pK, guint8 *pC, 
                 guint32 SizeN, guint32 SizeK, guint32 SizeC, MAC_T *pMac, 
		 guint8 Mode)
{
    guint8 wsn[EAX_SIZEOF_KEY];
    guint8 wsc[EAX_SIZEOF_KEY];
    int i;
    
    /* key size must match this implementation */
    if (SizeK != EAX_SIZEOF_KEY)
	return FALSE;

    /* the key is new */
    for (i = 0; i < EAX_SIZEOF_KEY; i++)
	instance.L[i] = 0;
    AesEncrypt(instance.L, pK);
    Dbl(instance.D, instance.L);
    Dbl(instance.Q, instance.D);
    /* the key is set up */
    /* first copy the nonce into our working space */
    BLK_CPY(wsn, instance.D);
    if (Mode == EAX_MODE_CLEARTEXT_AUTH) {
	dCMAC(pK, wsn, pN, SizeN, pC, SizeC);
    } else {
	CMAC(pK, wsn, pN, SizeN);
    }
    /* 
     *  In authentication mode the inputs are: pN, pK (and associated sizes), 
     *	the result is the 4 byte MAC.
     */
    if (Mode == EAX_MODE_CLEARTEXT_AUTH)
    {
        return (memcmp(pMac, &wsn[EAX_SIZEOF_KEY-sizeof(*pMac)], sizeof(*pMac)) ? FALSE : TRUE);
    
    }

    /* 
     * In cipher mode the inputs are: pN, pK, pP (and associated sizes), 
     * the results are pC (and its size) along with the 4 byte MAC.
     */
    else if (Mode == EAX_MODE_CIPHERTEXT_AUTH)
    {
	    if (SizeC == 0)
            return (memcmp(pMac, &wsn[EAX_SIZEOF_KEY-sizeof(*pMac)], sizeof(*pMac)) ? FALSE : TRUE);
	    {
	        /* first copy the nonce into our working space */
	        BLK_CPY(wsc, instance.Q);
	        CMAC(pK, wsc, pC, SizeC);
	        BLK_XOR(wsc, wsn);
	    }
	    if (memcmp(pMac, &wsc[EAX_SIZEOF_KEY-sizeof(*pMac)], sizeof(*pMac)) == 0)
	    {
	        CTR(wsn, pK, pC, SizeC);
	        return TRUE;
	    }
    }
    return FALSE;
}
 /* 
 * Output histogram
 */
 void Distribution::output(std::ostream& out) 
 {
    double x, rho;
    for (int i=0; i < nBin_; ++i) {
       x   = min_ + binWidth_*(double(i) + 0.5);
       rho = double(histogram_[i])/double(nSample_);
       rho = rho/binWidth_;
       out << Dbl(x, 18, 8) << Dbl(rho, 18, 8) << std::endl;
    }
 }
Example #3
0
int
p_sincos(value val_arg, type tag_arg,
	value val_sin, type tag_sin,
	value val_cos, type tag_cos)
{
        extern void sincos();       /* from the math library */
        double s, c;
        Prepare_Requests;

        Error_If_Ref(tag_arg);
        Check_Output_Float(tag_sin);
        Check_Output_Float(tag_cos);

        if (IsDouble(tag_arg))
            sincos(Dbl(val_arg), &s, &c);
        else if (IsInteger(tag_arg))
            sincos((double) val_arg.nint, &s, &c);
        else
        {
            Error(TYPE_ERROR);
        }
        Request_Unify_Float(val_sin, tag_sin, s);
        Request_Unify_Float(val_cos, tag_cos, c);
        Return_Unify;
}
Example #4
0
   /*
   * Add a sampled value to the ensemble (private method)
   *
   * If outFilePtr != 0, output block averages to outFilePtr
   */
   void Average::sample(double value, std::ostream* outFilePtr)
   {
      AverageStage::sample(value);

      // Process block average for output
      if (nSamplePerBlock_ && outFilePtr) {
         blockSum_  += value;
         ++iBlock_;
         if (iBlock_ == nSamplePerBlock_) {
            *outFilePtr << Dbl(blockSum_/double(nSamplePerBlock_))
                        << std::endl;
            blockSum_ = 0.0;
            iBlock_  = 0;
         }
      }
   }
Example #5
0
   /*
   * Output results to file after simulation is completed.
   */
   void ClusterHistogram::output() 
   {
      // Write parameter file
      fileMaster().openOutputFile(outputFileName(".prm"), outputFile_);
      writeParam(outputFile_);
      outputFile_.close();

      // Write histogram output
      fileMaster().openOutputFile(outputFileName(".hist"), outputFile_);
      // hist_.output(outputFile_);
      int min = hist_.min();
      int nBin = hist_.nBin();
      for (int i = 0; i < nBin; ++i) {
         outputFile_ << Int(i + min) << "  " 
                     <<  Dbl(double(hist_.data()[i])/double(nSample_)) << "\n";
      }
      outputFile_.close();
   }
Example #6
0
ppw(pword *pw)				/* print prolog words */
          
{

    int arity = 1;
    pword *queue_head = (pword *) 0;
    pword *queue_tail = (pword *) 0;

    for (;;)
    {
	char region;
	int t = TagType(pw->tag);

	if (t < TFORWARD || t > TBUFFER)
	    t = TUNKNOWN;

	if (TG_ORIG <= pw && pw < TG) region = 'g';
	else if (SP <= pw && pw < SP_ORIG) region = 'l';
	else if (B_ORIG <= pw && pw < B.args) region = 'c';
	else if (TT <= (pword **) pw && (pword **) pw < TT_ORIG) region = 't';
	else if (address_in_heap(&global_heap, (generic_ptr) pw)) region = 'h';
	else region = '?';

	p_fprintf(current_output_, "%c 0x%08x:  0x%08x 0x%08x  %s ", region,
			pw, pw->val.all, pw->tag.all, tag_string[t-TUNKNOWN]);
	switch (t)
	{
	case TFORWARD:
	case TMETA:
	case TNAME:
	    if (pw != pw->val.ptr)
	    {
		ec_outfs(current_output_, "--->");
		EnQueue_(pw->val.ptr, 1);
	    }
	    else
	    {
		ec_outfs(current_output_, IsNamed(pw->tag.kernel) ?
					DidName(TagDid(pw->tag.kernel)) : "_");
	    }
	    break;
	case TVAR_TAG:
	    if (pw != pw->val.ptr)
	    {
		ec_outfs(current_output_, "--->");
		EnQueue_(pw->val.ptr, 1);
	    }
	    else
		ec_outfs(current_output_, "_");
	    break;
	case TLIST:
	    EnQueue_(pw->val.ptr, 2);
	    break;
	case TCOMP:
	    if (pw->val.ptr)
		EnQueue_(pw->val.ptr, DidArity(pw->val.ptr->val.did)+1);
	    break;
	case TSTRG:
	    ec_outfs(current_output_, StringStart(pw->val));
	    break;
	case TSUSP:
	    break;
	case TDE:
	    break;
	case THANDLE:
	    break;
	case TNIL:
	    break;
	case TINT:
	    p_fprintf(current_output_, "%d", pw->val.nint);
	    break;
	case TDICT:
	    ec_outfs(current_output_, DidName(pw->val.did));
	    if (DidArity(pw->val.did))
		p_fprintf(current_output_, "/%d", DidArity(pw->val.did));
	    break;
	case TPTR:
	    break;
	case TPROC:
	case TEND:
	case TVARNUM:
	case TGRS:
	case TGRL:
	case TEXTERN:
	case TBUFFER:
	    break;
	case TDBL:
	    p_fprintf(current_output_, "%f", Dbl(pw->val));
	    break;
	case TBIG:
	case TRAT:
	default:
	    if (t >= 0 && t <= NTYPES)
	    {
		(void) tag_desc[t].write(QUOTED, current_output_,
			    pw->val, pw->tag);
	    }
	    break;
	}
	ec_newline(current_output_);
	if (--arity > 0)
	{
	    pw++;
	    continue;
	}
	ec_newline(current_output_);
	if (EmptyQueue())
	    break;
	DeQueue_(pw, arity);
    }
    Succeed_;
}
Example #7
0
   /*
   * Output statistical properties to file
   */
   void Average::output(std::ostream& out)
   {
      // Find first stage (descending) with nSample >= 16
      AverageStage* ptr = 0;
      int n = descendants_.size();
      int i = n;
      int nSample = 1;
      while (nSample < 16 && i > 0) {
         --i;
         ptr = descendants_[i];
         nSample = ptr->nSample();
      }

      double error  = ptr->error();
      double sigma  = error/sqrt(2.0*double(nSample-1));
      double weight = 1.0/(sigma*sigma);
      double sum    = error*weight;
      double norm   = weight;
      double aveErr = error;
      double oldSig;

      // Find weighted average within plateau
      bool next = true;
      while (next && i > 0) {
         oldSig = sigma;
         --i;
         ptr = descendants_[i];
         error = ptr->error();
         if (fabs(error - aveErr) < 2.0*oldSig) {
            nSample = ptr->nSample();
            sigma  = error/sqrt(2.0*double(nSample-1));
            weight = 1.0/(sigma*sigma);
            sum   += error*weight;
            norm  += weight;
            aveErr = sum/norm;
         } else {
            next = false;
         }
      }

      out <<  "Average   " << Dbl(average())         
          <<  "  +- " << Dbl(aveErr, 9, 2) << std::endl;
      out <<  "Variance  " << Dbl(variance())        << std::endl;
      out <<  "Std Dev   " << Dbl(stdDeviation())    << std::endl;
      out <<  std::endl;

      out << "Hierarchichal Error Analysis:" << std::endl;
      int interval;
      for (int i = 0; i < n; ++i) {
         ptr = descendants_[i];
         error    = ptr->error();
         nSample  = ptr->nSample();
         interval = ptr->stageInterval();
         if (nSample >= 16) {
            out << Int(i) 
                << Int(interval) 
                << Dbl(error) 
                << Dbl(error/sqrt(double(nSample)))
                << Int(nSample) << std::endl;
         }
      }
      out << std::endl;
   }
Example #8
0
   /*
   * Output statistics.
   */
   void Integrator::outputStatistics(std::ostream& out)
   {
      if (!domain().isMaster()) {
         UTIL_THROW("May be called only on domain master");
      }

      double time = timer().time();
      int nAtomTot = atomStorage().nAtomTotal();
      int nProc = 1;
      #ifdef UTIL_MPI
      nProc = domain().communicator().Get_size();
      #endif

      // Output total time for the run
      out << std::endl;
      out << "Time Statistics" << std::endl;
      out << "nStep                " << iStep_ << std::endl;
      out << "run time             " << time << " sec" << std::endl;
      out << "time / nStep         " << time/double(iStep_) 
          << " sec" << std::endl;


      double factor1 = 1.0/double(iStep_);
      double factor2 = double(nProc)/(double(iStep_)*double(nAtomTot));
      double totalT = 0.0;

      out << std::endl;
      out << "T = Time per processor, M = nstep = # steps" << std::endl
          << "P = # procs, N = # atoms (total, all processors)"
          << std::endl << std::endl;
      out << "                     " 
          << "   T/M [sec]   "
          << "   T*P/(N*M)   "
          << " Percent (%)" << std::endl;
      out << "Total                " 
          << Dbl(time*factor1, 12, 6)
          << "   "
          << Dbl(time*factor2, 12, 6)
          << "   " << Dbl(100.0, 12, 6, true) << std::endl;
      double integrate1T = timer().time(INTEGRATE1);
      totalT += integrate1T;
      out << "Integrate1           " 
          << Dbl(integrate1T*factor1, 12, 6) 
          << "   "
          << Dbl(integrate1T*factor2, 12, 6) 
          << "   " << Dbl(100.0*integrate1T/time, 12, 6, true) << std::endl;
      double checkT =  timer().time(CHECK);
      totalT += checkT;
      out << "Check                " 
          << Dbl(checkT*factor1, 12, 6)
          << "   "
          << Dbl(checkT*factor2, 12, 6)
          << "   " << Dbl(100.0*checkT/time, 12, 6, true) << std::endl;
      double allReduceT =  timer().time(ALLREDUCE);
      totalT += allReduceT;
      out << "AllReduce            " 
          << Dbl(allReduceT*factor1, 12, 6)
          << "   "
          << Dbl(allReduceT*factor2, 12, 6)
          << "   " << Dbl(100.0*allReduceT/time, 12, 6, true) << std::endl;
      double transformFT = timer().time(TRANSFORM_F);
      totalT += transformFT;
      out << "Transform (forward)  " 
          << Dbl(transformFT*factor1, 12, 6)
          << "   "
          << Dbl(transformFT*factor2, 12, 6)
          << "   " << Dbl(100.0*transformFT/time, 12, 6, true) << std::endl;
      double exchangeT = timer().time(EXCHANGE);
      totalT += exchangeT;
      out << "Exchange             " 
          << Dbl(exchangeT*factor1, 12, 6)
          << "   "
          << Dbl(exchangeT*factor2, 12, 6)
          << "   " << Dbl(100.0*exchangeT/time, 12, 6, true) << std::endl;
      double cellListT = timer().time(CELLLIST);
      totalT += cellListT;
      out << "CellList             " 
          << Dbl(cellListT*factor1, 12, 6)
          << "   "
          << Dbl(cellListT*factor2, 12, 6)
          << "   " << Dbl(100.0*cellListT/time, 12, 6, true) << std::endl;
      double transformRT = timer().time(TRANSFORM_R);
      totalT += transformRT;
      out << "Transform (reverse)  " 
          << Dbl(transformRT*factor1, 12, 6)
          << "   "
          << Dbl(transformRT*factor2, 12, 6)
          << "   " << Dbl(100.0*transformRT/time, 12, 6, true) << std::endl;
      double pairListT = timer().time(PAIRLIST);
      totalT += pairListT;
      out << "PairList             " 
          << Dbl(pairListT*factor1, 12, 6)
          << "   "
          << Dbl(pairListT*factor2, 12, 6)
          << "   " << Dbl(100.0*pairListT/time, 12, 6, true) << std::endl;
      double updateT = timer().time(UPDATE);
      totalT += updateT;
      out << "Update               "
          << Dbl(updateT*factor1, 12, 6)
          << "   "
          << Dbl(updateT*factor2, 12, 6)
          << "   " << Dbl(100.0*updateT/time, 12, 6, true) << std::endl;
      double zeroForceT = timer().time(ZERO_FORCE);
      totalT += zeroForceT;
      out << "Zero Forces          " 
          << Dbl(zeroForceT*factor1, 12, 6)
          << "   "
          << Dbl(zeroForceT*factor2, 12, 6)
          << "   " << Dbl(100.0*zeroForceT/time, 12 , 6, true) << std::endl;
      double pairForceT = timer().time(PAIR_FORCE);
      totalT += pairForceT;
      out << "Pair Forces          " 
          << Dbl(pairForceT*factor1, 12, 6)
          << "   "
          << Dbl(pairForceT*factor2, 12, 6)
          << "   " << Dbl(100.0*pairForceT/time, 12 , 6, true) << std::endl;
      #ifdef INTER_BOND
      if (nBondType()) {
         double bondForceT = timer().time(BOND_FORCE);
         totalT += bondForceT;
         out << "Bond Forces          " 
             << Dbl(bondForceT*factor1, 12, 6)
             << "   "
             << Dbl(bondForceT*factor2, 12, 6)
             << "   " << Dbl(100.0*bondForceT/time, 12 , 6, true) << std::endl;
      }
      #endif
      #ifdef INTER_ANGLE
      if (nAngleType()) {
         double angleForceT = timer().time(ANGLE_FORCE);
         totalT += angleForceT;
         out << "Angle Forces         " 
             << Dbl(angleForceT*factor1, 12, 6)
             << "   "
             << Dbl(angleForceT*factor2, 12, 6)
             << "   " << Dbl(100.0*angleForceT/time, 12 , 6, true) << std::endl;
      }
      #endif
      #ifdef INTER_DIHEDRAL
      if (nDihedralType()) {
         double dihedralForceT = timer().time(DIHEDRAL_FORCE);
         totalT += dihedralForceT;
         out << "Dihedral Forces      " 
             << Dbl(dihedralForceT*factor1, 12, 6) 
             << "   "
             << Dbl(dihedralForceT*factor2, 12, 6)
             << "   " << Dbl(100.0*dihedralForceT/time, 12 , 6, true) << std::endl;
      }
      #endif
      #ifdef INTER_EXTERNAL
      if (hasExternal()) {
         double externalForceT = timer().time(DIHEDRAL_FORCE);
         totalT += externalForceT;
         out << "External Forces      " 
             << Dbl(externalForceT*factor1, 12, 6) 
             << "   "
             << Dbl(externalForceT*factor2, 12, 6)
             << "   " << Dbl(100.0*externalForceT/time, 12 , 6, true) << std::endl;
      }
      #endif
      double integrate2T = timer().time(INTEGRATE2);
      totalT += integrate2T;
      out << "Integrate2           " 
          << Dbl(integrate2T*factor1, 12, 6) 
          << "   "
          << Dbl(integrate2T*factor2, 12, 6) 
          << "   " << Dbl(100.0*integrate2T/time, 12, 6, true) << std::endl;
      double analyzerT = timer().time(ANALYZER);
      totalT += analyzerT;
      out << "Analyzers            " 
          << Dbl(analyzerT*factor1, 12, 6)
          << "   "
          << Dbl(analyzerT*factor2, 12, 6)
          << "   " << Dbl(100.0*analyzerT/time, 12, 6, true) << std::endl;
      #ifdef DDMD_MODIFIERS
      double modifierT = timer().time(MODIFIER);
      totalT += modifierT;
      out << "Modifiers            " 
          << Dbl(modifierT*factor1, 12, 6)
          << "   "
          << Dbl(modifierT*factor2, 12, 6)
          << "   " << Dbl(100.0*modifierT/time, 12, 6, true) << std::endl;
      #endif
      out << std::endl;

      // Output info about timer resolution
      double tick = MPI::Wtick();
      out << "Timer resolution     " 
          << Dbl(tick, 12, 6) 
          << "   "
          << Dbl(tick*double(nProc)/double(nAtomTot), 12, 6) 
          << "   " << Dbl(100.0*tick*double(iStep_)/time, 12, 6, true) 
          << std::endl;
      out << std::endl;

      // Output exchange / reneighbor statistics
      int buildCounter = pairPotential().pairList().buildCounter(); 
      out << "buildCounter         " 
                  << Int(buildCounter, 12)
                  << std::endl;
      out << "steps per build      "
                  << Dbl(double(iStep_)/double(buildCounter), 12, 6)
                  << std::endl;
      out << std::endl;

   }
pword *
term_to_dbformat(pword *parg, dident mod)
{
    pword **save_tt = TT;
    register word arity = 1, len;
    register word curr_offset = 0, top_offset = 2;	/* in 'word's */
    register pword *queue_tail = (pword *) 0;
    pword *queue_head = (pword *) 0;
    register pword *pw;
    register char *dest, *stop;
    pword *header;
    temp_area	meta_attr;
    int		flag = 0;

    Temp_Create(meta_attr, 4 * ATTR_IO_TERM_SIZE * sizeof(pword));
    header = TG;
    dest = (char *) (header + 1) + 4;	/* space for the TBUFFER pword and for
					 * the external format header	*/

    for(;;)	/* handle <arity> consecutive pwords, starting at <parg> */
    {
	do	/* handle the pword pointed to by parg */
	{
	    pw = parg;

	    /* I need here a slightly modified version of Dereference_(pw)
	     * that stops also at MARKed words. Not very nice, I know.
	     */
	    while (IsRef(pw->tag) && !(pw->tag.kernel & MARK) && !IsSelfRef(pw))
		pw = pw->val.ptr;

	    Reserve_Space(6);

	    if (pw->tag.kernel & MARK)
	    {
		if (SameTypeC(pw->tag,TDE))		/* a suspension */
		{
		    Store_Byte(Tag(pw->tag.kernel));
		    Store_Int32((pw[SUSP_FLAGS].tag.kernel & ~MARK));
		    if (SuspDead(pw)) {
			curr_offset += Words(SUSP_HEADER_SIZE-1);
			parg += SUSP_HEADER_SIZE-1;
			arity -= SUSP_HEADER_SIZE-1;
		    } else {
			Store_Byte(SuspPrio(pw) + (SuspRunPrio(pw) << 4));
			curr_offset += Words(SUSP_GOAL-1);
			parg += SUSP_GOAL-1;
			arity -= SUSP_GOAL-1;
		    }
		}
		else if (pw->val.nint == curr_offset)	/* a nonstd variable */
		{
		    Store_Byte(Tag(pw->tag.kernel));
		    Store_Int(pw->val.nint);
		    if (!IsNamed(pw->tag.kernel))
		    {
			Store_Byte(0);
		    }
		    else		/* store its name */
		    {
			dident vdid = TagDid(pw->tag.kernel);
			len = DidLength(vdid);
			Store_Int(len);
			Reserve_Space(len);
			Store_String(len, DidName(vdid));
		    }
		}
		else	/* just a reference to an already encountered variable */
		{
		    Store_Byte(Tag(TVAR_TAG));
		    Store_Int(pw->val.nint);
		}
	    }
	    else switch (TagType(pw->tag))
	    {
	    case TINT:
#if SIZEOF_CHAR_P > 4
		if (pw->val.nint <  WSUF(-2147483648) || WSUF(2147483648) <= pw->val.nint)
		{
		    /* store as a bignum (to be readable on 32bit machines) */
		    len = tag_desc[pw->tag.kernel].string_size(pw->val, pw->tag, 1);
		    Store_Byte(TBIG);
		    Store_Int(len);
		    Reserve_Space(len+1);
		    stop = dest+len;
		    dest += tag_desc[pw->tag.kernel].to_string(pw->val, pw->tag,
			dest, 1);
		    while (dest <= stop)	/* pad and terminate */
		    	*dest++ = 0;
		    break;
		}
#endif
		Store_Byte(TINT);
#ifdef OLD_FORMAT
		Store_Int32(pw->val.nint);
#else
		Store_Int(pw->val.nint);
#endif
		break;

	    case TNIL:
		Store_Byte(Tag(pw->tag.kernel));
		break;

	    case TDICT:
		len = DidLength(pw->val.did);
		Store_Byte(TDICT);
		Store_Int(DidArity(pw->val.did));
		Store_Int(len);
		Reserve_Space(len);
		Store_String(len, DidName(pw->val.did));
		break;

	    case TDBL:
	    {
		ieee_double d;
		d.as_dbl = Dbl(pw->val);
		Store_Byte(TDBL);
		Store_Byte(sizeof(double)-1);	/* backward compat */
		Reserve_Space(sizeof(double));
		Store_Int32(d.as_struct.mant1);
		Store_Int32(d.as_struct.mant0);
		break;
	    }

	    case TIVL:
	    {
		ieee_double dlwb, dupb;
		dlwb.as_dbl = IvlLwb(pw->val.ptr);
		dupb.as_dbl = IvlUpb(pw->val.ptr);
		Store_Byte(TIVL);
		Reserve_Space(2*sizeof(double));
		Store_Int32(dlwb.as_struct.mant1);
		Store_Int32(dlwb.as_struct.mant0);
		Store_Int32(dupb.as_struct.mant1);
		Store_Int32(dupb.as_struct.mant0);
		break;
	    }

	    case TSTRG:
		len = StringLength(pw->val);
		Store_Byte(TSTRG);
		Store_Int(len);
		Reserve_Space(len);
		Store_String(len, StringStart(pw->val));
		break;

	    case TVAR_TAG:	/* standard variable */
		Store_Byte(Tag(TVAR_TAG));
		Store_Int(curr_offset);
		Trail_(pw);
		pw->val.nint = curr_offset;
		pw->tag.kernel |= MARK;
		break;

	    case TNAME:
	    case TUNIV:
		Store_Byte(Tag(TVAR_TAG));
		Store_Int(top_offset);
		Trail_Tag(pw);
		pw->val.nint = top_offset;
		pw->tag.kernel |= MARK;
		top_offset += 2;
		EnQueue_(pw, 1, 0);
		break;

	    case TMETA:
		Store_Byte(Tag(TVAR_TAG));
		Store_Int(top_offset);
		Trail_Tag(pw);
		pw->val.nint = top_offset;
		pw->tag.kernel |= MARK;
		top_offset += 4;
		EnQueue_(pw, 2, QUEUE_MASK_META);
		break;

	    case TSUSP:
		Store_Byte(Tag(TSUSP));
		pw = pw->val.ptr;
		if (pw->tag.kernel & MARK)	/* not the first encounter */
		{
		    Store_Int(pw->val.nint);
		}
		else
		{
		    Store_Int(top_offset);
		    Trail_Pword(pw);
		    pw->tag.kernel |= MARK;
		    pw->val.nint = top_offset;
		    if (SuspDead(pw))
		    {
			top_offset += Words(SUSP_HEADER_SIZE);	/* for TDE */
			EnQueue_(pw, SUSP_HEADER_SIZE, 0);
		    }
		    else
		    {
			top_offset += Words(SUSP_SIZE);	/* for TDE */
			EnQueue_(pw, SUSP_SIZE, 0);
		    }
		}
		break;

	    case TLIST:
		Store_Byte(Tag(TLIST));
		Store_Int(top_offset);
		top_offset += 4;
		EnQueue_(pw->val.ptr, 2, 0);
		break;

	    case TCOMP:
		Store_Byte(Tag(TCOMP));
		Store_Int(top_offset);
		if (flag) {
		    pword pw_out;
		    (void) transf_meta_out(pw->val, pw->tag,
			    (pword *) TempAlloc(meta_attr, ATTR_IO_TERM_SIZE * sizeof(pword)),
			    D_UNKNOWN, &pw_out);
		    pw = pw_out.val.ptr;
		    len = 1 + DidArity(pw->val.did);
		    EnQueue_(pw, len, 0);
		} else {
		    len = 1 + DidArity(pw->val.ptr->val.did);
		    EnQueue_(pw->val.ptr, len, 0);
		}
		top_offset += 2*len;
		break;

	    default:
		if (TagType(pw->tag) >= 0 && TagType(pw->tag) <= NTYPES)
		{
		    len = tag_desc[TagType(pw->tag)].string_size(pw->val, pw->tag, 1);
		    Store_Byte(Tag(pw->tag.kernel));
		    Store_Int(len);
		    Reserve_Space(len+1);
		    stop = dest+len;
		    dest += tag_desc[TagType(pw->tag)].to_string(pw->val, pw->tag,
			dest, 1);
		    while (dest <= stop)	/* pad and terminate */
		    	*dest++ = 0;
		}
		else
		{
		    p_fprintf(current_err_,
			"bad type in term_to_dbformat: 0x%x\n",
			pw->tag.kernel);
		}
		break;
	    }
	    curr_offset += Words(1);
	    ++parg;
	} while (--arity);
	if (EmptyQueue())
	    break;
	DeQueue_(parg, arity, flag);
    }
					/* # bytes of external representation */
    Store_Byte(0);			/* add a terminating 0		*/
    Set_Buffer_Size(header, dest - (char*) header - sizeof(pword));
    header->tag.kernel = TBUFFER;
    Align();				/* align the global stack pointer */
    TG = (pword *) dest;
    dest = (char *) (header + 1);	/* fill in the external format header */
    Store_Int32(top_offset);		/* (size of term after restoring) */
    Untrail_Variables(save_tt);
    Temp_Destroy(meta_attr);
    return header;
}
 void ChainMaker::writeChainsDdMd(std::ostream& out)
 {
    Vector r;
    Vector velocity;
    Vector v; 
    double beta = 1.0;
    int atomType = 0;
    int bondType = 0;
    int iMol, iAtom, i, j;
 
    out << "BOUNDARY" << std::endl;
    out << std::endl;
    out << boundary_ << std::endl;
    out << std::endl;
    out << "ATOMS" << std::endl;
    out << "nAtom  " << nMolecule_*nAtomPerMolecule_ << std::endl;
 
    i = 0;
    velocity.zero();
    for (iMol = 0; iMol < nMolecule_; ++iMol) {
 
       boundary_.randomPosition(random_, r);
 
       for (iAtom = 0; iAtom < nAtomPerMolecule_; ++iAtom) {
 
          out << Int(i,6) << Int(atomType, 10);
          for (j = 0; j < Dimension; ++j) {
             out << Dbl(r[j], 15, 6);
          }
          out << "  ";
          for (j = 0; j < Dimension; ++j) {
             out << Dbl(0.0, 12, 4);
          }
          out << std::endl;
 
          if (iAtom < nAtomPerMolecule_ - 1) {
             random_.unitVector(v);
             v *= bondPotential_.randomBondLength(&random_, beta, bondType);
             r += v;
             boundary_.shift(r);
          }
 
          ++i;
       }
    }
 
    // Write bonds
    out << std::endl;
    out << "BONDS" << std::endl;
    out << "nBond  " << nMolecule_*(nAtomPerMolecule_ -1 ) << std::endl;
    i = 0;
    j = 0;
    for (iMol = 0; iMol < nMolecule_; ++iMol) {
       for (iAtom = 0; iAtom < nAtomPerMolecule_ - 1; ++iAtom) {
          out << Int(j,5) <<  Int(bondType, 5) << "  ";
          out << Int(i, 10) << Int(i + 1, 10) << std::endl;
          ++i;
          ++j;
       }
       ++i;
    }
 
    // Write angles
    int angleType = 0;
    out << std::endl;
    out << "ANGLES" << std::endl;
    out << "nAngle  " << nMolecule_*(nAtomPerMolecule_ -2) << std::endl;
    i = 0;
    j = 0;
    for (iMol = 0; iMol < nMolecule_; ++iMol) {
       for (iAtom = 0; iAtom < nAtomPerMolecule_ - 2; ++iAtom) {
          out << Int(j,5) <<  Int(angleType, 5) << "  ";
          out << Int(i, 10) << Int(i + 1, 10) << Int(i + 2, 10)
              << std::endl;
          ++i;
          ++j;
       }
       i += 2;
    }
 
    // Write dihedrals
    int dihedralType = 0;
    out << std::endl;
    out << "DIHEDRALS" << std::endl;
    out << "nDihedral  " << nMolecule_*(nAtomPerMolecule_ -3) << std::endl;
    i = 0;
    j = 0;
    for (iMol = 0; iMol < nMolecule_; ++iMol) {
       for (iAtom = 0; iAtom < nAtomPerMolecule_ - 3; ++iAtom) {
          out << Int(j,5) <<  Int(dihedralType, 5) << "  ";
          out << Int(i, 10) << Int(i + 1, 10) << Int(i + 2, 10)
              << Int(i + 3, 10) << std::endl;
          ++i;
          ++j;
       }
       i += 3;
    }
 
 }