emPOWer your commits. Pointlessly flex on your coworkers with bespoke commit hashes, all with the convenience of a single command.
A Proof of Work is a cryptographic proof
that an amount of work has been done. Often, these are seen in the form of
Hash(data || nonce)
where the result of the hash has some number of leading zero bits.
Since hashes are one-way functions, this is effectively a O(2^n) brute force for n leading
zero bits. Since git commits are identified with a hash, and you can insert arbitrary
fields into a commit header, you can generate many hashes for one set of changes and
effectively compute a Proof of Work for a git commit. This tool does that, with a
configurable number of threads and leading zero bits on the commit hash.
Some joke about "Git is a blockchain" went too far, now we have this.
Reasonably. On my fanless M2 MacBook Air, it can compute about 30MH/s at peak CPU core boost clocks. If you account for the less-than-stellar MacBook thermals, it drops to about 21MH/s. But assuming you can get good speeds, and assuming you want to calculate a hash with 32 leading zero bits, this should take (2^32 / 30,000,000) ~= 140 seconds on average, though the variance is pretty high. Hashcat's benchmark reports my CPU can do about 725MH/s for SHA-1, so OpenSSL's hash implementation is probably not optimized well for this. Maybe someone can look into adapting Hashcat into this, but it's a bit beyond the scope I'm willing to do.
git-power [bits [threads]]
git-power
operates on the git repository in the current working directory.
The only supported run options are the number of leading bits to brute-force and the
number of threads created to do the work. By default, git-power
will use 32 bits and
the max number of hardware threads supported.
When a matching commit hash is found, it will automatically update your repository HEAD and replace the latest commit. NEW: If your commit is GPG-signed, it will stay signed even after running this! See the source for details on how this witchcraft is performed.
If you want to retroactively emPOWer all of your commits, you can combine git power
with the brilliance of git rebase --interactive
:
# emPOWer entire tree (preferred method)
git rebase --interactive --exec "git power" --root
# emPOWer unpushed commits
git rebase --interactive --exec "git power" origin/master
# emPOWer everything after a specific commit
git rebase --interactive --exec "git power" 00000000da6a1220576d8c00dff8aa9619b44048
This tool requires cmake
, libgit2
, and OpenSSL
to build. You can get libgit2
and
OpenSSL
through your package manager, or at libgit2.org.
Build steps are straight-forward from there:
cmake -B build && cmake --build build
On macOS, Apple is rude and won't let you link with the system-provided libcrypto
, so
you need to brew install openssl
(or build it yourself). Then you can pretend you have a
real unix system:
cmake -B build -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl && cmake --build build
On Windows, you need to compile libgit2
and OpenSSL
yourself. Then just point cmake
at them, and you should be good:
# Be sure to specify the correct arch
cmake -B build -A x64 "-DCMAKE_PREFIX_PATH=C:\Program Files\libgit2" "-DOPENSSL_ROOT_DIR=C:\Program Files\OpenSSL"
cmake --build build
First, install via cmake
:
cmake --install build
Then, you can use it through git
like any other utility:
# Default settings: 32 and <hardware thread count>
git power
# MacBook-friendly
git power 24 8
Drop git-power.exe
, git2.dll
, and crypto.dll
in your git installation's bin
directory. On my machine, that's at C:\Program Files\Git\mingw64\bin
. Then you can use
it like normal.
# Default settings: 32 and <hardware thread count>
git power
# APU-friendly
git power 24 8
MIT license. I'm really not sure who would want to reuse this, but it's here if you want.
Too long.
It wouldn't be too hard. Feel free to submit a pull request whose commit hash starts with
at least 32 zero bits. I have received news that someone is doing this..
There is also lucky-commit, written in Rust,
that has the same idea as git-power
, but with GPU acceleration and the ability to choose
a custom prefix. Looks like their Rust implementation (with or without GPU) is significantly
faster than this C++ implementation. Crab language wins again, so it seems.
Sorry.