package uc.crypto; //import java.io.IOException; //import java.security.MessageDigest; //import java.security.NoSuchAlgorithmException; //import java.nio.channels.FileChannel; //import java.nio.ByteBuffer; //import java.util.LinkedList; import fr.cryptohash.Digest; /** * * Was first an implementation of TTH ... * now its just left overs some static convenience * methods to calculate the tiger digest of given data. * * @author Quicksilver * */ public class Tiger { // // public Tiger(){ // try { // // Obtain a message digest object of provider "provider" using // // algorithm "hashfunction". // md = MessageDigest.getInstance("Tiger", new CryptixCrypto()); // } // catch (NoSuchAlgorithmException nsae) { // nsae.printStackTrace(); // } // small[0]=(byte) 0; // // } // // // private static final int digestlength = 24; // // // Variable containing the MD object. // private MessageDigest md = null; // /* A Base 32 Encoder */ //// private BASE32Encoder enc=null; // // private static final int chunksInBig=5*1024 * Runtime.getRuntime().availableProcessors(); // /**ABuffer for Reading in large chunks of data**/ // private ByteBuffer big=ByteBuffer.allocateDirect(1024*chunksInBig); // bytebuffer for readin of the file // private byte[] small=new byte[1025]; // a 1 + 1024 Byte buffer for giving to digest method // // // // private int totalTreeDepth; // private int storedepth; // // //all the values we still need that won't be kept // private Hashval[] unfinished; // // // all the values we need that will be kept..the lowest line in the tree usually the depth7 2^6 values ->64 // private byte[][] finished; // private int position; // // // //Debug // int nrOfBlocks; // // /** // * // * @param fc // * @param start // * @param end // * @param root // * @return // * @deprecated use the IHashEngine instead // */ // public boolean checkBlock(FileChannel fc, long start , long end , byte[] root){ // try{ // long length = end-start; // nrOfBlocks= Math.max(1,(int)(length/1024) + ((length%1024)!=0 ? 1: 0 )); // number of blocks // // System.out.println("nrOfBlocks: "+nrOfBlocks ); // // totalTreeDepth = depth(nrOfBlocks); // // System.out.println("Totaltreedepth: "+totalTreeDeph ); // // storedepth= 0;//Math.max(1, Math.min( 7 + (length > 500*1024*1024 ? 1 :0 ) , totalTreeDepth-7 )); //small files have 1 -7 lines usually 7 500MB upwards makes 8 // // System.out.println("storedepth: "+storedepth ); // // unfinished=new Hashval[ totalTreeDepth ]; // // finished= new byte[pow(storedepth) ][digestlength]; // // position=0; // int lastremaining=0; // long fileposition=start; // int cur; // while(-1 != ( cur = fc.read(big,fileposition))){ // fileposition+=cur; // if(fileposition < end) // big.flip(); // else{ // big.rewind(); // big.limit(cur+lastremaining); // } // // while( big.remaining() > 1024 ){ // md.reset(); // big.get(small, 1 , 1024); // addToTree( new Hashval(totalTreeDepth-1 ,md.digest( small ))); // } // if(big.hasRemaining()){ // lastremaining=big.remaining(); // big.compact(); // }else{ // lastremaining=0; // big.rewind(); // } // if(fileposition >= end) // break; // } // // big.flip(); // if(big.hasRemaining()){ // md.reset(); // md.update((byte)0); // while(big.hasRemaining() ) // md.update(big.get()); // addToTree( new Hashval(totalTreeDepth-1 ,md.digest())); // } // big.rewind(); // // byte[] computedRoot= finishTree()[0]; // // // for(int i=0; i < root.length; i++) // if(root[i]!= computedRoot[i]) // return false; // return true; // // // }catch(IOException ioe){ // ioe.printStackTrace(); // } // // return false; // } // // /* // * Running the specified message digest algorithm of a provider on a file. // * // * @param hashfunction String Name of the hashfunction<P> // * which should be used. // * @param provider String Name of the provider that should be used. // * @param filename String Name of the file which has to be hashed. // * @return true or false. // * @deprecated use IHashEngine and interleaves instead // * // public MerkleTree run(File file){ // // // FileInputStream fis = null; // FileChannel file_input_chan = null; // // try { // // // Get FileInputStream for reading a few bytes from a file. // fis = new FileInputStream(file); // file_input_chan = fis.getChannel(); // // // nrOfBlocks= Math.max(1,(int)(file.length()/1024) + ((file.length()%1024)!=0 ? 1: 0 )); // number of blocks // // System.out.println("nrOfBlocks: "+nrOfBlocks ); // // totalTreeDepth = depth(nrOfBlocks); // // System.out.println("Totaltreedepth: "+totalTreeDeph ); // // storedepth= Math.max(1, Math.min( 7 + (file.length() > 500*1024*1024 ? 1 :0 ), totalTreeDepth-7 )); //small files have 1 -7 lines usually 7 500MB upwards makes 8 // // System.out.println("storedepth: "+storedepth ); // // unfinished=new Hashval[ totalTreeDepth ]; // // finished= new byte[pow(storedepth) ][digestlength]; // // position=0; // // while(-1 != file_input_chan.read(big)){ // big.flip(); // while( big.remaining() > 1024 ){ // md.reset(); // big.get(small, 1 , 1024); // addToTree( new Hashval(totalTreeDepth-1 ,md.digest( small ))); // } // if(big.hasRemaining()) // big.compact(); // else // big.rewind(); // // } // // big.flip(); // md.reset(); // md.update((byte)0); // while(big.hasRemaining() ) // md.update(big.get()); // addToTree( new Hashval(totalTreeDepth-1 ,md.digest())); // // big.rewind(); // fis.close(); // file_input_chan.close(); // // // and finishing the last level of the tree.. and printing out the hash // return new MerkleTree(finishTree()); // // }catch (IOException ioe){ // ioe.printStackTrace(); // } // // // // return null; // // } // // /** // * checks if the info in the tree is konsistent // * @param mt the merkletree to check // * @return true if everything is ok with the tree .. false otherwise // * @deprecated MerkleTree is no longer in use // * // public boolean validateTree(MerkleTree mt){ // return true; // }*/ // // /** // * Computes the internal hash value of to childs in the tree.. // * @param firstchild // * @param secondchild // * @return // * @deprecated see IHashEngine // */ // private Hashval internalHash(Hashval leftchild, Hashval rightchild){ // md.reset(); // md.update((byte)1); // md.update(leftchild.val); // return new Hashval( --leftchild.treedepth, md.digest(rightchild.val) ); // } // // /** // * // * @param a - a hashval // * @deprecated use IHashEngine .. // */ // private void addToTree(Hashval a ){ // try{ // if(a.treedepth < storedepth ) // finished[position++]=a.val; // else // if(unfinished[a.treedepth]==null ) // unfinished[a.treedepth]=a; // else{ // int x=a.treedepth; // addToTree( internalHash( unfinished[x], a ) ); // unfinished[x]= null; // } // }catch(Exception e){ // System.out.println("Totaldepth: "+totalTreeDepth+" , storedepth: "+storedepth+" , nrOfBlocks: "+ nrOfBlocks ); // // e.printStackTrace(); // } // } // // // /** // * called after the all leafs are hashed performs last operations on the tree.. // * @deprecated use IHashEngine // */ // private byte[][] finishTree(){ // for(int i=totalTreeDepth-1; i >= storedepth; i--){ // trimming unbalanced tree.. // if(unfinished[i]!= null){ // unfinished[i].treedepth--; // addToTree(unfinished[i] ); // unfinished[i]=null; // } // } // position=0; // // //return an ordered array // // //new StringBuilder(enc.encode(current[0].val)).append(erg).toString() ; // return treeFromInterleaves(finished); // } // // /** // * // * @param interleaves creates a tree from interleaves.. // * @return the tree in bytearray form // * @deprecated Merkletree is no longer in use // */ // byte[][] treeFromInterleaves(byte[][] interleaves ){ // LinkedList<byte[]> retval=new LinkedList<byte[]>(); // // StringBuilder erg=new StringBuilder(""); // // int counter=1; // while(counter < interleaves.length) // counter*=2; // byte[][] current; // if(counter == interleaves.length) // current= interleaves; // else{ // current= new byte[counter][digestlength]; // System.arraycopy(interleaves, 0 , current, 0 , interleaves.length); // } // while(current.length > 1){ //Computing from base finished level to higher levels.. // byte[][] next=new byte[current.length/2 ][digestlength]; // for(int i=0; i < next.length; i++ ){ // if(current[2*i]==null) // break; // if(current[2*i+1]==null){ // // byte[] a= new byte[digestlength]; // System.arraycopy(current[2*i],0,next[i],0,digestlength); // // next[i]=new Hashval( current[2*i].treedepth-1 , a).val; // break; // } // next[i]=internalHash( new Hashval(1,current[2*i]) , new Hashval(1, current[2*i+1]) ).val; // } // for(int i=current.length-1;i >= 0; i-- ) //printing the output // if(current[i]!= null) // retval.addFirst(current[i]); // // erg= new StringBuilder(" "+ enc.encode(current[i].val) ).append(erg); // // current=next; // } // retval.addFirst(current[0]); // // return retval.toArray(new byte[0][digestlength]); // } // // // // // // // /** // * // * // * @depreacted use HashValue instead // */ // private static class Hashval { // final byte[] val; // int treedepth; // public Hashval(int treedepth, byte[] val){ // this.treedepth=treedepth; // this.val=val; // } // } // /** // * // * // * @deprecated .. no longer in use // */ // private int depth(int blocks){ // if(blocks==1) // return 1; // return 1+ depth(blocks/2); // } // /** // * // * // * @deprecated .. no longer in use // */ // private int pow(int n){ // if(n==0) // return 1; // else // return 2*pow(n-1); // } // static { staticmessageDigest = new fr.cryptohash.Tiger(); } private static Digest staticmessageDigest; public static HashValue tigerOfString(String toHash) { synchronized(staticmessageDigest){ staticmessageDigest.reset(); //reset the digest return HashValue.createHash(staticmessageDigest.digest( toHash.getBytes() )); //then put in the bytes hash and reencode } } public static HashValue tigerOfHash(HashValue toHash) { synchronized(staticmessageDigest){ staticmessageDigest.reset(); //reset the digest return HashValue.createHash(staticmessageDigest.digest( toHash.getRaw() )); //then put in the bytes hash and reencode } } public static HashValue tigerOfBytes(byte... bytes) { synchronized(staticmessageDigest){ staticmessageDigest.reset(); //reset the digest return HashValue.createHash(staticmessageDigest.digest( bytes )); //then put in the bytes hash and reencode } } /** * Computes the internal hash value of to childs in the tree.. * @param firstchild * @param secondchild * @return */ public static HashValue internalHash(HashValue leftchild, HashValue rightchild){ synchronized(staticmessageDigest) { staticmessageDigest.reset(); staticmessageDigest.update((byte)1); staticmessageDigest.update(leftchild.getRaw()); byte[] hash = staticmessageDigest.digest(rightchild.getRaw()); return new TigerHashValue(hash); } } }