From: Jeff King <peff@peff.net>
To: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Cc: Git Mailing List <git@vger.kernel.org>
Subject: Re: [IGNORETHIS/PATCH] Choosing the sha1 prefix of your commits
Date: Wed, 19 Oct 2011 15:38:34 -0400 [thread overview]
Message-ID: <20111019193834.GA14168@sigill.intra.peff.net> (raw)
In-Reply-To: <20111019190114.GA4670@sigill.intra.peff.net>
On Wed, Oct 19, 2011 at 03:01:14PM -0400, Jeff King wrote:
> Too bad it won't work in an append only way. The internal state of sha1
> after a certain set of bytes is deterministic, so you could do something
> like:
OK, here's a patch which does that. It's way faster:
$ git init
$ time for i in `seq 1 10`; do
echo $i >file
git add file
git commit -q -m $i
done
real 0m1.212s
user 0m1.132s
sys 0m0.028s
So that's about .12 seconds per commit. Without my patch, it's about .01
seconds. So you waste a tenth of a second generating the collision. Not
too bad.
And the result:
$ git log --oneline
31337a1 10
313376b 9
3133782 8
31337cf 7
313377a 6
313374b 5
31337b1 4
31337a3 3
3133703 2
3133706 1
And nothing shows up in the body, because git truncates at the NUL we
added:
$ git show
commit 31337a1093af2d97eb2e6c08b261c2946395fdd3
Author: Jeff King <peff@peff.net>
Date: Wed Oct 19 15:34:00 2011 -0400
10
diff --git a/file b/file
index ec63514..f599e28 100644
--- a/file
+++ b/file
@@ -1 +1 @@
-9
+10
It also parameterizes the desired sha1, so you could easily find hashes
ending in 31337, or any other pattern. Or add "git commit
--collide=31337".
---
diff --git a/commit.c b/commit.c
index 73b7e00..c478752 100644
--- a/commit.c
+++ b/commit.c
@@ -840,6 +840,57 @@ struct commit_list *reduce_heads(struct commit_list *heads)
return result;
}
+static unsigned char elite_want[20] = { 0x31, 0x33, 0x70 };
+static unsigned char elite_mask[20] = { 0xff, 0xff, 0xf0 };
+
+static inline int sha1_match_mask(unsigned char *sha1,
+ unsigned char *want,
+ unsigned char *mask)
+{
+ int i;
+ for (i = 0; i < 20; i++)
+ if ((want[i] & mask[i]) != (sha1[i] & mask[i]))
+ return 0;
+ return 1;
+}
+
+static void collide_commit(struct strbuf *data,
+ unsigned char want[20],
+ unsigned char mask[20])
+{
+ static const char terminator[] = { 0 };
+ char header[32];
+ int header_len;
+ unsigned int lulz;
+ SHA_CTX base;
+
+ header_len = snprintf(header, sizeof(header),
+ "commit %lu",
+ data->len + 1 + sizeof(lulz)) + 1;
+ SHA1_Init(&base);
+ SHA1_Update(&base, header, header_len);
+ SHA1_Update(&base, data->buf, data->len);
+ SHA1_Update(&base, terminator, sizeof(terminator));
+
+ lulz = 0;
+ do {
+ SHA_CTX guess;
+ unsigned char sha1[20];
+
+ memcpy(&guess, &base, sizeof(guess));
+ SHA1_Update(&guess, &lulz, sizeof(lulz));
+ SHA1_Final(sha1, &guess);
+
+ if (sha1_match_mask(sha1, want, mask)) {
+ strbuf_add(data, terminator, sizeof(terminator));
+ strbuf_add(data, &lulz, sizeof(lulz));
+ return;
+ }
+
+ lulz++;
+ } while (1);
+}
+
static const char commit_utf8_warn[] =
"Warning: commit message does not conform to UTF-8.\n"
"You may want to amend it after fixing the message, or set the config\n"
@@ -890,6 +941,8 @@ int commit_tree(const char *msg, unsigned char *tree,
if (encoding_is_utf8 && !is_utf8(buffer.buf))
fprintf(stderr, commit_utf8_warn);
+ collide_commit(&buffer, elite_want, elite_mask);
+
result = write_sha1_file(buffer.buf, buffer.len, commit_type, ret);
strbuf_release(&buffer);
return result;
next prev parent reply other threads:[~2011-10-19 19:38 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-19 18:03 [IGNORETHIS/PATCH] Choosing the sha1 prefix of your commits Ævar Arnfjörð Bjarmason
2011-10-19 19:01 ` Jeff King
2011-10-19 19:38 ` Jeff King [this message]
2011-10-20 2:51 ` Jeff King
2011-10-20 4:15 ` Kyle Moffett
2011-10-20 4:25 ` Jeff King
2011-10-20 4:27 ` Junio C Hamano
2011-10-20 4:32 ` Kyle Moffett
2011-10-24 20:47 ` Jeff King
2011-10-20 4:31 ` Junio C Hamano
2011-10-20 4:34 ` Jeff King
2011-10-20 6:57 ` Junio C Hamano
2011-10-20 7:13 ` Jeff King
2011-10-20 13:14 ` Ted Ts'o
2011-10-20 15:56 ` Jeff King
2011-10-25 22:35 ` Drew Northup
2011-10-20 18:36 ` Re* " Junio C Hamano
2011-10-20 19:00 ` Jeff King
2011-10-20 7:27 ` Nguyen Thai Ngoc Duy
2011-10-20 9:14 ` Nguyen Thai Ngoc Duy
2011-10-20 15:44 ` Jeff King
2011-10-20 9:38 ` Mikael Magnusson
2011-10-20 13:44 ` Elijah Newren
2011-10-19 22:09 ` Jonathan Nieder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111019193834.GA14168@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).