From 109503cbf93e5e202cc15a8d05a35b05b1d41e52 Mon Sep 17 00:00:00 2001 From: "Roy G. Cmiel" Date: Thu, 17 Jun 2021 10:31:39 +0200 Subject: [PATCH] added test for hashcash and starting signatures --- .gitignore | 2 + PerlWebSocketEchoServer.pl | 16 +++++++ _data/timelog.yml | 2 + block0.yml | 10 ++--- eckeygen.pl | 32 ++++++++++++++ encode.pm | 86 ++++++++++++++++++++++++++++++++++++++ misc.pm | 13 ++++++ notes.md | 9 +++- seed.pm | 50 ++++++++++++++++++++++ signatures.pm | 12 ++++++ t/blockaddr.t | 32 ++++++++++++++ t/hashcash.t | 37 ++++++++++++++++ t/random.t | 13 ++++++ 13 files changed, 307 insertions(+), 7 deletions(-) create mode 100644 .gitignore create mode 100644 PerlWebSocketEchoServer.pl create mode 100644 eckeygen.pl create mode 100644 encode.pm create mode 100644 seed.pm create mode 100644 signatures.pm create mode 100644 t/blockaddr.t create mode 100644 t/hashcash.t create mode 100644 t/random.t diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d40ed65 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~1 +.*cache diff --git a/PerlWebSocketEchoServer.pl b/PerlWebSocketEchoServer.pl new file mode 100644 index 0000000..e09ce92 --- /dev/null +++ b/PerlWebSocketEchoServer.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl +use Net::WebSocket::Server; + +Net::WebSocket::Server->new( + listen => 8080, + on_connect => sub { + my ($serv, $conn) = @_; + $conn->on( + utf8 => sub { + my ($conn, $msg) = @_; + $conn->send_utf8($msg); + }, + ); + }, +)->start; +1; diff --git a/_data/timelog.yml b/_data/timelog.yml index 6a240e3..7ce3166 100644 --- a/_data/timelog.yml +++ b/_data/timelog.yml @@ -2,3 +2,5 @@ 1623740460598930744: start toptal design analysis -- ~rg/toychain 1623748350994233358: stop toptal -- ~rg/toychain 1623820719262653597: start toptal -- /drg/toychain +1623840120298864700: stop toptal -- /drg/toychain +1623918295152043953: start toptal keygeneration -- /drg/toychain diff --git a/block0.yml b/block0.yml index 6f13747..7cdf6b0 100644 --- a/block0.yml +++ b/block0.yml @@ -1,7 +1,7 @@ --- # block genesis -n: 0 # blocknumber (on 32bit max block-number : 4294967296) -txroot: QmNonce+qmerkle-without-zeros -# echo -n '' | ipfs add -txprev: QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH +ver: 0x00 +seq: 0 # blocknumber (on 32bit max block-number : 4294967296) # ipfs object new unixfs-dir -payload: QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn +data: QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn +# echo -n '' | ipfs add +bkprev: QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH diff --git a/eckeygen.pl b/eckeygen.pl new file mode 100644 index 0000000..71a3ce6 --- /dev/null +++ b/eckeygen.pl @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# +# testing out ecdsa key generation ... + +use Crypt::PK::ECC; +use YAML::Syck qw(Dump); + +#Key generation +my $pk = Crypt::PK::ECC->new(); +$pk->generate_key('secp256k1'); +my $private_der = $pk->export_key_der('private'); + +my $public_pem = $pk->export_key_pem('public'); + +local *PK; +open PK,'>','eckey-priv.der'; binmode(PK); +print PK $private_der; +close +open PK,'>','eckey-pub.pem'; +print PK $public_pem; +close PK; + +open PK,'>','eckey.yml'; +print PK "--- # eckey\n"; +printf PK "pk: %s\n",Dump($pk->key2hash); +printf PK "...\n"; +close PK; + + +exit $?; + +1; # $Source: /my/perl/script/eckeygen.pl $ diff --git a/encode.pm b/encode.pm new file mode 100644 index 0000000..7db2d98 --- /dev/null +++ b/encode.pm @@ -0,0 +1,86 @@ +# +# Intent: +# provide encoding routines +# +# Note: +# This work has been done during my time at Doctor I·T +# +# -- Copyright drit, 2021 -- +# +BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } } +# +package encode; +require Exporter; +@ISA = qw(Exporter); +# Subs we export by default. +@EXPORT = qw(); +# Subs we will export if asked. +#@EXPORT_OK = qw(nickname); +@EXPORT_OK = grep { $_ !~ m/^_/ && defined &$_; } keys %{__PACKAGE__ . '::'}; + +use strict; +use misc qw(version); + +# The "use vars" and "$VERSION" statements seem to be required. +use vars qw/$dbug $VERSION/; +# ---------------------------------------------------- +our $VERSION = sprintf "%d.%02d", q$Revision: 0.0 $ =~ /: (\d+)\.(\d+)/; +my ($State) = q$State: Exp $ =~ /: (\w+)/; our $dbug = ($State eq 'dbug')?1:0; +# ---------------------------------------------------- +$VERSION = &version(__FILE__) unless ($VERSION ne '0.00'); + +sub mbase58 { + my $mh = sprintf'Z%s',&encode_base58f(@_); + return $mh; +} +sub mbase36 { + my $mh = sprintf'K%s',uc&encode_base36(@_); + return $mh; +} +sub mbase16 { + my $mh = sprintf'f%s',unpack'H*',@_; + return $mh; +} + + +sub encode_base36 { + use Math::BigInt; + use Math::Base36 qw(); + my $n = Math::BigInt->from_bytes(shift); + my $k36 = Math::Base36::encode_base36($n,@_); + #$k36 =~ y,0-9A-Z,A-Z0-9,; + return $k36; +} +sub decode_base36 { + use Math::BigInt; + use Math::Base36 qw(); + #$k36 = uc($_[0]) + #$k36 =~ y,A-Z0-9,0-9A-Z; + my $n = Math::Base36::decode_base36($_[0]); + my $bin = Math::BigInt->new($n)->as_bytes(); + return $bin; +} + +sub encode_base58f { # flickr + 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_base58f { + 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); + my $bin = Math::BigInt->new($bint)->as_bytes(); + return $bin; +} + +# ----------------------------------------------------------------------- +1; # $Source: /my/perl/modules/encode.pm $ + diff --git a/misc.pm b/misc.pm index a893f8b..ebb5028 100644 --- a/misc.pm +++ b/misc.pm @@ -28,6 +28,19 @@ my ($State) = q$State: Exp $ =~ /: (\w+)/; our $dbug = ($State eq 'dbug')?1:0; # ---------------------------------------------------- $VERSION = &version(__FILE__) unless ($VERSION ne '0.00'); +# ----------------------------------------------------------------------- +sub jsonify { + use JSON qw(encode_json); + my $obj = shift; + my $json = encode_json( $obj ); # /!\ keys are note sorted ! + return $json; +} +sub yamlify { + use YAML::Syck qw(Dump); + my $obj = shift; + my $yml = Dump($obj); + return $yml; +} # ----------------------------------------------------------------------- sub khash { # keyed hash use Crypt::Digest qw(); diff --git a/notes.md b/notes.md index e6696a0..5017ef6 100644 --- a/notes.md +++ b/notes.md @@ -1,13 +1,18 @@ # Design Notes -Initial design choices +## Initial design choices - protocol/routing/network layer: websockets (multi nonblocking clients) - server-side fileformat : yaml - client-side fileformat : JSON -Language choice: +## Language choice: serverside: perl (or nodejs) clienside: javascript +## block chain structure + + minimally sized blocks : + - segreated signature, timestamp, audit etc. + - {seq number, hash, previous} diff --git a/seed.pm b/seed.pm new file mode 100644 index 0000000..74e1304 --- /dev/null +++ b/seed.pm @@ -0,0 +1,50 @@ +# +# Intent: +# entropy routines grasping source intention ! +# +# Note: +# This work has been done during my time at Doctor I·T +# +# -- Copyright drit, 2021 -- +BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } } +# +package seed; +require Exporter; +@ISA = qw(Exporter); +# Subs we export by default. +@EXPORT = qw(); +# Subs we will export if asked. +#@EXPORT_OK = qw(nickname); +@EXPORT_OK = grep { $_ !~ m/^_/ && defined &$_; } keys %{__PACKAGE__ . '::'}; + +use strict; +use misc qw(version); + +# The "use vars" and "$VERSION" statements seem to be required. +use vars qw/$dbug $VERSION/; +# ---------------------------------------------------- +our $VERSION = sprintf "%d.%02d", q$Revision: 0.0 $ =~ /: (\d+)\.(\d+)/; +my ($State) = q$State: Exp $ =~ /: (\w+)/; our $dbug = ($State eq 'dbug')?1:0; +# ---------------------------------------------------- +$VERSION = &version(__FILE__) unless ($VERSION ne '0.00'); + + +sub setseed { + our $seed = undef; + # ecf7fa3d : 15min + $seed = ($_[0]) ? srand($_[0]) : srand(); + printf "seed: %08x\n",$seed; + return $seed; +} +# ----------------------------------------------------------------------- +sub rand64 { # /!\ NOT Cryptographycally safe + my $i1 = int(rand(0xFFFF_FFFF)); + my $i2 = int(rand(0xFFFF_FFFF)); + my $q = $i1 <<32 | $i2; + printf "i1: %08x\n",$i1; + printf "i2: %08x\n",$i2; + printf "rnd64: %s\n",unpack'H*',pack'Q',$q; + return $q; +} +# ----------------------------------------------------------------------- +1; # $Source: /my/perl/modules/pseudorandom.pm $ diff --git a/signatures.pm b/signatures.pm new file mode 100644 index 0000000..537834e --- /dev/null +++ b/signatures.pm @@ -0,0 +1,12 @@ +#!/usr/bin/perl + + +use Crypt::OpenSSL::ECDSA; +$sig = Crypt::OpenSSL::ECDSA::ECDSA_do_sign( $digest, $eckey ); +$r = $sig->get_r; +$s = $sig->get_s; + +$sig = Crypt::OpenSSL::ECDSA::ECDSA_SIG->new(); +$sig->set_r($r); +$sig->set_s($s); +Crypt::OpenSSL::ECDSA::ECDSA_do_verify( $digest, $sig, $eckey ); diff --git a/t/blockaddr.t b/t/blockaddr.t new file mode 100644 index 0000000..078f1ff --- /dev/null +++ b/t/blockaddr.t @@ -0,0 +1,32 @@ +#!/usr/bin/perl + +# +# Intent: +# testing it ! +# +# Note: +# This work has been done during my time at Doctor I·T +# +# -- Copyright drit, 2021 -- +# +BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } } + +#use if -e $LIB, $LIB.'/seed'; +use seed qw(rand64); +use toychain qw(blockAddr); +use YAML::Syck qw(Dump); +print "testing blockaddr\n"; +printf "chain.addr: %s\n",$toychain::chain->{bkaddr}; + +# f96885aa : 21.4min +# 044ce1de : 20.5min +my $n0 = rand64(); # n < 18446744073709551616 +printf "n0:%s\n",$n0; + +my $addr = &blockAddr($toychain::genesis); +printf "genesis.addr: %s\n",$addr; + +exit $?; + + +1; diff --git a/t/hashcash.t b/t/hashcash.t new file mode 100644 index 0000000..2fbf2d3 --- /dev/null +++ b/t/hashcash.t @@ -0,0 +1,37 @@ +#!/usr/bin/perl + +# +# Intent: +# testing it ! +# +# Note: +# This work has been done during my time at Doctor I·T +# +# -- Copyright drit, 2021 -- +# +BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } } + +printf "// initialization $0\n"; +#use if -e $LIB, $LIB.'/seed'; +use seed qw(rand64); +use toychain qw(hashcash); + +printf "// testing $0\n"; + +&seed::setseed(0x2f392c85); + +# f96885aa : 21.4min +# 044ce1de : 20.5min +my $n0 = rand64(); # n < 18446744073709551616 +printf "n0:%s\n",$n0; + + +my ($hc,$n) = &hashcash('SHA256','hello world',$n0,5); +printf "hc: %s %x %s\n",unpack('H*',$hc),$n,unpack'H*',pack('Q',$n); + +printf "// done $0\n"; + +exit $?; + + +1; diff --git a/t/random.t b/t/random.t new file mode 100644 index 0000000..711da84 --- /dev/null +++ b/t/random.t @@ -0,0 +1,13 @@ +#!/usr/bin/perl + +BEGIN { if (-e $ENV{SITE}.'/lib') { use lib $ENV{SITE}.'/lib'; } } +use seed qw(rand64); + +&seed::setseed(0x49b1cffe || undef); +my $n0 = seed::rand64(); # n < 18446744073709551616 +printf "n0: %s\n",$n0; + +exit $?; + + +1;