emPOWer your commits. Pointlessly flex on your coworkers with bespoke commit hashes, all with the convenience of a single command.

Overview

git-power

emPOWer your commits. Pointlessly flex on your coworkers with bespoke commit hashes, all with the convenience of a single command.

demo

What is it?

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.

Why?

Some joke about "Git is a blockchain" went too far, now we have this.

Is it fast?

Reasonably. On my Intel i9 9880H @ 2.3GHz with 16 threads, it can compute about 12MH/s at peak CPU core boost clocks. If you account for the less-than-stellar MacBook thermals, it drops to about 8MH/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 / 12,000,000) ~= 360 seconds on average, though the variance is pretty high. Hashcat's benchmark reports my CPU can do about 315MH/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.

Usage

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.

Retroactively

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

Building

Linux

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

macOS

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

Windows

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

Installing

macOS / Linux

First, install via cmake:

cmake --install build

Then, you can use it through git like any other utility:

# Default settings: 32 and 
git power

# MacBook-friendly
git power 24 8

Windows

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 
git power

# APU-friendly
git power 24 8

License

MIT license. I'm really not sure who would want to reuse this, but it's here if you want.

How long did you spend running it on this repo

Too long.

Will you Rewrite it in Rust (TM)?

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.

Please apologize for creating this

Sorry.

