Skip to content

Instantly share code, notes, and snippets.

@DrI-T
Last active March 10, 2022 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DrI-T/91bb4010dd4523ea281a066fe147ceab to your computer and use it in GitHub Desktop.
Save DrI-T/91bb4010dd4523ea281a066fe147ceab to your computer and use it in GitHub Desktop.
GitChain: a eco-organic git based blockchain

decentralized pull-request

Any system with a publicly accessible inbound channel is subject to sybil attack (i.e. SPAM).

Indeed the price of "identity" being zero we can naturally assume

  • creating new block on the chain
  • appending of logs
  • pushing a git commit
  • sending an email

All these can be abuse to a point of a DDoSing risk.

It is then key to minimize any amplification before screening request for validity.

Mitigation :

  • Increasing the cost of "push" we can greatly diminish the returns of these DDoS attacks.
  • decreasing the time and effort to validate each query
  • option to divert an attack will prevent DoS
  • rate limiting of each inbound channel using build-in slowness (! PoTime )

see also

#
echo IPFS_PATH: ${IPFS_PATH:-$HOME/.ipfs}
pkr=${1:-QmcbBtgD511KiRzTdngGK2SkvC66gAHmnD7ZdRBCPA1ouS}
if ipfs key list | grep -q -w DPKI; then
key=$(ipfs key list -l --ipns-base b58mh | grep -w DPKI | cut -d' ' -f1)
else
key=$(ipfs key gen -t ed25519 --ipns-base b58mh DPKI)
fi
name=$(perl -S fullname.pl $key)
echo "key: $key ($name)"
if ! ipfs key export -o /dev/null DPKI 2>/dev/null; then
ipfs shutdown
fi
sku=$(ipfs key export -o /dev/stdout DPKI | base64 -w 0)
name=$(perl -S fullname.pl $pkr)
echo "pkr: $pkr ($name)"
echo sku: $sku
ipfs key rm dhkey 2>/dev/null
pkey=$(echo $sku | perl DHkeys.pl $pkr | grep privkey: | cut -d' ' -f2 )
dhkey=$(echo $pkey | xxd -r -p | ipfs key import --ipns-base b58mh -- dhkey -)
name=$(perl -S fullname.pl $dhkey)
echo "dhkey: $dhkey ($name)"
#!/usr/bin/perl
#BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } }
# usage:
# ipfs key export -o /dev/stdout DPKI | perl DHkeys.pl $pku
# header: 08011240
# ipfs key list -l --ipns-base base16 | grep self
# pub-self: f01721220d4ca21fd67b197375c10392f392adc4cd33fbce4575d435e23a664f0cbac60f7
# ........ 1 2 3 4 5 6
# ........0123456789.123456789.123456789.123456789.123456789.123456789.123
# pub-self: f0172002408011220cb574dd68763332e5d19aaf7d229b1f0d1229f1a40cc5a350e66b114145367de
# priv-self: f080112407ee64c96a7746b2115f311f42d3de292ea5997ab84a0ba3d246caffb684f8290
# cb574dd68763332e5d19aaf7d229b1f0d1229f1a40cc5a350e66b114145367de
use MIME::Base64 qw(encode_base64 decode_base64);
use lib '.';
use botname qw(botname);
# ed25519 (2^255 - 19)
my $buf64 = <STDIN>;
my $buf = &decode_base64($buf64);
printf "buf: %s (%dc)\n",unpack('H*',$buf),length($buf);
my $sku = substr($buf,4,32);
my $pku = substr($buf,32+4);
printf "sku: f%s (%dc)\n",unpack('H*',$sku),length($sku);
printf "pku: f%s (%dc)\n",unpack('H*',$pku),length($pku);
my $pubkey = shift || '12D3KooWPW89HLc7Ft1UqZGFUfxqxnAKM6sr6rBNLKkGigLC1iFX';
my $pubkey_raw = substr(decode_mbase58($pubkey),-32);
printf "pubkey: f%s\n",unpack'H*',$pubkey_raw;
#my $ecdh = &ecsecret($sku,$pubkey_raw);
my $eddh = &edsecret($sku,$pubkey_raw);
my $key = &edkeygen($eddh);
printf "key: f%s\n",unpack'H*',$key;
my $key64 = &encode_base64(pack('H12','002408011240').$key,'');
printf "key64: %s\n",$key64;
printf "privkey: 08011240%s\n",unpack'H*',$key;
exit $?;
sub edsecret(@) {
use Crypt::Ed25519 qw(); # no symbols exported
#my $curve = 'ed25519';
my $recipient_public_raw = pop;
my $origin_private_raw = shift;
#printf "priv58: %s\n",encode_mbase58($private_raw);
#printf "pub58 : %s\n",encode_mbase58($public_raw);
my ($pko, $sko) = Crypt::Ed25519::generate_keypair $origin_private_raw;
#my $origin_public_raw = Crypt::Ed22519::eddsa_public_key($origin_private_raw);
printf "pko: f%s\n",unpack'H*',$pko;
# fc02c7b8a7d67b07e4d7f788e19f4af0f89631ac23c6641d88292f8769139fc4b270f9eb9d380ada9b507e3e3eb498e6e198e70b779985cc72cf153359ee1cd40
printf "sko: f%s (%uc)\n",unpack('H*',$sko),length($sko);
$shared_secret = Crypt::Ed25519::key_exchange($recipient_public_raw, $sko);
#printf "edsecret: f%s\n",unpack'H*',$shared_secret;
if (wantarray) {
my $secret58 = &encode_mbase58($shared_secret);
my $origin_public58 = &encode_mbase58($pko);
my $recipient_public58 = &encode_mbase58($recipient_public_raw);
printf "DH(%s,%s) = %s\n",&botname($origin_public58),&botname($recipient_public58),$secret58;;
return ($shared_secret,$public58,$pubkey58);
} else {
return $shared_secret;
}
return $shared_secret;
}
sub edkeygen($){
my $secret = shift;
my ($pko, $sko) = Crypt::Ed25519::generate_keypair $secret;
my $key = $secret . $pko;
return $key;
}
sub ecsecret(@) {
use Crypt::PK::ECC;
our $secrets;
my $curve = 'secp256k1';
my $public_raw = pop;
my $private_raw = shift;
#printf "priv58: %s\n",encode_mbase58($private_raw);
#printf "pub58 : %s\n",encode_mbase58($public_raw);
my $sk = Crypt::PK::ECC->new();
my $priv = $sk->import_key_raw($private_raw, $curve);
my $pk = Crypt::PK::ECC->new();
my $pub = $pk->import_key_raw($public_raw ,$curve);
my $shared_secret = $priv->shared_secret($pub);
if (wantarray) {
my $secret58 = &encode_mbase58($shared_secret);
my $origin_raw = $priv->export_key_raw('public_compressed');
my $public58 = &encode_mbase58($origin_raw);
my $pubkey58 = &encode_mbase58($public_raw);
printf "DH(%s,%s) = %s\n",&botname($public58),&botname($pubkey58),$secret58;;
return ($shared_secret,$public58,$pubkey58);
} else {
return $shared_secret;
}
}
sub encode_mbase58 {
my $mh = sprintf'z%s',&encode_base58(@_);
return $mh;
}
sub decode_mbase58 {
my $raw;
if ($_[0] =~ m/^z/) {
$raw = decode_base58(substr($_[0],1));
} else {
$raw = decode_base58($_[0]);
}
return $raw;
}
sub encode_base58 { # btc
use Math::BigInt;
use Encode::Base58::BigInt qw();
my $bin = join'',@_;
my $bint = Math::BigInt->from_bytes($bin);
my $h58 = Encode::Base58::BigInt::encode_base58($bint);
$h58 =~ tr/a-km-zA-HJ-NP-Z/A-HJ-NP-Za-km-z/; # btc
return $h58;
}
sub decode_base58 {
use Carp qw(cluck);
use Math::BigInt;
use Encode::Base58::BigInt qw();
my $s = $_[0];
$s =~ tr/A-HJ-NP-Za-km-zIO0l/a-km-zA-HJ-NP-ZiooL/; # btc
$s =~ tr/IO0l/iooL/; # forbidden chars
my $bint = Encode::Base58::BigInt::decode_base58($s);
cluck "error decoding $s!" unless $bint;
my $bin = Math::BigInt->new($bint)->as_bytes();
return $bin;
}
# ------------------------------------------------------------------
1; #
__DATA__
syntax = "proto2";
enum KeyType {
RSA = 0;
Ed25519 = 1;
Secp256k1 = 2;
ECDSA = 3;
}
message PublicKey {
required KeyType Type = 1;
required bytes Data = 2;
}
message PrivateKey {
required KeyType Type = 1;
required bytes Data = 2;
}
__END__
#
if ! ipfs swarm addrs local 2>/dev/null; then
ipfs daemon &
sleep 12
fi
tic=$(date +%s%N | cut -c-13)
echo repo: ${IPFS_PATH:-$HOME/.ipfs}
peerid=$(ipfs config Identity.PeerID)
gwport=$(ipfs config Addresses.Gateway | cut -d'/' -f 5)
apiport=$(ipfs config Addresses.API | cut -d'/' -f 5)
token=$(echo "$@" | openssl sha256 -r | cut -d' ' -f1)
qm=$(echo $token | xxd -r -p | ipfs add -Q --pin=true)
token=$(ipfs cat $qm | xxd -p -c 64)
echo "$tic: $qm $@" >> joined.log
echo token: $token
echo addr: $qm
peer=$(ipfs dht findprovs $qm -n 2 --timeout 2s 2>/dev/null | tail -1)
name=$(perl -S fullname.pl $peer)
echo "peer: $peer ($name)"
if [ "x$peer" = "x$peerid" ]; then
peer=12D3KooWFeHu75n14FDrSUDXbb7cXhRUJCYxsRCQLA8nZ9R7uJEg
fi
route=$(ipfs dht findpeer $peer | grep -v 127 | grep ip4| grep quic | tail -1)
if [ "no$route" != 'no' ]; then
echo ipfs swarm connect $route/p2p/$peer
fi
echo ipfs dag get /ipfs/$qm
time curl -s https://ipfs.safewatch.ml/ipfs/$qm | xxd
echo xdg-open https://gateway.ipfs.io/api/v0/dag/get?arg=$qm
echo curl -s -X POST http://127.0.0.1:$apiport/api/v0/dag/get?arg=$qm
#
tic=$(date +%s%N | cut -c-13)
echo repo: ${IPFS_PATH:-$HOME/.ipfs}
peerid=$(ipfs config Identity.PeerID)
gwport=$(ipfs config Addresses.Gateway | cut -d'/' -f 5)
apiport=$(ipfs config Addresses.API | cut -d'/' -f 5)
token=$(echo "$@" | openssl sha256 -r | cut -d' ' -f1)
qm=$(echo $token | xxd -r -p | ipfs add -n -Q)
token=$(ipfs cat $qm | xxd -p -c 64)
echo "$tic: $qm $@"
echo token: $token
echo addr: $qm
ipfs dht findprovs $qm -n 2 --timeout 2s 2>/dev/null | while read peer; do
name=$(perl -S fullname.pl $peer)
echo "peer: $peer ($name)"
if [ "x$peer" != "x$peerid" ]; then
route=$(ipfs dht findpeer $peer | grep -v 127 | grep ip4| grep quic | tail -1)
if [ "no$route" != 'no' ]; then
echo ipfs swarm connect $route/p2p/$peer
fi
fi
done
#
pku=${1:-12D3KooWSA6F2J56PtcEstXH9UQv3uvjyFBVFoxUR7gfLJ7uaUnt}
echo "Pull request for $pku" | ipfs add -q --hash sha1 --cid-base base58btc --pin=true
#
peerid=$(ipfs config Identity.PeerID)
token=$(echo "Pull request for $peerid" | ipfs add -Q -n --hash sha1 --cid-base base58btc --pin=true)
echo "token: $token"
if ! ipfs swarm addrs local >/dev/null 2>&1; then
ipfs daemon &
sleep 12
fi
ipfs dht findprovs $token
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
SequenceDiagram [frame=true framecolor=steelblue label="GIT pullRequest Sequence Diagram"] {
actor owner
lifeline "GIT repository" as git
lifeline "ipfs repository" as ipfs
actor user
owner --> git "publish public secret"
activate git
user --> ipfs "get public secret"
git -r-> ipfs
user <-r- ipfs "public secret"
user --> user "compute OT skPRi"
user --> ipfs "push commit to inboundPR branch"
user --> owner "notify w/ token(pkPRi used)"
owner --> git "fetch inboundPR branch"
ipfs -r-> git ""
git --> git "test new branch"
owner --> git "merge branch"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment