/** * Finish the digest and return the resulting hash. * <p> * Once {@code digest()} is called, this instance should be discarded. * * @return the ObjectId for the resulting hash. * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ public ObjectId toObjectId() throws Sha1CollisionException { finish(); return h.toObjectId(); }
/** * Update the digest computation by adding bytes to the message. * * @param in * input array of bytes. */ public void update(byte[] in) { update(in, 0, in.length); }
/** * Reset this instance to compute another hash. * * @return {@code this}. */ public SHA1 reset() { h.init(); length = 0; foundCollision = false; return this; }
private void compress(byte[] block, int p) { initBlock(block, p); int ubcDvMask = detectCollision ? UbcCheck.check(w) : 0; compress(); while (ubcDvMask != 0) { int b = numberOfTrailingZeros(lowestOneBit(ubcDvMask)); UbcCheck.DvInfo dv = UbcCheck.DV[b]; for (int i = 0; i < 80; i++) { w2[i] = w[i] ^ dv.dm[i]; } recompress(dv.testt); if (eq(hTmp, h)) { foundCollision = true; break; } ubcDvMask &= ~(1 << b); } }
e += s1(a, b, c, d,w[ 0]); b = rotateLeft( b, 30); d += s1(e, a, b, c,w[ 1]); a = rotateLeft( a, 30); c += s1(d, e, a, b,w[ 2]); e = rotateLeft( e, 30); b += s1(c, d, e, a,w[ 3]); d = rotateLeft( d, 30); a += s1(b, c, d, e,w[ 4]); c = rotateLeft( c, 30); e += s1(a, b, c, d,w[ 5]); b = rotateLeft( b, 30); d += s1(e, a, b, c,w[ 6]); a = rotateLeft( a, 30); c += s1(d, e, a, b,w[ 7]); e = rotateLeft( e, 30); b += s1(c, d, e, a,w[ 8]); d = rotateLeft( d, 30); a += s1(b, c, d, e,w[ 9]); c = rotateLeft( c, 30); e += s1(a, b, c, d,w[ 10]); b = rotateLeft( b, 30); d += s1(e, a, b, c,w[ 11]); a = rotateLeft( a, 30); c += s1(d, e, a, b,w[ 12]); e = rotateLeft( e, 30); b += s1(c, d, e, a,w[ 13]); d = rotateLeft( d, 30); a += s1(b, c, d, e,w[ 14]); c = rotateLeft( c, 30); e += s1(a, b, c, d,w[ 15]); b = rotateLeft( b, 30); d += s1(e, a, b, c,w[ 16]); a = rotateLeft( a, 30); c += s1(d, e, a, b,w[ 17]); e = rotateLeft( e, 30); b += s1(c, d, e, a,w[ 18]); d = rotateLeft( d, 30); a += s1(b, c, d, e,w[ 19]); c = rotateLeft( c, 30); e += s2(a, b, c, d,w[ 20]); b = rotateLeft( b, 30); d += s2(e, a, b, c,w[ 21]); a = rotateLeft( a, 30); c += s2(d, e, a, b,w[ 22]); e = rotateLeft( e, 30); b += s2(c, d, e, a,w[ 23]); d = rotateLeft( d, 30); a += s2(b, c, d, e,w[ 24]); c = rotateLeft( c, 30); e += s2(a, b, c, d,w[ 25]); b = rotateLeft( b, 30); d += s2(e, a, b, c,w[ 26]); a = rotateLeft( a, 30); c += s2(d, e, a, b,w[ 27]); e = rotateLeft( e, 30);
private byte[] computeHash(InputStream in, long length) throws IOException { SHA1 contentDigest = SHA1.newInstance(); final byte[] contentReadBuffer = state.contentReadBuffer; contentDigest.update(hblob); contentDigest.update((byte) ' '); long sz = length; if (sz == 0) { contentDigest.update((byte) '0'); } else { final int bufn = contentReadBuffer.length; int p = bufn; do { contentReadBuffer[--p] = digits[(int) (sz % 10)]; sz /= 10; } while (sz > 0); contentDigest.update(contentReadBuffer, p, bufn - p); } contentDigest.update((byte) 0); for (;;) { final int r = in.read(contentReadBuffer); if (r <= 0) break; contentDigest.update(contentReadBuffer, 0, r); sz += r; } if (sz != length) return zeroid; return contentDigest.digest(); }
/** * Compute the name of an object, without inserting it. * * @param type * type code of the object to store. * @param data * complete content of the object. * @param off * first position within {@code data}. * @param len * number of bytes to copy from {@code data}. * @return the name of the object. */ public ObjectId idFor(int type, byte[] data, int off, int len) { SHA1 md = SHA1.newInstance(); md.update(Constants.encodedTypeString(type)); md.update((byte) ' '); md.update(Constants.encodeASCII(len)); md.update((byte) 0); md.update(data, off, len); return md.toObjectId(); }
private void finish() { int bufferLen = (int) (length & 63); if (bufferLen > 55) { // Last block is too small; pad, compress, pad another block. buffer[bufferLen++] = (byte) 0x80; Arrays.fill(buffer, bufferLen, 64, (byte) 0); compress(buffer, 0); Arrays.fill(buffer, 0, 56, (byte) 0); } else { // Last block can hold padding and length. buffer[bufferLen++] = (byte) 0x80; Arrays.fill(buffer, bufferLen, 56, (byte) 0); } // SHA-1 appends the length of the message in bits after the // padding block (above). Here length is in bytes. Multiply by // 8 by shifting by 3 as part of storing the 64 bit byte length // into the two words expected in the trailer. NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3))); NB.encodeInt32(buffer, 60, (int) (length << 3)); compress(buffer, 0); if (foundCollision) { ObjectId id = h.toObjectId(); LOG.warn("possible SHA-1 collision " + id.name()); //$NON-NLS-1$ throw new Sha1CollisionException(id); } }
/** * Finish the digest and return the resulting hash. * <p> * Once {@code digest()} is called, this instance should be discarded. * * @param id * destination to copy the digest to. * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ public void digest(MutableObjectId id) throws Sha1CollisionException { finish(); id.set(h.a, h.b, h.c, h.d, h.e); }
/** * Create a new context to compute a SHA-1 hash of data. * * @return a new context to compute a SHA-1 hash of data. */ public static SHA1 newInstance() { return new SHA1(); }
/** * Compute digest to help compute an ObjectId * * @return digest to help compute an ObjectId * @since 4.7 */ protected SHA1 digest() { return hasher.reset(); }
final void init() { // Magic initialization constants defined by FIPS180. save(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0); }
/** * Update the digest computation by adding a byte. * * @param b a byte. */ public void update(byte b) { int bufferLen = (int) (length & 63); length++; buffer[bufferLen] = b; if (bufferLen == 63) { compress(buffer, 0); } }
/** Wraps a delegate ObjectInserter. */ public static abstract class Filter extends ObjectInserter { /** @return delegate ObjectInserter to handle all processing. */ protected abstract ObjectInserter delegate(); @Override protected byte[] buffer() { return delegate().buffer(); } @Override public ObjectId idFor(int type, byte[] data) { return delegate().idFor(type, data); } @Override public ObjectId idFor(int type, byte[] data, int off, int len) { return delegate().idFor(type, data, off, len); } @Override public ObjectId idFor(int objectType, long length, InputStream in) throws IOException { return delegate().idFor(objectType, length, in); } @Override public ObjectId idFor(TreeFormatter formatter) { return delegate().idFor(formatter); }
/** * Insert a loose object into the database. If createDuplicate is true, * write the loose object even if we already have it in the loose or packed * ODB. * * @param type * @param len * @param is * @param createDuplicate * @return ObjectId * @throws IOException */ ObjectId insert(int type, long len, InputStream is, boolean createDuplicate) throws IOException { if (len <= buffer().length) { byte[] buf = buffer(); int actLen = IO.readFully(is, buf, 0); return insert(type, buf, 0, actLen, createDuplicate); } else { SHA1 md = digest(); File tmp = toTemp(md, type, len, is); ObjectId id = md.toObjectId(); return insertOneObject(tmp, id, createDuplicate); } }
@Override public void write(byte[] in, int p, int n) throws IOException { md.update(in, p, n); out.write(in, p, n); } }
private SHA1() { h.init(); }
/** * Finish the digest and return the resulting hash. * <p> * Once {@code digest()} is called, this instance should be discarded. * * @return the bytes for the resulting hash. * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ public byte[] digest() throws Sha1CollisionException { finish(); byte[] b = new byte[20]; NB.encodeInt32(b, 0, h.a); NB.encodeInt32(b, 4, h.b); NB.encodeInt32(b, 8, h.c); NB.encodeInt32(b, 12, h.d); NB.encodeInt32(b, 16, h.e); return b; }
@Override public void write(int b) throws IOException { md.update((byte) b); out.write(b); }