Comments
  • Only exact number of zero bits is accepted

    Only exact number of zero bits is accepted

    Runs: 715684864 Best found: 00000001d6e8e98fb21368b96a075ae30c6c8e39 (31/28 bits) Time: 289.670476 ~2.470686MH/s000000

    I tried 32 bits first but stopped after it took too long. Then I tried 28 and it found 31 zero bits rather quickly. But it did not stop and use that hash and instead continued searching for 28.

    I would have been satisfied with 31 of course.

    It would be nice if you could at least choose to accept longer hashes.

    I think it might even deadlock if it finds more bits than required. Hence why it hangs for finding small amounts of zero bits (1,2,3 even 10)

    opened by 616slayer616 2
  • Fix cmake for Mac

    Fix cmake for Mac

    With cmake -B build -DOPENSSL_ROOT_PATH=/usr/local/opt/openssl, I am getting below error:

    CMake Error at /usr/local/Cellar/cmake/3.20.5/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
      Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
      system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY
      OPENSSL_INCLUDE_DIR)
    

    With cmake -B build -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl, its working fine. I am using cmake version 3.20.5

    opened by 0x6773 1
  • Fix

    Fix "Unknown armor header" gpg message for signed commits

    Using Git CLI like this:

    git log --show-signature
    

    Right now it shows a message like gpg: unknown armor header: Nonce: UXS^O AAAAA1316 (please see the screenshot).

    MR fixes this, you can pull my commit to compare it against yours locally.
    I'm not sure the fix is clearly correct, but it works also for other commits.

    Screenshot

    image

    opened by SlayerShadow 0
  • Support building on older systems

    Support building on older systems

    Even if you choose not to, here's the fixes for anyone trying with cmake 3.13.4 and libgit2 0.27.7:

    CMake Error at CMakeLists.txt:29 (install):
      install TARGETS given no RUNTIME DESTINATION for executable target
      "git-power".
    ...
    git-power/main.cpp: In function ‘void try_commits(size_t, size_t, size_t, char*, size_t)’:
    git-power/main.cpp:300:47: error: ‘GIT_OBJECT_COMMIT’ was not declared in this scope
      git_odb_hash(&hash, commit_buf, commit_size, GIT_OBJECT_COMMIT);
                                                   ^~~~~~~~~~~~~~~~~
    
    diff --git i/CMakeLists.txt w/CMakeLists.txt
    index 4604d57..f5a26d6 100644
    --- i/CMakeLists.txt
    +++ w/CMakeLists.txt
    @@ -26,4 +26,4 @@ if (UNIX AND NOT APPLE)
         target_link_libraries(git-power PRIVATE pthread atomic)
     endif ()
     
    -install(TARGETS git-power)
    +install(TARGETS git-power RUNTIME DESTINATION bin)
    diff --git i/main.cpp w/main.cpp
    index 4cf9a9e..983bc9d 100644
    --- i/main.cpp
    +++ w/main.cpp
    @@ -297,7 +297,7 @@ I should not be allowed near this
     
            // Big sanity check here since we think this is a good hash
            git_oid hash;
    -       git_odb_hash(&hash, commit_buf, commit_size, GIT_OBJECT_COMMIT);
    +       git_odb_hash(&hash, commit_buf, commit_size, GIT_OBJ_COMMIT);
            int test = 0;
            for (size_t n = 0; n < bits; n++) {
                    // Test will be the OR of the first `n` bits
    @@ -473,7 +473,7 @@ int main(int argc, const char **argv) {
     
                    // And make the commit for them
                    git_oid hash;
    -               git_odb_write(&hash, db, commit_buffer, commit_size, GIT_OBJECT_COMMIT);
    +               git_odb_write(&hash, db, commit_buffer, commit_size, GIT_OBJ_COMMIT);
     
                    // Fancy print
                    char id[0x100];
    @@ -486,7 +486,7 @@ int main(int argc, const char **argv) {
     
                    // Soft reset to this commit so it is now branch head
                    git_object *new_commit;
    -               git_object_lookup(&new_commit, repository, &hash, GIT_OBJECT_COMMIT);
    +               git_object_lookup(&new_commit, repository, &hash, GIT_OBJ_COMMIT);
     
                    git_reset(repository, new_commit, GIT_RESET_SOFT, nullptr);
     
    
    opened by emorrp1 0
  • Improvements

    Improvements

    • Added a proper command line option parsing utility (CLI11 https://github.com/CLIUtils/CLI11)
    • Updated the headers to be the proper ones for C++
    • Moved C headers into the proper C++ extern section.
    • Changed current directory to "./" which should be understood by any modern operating system.
    • Added optional compiler flags for better debugging.

    And I might have tashed your formatting by accident.

    opened by psygate 0
  • Performance tuning suggestions

    Performance tuning suggestions

    Since it seems like more people have joined the "customize git commit hashes because why not" bandwagon (welcome!), I figured I'd share some insights from doing a lot of performance tuning on my own implementation from a few years ago. Obviously, none of this should be taken to discourage new implementations or to ruin any fun.

    In decreasing order of effectiveness, the main things that helped were:

    • Running on a GPU (this improved performance by roughly a factor of 10, depending on hardware)
    • Caching SHA1 buffer state. The tl;dr is that if you put the nonce at the end of your commit message (or signature, if applicable), you can cache the state of the SHA1 algorithm as applied to all but the last ~64 bytes of the commit, and then reapply the cached state to the last 64 bytes on each attempt. This improved performance by a factor of about 4-5 or more, depending on how big the commit is.
    • If the nonce is always the same length, then the trailer that the SHA1 puts at the end of data when hashing is also effectively fixed, and I was able to improve the performance of lucky-commit by about 25% by not recomputing it each time.

    (Also mentioning @mkrasnitski from https://github.com/mkrasnitski/git-power-rs)

    opened by not-an-aardvark 3
Owner
Glenn Smith
Security, games, game "security." C++/Rust and sometimes web/C#. @RPISEC
Glenn Smith
Animated sprite editor & pixel art tool -- Fork of the last GPLv2 commit of Aseprite

LibreSprite Introduction LibreSprite is a free and open source program for creating and animating your sprites. Real-time animation previews. Onion sk

null 2.9k Dec 31, 2022
A simple Jasper interpreter made with Flex, Bison and the LLVM IR

JasperCompiler A simple Jasper interpreter (for now) made with Flex and Bison. Jasper? Jasper is "a scripting language inspired by Haskell, Javascript

Emmanuel 2 Jan 16, 2022
A simple programming language using Bison and Flex in C++.

Yu Language - yulang A toy project for creating a simple programming language using Bison and Flex in C++. interface $ ./yulang Yu Language 0.0.1 (uns

Yudha Styawan 1 Oct 27, 2021
USB-C_PCB_experiments - USB-C ports made from a flex PCB and an ATtiny84A

USB-C PCB Experiments This is part of an ongoing series of projects involving creative interpretations of the USB mechanical standards. You've probabl

Sam Ettinger 23 Sep 5, 2022
A program to backup all of your game savefiles on your system, neatly, and into a single folder.

Savefile Saver I created this project as a solution to a simple, but annoying problem: Backing up my game savefiles. I wanted to be able to copy all o

Dominic Esposito 6 Oct 24, 2022
WisBlock API takes care of all the LoRaWAN, BLE, AT command functionality

WisBlock-API Targeting low power consumption, this Arduino library for RAKwireless WisBlock Core modules takes care of all the LoRaWAN, BLE, AT comman

Bernd Giesecke 19 Dec 7, 2022
Tuibox - A single-header terminal UI (TUI) library, capable of creating mouse-driven, interactive applications on the command line.

tuibox tuibox ("toybox") is a single-header terminal UI library, capable of creating mouse-driven, interactive applications on the command line. It is

Andrew 37 Dec 24, 2022
A header maker, this project will create your header file with all your declaration in

Headermaker Install: git clone https://github.com/rmechety42/Headermaker.git cd Headermaker make install Usage: Headermaker src_folder_you_want_to

Rayan Mechety 35 Dec 8, 2022
This repository shows my all (maybe all) solved problem (CodeForces & AtCoder) and their description with my Codes!!!

Submissions Auto-generated with ❤ using Harwest Introduction A repository to keep track of problem solving practice, containing solutions from platfor

Obaydullah Khan  3 Aug 4, 2022
RaspberryPiCM4Handheld7Inch - A single source for all of the information around my Raspberry Pi CM4 7" Handheld

Raspberry Pi CM4 Handheld 7 - Aegis" A repository for the Aegis, a 7" Raspberry Pi CM4 handheld device. NOTE: This is still a work in progress. The de

null 245 Dec 22, 2022
The Gecko SDK (GSDK) combines all Silicon Labs 32-bit IoT product software development kits (SDKs) based on Gecko Platform into a single, integrated SDK.

Silicon Labs Gecko SDK (GSDK) The Gecko SDK (GSDK) combines Silicon Labs wireless software development kits (SDKs) and Gecko Platform into a single, i

Silicon Labs 163 Dec 28, 2022
A single file, single function, header to make notifications on the PS4 easier

Notifi Synopsis Adds a single function notifi(). It functions like printf however the first arg is the image to use (NULL and any invalid input should

Al Azif 9 Oct 4, 2022
Bobby Cooke 328 Dec 25, 2022
The command line app automatically determines your location using GeoIP and adjusts the color temperature depending on time

go-sct A color temperature setting library and CLI that operates in a similar way to f.lux and Redshift. The command line app automatically determines

Florine Sueur 1.1k Jan 25, 2022
All type of codes(Beginner, Intermediate and Advance) feel free to add your codes to this repo !

Hello everyone, Welcome to Basic_codes ?? All type of codes (Beginner, Intermediate and Advance) feel free to add your codes to this repo! ?? ?? You w

Nikhil Verma 2 Oct 15, 2021
Watch TV channels on your device via internet from all over the world for free. IPTV API Implemented with QT C++

IPTV Desktop Description IPTV-Desktop is GUI application made with Qt C++ using IPTV API, which was developed by iptv-org. Watch free tv channels via

Not Your Surya 4 Oct 24, 2022
All-in-One firmware for your 32-bit Prusa MK3S/+ Bear!

Prusa All-in-One Marlin Firmware About All-in-One firmware for your 32-bit Prusa MK3S/+ Bear! Configuring & Building Prusa All-in-One Firmware To conf

Keith Bennett 15 Dec 18, 2022
Embed read-only filesystems into any C++11 program w. a single header, zero dependencies and zero modifications to your code

c-embed Embed read-only filesystems into any C++11 program w. a single header, zero dependencies and zero modifications to your code. Usage c-embed al

Nick McDonald 9 Dec 29, 2022