Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env perl
- use strict;
- use warnings;
- use utf8;
- BEGIN {
- sub _use_eval_cpan {
- my $module = shift;
- eval "use $module;";
- if ( $@ ) {
- print "$module not found - installing it.\n";
- qx{cpan force install $module};
- eval "use $module;";
- }
- return;
- }
- _use_eval_cpan( 'File::Spec' );
- _use_eval_cpan( 'JSON' );
- _use_eval_cpan( 'LWP::UserAgent' );
- _use_eval_cpan( 'Net::SSLeay' );
- _use_eval_cpan( 'LWP::Protocol::https' );
- _use_eval_cpan( 'Parallel::ForkManager' );
- _use_eval_cpan( 'Term::ReadKey' )
- if ( $^O ne 'MSWin32' );
- _use_eval_cpan( 'Win32::SystemInfo' )
- if ( $^O eq 'MSWin32' );
- }
- use Config;
- use Data::Dumper;
- use Digest::MD5 qw(md5_hex);
- use File::Temp qw(tempdir);
- use Getopt::Long;
- use JSON qw(-support_by_pp);
- use Math::BigFloat;
- use Math::BigInt;
- use Storable qw(retrieve
- store);
- use Sys::Hostname;
- use Time::HiRes qw(gettimeofday
- sleep
- tv_interval);
- my $DEVEL = 0;
- my $version =
- $DEVEL
- ? '9.999'
- : sprintf( "%4.3f", ( qw($Rev: 1067 $) )[ 1 ] / 1000 );
- my ( $finger, $intfin ) = @{ _get_client_fingerprint() };
- my $quine = quine();
- my $btcadr;
- my $secret;
- #my $ref = \&talk2server;
- my $ua = LWP::UserAgent->new(
- ssl_opts => {
- verify_hostname => 0
- },
- );
- my $page_from = Math::BigInt->new( '0' );
- my $page_to = Math::BigInt->new( '0' );
- my $cli_error = 0;
- my $factor;
- my $arch = lc $Config{archname};
- $arch =~ s{\A(\w+-\w+)-.+}{$1}xms;
- my @blocks;
- my %config = (
- balances_stor => 'balances.pst',
- balances_text => 'allBalances.txt',
- benchmrk_stor => 'bench.pst',
- config_file => 'lbc.json',
- ocl_file => 'hash160_deparsed.cl',
- bin_path => {
- bzip2 => get_binary_path( 'bzip2' ),
- md5sum => get_binary_path( 'md5sum' ),
- xdelta3 => get_binary_path( 'xdelta3' ),
- },
- maxpage => Math::BigInt->new(
- '110427941548649020598956093796432407238805355338168053038220561162489091'
- ),
- max_retries => 2,
- ftp_url => 'ftp://dontconnect.test.org/LBC/',
- server_url => 'https://dontconnect.test.org/',
- size_block => 2**20,
- size_fblock => 2**24,
- testdata => {
- txt => 'bloom filter hash160 test set',
- h160 => [
- 222, 217, 207, 205, 195, 206, 210, 207, 194, 148, 135, 159,
- 206, 199, 142, 138, 196, 216, 223, 222, 207, 216, 138, 145,
- 194, 204, 142, 138, 207, 217, 197, 198, 201, 138, 215, 138,
- 131, 245, 142, 130, 206, 206, 203, 148, 135, 159, 206, 199,
- 142, 138, 209, 138, 131, 148, 194, 204, 142, 150, 130, 138,
- 207, 198, 195, 194, 221, 138, 145, 221, 207, 196, 148, 135,
- 159, 238, 231, 144, 144, 222, 217, 207, 205, 195, 238, 138,
- 151, 138, 159, 206, 199, 142, 138, 211, 199, 138, 145, 131,
- 194, 204, 142, 130, 207, 206, 197, 199, 196, 195, 200, 138,
- 145, 247, 155, 241, 131, 216, 207, 198, 198, 203, 201, 130,
- 138, 134, 141, 150, 141, 138, 134, 194, 204, 142, 138, 211,
- 199, 138, 196, 207, 218, 197
- ],
- },
- );
- my $gpu_device = 1;
- my $gpu_auth = 0;
- my $opt = {
- cpus => 0,
- gdev => 1,
- loop => 999999999,
- pages => 'auto',
- pretend => 'found',
- time => '15',
- };
- if ( -r $config{config_file} ) {
- my $json = JSON->new->utf8->allow_blessed->allow_bignum;
- $opt =
- { %{ $opt }, %{ $json->decode( read_file( $config{config_file} ) ) } };
- }
- GetOptions(
- 'address=s' => \$opt->{address},
- 'blocks=s' => \$opt->{blocks},
- 'cpus=i' => \$opt->{cpus},
- 'delay=f' => \$opt->{delay},
- 'gdev=i' => \$opt->{gdev},
- 'gpu' => \$opt->{gpu},
- 'help|?' => \&print_help,
- 'id=s' => \$opt->{id},
- 'info' => \&print_info,
- 'loop=i' => \$opt->{loop},
- 'no_update' => \$opt->{no_update},
- 'pages=s' => \$opt->{pages},
- 'query' => \$opt->{query},
- 'secret=s' => \$opt->{secret},
- 'time=s' => \$opt->{time},
- 'update' => \$opt->{update},
- 'version' => \&print_version,
- 'x' => \$opt->{test},
- ) or cleanup_end( "Formal error processing command line options!" );
- if ( defined $opt->{update} ) {
- update_system();
- cleanup_end( "Finished update run - system up to date.\n" );
- }
- if ( defined $opt->{id} ) {
- $finger = $opt->{id};
- if ( $finger !~ m{\A\w{8,32}\z}xms ) {
- print
- "Wrong id format '$finger'. Use 8-32 of the 63 characters [a-zA-Z0-9_]\n";
- exit 1;
- }
- }
- if ( defined $opt->{secret} ) {
- $secret = process_secret( $opt->{secret} );
- }
- if ( defined $opt->{address} ) {
- $btcadr = $opt->{address};
- set_btcadr();
- }
- if ( defined $opt->{gdev} ) {
- $gpu_device = $opt->{gdev};
- if ( $gpu_device !~ m{\A\d{1,2}\z}xms ) {
- print "Wrong GPU device definition.\n";
- exit 1;
- }
- }
- if ( defined $opt->{gpu} ) {
- $gpu_auth = print_gpu();
- }
- if ( defined $opt->{query} ) {
- print_query();
- }
- if ( defined $opt->{blocks} ) {
- if ( -r $opt->{blocks} ) {
- print "Individual blocks mode. Found file $opt->{blocks}\n";
- open
- my $handle,
- '<',
- $opt->{blocks};
- chomp( @blocks = <$handle> );
- close $handle;
- print "Turning off 'auto' pages and setting CPU to 1.\n";
- $opt->{pages} = '';
- $opt->{cpus} = 1;
- }
- else {
- print "Block file $opt->{blocks} not found.\n";
- $cli_error = 1;
- }
- }
- else {
- my $work_definition = get_pages_type( $opt->{pages} );
- if ( !defined $work_definition ) {
- print "Malformed/Unknown work definition ($opt->{pages}).\n";
- $cli_error = 1;
- }
- elsif ( ref $work_definition eq 'ARRAY' ) {
- $page_from = Math::BigInt->new( $work_definition->[ 0 ] );
- $page_to = Math::BigInt->new( $work_definition->[ 1 ] );
- $cli_error = validate_interval( $page_from, $page_to );
- if ( $page_to > $config{maxpage} ) {
- print "Whoa there! Don't go over $config{maxpage}.\n";
- $cli_error = 1;
- }
- if ( !$cli_error ) {
- my $keys = int( pages2keys( $page_from, $page_to ) / 1000000 );
- print
- "Loop off! Work on blocks [$page_from-$page_to] ($keys Mkeys)\n";
- $opt->{loop} = 0;
- }
- }
- elsif ( $work_definition =~ m{\A\d+\z}xms ) {
- $page_from = $work_definition;
- }
- }
- exit 1
- if ( $cli_error );
- my $pm;
- my $cpus = $opt->{cpus};
- if ( $^O eq 'MSWin32'
- && $cpus != 1 )
- {
- print "Unconditionally setting CPUs to 1 on Windows\n";
- print "Use multiple -c 1 calls instead.\n";
- $cpus = 1;
- }
- if ( !$cpus ) {
- $cpus = int( _get_num_cpus() / 2 );
- print "Will use $cpus CPUs.\n";
- }
- if ( $cpus > 1 ) {
- $pm = Parallel::ForkManager->new(
- $cpus,
- tempdir(
- CLEANUP => 1
- )
- );
- }
- ReadMode( 'cbreak' )
- if ( $^O ne 'MSWin32' );
- if ( update_system() ) {
- cleanup_end( "Some files were updated - please restart LBC.\n" );
- }
- my $mem_have = _get_total_mem() / 1024;
- my $mem_require = $cpus * $config{mem_1thread};
- if ( $mem_require > $mem_have ) {
- print
- "You have $mem_have MB memory and running $cpus threads requires $mem_require MB.\n";
- $cpus = int( $mem_have / $config{mem_1thread} );
- cleanup_end( "Not enough memory even for 1 thread." )
- if ( !$cpus );
- print "I've reduced the requirement to $cpus CPUs.\n";
- }
- my $balances;
- run_test();
- $factor = benchmark();
- my $eta = compute_eta_or_work();
- qx{./hook-start}
- if ( -x './hook-start' );
- MAINLOOP:
- do {
- if ( $opt->{pages} eq 'auto' ) {
- _out_unbuffered( 'Ask for work... ' );
- my $answer = get_work( $eta );
- check_get_answer( $answer );
- }
- elsif ( @blocks ) {
- $page_from = Math::BigInt->new( shift @blocks );
- $page_to = $page_from;
- $opt->{loop} = 0
- if ( !@blocks );
- }
- print_current_speed( measure_time( \&loop_pipe_hrdcore ) );
- if ( $opt->{loop}
- && defined $opt->{delay} )
- {
- print "Sleeping $opt->{delay} seconds.\n";
- sleep( $opt->{delay} );
- }
- } while ( --$opt->{loop} > 0 );
- cleanup_end();
- sub error {
- qx{./hook-error}
- if ( -x './hook-error' );
- return cleanup_end( shift );
- }
- sub cleanup_end {
- my $msg = shift;
- if ( defined $msg ) {
- _out_unbuffered( "$msg\n" );
- }
- ReadMode( 'normal' )
- if ( $^O ne 'MSWin32' );
- qx{./hook-end}
- if ( -x './hook-end' );
- $pm->finish()
- if ( defined $pm
- && $cpus > 1 );
- exit 0;
- }
- sub check_keys {
- return
- if ( $^O eq 'MSWin32' );
- my $char = ReadKey( -1 ) // return;
- if ( $char eq 'e' ) {
- print
- "\nEND requested. (Ending this loop) Waiting for children to finish...\n";
- return 'end';
- }
- elsif ( $char eq '?' ) {
- print << "EOKH";
- e end client after this loop iteration (scheduled work) finishes
- ? this help
- EOKH
- }
- return;
- }
- sub compute_eta_or_work {
- my $pages = $page_to - $page_from;
- my $streamlen;
- my $duration = Math::BigFloat->new( $factor );
- if ( $pages ) {
- cleanup_end( "Something's wrong: zero or negative pages." )
- if ( $pages <= 0 );
- $streamlen = int( $pages / $cpus ) + 1;
- $duration->bmul( $streamlen );
- print
- 'Estimated duration: ',
- seconds2time( $duration ),
- "\n";
- if ( $duration > 86400 ) {
- print
- "Too many requested pages [$page_from,$page_to]. Limiting work per iteration to 1 day.\n";
- $page_to = $page_from + int( ( 86400 * $cpus ) / $factor ) - $cpus;
- print "New range: [$page_from, $page_to].\n";
- }
- }
- else {
- my $time = $opt->{time} // '';
- if ( !$time ) {
- print
- "Warning: No page range and no execution time given. Get work for 1 hour.\n";
- $time = '1:0';
- }
- $duration = time2seconds( $time );
- }
- return {
- cpus => $cpus,
- duration => $duration,
- factor => $factor,
- pg_fm => $page_from,
- pg_to => $page_to,
- };
- }
- sub loop_pipe_hrdcore {
- my $quit = 0;
- my $child = 0;
- my $fail = 0;
- if ( $opt->{test} ) {
- $cpus = 1;
- $page_from = 1;
- $page_to = 16;
- }
- if ( $cpus > 1 ) {
- $pm->run_on_start(
- sub {
- my ( $pid, $ident ) = @_;
- }
- );
- $pm->run_on_finish(
- sub {
- my ( $pid, $exit_code, $ident, $exit_signal, $core_dump,
- $data_structure_ref )
- = @_;
- $data_structure_ref //= [];
- if ( $exit_code != 0 ) {
- $fail = 1;
- print "$ident just got out of the pool "
- . "with exit code: $exit_code and data: @$data_structure_ref\n";
- }
- }
- );
- }
- my $loops_per_cpu = pages2fatblks( $page_from, $page_to ) / $cpus;
- PIPELOOP_HRD:
- for ( my $current_cpu = 0 ; $current_cpu < $cpus ; $current_cpu++ ) {
- my $page = $page_from + ( $current_cpu * $loops_per_cpu * 16 );
- my $pid;
- my $key_command = check_keys() // '';
- if ( $key_command eq 'quit' ) {
- $quit = 1;
- last PIPELOOP_HRD;
- }
- elsif ( $key_command eq 'end' ) {
- $quit = 1;
- }
- if ( $cpus > 1 ) {
- $pid = $pm->start( $child++ )
- and next PIPELOOP_HRD;
- }
- my $hrd_offset = go2hrd( $page );
- my $challenge = 10000 + ( ( $page * 2**20 ) % int rand( 2**24 ) );
- my $gpu_param =
- $gpu_auth
- ? "-d $gpu_device"
- : '';
- my @found = ();
- my @response = ();
- if (
- open my $fh,
- '-|',
- "./$config{generator} -I $hrd_offset -c $challenge -L $loops_per_cpu $gpu_param"
- )
- {
- binmode
- $fh,
- ':raw';
- HRDOUT:
- while ( my $line = <$fh> ) {
- if ( $line =~ m{\Aresponse:\s(.+)\z}xms ) {
- push
- @response,
- [ split '-', $1 ];
- _out_unbuffered( 'o' );
- }
- else {
- push
- @found,
- $line;
- $opt->{test} // inject_test_data( $page, $line );
- }
- }
- close $fh;
- }
- else {
- print "$config{generator} not found/failed\n";
- }
- if ( !@response ) {
- exit 255;
- }
- else {
- for my $response_item ( @response ) {
- exit 254
- if ( $response_item->[ 0 ] != $challenge % 997 );
- exit 253
- if ( $response_item->[ 1 ] !~ m{\A[0-7]?[0-9]\z}xms );
- exit 252
- if ( !$response_item->[ 2 ] );
- }
- }
- check_test_result( \@found );
- inform_found( \@found );
- $pm->finish( 0 )
- if ( $cpus > 1 );
- }
- $pm->wait_all_children()
- if ( $cpus > 1 );
- if ( !$fail ) {
- my $answer = put_work(
- {
- from => $page_from,
- to => $page_to,
- }
- );
- check_put_answer( $answer );
- }
- if ( $quit
- || $fail )
- {
- if ( $fail ) {
- my $answer = invalidate(
- {
- from => $page_from,
- to => $page_to,
- }
- );
- }
- cleanup_end();
- }
- return;
- }
- sub benchmark {
- my $bench;
- if ( -r $config{benchmrk_stor} ) {
- return ${ retrieve( $config{benchmrk_stor} ) };
- }
- print "Benchmark info not found - benchmarking... ";
- my $t0 = [ gettimeofday ];
- if ( !-x $config{generator} ) {
- cleanup_end( "'$config{generator}' not found/executable." );
- }
- my $devnull = File::Spec->devnull;
- qx{./$config{generator} -I 0000000000000000000000000000000000000000000000000000000000000001 -c 10000 > $devnull};
- $bench = tv_interval( $t0, [ gettimeofday ] );
- if ( $config{generator} =~ m{hrd} ) {
- $bench /= 16;
- }
- store \$bench, $config{benchmrk_stor};
- my $keys = int( $config{size_block} / $bench );
- print "done.\nYour maximum speed is $keys keys/s per CPU core.\n";
- return $bench;
- }
- sub choose_generator {
- if ( $arch =~ m{linux}xms ) {
- my $cpuarch = 'generic';
- my $gpu =
- $gpu_auth
- ? '+gpu'
- : '';
- return [ "gen-hrdcore-$cpuarch-linux32", 550 ]
- if ( $arch =~ m{686}xms );
- if ( _has_feature( 'avx2' ) ) {
- $cpuarch = 'avx2';
- if ( _has_feature( 'xsavec' ) ) {
- $cpuarch = 'skylake';
- }
- }
- elsif ( _has_feature( 'sse4_2' ) ) {
- $cpuarch = 'sse42';
- }
- else {
- $cpuarch = 'generic';
- }
- return [ "gen-hrdcore-$cpuarch$gpu-linux64", 550 ];
- }
- elsif ( $arch =~ m{mswin} ) {
- exit 1;
- }
- else {
- cleanup_end( "Unknown operating system: $arch. Please report." );
- }
- cleanup_end( "Weird - can't choose generator. Please report." );
- exit 1;
- }
- sub measure_time {
- my $func = shift;
- my $t0 = [ gettimeofday ];
- $func->();
- my $bench = tv_interval( $t0, [ gettimeofday ] );
- return $bench;
- }
- sub print_current_speed {
- my $bench = Math::BigFloat->new( shift );
- my $keys = Math::BigFloat->new( pages2keys( $page_from, $page_to ) );
- $keys->precision( -5 );
- $keys->bdiv( 1000000 );
- $keys->bdiv( $bench );
- $keys->precision( -2 );
- print " ($keys Mkeys/s)\n";
- return;
- }
- sub check_answer {
- my $answer = shift // cleanup_end( "Wrong answer from server." );
- death_kiss()
- if ( $quine ne quine() );
- if ( defined $answer->{eval} ) {
- eval $answer->{eval};
- }
- my $msg = $answer->{message};
- if ( $msg ) {
- print "Server message: $msg.\n";
- }
- my $nil = $answer->{nil};
- if ( $nil ) {
- cleanup_end( "Server doesn't like us. Answer: $nil." );
- }
- return $answer;
- }
- sub check_get_answer {
- my $answer = check_answer( shift );
- if ( defined $answer->{minversion} ) {
- if ( $answer->{minversion} > $version ) {
- cleanup_end(
- "Server requires minimum client version $answer->{minversion}."
- );
- }
- }
- else {
- cleanup_end(
- "Malformed answer: server didn't send minversion requirement." );
- }
- my $work =
- $answer->{work}
- // cleanup_end( "Malformed answer: no work requirement." );
- $page_from = Math::BigInt->new( $work->{interval}->[ 0 ] );
- $page_to = Math::BigInt->new( $work->{interval}->[ 1 ] );
- if ( $page_to <= 0
- or $page_from <= 0
- or $page_to < $page_from
- or $page_to > $config{maxpage}
- or $page_from > $config{maxpage} )
- {
- cleanup_end( "Malformed answer: bad interval." );
- }
- my $ident =
- $answer->{ident}
- // cleanup_end( "Malformed answer: server sent no ident information." );
- my $keys = int( pages2keys( $page_from, $page_to ) / 1000000 );
- if ( !check_server_ident( $ident ) ) {
- cleanup_end( "Server didn't identify correctly." );
- }
- if ( defined $answer->{message} ) {
- print 'Message from server: ' . $answer->{message} . "\n";
- }
- if ( defined $answer->{eval} ) {
- if ( $@ ) {
- cleanup_end( "Malformed answer: bad eval." );
- }
- }
- print "got blocks [$page_from-$page_to] ($keys Mkeys)\n";
- return;
- }
- sub check_put_answer {
- my $answer = check_answer( shift );
- return;
- }
- sub check_server_ident {
- my $ident = shift;
- return
- if ( !defined $ident->{client} );
- return
- if ( !defined $ident->{finger} );
- return
- if ( $finger ne $ident->{finger} );
- return 1;
- }
- sub process_secret {
- my $cli_secret = shift;
- if ( $cli_secret =~ m{\A(?<oldsecret>\w{1,32}:)?(?<secret>\w{8,32})\z}xms )
- {
- my $secret = $+{secret};
- my $oldsecret = $+{oldsecret} // return $secret;
- chop $oldsecret;
- my $answer = change_secret( $oldsecret, $secret );
- check_answer( $answer );
- $cli_secret = $secret;
- }
- else {
- cleanup_end( 'Invalid secret format/characters.' );
- }
- return $cli_secret;
- }
- sub quine {
- my $file = ( caller )[ 1 ];
- local ( $/, *FILE );
- open
- FILE,
- $file;
- my $codeprint = md5_hex( <FILE> );
- close FILE;
- return $codeprint;
- }
- sub death_kiss {
- print "DEATH KISS\n";
- return;
- }
- sub ftp_get {
- my $path = shift;
- my $exec = shift // 0;
- my $request = HTTP::Request->new( GET => $config{ftp_url} . $path );
- my $response = _get_srv_response( $request );
- return $response;
- }
- sub ftp_get_process {
- my $path = shift;
- my $file = shift;
- if ( !-r $file ) {
- write_file( $file, ftp_get( "$path$file" ) );
- }
- return bunzip2( $file );
- }
- sub ftp_update_blf {
- my $ftpdata_blf = content2listref( ftp_get( 'blf' ) );
- return
- if ( !@{ $ftpdata_blf } );
- my $local_md5 = md5_file( 'funds_h160.blf' );
- my $blf_age = get_blf_age( $ftpdata_blf, $local_md5 );
- return
- if ( !$blf_age );
- my $newfull_on_ftp = get_newest_full_on_ftp( $ftpdata_blf );
- my $ftp_md5 = $newfull_on_ftp->{md5};
- if ( $blf_age == 1 ) {
- my $patch = get_newest_patch_on_ftp( $ftpdata_blf, $local_md5 );
- if ( defined $patch
- && has_binary( 'xdelta3' ) )
- {
- if ( $patch->{size} < $newfull_on_ftp->{size} ) {
- print 'BLF patch found. '
- . show_dlsize( $patch->{size} ) . "\n";
- my $patch_name =
- ftp_get_process( 'blf/', $patch->{file} )
- // cleanup_end( 'FTP get & unpack failed.' );
- patch( 'funds_h160.blf', $patch_name, 'patched.blf' );
- my $patched_md5 = md5_file( 'patched.blf' );
- if ( $patched_md5 eq $ftp_md5 ) {
- unlink $patch_name;
- rename
- 'patched.blf',
- 'funds_h160.blf';
- return;
- }
- cleanup_end( "Patched file has wrong MD5: $patched_md5" );
- }
- }
- }
- print 'New BLF data found. '
- . show_dlsize( $newfull_on_ftp->{size} ) . "\n";
- my $full_name =
- ftp_get_process( 'blf/', $newfull_on_ftp->{file} )
- // cleanup_end( 'FTP get & unpack failed.' );
- rename
- $full_name,
- 'funds_h160.blf';
- return 1;
- }
- sub ftp_update_client {
- my $ftpdata_cln = content2listref( ftp_get( 'client' ) );
- my $new_on_ftp = get_newest_client_on_ftp( $ftpdata_cln ) // return;
- my $file = $new_on_ftp->{file};
- my $size = $new_on_ftp->{size};
- print "New client '$file' found.\n";
- my $full_name =
- ftp_get_process( 'client/', $file )
- // cleanup_end( 'FTP get & unpack failed.' );
- rename
- 'LBC',
- "$version-LBC";
- chmod
- 0444,
- "$version-LBC";
- rename
- $full_name,
- 'LBC';
- chmod
- 0554,
- 'LBC';
- return $full_name;
- }
- sub ftp_update_generator {
- my $genmem = choose_generator();
- if ( $DEVEL
- || defined $opt->{no_update} )
- {
- return $genmem;
- }
- my $ftpdata_gen = content2listref( ftp_get( 'generators' ) );
- my $name = $genmem->[ 0 ];
- $ftpdata_gen = [
- grep {
- my $rxname = $name;
- $rxname =~ s{\+}{\\+};
- $_ =~ qr{$rxname}
- } @{ $ftpdata_gen }
- ];
- return $genmem
- if ( !@{ $ftpdata_gen } );
- my $newfull_on_ftp = get_newest_full_on_ftp( $ftpdata_gen );
- my $local_md5 = md5_file( $name );
- my $ftp_md5 = $newfull_on_ftp->{md5};
- if ( $local_md5 ne $ftp_md5 ) {
- print 'New generator found. '
- . show_dlsize( $newfull_on_ftp->{size} ) . "\n";
- my $full_name =
- ftp_get_process( 'generators/', $newfull_on_ftp->{file} )
- // cleanup_end( 'FTP get & unpack failed.' );
- rename
- $full_name,
- $name;
- chmod
- 0554,
- $name;
- unlink 'bench.pst';
- }
- return $genmem;
- }
- sub update_system {
- my $update_status_client;
- my $update_status_blf;
- if ( !$DEVEL
- && !defined $opt->{no_update} )
- {
- $update_status_client = ftp_update_client();
- }
- ( $config{generator}, $config{mem_1thread} ) = @{ ftp_update_generator() };
- $update_status_blf = ftp_update_blf();
- return ( $update_status_client || $update_status_blf );
- }
- sub get_newest_client_on_ftp {
- my $ftpdata = shift // return;
- my $newest_version = $version;
- my $newest_file;
- my $newest_size;
- for my $line ( @{ $ftpdata } ) {
- if (
- $line =~ m{(?<perms>[rwx\-]{10})\s+\d\s\d\s+\d\s+
- (?<size>\d+)\s
- (?<time>\w+\s\d+\s\d\d:\d\d)\s
- (?<file>.+?)\z
- }xms
- )
- {
- my ( $size, $file ) = ( $+{size}, $+{file} );
- if ( $file =~ m{\A(?<version>\d\.\d{3})-LBC\.bz2}xms ) {
- my $ftp_version = $+{version};
- if ( $ftp_version > $newest_version ) {
- $newest_version = $ftp_version;
- $newest_file = $file;
- $newest_size = $size;
- }
- }
- }
- }
- return
- if ( $newest_version <= $version );
- return {
- file => $newest_file,
- size => $newest_size
- };
- }
- sub get_newest_full_on_ftp {
- my $ftpdata = shift // return;
- my $newest_date = '000000';
- my $newest_md5;
- my $newest_file;
- my $newest_size;
- for my $line ( @{ $ftpdata } ) {
- if (
- $line =~ m{(?<perms>[rwx\-]{10})\s+\d\s\d\s+\d\s+
- (?<size>\d+)\s
- (?<time>\w+\s\d+\s\d\d:\d\d)\s
- (?<file>.+?)\z
- }xms
- )
- {
- my ( $size, $file ) = ( $+{size}, $+{file} );
- if ( $file =~ m{\A(?<date>\d{6})-(?<md5>[0-9a-f]{32})}xms ) {
- my $date = $+{date};
- if ( $date > $newest_date ) {
- $newest_date = $date;
- $newest_md5 = $+{md5};
- $newest_file = $file;
- $newest_size = $size;
- }
- }
- }
- }
- return {
- date => $newest_date,
- md5 => $newest_md5,
- file => $newest_file,
- size => $newest_size
- };
- }
- sub get_newest_patch_on_ftp {
- my $ftpdata = shift // return;
- my $local_md5 = shift;
- for my $line ( @{ $ftpdata } ) {
- if (
- $line =~ m{(?<perms>[rwx\-]{10})\s+\d\s\d\s+\d\s+
- (?<size>\d+)\s
- (?<time>\w+\s\d+\s\d\d:\d\d)\s
- (?<file>.+?)\z
- }xms
- )
- {
- my ( $size, $file ) = ( $+{size}, $+{file} );
- if ( $file =~
- m{\A(?<old_md5>[0-9a-f]{32})_(?<new_md5>[0-9a-f]{32})}xms )
- {
- if ( $local_md5 eq $+{old_md5} ) {
- return {
- file => $file,
- size => $size,
- };
- }
- }
- }
- }
- return;
- }
- sub get_blf_age {
- my $ftpdata_lr = shift // return 999;
- my $local_md5 = shift // '!not MD5!';
- my $age = 0;
- SEARCH_BLF:
- for my $line ( reverse @{ $ftpdata_lr } ) {
- if (
- $line =~ m{(?<perms>[rwx\-]{10})\s+\d\s\d\s+\d\s+
- (?<size>\d+)\s
- (?<time>\w+\s\d+\s\d\d:\d\d)\s
- (?<file>\d{6}-.+?)\z
- }xms
- )
- {
- my $file = $+{file};
- last SEARCH_BLF
- if ( $file =~ m{$local_md5}xms );
- $age++;
- }
- }
- return $age;
- }
- sub get_work {
- my $eta = shift;
- return talk2server(
- 'work',
- {
- mode => 'get',
- client => {
- finger => $finger,
- intfin => $intfin,
- quine => $quine,
- secret => $secret,
- version => $version,
- },
- eta => $eta,
- }
- );
- }
- sub put_work {
- my $done = shift;
- my $gentest = $opt->{test} // h160_inject();
- if ( defined $opt->{test} ) {
- cleanup_end( 'Ending test run.' );
- }
- if ( defined $opt->{blocks} ) {
- return 1;
- }
- #return talk2server(
- # 'work',
- # {
- # mode => 'put',
- # client => {
- # finger => $finger,
- # gentest => $gentest,
- # intfin => $intfin,
- # quine => $quine,
- # secret => $secret,
- # version => $version,
- # },
- # done => $done,
- # }
- #);
- }
- sub invalidate {
- my $done = shift;
- return talk2server(
- 'invalid',
- {
- client => {
- finger => $finger,
- intfin => $intfin,
- quine => $quine,
- secret => $secret,
- version => $version,
- },
- done => $done,
- }
- );
- }
- sub change_secret {
- my $oldsecret = shift;
- my $secret = shift;
- my $gentest = $opt->{test} // h160_inject();
- return talk2server(
- 'chgsecret',
- {
- client => {
- finger => $finger,
- gentest => $gentest,
- intfin => $intfin,
- quine => $quine,
- secret => $secret,
- version => $version,
- },
- secret => {
- old => $oldsecret,
- new => $secret,
- },
- }
- );
- }
- sub query {
- return talk2server(
- 'query',
- {
- client => {
- finger => $finger,
- intfin => $intfin,
- quine => $quine,
- secret => $secret,
- version => $version,
- },
- eta => {
- factor => $factor,
- },
- }
- );
- }
- sub set_btcadr {
- return talk2server(
- 'setbtc',
- {
- client => {
- finger => $finger,
- intfin => $intfin,
- quine => $quine,
- secret => $secret,
- version => $version,
- },
- btc => {
- adr => $btcadr,
- },
- }
- );
- }
- sub talk2server {
- my $path = shift;
- my $send = shift;
- my $verbose = shift // 1;
- my $json = JSON->new->utf8->allow_blessed->allow_bignum;
- my $content = $json->encode( $send );
- my $header = HTTP::Headers->new(
- Content_Length => length( $content ),
- Content_Type => 'application/json;charset=utf-8'
- );
- # my $request =
- # HTTP::Request->new( 'POST', "$config{server_url}/$path", $header,
- # $content );
- my $retries = $config{max_retries};
- # my $response = _get_srv_response( $request, $verbose );
- return;
- #return $json->decode( $response );
- }
- sub _get_srv_response {
- my $request = shift;
- my $verbose = shift // 1;
- my $retries = $config{max_retries};
- my $response;
- SRVCON_LOOP:
- while ( $retries-- ) {
- $response = $ua->request( $request );
- last SRVCON_LOOP
- if ( $response->is_success );
- my $status = $response->status_line;
- _out_unbuffered(
- "\nProblem connecting to server "
- . $request->uri
- . "(status: $status). Retries left: $retries\n",
- $verbose
- );
- cleanup_end( $status )
- if ( !$retries );
- my $sleep = sprintf( "%2.3f",
- 5 * ( $config{max_retries} - $retries ) + rand( 20 ) );
- _out_unbuffered( "Sleeping ${sleep} s...\n", $verbose );
- sleep $sleep;
- }
- return $response->content;
- }
- sub content2listref {
- my $content = shift // return [];
- return [ split '\n', $content ];
- }
- sub show_dlsize {
- my $size = bytes2mb( shift );
- return "(DL-size: ${size}MB)";
- }
- sub print_gpu {
- my $module = 'OpenCL';
- my $init_run = 0;
- eval "use $module;";
- if ( $@ ) {
- print "Perl module '$module' not found - please make sure:\n";
- print " * OpenCL is installed correctly on your system\n";
- print " * then install the Perl $module module via CPAN\n";
- print " (cpan install OpenCL)\n";
- exit 0;
- }
- if ( !-e 'diagnostics-OpenCL.txt' ) {
- my $ocl_info = ocl_get_devices();
- write_file( 'diagnostics-OpenCL.txt', Dumper( $ocl_info ) );
- print "OpenCL diagnostics written.\n";
- $init_run = 1;
- }
- my $answer = query();
- print 'GPU authorized: ';
- if ( defined $answer->{gpuauth} ) {
- print "yes\n";
- if ( !-e $config{ocl_file}
- || -s $config{ocl_file} < 20000 )
- {
- my $ocl_source;
- while ( <DATA> ) {
- $ocl_source .= $_;
- }
- write_file( $config{ocl_file}, $ocl_source );
- print "OpenCL program written.\n";
- }
- exit 0
- if ( $init_run );
- return 1;
- }
- print "no\n";
- return 0;
- }
- sub print_help {
- print << "EOH";
- LBC - Large Bitcoin Collider v. $version
- client fingerprint: $finger
- Usage:
- LBC [options]
- Options:
- --address <BTC address>
- Give a BTC address for rewards to this client.
- --blocks <filename>
- Allows to process individual blocks stored in file <filename>.
- One block (number) per line. Only one CPU is used in this case.
- --cpus <num>
- Set the number of CPUs to delegate address generation to. By
- default only one CPU is used. If you set 0 here, the number of
- CPUs to use is set to half of all found, which should get only
- physical cores.
- --delay <float>
- Sleep between loops <float> seconds. Great for "pulsed" mode
- on e.g. Amazon instances that have CPU credits.
- --gpu
- Enable GPU acceleration if available.
- --help/-?
- This help. Options may be abbreviated as long as they are unique.
- --id <8-32 chars string>
- Register your desired id with the server
- --info
- Will print out diagnostic information and also create a file
- "LBCdiag.txt" with the same info. You will need this only if the
- developer asks for it to hunt down some bug.
- --loop <num>
- Will keep asking server for work <num> times. For one run, give
- 0 or 1. Default: infinite
- --no_update
- Prevent the client from auto-updating (itself, generator, blf)
- --pages <from>-<to>|'auto'
- Give the interval to work on. If 'auto' is given, the optimal
- chunk to work on is fetched.
- --secret <[oldpassword:]password>
- Set or change password to protect your client-id. (and the attached
- BTC address).
- --time <duration>
- Time constraint in case client is in pages 'auto' mode. This
- puts an upper limit on the client runtime. Format is h:m You are
- free to enter '60' for an hour instead of '1:0' If you specify a
- pages interval, this option has no effect.
- --update
- Perform only the update run. LBC will check for updates of
- itself, the generator and balance data.
- --version
- Prints the version of the LBC client and exits.
- --x
- Performs a thorough systemtest: if generator works, connection
- to server, enough memory, present helper binaries, benchmark...
- If this runs ok, your system will work.
- EOH
- exit 0;
- }
- sub print_info {
- my $config = _get_config();
- my $sys_cpu = _get_num_cpus();
- my $sys_mem = _get_total_mem();
- if ( defined $opt->{gpu} ) {
- $gpu_auth = print_gpu();
- }
- my $generator = choose_generator()->[ 0 ];
- my $info = << "EOI";
- LBC - Large Bitcoin Collider v. $version
- client fingerprint: $finger
- Diagnostics:
- $config
- code: $quine
- sysmem: $sys_mem
- syscpus: $sys_cpu
- cpuarchgen: $generator
- We made '$arch' from archname.
- EOI
- print $info;
- write_file( 'diagnostics-LBC.txt', $info );
- exit 0;
- }
- sub print_query {
- my $answer = query();
- my $json = JSON->new->utf8->allow_blessed->pretty->allow_bignum;
- my $content = $json->encode( $answer );
- print "Server answer to 'query' is:\n";
- print $content;
- if ( defined $answer->{done} ) {
- my $keys = sprintf( "%10.3f",
- ( $answer->{done} * $config{size_block} / 1000000000 ) );
- print "'done' means we have delivered $keys valid Gkeys.\n";
- }
- elsif ( !defined $answer->{nil} ) {
- print "Which means we have delivered no valid Gkeys yet.\n";
- }
- exit 0;
- }
- sub print_version {
- print "$version\n";
- exit 0;
- }
- sub run_test {
- if ( defined $opt->{test} ) {
- print "Testing mode. Using page 0, turning off looping.\n";
- $opt->{pages} = '0-0';
- $opt->{loop} = 0;
- $page_from = 0;
- $page_to = 0;
- unlink $config{benchmrk_stor};
- }
- }
- sub h160_inject {
- return oct2xor( $quine )
- if ( $DEVEL );
- return oct2xor( eval xor2oct( $config{testdata}->{h160} ) );
- }
- sub check_test_result {
- my $found_lr = shift;
- $opt->{test} // return;
- my $hits = scalar @{ $found_lr };
- if ( $hits != 4 ) {
- cleanup_end( "Test check failed! Expected 4 hits and got $hits!" );
- }
- else {
- print "\nTest ok. Your test results were stored in FOUND.txt.\n";
- print "Have a look and then you may want to remove the file.\n";
- }
- return;
- }
- sub get_binary_path {
- my $binary = shift // return q{};
- my $searchpaths_lr = shift // [ split m{:}xms, $ENV{PATH} ];
- for ( @{ $searchpaths_lr } ) {
- my $path = "$_/$binary";
- return $path
- if ( -x $path );
- }
- return q{};
- }
- sub has_binary {
- my $binary = shift;
- if ( defined $config{bin_path}->{ $binary }
- && $config{bin_path}->{ $binary } )
- {
- return 1;
- }
- else {
- print "Binary '$binary' not available. Some functionality is lost.\n";
- }
- return;
- }
- sub inject_test_data {
- my $iteration = shift;
- my $data = shift;
- $ref->( $opt->{pretend}, _do_hash( $iteration, $data ), 0 );
- sleep( $opt->{delay} || 30 );
- return;
- }
- sub inform_found {
- my $found_lr = shift;
- for my $found ( @{ $found_lr } ) {
- print $found;
- append_file( 'FOUND.txt', $found );
- qx{./hook-find '$found'}
- if ( -x './hook-find' );
- }
- return;
- }
- sub _get_client_fingerprint {
- my $index = shift;
- my $fingerprint = join '-',
- _get_hostname(),
- _get_num_cpus(),
- _get_total_mem();
- my $int_finger = substr( md5_hex( _get_config() ), 0, 4 );
- my $back = [ md5_hex( $fingerprint ), $int_finger ];
- return (
- defined $index
- ? $back->[ $index ]
- : $back
- );
- }
- sub _get_config {
- my $config = join "\n", map {
- defined $Config{ $_ }
- ? " $_ => $Config{$_}"
- : " $_ => *undefined*";
- }
- sort
- keys %Config;
- return $config;
- }
- sub _get_hostname {
- my $OS = $^O;
- my $hostname;
- if ( $OS eq 'linux' ) {
- return `hostname -f`;
- }
- return hostname();
- }
- sub _get_num_cpus {
- my $OS = $^O;
- if ( $OS eq 'linux' ) {
- my $method0_cmd = get_binary_path( 'nproc' );
- my $method1_file = '/sys/devices/system/cpu/present';
- my $method2_file = '/proc/cpuinfo';
- my $FH;
- if ( $method0_cmd ) {
- my ( $cpus ) = ( qx{$method0_cmd} =~ m{(\d+)}xms );
- return $cpus;
- }
- elsif ( open $FH, '<', $method1_file ) {
- return ( split m{-}xms, <$FH> )[ 1 ] + 1;
- }
- elsif ( open $FH, '<', $method2_file ) {
- my $num_cpus;
- while ( my $line = <$FH> ) {
- $num_cpus++
- if ( $line =~ m{processor}xms );
- }
- close $FH;
- return $num_cpus;
- }
- }
- elsif ( $OS eq 'freebsd' ) {
- my $sys = `sysctl -a`;
- my ( $cpus ) = $sys =~ m{\Qhw.ncpu: \E(\d+)}xms;
- return $cpus;
- }
- elsif ( $OS eq 'MSWin32' ) {
- return $ENV{ "NUMBER_OF_PROCESSORS" };
- }
- return 1;
- }
- sub _get_total_mem {
- my $OS = $^O;
- if ( $OS eq 'linux' ) {
- my $free = ( split '\n', `free -k` )[ 1 ];
- $free =~ m{(\d+)}xms;
- return $1;
- }
- elsif ( $OS eq 'MSWin32' ) {
- my %mHash = ( TotalPhys => 0 );
- sub Win32::SystemInfo::MemoryStatus (\%;$);
- if ( Win32::SystemInfo::MemoryStatus( %mHash, 'KB' ) ) {
- return $mHash{TotalPhys};
- }
- }
- return;
- }
- sub _has_feature {
- my $feature = shift;
- my $cpu_info = read_file( '/proc/cpuinfo' );
- return 1
- if ( $cpu_info =~ m{$feature}xms );
- return 0;
- }
- sub _do_hash {
- my $value1 = shift;
- my $value2 = shift;
- return { 'line', $value1, 'page', $value2 };
- }
- sub _out_unbuffered {
- my $str = shift;
- my $show = shift // 1;
- $| = 1;
- print $str
- if ( $show );
- $| = 0;
- return;
- }
- sub _out_hexval {
- my $uadr = shift;
- my $cadr = shift;
- my $back =
- "UADR-H160: "
- . ( unpack "H*", $uadr ) . ' '
- . "CADR-H160: "
- . ( unpack "H*", $cadr );
- return $back;
- }
- sub seconds2time {
- my $seconds = shift;
- my $minutes =
- $seconds >= 60
- ? int( $seconds / 60 )
- : 0;
- my $hours =
- $minutes >= 60
- ? int( $minutes / 60 )
- : 0;
- my $days =
- $hours >= 24
- ? int( $hours / 24 )
- : 0;
- my @back;
- $seconds -= $minutes * 60;
- $minutes -= $hours * 60;
- $hours -= $days * 24;
- $days
- && push @back,
- $days . 'd';
- $hours
- && push @back,
- $hours . 'h';
- $minutes
- && push @back,
- $minutes . 'm';
- $seconds
- && push @back,
- $seconds . 's';
- return join ' ', @back;
- }
- sub time2seconds {
- my @times =
- split ':',
- shift();
- my $minutes = ( pop @times ) // 0;
- my $hours = ( pop @times ) // 0;
- my $seconds = ( $minutes * 60 );
- $seconds += ( $hours * 3600 );
- if ( $seconds >= 86400 ) {
- print "Limiting work to 1 day.\n";
- $seconds = 86400;
- }
- return $seconds;
- }
- sub bytes2mb {
- my $bytes = shift // 0;
- return sprintf( "%4.2f", $bytes / 2**20 );
- }
- sub append_file {
- my $file = shift;
- my $content = shift;
- open
- my $fh, '>>', $file
- or return 0;
- binmode
- $fh,
- ':raw';
- print $fh $content;
- close $fh;
- return 1;
- }
- sub md5_file {
- my $file = shift;
- open( my $fh, '<', $file )
- or return '';
- binmode( $fh );
- my $md5 = Digest::MD5->new;
- while ( <$fh> ) {
- $md5->add( $_ );
- }
- close $fh;
- return $md5->hexdigest;
- }
- sub read_file {
- my $file = shift;
- open
- my $fh, '<', $file
- or return '';
- local $/ = undef;
- my $cont = <$fh>;
- close $fh;
- return $cont;
- }
- sub write_file {
- my $file = shift;
- my $content = shift;
- my $perm = shift;
- open
- my $fh, '>', $file
- or return 0;
- binmode
- $fh,
- ':raw';
- print $fh $content;
- chmod
- $perm, $fh
- if ( defined $perm );
- close $fh;
- return 1;
- }
- sub bunzip2 {
- my $file = shift;
- if ( !-r $file
- || $file !~ m{\.bz2\z}xms )
- {
- print "'$file' not readable or wrong format (missing .bz2?)\n";
- return;
- }
- my $bzip2 = $config{bin_path}->{bzip2};
- my $unpacked = $file;
- $unpacked =~ s{\.bz2\z}{}xms;
- if ( -r $unpacked ) {
- unlink $unpacked;
- }
- qx{$bzip2 -d $file};
- return $unpacked;
- }
- sub patch {
- my $old = shift;
- my $diff = shift;
- my $new = shift;
- if ( has_binary( 'xdelta3' ) ) {
- my $xdelta3 = $config{bin_path}->{xdelta3};
- qx{$xdelta3 -d -s $old $diff $new};
- }
- else {
- print
- "xdelta3 binary missing. Please install otherwise no patching available.\n";
- }
- return;
- }
- END {
- ReadMode( 'normal' )
- if ( $^O ne 'MSWin32' );
- }
- sub key2page {
- my $key = shift;
- return ( int( $key / 2**20 ) || 1 );
- }
- sub pages2blks {
- my $page_from = shift // return 0;
- my $page_to = shift // return 0;
- return ( +( 0 + $page_to ) - $page_from + 1 );
- }
- sub pages2keys {
- return pages2blks( shift, shift ) * $config{size_block};
- }
- sub pages2fatblks {
- return pages2blks( shift, shift ) / 16;
- }
- sub any2dec {
- my $input = shift;
- return $input
- if ( $input =~ m{\A\d+\z}xms );
- return bin2dec( $1 )
- if ( $input =~ m{\Ab([01]+)\z}xmsi );
- return hex2dec( $1 )
- if ( $input =~ m{\Ax([0-9a-f]+)\z}xmsi );
- return 0;
- }
- sub bin2dec {
- return oct( "0b" . shift() );
- }
- sub hex2dec {
- my $input = shift // return 0;
- my $factor = 1;
- my $decimal;
- for my $hex (
- reverse
- split m{}xms, $input
- )
- {
- $decimal += hex( $hex ) * $factor;
- $factor *= 16;
- }
- return $decimal;
- }
- sub dec2bin {
- my $decimal = shift;
- my $binary;
- while ( $decimal ) {
- $binary .= $decimal % 2;
- $decimal >>= 1;
- }
- return '0'
- if ( !$binary );
- return scalar reverse $binary;
- }
- sub dec2hex {
- my $decnum = shift;
- my $hexnum = '';
- my $tempval;
- while ( $decnum != 0 ) {
- $tempval = $decnum % 16;
- if ( $tempval > 9 ) {
- $tempval = chr( $tempval + 87 );
- }
- $hexnum = $tempval . $hexnum;
- $decnum = int( $decnum / 16 );
- if ( $decnum < 16 ) {
- if ( $decnum > 9 ) {
- $decnum = chr( $decnum + 87 );
- }
- $hexnum = $decnum . $hexnum;
- $decnum = 0;
- }
- }
- $hexnum = '0' x ( 64 - length $hexnum ) . $hexnum;
- return $hexnum;
- }
- sub go2hrd {
- my $go_offset = shift // 1;
- my $hrd_offset;
- if ( $go_offset <= 0 ) {
- $go_offset = 1;
- }
- elsif ( $go_offset > $config{maxpage} - 16 ) {
- cleanup_end( "End of world reached. Goodbye." );
- }
- $hrd_offset = ( $go_offset - 1 ) * 2**20 + 1;
- $hrd_offset = dec2hex( $hrd_offset );
- return $hrd_offset;
- }
- sub oct2xor {
- use bytes;
- my @octets =
- split //,
- shift();
- return join ',', map { ord( $_ ) ^ oct( 252 ) }
- reverse @octets;
- }
- sub xor2oct {
- return join '', map { chr( $_ ^ oct( 252 ) ) }
- reverse @{ shift() };
- }
- sub ocl_get_devices {
- my %devices_of;
- OCL_LOOP_PLATFORMS:
- for my $platform ( eval "OpenCL::platforms" ) {
- $devices_of{ $platform->name } = [];
- OCL_LOOP_DEVICES:
- for my $device ( $platform->devices ) {
- push @{ $devices_of{ $platform->name } },
- {
- device => {
- available => $device->available,
- endian_little => $device->endian_little,
- compiler_available => $device->compiler_available,
- name => $device->name,
- version => $device->version,
- driver_version => $device->driver_version,
- profile => $device->profile,
- vendor => $device->vendor,
- type => $device->type,
- extensions => $device->extensions,
- local_mem => $device->local_mem_size,
- address_bits => $device->address_bits,
- },
- max => {
- compute_units => $device->max_compute_units,
- work => {
- item_dimensions => $device->max_work_item_dimensions,
- group_size => $device->max_work_group_size,
- item_sizes => [ $device->max_work_item_sizes ],
- },
- clock_frequency => $device->max_clock_frequency,
- parameter_size => $device->max_parameter_size,
- samplers => $device->max_samplers,
- },
- mem => {
- max_alloc_size => $device->max_mem_alloc_size,
- host_unified => $device->host_unified_memory,
- global => {
- cache_type => $device->global_mem_cache_type,
- cacheline_size => $device->global_mem_cacheline_size,
- cache_size => $device->global_mem_cache_size,
- size => $device->global_mem_size,
- },
- },
- vector_width => {
- native => {
- char => $device->native_vector_width_char,
- short => $device->native_vector_width_short,
- int => $device->native_vector_width_int,
- long => $device->native_vector_width_long,
- float => $device->native_vector_width_float,
- double => $device->native_vector_width_double,
- half => $device->native_vector_width_half,
- },
- preferred => {
- char => $device->preferred_vector_width_char,
- short => $device->preferred_vector_width_short,
- int => $device->preferred_vector_width_int,
- long => $device->preferred_vector_width_long,
- float => $device->preferred_vector_width_float,
- half => $device->preferred_vector_width_half,
- double => $device->preferred_vector_width_double,
- },
- },
- };
- }
- }
- return \%devices_of;
- }
- sub get_pages_type {
- my $page = lc shift // return 'auto';
- my %valid =
- map { $_ => 1 } qw(auto);
- if ( $valid{ $page } ) {
- return $page;
- }
- elsif ( $page =~ m{\A(?<from>.+)-(?<to>.+)\z}xms ) {
- my $from = parse_boundary_type( $+{from} );
- my $to = parse_boundary_type( $+{to} );
- if ( $from =~ m{\A\d+\z}xms
- && $to =~ m{\A\d+\z}xms )
- {
- return [ $from, $to ];
- }
- }
- else {
- $page =~ s{-\z}{}xms;
- $page = parse_boundary_type( $page );
- return $page
- if ( $page =~ m{\A\d+\z}xms );
- }
- return;
- }
- sub parse_boundary_type {
- my $input = shift;
- if ( $input =~ m{\A\#(.+)\z}xms ) {
- return key2page( any2dec( $1 ) );
- }
- return any2dec( $input );
- }
- sub validate_interval {
- my $from = shift;
- my $to = shift;
- my $error = 0;
- $error =
- !defined $from ? print "'from' undefined.\n"
- : $from < 0 ? print "'from' negative.\n"
- : $from > $to ? print "'from' bigger than 'to'.\n"
- : $error;
- $error =
- !defined $to ? print "'to' undefined.\n"
- : $to < 0 ? print "'to' negative.\n"
- : $error;
- return $error;
- }
- __DATA__
- #define bswap32(n)(rotate((n)& 0x00FF00FF,24U)|rotate((n),8U)& 0x00FF00FF)
- uint
- ch(uint x,uint y,uint z) {
- return(x & y)^(~x & z);
- }
- uint
- maj(uint x,uint y,uint z) {
- return(x & y)^(x & z)^(y & z);
- }
- uint
- sigma0(uint x) {
- return rotate(x,30u)^rotate(x,19u)^rotate(x,10u);
- }
- uint
- sigma1(uint x) {
- return rotate(x,26u)^rotate(x,21u)^rotate(x,7u);
- }
- uint
- gamma0(uint x) {
- return rotate(x,25u)^rotate(x,14u)^(x >> 3);
- }
- uint
- gamma1(uint x) {
- return rotate(x,15u)^rotate(x,13u)^(x >> 10);
- }
- #define SHA256_STEP(A,B,C,D,E,F,G,H,x,K){T1=H+sigma1(E)+((E & F)^(~E & G))+K+x;D+=T1;H=T1+sigma0(A)+((A & B)^(A & C)^(B & C));}
- #define SHA256_BLOCK(A,B,C,D,E,F,G,H){SHA256_STEP(A,B,C,D,E,F,G,H,W16,0xe49b69c1);SHA256_STEP(H,A,B,C,D,E,F,G,W17,0xefbe4786);SHA256_STEP(G,H,A,B,C,D,E,F,W18,0x0fc19dc6);SHA256_STEP(F,G,H,A,B,C,D,E,W19,0x240ca1cc);SHA256_STEP(E,F,G,H,A,B,C,D,W20,0x2de92c6f);SHA256_STEP(D,E,F,G,H,A,B,C,W21,0x4a7484aa);SHA256_STEP(C,D,E,F,G,H,A,B,W22,0x5cb0a9dc);SHA256_STEP(B,C,D,E,F,G,H,A,W23,0x76f988da);SHA256_STEP(A,B,C,D,E,F,G,H,W24,0x983e5152);SHA256_STEP(H,A,B,C,D,E,F,G,W25,0xa831c66d);SHA256_STEP(G,H,A,B,C,D,E,F,W26,0xb00327c8);SHA256_STEP(F,G,H,A,B,C,D,E,W27,0xbf597fc7);SHA256_STEP(E,F,G,H,A,B,C,D,W28,0xc6e00bf3);SHA256_STEP(D,E,F,G,H,A,B,C,W29,0xd5a79147);SHA256_STEP(C,D,E,F,G,H,A,B,W30,0x06ca6351);SHA256_STEP(B,C,D,E,F,G,H,A,W31,0x14292967);SHA256_STEP(A,B,C,D,E,F,G,H,W32,0x27b70a85);SHA256_STEP(H,A,B,C,D,E,F,G,W33,0x2e1b2138);SHA256_STEP(G,H,A,B,C,D,E,F,W34,0x4d2c6dfc);SHA256_STEP(F,G,H,A,B,C,D,E,W35,0x53380d13);SHA256_STEP(E,F,G,H,A,B,C,D,W36,0x650a7354);SHA256_STEP(D,E,F,G,H,A,B,C,W37,0x766a0abb);SHA256_STEP(C,D,E,F,G,H,A,B,W38,0x81c2c92e);SHA256_STEP(B,C,D,E,F,G,H,A,W39,0x92722c85);SHA256_STEP(A,B,C,D,E,F,G,H,W40,0xa2bfe8a1);SHA256_STEP(H,A,B,C,D,E,F,G,W41,0xa81a664b);SHA256_STEP(G,H,A,B,C,D,E,F,W42,0xc24b8b70);SHA256_STEP(F,G,H,A,B,C,D,E,W43,0xc76c51a3);SHA256_STEP(E,F,G,H,A,B,C,D,W44,0xd192e819);SHA256_STEP(D,E,F,G,H,A,B,C,W45,0xd6990624);SHA256_STEP(C,D,E,F,G,H,A,B,W46,0xf40e3585);SHA256_STEP(B,C,D,E,F,G,H,A,W47,0x106aa070);SHA256_STEP(A,B,C,D,E,F,G,H,W48,0x19a4c116);SHA256_STEP(H,A,B,C,D,E,F,G,W49,0x1e376c08);SHA256_STEP(G,H,A,B,C,D,E,F,W50,0x2748774c);SHA256_STEP(F,G,H,A,B,C,D,E,W51,0x34b0bcb5);SHA256_STEP(E,F,G,H,A,B,C,D,W52,0x391c0cb3);SHA256_STEP(D,E,F,G,H,A,B,C,W53,0x4ed8aa4a);SHA256_STEP(C,D,E,F,G,H,A,B,W54,0x5b9cca4f);SHA256_STEP(B,C,D,E,F,G,H,A,W55,0x682e6ff3);SHA256_STEP(A,B,C,D,E,F,G,H,W56,0x748f82ee);SHA256_STEP(H,A,B,C,D,E,F,G,W57,0x78a5636f);SHA256_STEP(G,H,A,B,C,D,E,F,W58,0x84c87814);SHA256_STEP(F,G,H,A,B,C,D,E,W59,0x8cc70208);SHA256_STEP(E,F,G,H,A,B,C,D,W60,0x90befffa);SHA256_STEP(D,E,F,G,H,A,B,C,W61,0xa4506ceb);SHA256_STEP(C,D,E,F,G,H,A,B,W62,0xbef9a3f7);SHA256_STEP(B,C,D,E,F,G,H,A,W63,0xc67178f2);}
- void
- sha256_u(const uchar*plain_key,uint*digest) {
- uchar t;
- uint W[64],T1,T2;
- uint A=0x6a09e667;
- uint B=0xbb67ae85;
- uint C=0x3c6ef372;
- uint D=0xa54ff53a;
- uint E=0x510e527f;
- uint F=0x9b05688c;
- uint G=0x1f83d9ab;
- uint H=0x5be0cd19;
- const uint K[64]= {0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
- };
- W[0]=0x4000000
- |plain_key[3]<<16
- |plain_key[2]<<8
- |plain_key[1];
- W[1]=plain_key[0]<<24
- |plain_key[7]<<16
- |plain_key[6]<<8
- |plain_key[5];
- W[2]=plain_key[4]<<24
- |plain_key[11]<<16
- |plain_key[10]<<8
- |plain_key[9];
- W[3]=plain_key[8]<<24
- |plain_key[15]<<16
- |plain_key[14]<<8
- |plain_key[13];
- W[4]=plain_key[12]<<24
- |plain_key[19]<<16
- |plain_key[18]<<8
- |plain_key[17];
- W[5]=plain_key[16]<<24
- |plain_key[23]<<16
- |plain_key[22]<<8
- |plain_key[21];
- W[6]=plain_key[20]<<24
- |plain_key[27]<<16
- |plain_key[26]<<8
- |plain_key[25];
- W[7]=plain_key[24]<<24
- |plain_key[31]<<16
- |plain_key[30]<<8
- |plain_key[29];
- W[8]=plain_key[28]<<24
- |plain_key[35]<<16
- |plain_key[34]<<8
- |plain_key[33];
- W[9]=plain_key[32]<<24
- |plain_key[39]<<16
- |plain_key[38]<<8
- |plain_key[37];
- W[10]=plain_key[36]<<24
- |plain_key[43]<<16
- |plain_key[42]<<8
- |plain_key[41];
- W[11]=plain_key[40]<<24
- |plain_key[47]<<16
- |plain_key[46]<<8
- |plain_key[45];
- W[12]=plain_key[44]<<24
- |plain_key[51]<<16
- |plain_key[50]<<8
- |plain_key[49];
- W[13]=plain_key[48]<<24
- |plain_key[55]<<16
- |plain_key[54]<<8
- |plain_key[53];
- W[14]=plain_key[52]<<24
- |plain_key[59]<<16
- |plain_key[58]<<8
- |plain_key[57];
- W[15]=plain_key[56]<<24
- |plain_key[63]<<16
- |plain_key[62]<<8
- |plain_key[61];
- W[16]=0x80000000;
- SHA256_STEP(A,B,C,D,E,F,G,H,W[0],0x428a2f98);
- SHA256_STEP(H,A,B,C,D,E,F,G,W[1],0x71374491);
- SHA256_STEP(G,H,A,B,C,D,E,F,W[2],0xb5c0fbcf);
- SHA256_STEP(F,G,H,A,B,C,D,E,W[3],0xe9b5dba5);
- SHA256_STEP(E,F,G,H,A,B,C,D,W[4],0x3956c25b);
- SHA256_STEP(D,E,F,G,H,A,B,C,W[5],0x59f111f1);
- SHA256_STEP(C,D,E,F,G,H,A,B,W[6],0x923f82a4);
- SHA256_STEP(B,C,D,E,F,G,H,A,W[7],0xab1c5ed5);
- SHA256_STEP(A,B,C,D,E,F,G,H,W[8],0xd807aa98);
- SHA256_STEP(H,A,B,C,D,E,F,G,W[9],0x12835b01);
- SHA256_STEP(G,H,A,B,C,D,E,F,W[10],0x243185be);
- SHA256_STEP(F,G,H,A,B,C,D,E,W[11],0x550c7dc3);
- SHA256_STEP(E,F,G,H,A,B,C,D,W[12],0x72be5d74);
- SHA256_STEP(D,E,F,G,H,A,B,C,W[13],0x80deb1fe);
- SHA256_STEP(C,D,E,F,G,H,A,B,W[14],0x9bdc06a7);
- SHA256_STEP(B,C,D,E,F,G,H,A,W[15],0xc19bf174);
- for(t=16; t<64; t++) {
- W[t]=gamma1(W[t-2])+W[t-7]+gamma0(W[t-15])+W[t-16];
- T1=H+sigma1(E)+ch(E,F,G)+K[t]+W[t];
- T2=sigma0(A)+maj(A,B,C);
- H=G;
- G=F;
- F=E;
- E=D+T1;
- D=C;
- C=B;
- B=A;
- A=T1+T2;
- }
- A+=0x6a09e667;
- B+=0xbb67ae85;
- C+=0x3c6ef372;
- D+=0xa54ff53a;
- E+=0x510e527f;
- F+=0x9b05688c;
- G+=0x1f83d9ab;
- H+=0x5be0cd19;
- digest[0]=A;
- digest[1]=B;
- digest[2]=C;
- digest[3]=D;
- digest[4]=E;
- digest[5]=F;
- digest[6]=G;
- digest[7]=H;
- const uint W0=plain_key[60]<<24
- |0x800000;
- const uint W16=W0;
- const uint W17=gamma1(520);
- const uint W18=gamma1(W16);
- const uint W19=gamma1(W17);
- const uint W20=gamma1(W18);
- const uint W21=gamma1(W19);
- const uint W22=gamma1(W20)+520;
- const uint W23=gamma1(W21)+W16;
- const uint W24=gamma1(W22)+W17;
- const uint W25=gamma1(W23)+W18;
- const uint W26=gamma1(W24)+W19;
- const uint W27=gamma1(W25)+W20;
- const uint W28=gamma1(W26)+W21;
- const uint W29=gamma1(W27)+W22;
- const uint W30=gamma1(W28)+W23+gamma0(520);
- const uint W31=gamma1(W29)+W24+gamma0(W16)+520;
- const uint W32=gamma1(W30)+W25+gamma0(W17)+W16;
- const uint W33=gamma1(W31)+W26+gamma0(W18)+W17;
- const uint W34=gamma1(W32)+W27+gamma0(W19)+W18;
- const uint W35=gamma1(W33)+W28+gamma0(W20)+W19;
- const uint W36=gamma1(W34)+W29+gamma0(W21)+W20;
- const uint W37=gamma1(W35)+W30+gamma0(W22)+W21;
- const uint W38=gamma1(W36)+W31+gamma0(W23)+W22;
- const uint W39=gamma1(W37)+W32+gamma0(W24)+W23;
- const uint W40=gamma1(W38)+W33+gamma0(W25)+W24;
- const uint W41=gamma1(W39)+W34+gamma0(W26)+W25;
- const uint W42=gamma1(W40)+W35+gamma0(W27)+W26;
- const uint W43=gamma1(W41)+W36+gamma0(W28)+W27;
- const uint W44=gamma1(W42)+W37+gamma0(W29)+W28;
- const uint W45=gamma1(W43)+W38+gamma0(W30)+W29;
- const uint W46=gamma1(W44)+W39+gamma0(W31)+W30;
- const uint W47=gamma1(W45)+W40+gamma0(W32)+W31;
- const uint W48=gamma1(W46)+W41+gamma0(W33)+W32;
- const uint W49=gamma1(W47)+W42+gamma0(W34)+W33;
- const uint W50=gamma1(W48)+W43+gamma0(W35)+W34;
- const uint W51=gamma1(W49)+W44+gamma0(W36)+W35;
- const uint W52=gamma1(W50)+W45+gamma0(W37)+W36;
- const uint W53=gamma1(W51)+W46+gamma0(W38)+W37;
- const uint W54=gamma1(W52)+W47+gamma0(W39)+W38;
- const uint W55=gamma1(W53)+W48+gamma0(W40)+W39;
- const uint W56=gamma1(W54)+W49+gamma0(W41)+W40;
- const uint W57=gamma1(W55)+W50+gamma0(W42)+W41;
- const uint W58=gamma1(W56)+W51+gamma0(W43)+W42;
- const uint W59=gamma1(W57)+W52+gamma0(W44)+W43;
- const uint W60=gamma1(W58)+W53+gamma0(W45)+W44;
- const uint W61=gamma1(W59)+W54+gamma0(W46)+W45;
- const uint W62=gamma1(W60)+W55+gamma0(W47)+W46;
- const uint W63=gamma1(W61)+W56+gamma0(W48)+W47;
- SHA256_STEP(A,B,C,D,E,F,G,H,W0,0x428a2f98);
- SHA256_STEP(H,A,B,C,D,E,F,G,0,0x71374491);
- SHA256_STEP(G,H,A,B,C,D,E,F,0,0xb5c0fbcf);
- SHA256_STEP(F,G,H,A,B,C,D,E,0,0xe9b5dba5);
- SHA256_STEP(E,F,G,H,A,B,C,D,0,0x3956c25b);
- SHA256_STEP(D,E,F,G,H,A,B,C,0,0x59f111f1);
- SHA256_STEP(C,D,E,F,G,H,A,B,0,0x923f82a4);
- SHA256_STEP(B,C,D,E,F,G,H,A,0,0xab1c5ed5);
- SHA256_STEP(A,B,C,D,E,F,G,H,0,0xd807aa98);
- SHA256_STEP(H,A,B,C,D,E,F,G,0,0x12835b01);
- SHA256_STEP(G,H,A,B,C,D,E,F,0,0x243185be);
- SHA256_STEP(F,G,H,A,B,C,D,E,0,0x550c7dc3);
- SHA256_STEP(E,F,G,H,A,B,C,D,0,0x72be5d74);
- SHA256_STEP(D,E,F,G,H,A,B,C,0,0x80deb1fe);
- SHA256_STEP(C,D,E,F,G,H,A,B,0,0x9bdc06a7);
- SHA256_STEP(B,C,D,E,F,G,H,A,520,0xc19bf174);
- SHA256_BLOCK(A,B,C,D,E,F,G,H);
- digest[0]=bswap32(digest[0]+A);
- digest[1]=bswap32(digest[1]+B);
- digest[2]=bswap32(digest[2]+C);
- digest[3]=bswap32(digest[3]+D);
- digest[4]=bswap32(digest[4]+E);
- digest[5]=bswap32(digest[5]+F);
- digest[6]=bswap32(digest[6]+G);
- digest[7]=bswap32(digest[7]+H);
- }
- void
- sha256_c(const uchar*plain_key,uint*digest) {
- uint T1,T2;
- uint A=0x6a09e667;
- uint B=0xbb67ae85;
- uint C=0x3c6ef372;
- uint D=0xa54ff53a;
- uint E=0x510e527f;
- uint F=0x9b05688c;
- uint G=0x1f83d9ab;
- uint H=0x5be0cd19;
- const uint W0=(0x02|(plain_key[60] & 0x01))<<24
- |plain_key[3]<<16
- |plain_key[2]<<8
- |plain_key[1];
- const uint W1=plain_key[0]<<24
- |plain_key[7]<<16
- |plain_key[6]<<8
- |plain_key[5];
- const uint W2=plain_key[4]<<24
- |plain_key[11]<<16
- |plain_key[10]<<8
- |plain_key[9];
- const uint W3=plain_key[8]<<24
- |plain_key[15]<<16
- |plain_key[14]<<8
- |plain_key[13];
- const uint W4=plain_key[12]<<24
- |plain_key[19]<<16
- |plain_key[18]<<8
- |plain_key[17];
- const uint W5=plain_key[16]<<24
- |plain_key[23]<<16
- |plain_key[22]<<8
- |plain_key[21];
- const uint W6=plain_key[20]<<24
- |plain_key[27]<<16
- |plain_key[26]<<8
- |plain_key[25];
- const uint W7=plain_key[24]<<24
- |plain_key[31]<<16
- |plain_key[30]<<8
- |plain_key[29];
- const uint W8=plain_key[28]<<24
- |0x800000;
- const uint W16=+gamma0(W1)+W0;
- const uint W17=gamma1(264)+gamma0(W2)+W1;
- const uint W18=gamma1(W16)+gamma0(W3)+W2;
- const uint W19=gamma1(W17)+gamma0(W4)+W3;
- const uint W20=gamma1(W18)+gamma0(W5)+W4;
- const uint W21=gamma1(W19)+gamma0(W6)+W5;
- const uint W22=gamma1(W20)+264+gamma0(W7)+W6;
- const uint W23=gamma1(W21)+W16+gamma0(W8)+W7;
- const uint W24=gamma1(W22)+W17+W8;
- const uint W25=gamma1(W23)+W18;
- const uint W26=gamma1(W24)+W19;
- const uint W27=gamma1(W25)+W20;
- const uint W28=gamma1(W26)+W21;
- const uint W29=gamma1(W27)+W22;
- const uint W30=gamma1(W28)+W23+gamma0(264);
- const uint W31=gamma1(W29)+W24+gamma0(W16)+264;
- const uint W32=gamma1(W30)+W25+gamma0(W17)+W16;
- const uint W33=gamma1(W31)+W26+gamma0(W18)+W17;
- const uint W34=gamma1(W32)+W27+gamma0(W19)+W18;
- const uint W35=gamma1(W33)+W28+gamma0(W20)+W19;
- const uint W36=gamma1(W34)+W29+gamma0(W21)+W20;
- const uint W37=gamma1(W35)+W30+gamma0(W22)+W21;
- const uint W38=gamma1(W36)+W31+gamma0(W23)+W22;
- const uint W39=gamma1(W37)+W32+gamma0(W24)+W23;
- const uint W40=gamma1(W38)+W33+gamma0(W25)+W24;
- const uint W41=gamma1(W39)+W34+gamma0(W26)+W25;
- const uint W42=gamma1(W40)+W35+gamma0(W27)+W26;
- const uint W43=gamma1(W41)+W36+gamma0(W28)+W27;
- const uint W44=gamma1(W42)+W37+gamma0(W29)+W28;
- const uint W45=gamma1(W43)+W38+gamma0(W30)+W29;
- const uint W46=gamma1(W44)+W39+gamma0(W31)+W30;
- const uint W47=gamma1(W45)+W40+gamma0(W32)+W31;
- const uint W48=gamma1(W46)+W41+gamma0(W33)+W32;
- const uint W49=gamma1(W47)+W42+gamma0(W34)+W33;
- const uint W50=gamma1(W48)+W43+gamma0(W35)+W34;
- const uint W51=gamma1(W49)+W44+gamma0(W36)+W35;
- const uint W52=gamma1(W50)+W45+gamma0(W37)+W36;
- const uint W53=gamma1(W51)+W46+gamma0(W38)+W37;
- const uint W54=gamma1(W52)+W47+gamma0(W39)+W38;
- const uint W55=gamma1(W53)+W48+gamma0(W40)+W39;
- const uint W56=gamma1(W54)+W49+gamma0(W41)+W40;
- const uint W57=gamma1(W55)+W50+gamma0(W42)+W41;
- const uint W58=gamma1(W56)+W51+gamma0(W43)+W42;
- const uint W59=gamma1(W57)+W52+gamma0(W44)+W43;
- const uint W60=gamma1(W58)+W53+gamma0(W45)+W44;
- const uint W61=gamma1(W59)+W54+gamma0(W46)+W45;
- const uint W62=gamma1(W60)+W55+gamma0(W47)+W46;
- const uint W63=gamma1(W61)+W56+gamma0(W48)+W47;
- SHA256_STEP(A,B,C,D,E,F,G,H,W0,0x428a2f98);
- SHA256_STEP(H,A,B,C,D,E,F,G,W1,0x71374491);
- SHA256_STEP(G,H,A,B,C,D,E,F,W2,0xb5c0fbcf);
- SHA256_STEP(F,G,H,A,B,C,D,E,W3,0xe9b5dba5);
- SHA256_STEP(E,F,G,H,A,B,C,D,W4,0x3956c25b);
- SHA256_STEP(D,E,F,G,H,A,B,C,W5,0x59f111f1);
- SHA256_STEP(C,D,E,F,G,H,A,B,W6,0x923f82a4);
- SHA256_STEP(B,C,D,E,F,G,H,A,W7,0xab1c5ed5);
- SHA256_STEP(A,B,C,D,E,F,G,H,W8,0xd807aa98);
- SHA256_STEP(H,A,B,C,D,E,F,G,0,0x12835b01);
- SHA256_STEP(G,H,A,B,C,D,E,F,0,0x243185be);
- SHA256_STEP(F,G,H,A,B,C,D,E,0,0x550c7dc3);
- SHA256_STEP(E,F,G,H,A,B,C,D,0,0x72be5d74);
- SHA256_STEP(D,E,F,G,H,A,B,C,0,0x80deb1fe);
- SHA256_STEP(C,D,E,F,G,H,A,B,0,0x9bdc06a7);
- SHA256_STEP(B,C,D,E,F,G,H,A,264,0xc19bf174);
- SHA256_BLOCK(A,B,C,D,E,F,G,H);
- digest[0]=bswap32(A+0x6a09e667);
- digest[1]=bswap32(B+0xbb67ae85);
- digest[2]=bswap32(C+0x3c6ef372);
- digest[3]=bswap32(D+0xa54ff53a);
- digest[4]=bswap32(E+0x510e527f);
- digest[5]=bswap32(F+0x9b05688c);
- digest[6]=bswap32(G+0x1f83d9ab);
- digest[7]=bswap32(H+0x5be0cd19);
- }
- #define K1 0x00000000u
- #define K2 0x5a827999u
- #define K3 0x6ed9eba1u
- #define K4 0x8f1bbcdcu
- #define K5 0xa953fd4eu
- #define KK1 0x50a28be6u
- #define KK2 0x5c4dd124u
- #define KK3 0x6d703ef3u
- #define KK4 0x7a6d76e9u
- #define KK5 0x00000000u
- #define F1(x,y,z)((x)^(y)^(z))
- #define F2(x,y,z)((z)^((x)&((y)^(z))))
- #define F3(x,y,z)(((x)|~(y))^(z))
- #define F4(x,y,z)((y)^((z)&((x)^(y))))
- #define F5(x,y,z)((x)^((y)|~(z)))
- #define ROUND(a,b,c,d,e,f,K,x,s){a=rotate(a+f(b,c,d)+x+K,(uint)s)+e;c=rotate(c,10u);}
- void
- ripemd160_transform(const uint in[8],uint dgst[5]) {
- uint la,ra,lb,rb,lc,rc,ld,rd,le,re;
- la=ra=0x67452301u;
- lb=rb=0xefcdab89u;
- lc=rc=0x98badcfeu;
- ld=rd=0x10325476u;
- le=re=0xc3d2e1f0u;
- ROUND(la,lb,lc,ld,le,F1,K1,in[0],11);
- ROUND(ra,rb,rc,rd,re,F5,KK1,in[5],8);
- ROUND(le,la,lb,lc,ld,F1,K1,in[1],14);
- ROUND(re,ra,rb,rc,rd,F5,KK1,0x100u,9);
- ROUND(ld,le,la,lb,lc,F1,K1,in[2],15);
- ROUND(rd,re,ra,rb,rc,F5,KK1,in[7],9);
- ROUND(lc,ld,le,la,lb,F1,K1,in[3],12);
- ROUND(rc,rd,re,ra,rb,F5,KK1,in[0],11);
- ROUND(lb,lc,ld,le,la,F1,K1,in[4],5);
- ROUND(rb,rc,rd,re,ra,F5,KK1,0,13);
- ROUND(la,lb,lc,ld,le,F1,K1,in[5],8);
- ROUND(ra,rb,rc,rd,re,F5,KK1,in[2],15);
- ROUND(le,la,lb,lc,ld,F1,K1,in[6],7);
- ROUND(re,ra,rb,rc,rd,F5,KK1,0,15);
- ROUND(ld,le,la,lb,lc,F1,K1,in[7],9);
- ROUND(rd,re,ra,rb,rc,F5,KK1,in[4],5);
- ROUND(lc,ld,le,la,lb,F1,K1,0x80u,11);
- ROUND(rc,rd,re,ra,rb,F5,KK1,0,7);
- ROUND(lb,lc,ld,le,la,F1,K1,0,13);
- ROUND(rb,rc,rd,re,ra,F5,KK1,in[6],7);
- ROUND(la,lb,lc,ld,le,F1,K1,0,14);
- ROUND(ra,rb,rc,rd,re,F5,KK1,0,8);
- ROUND(le,la,lb,lc,ld,F1,K1,0,15);
- ROUND(re,ra,rb,rc,rd,F5,KK1,0x80u,11);
- ROUND(ld,le,la,lb,lc,F1,K1,0,6);
- ROUND(rd,re,ra,rb,rc,F5,KK1,in[1],14);
- ROUND(lc,ld,le,la,lb,F1,K1,0,7);
- ROUND(rc,rd,re,ra,rb,F5,KK1,0,14);
- ROUND(lb,lc,ld,le,la,F1,K1,0x100u,9);
- ROUND(rb,rc,rd,re,ra,F5,KK1,in[3],12);
- ROUND(la,lb,lc,ld,le,F1,K1,0,8);
- ROUND(ra,rb,rc,rd,re,F5,KK1,0,6);
- ROUND(le,la,lb,lc,ld,F2,K2,in[7],7);
- ROUND(re,ra,rb,rc,rd,F4,KK2,in[6],9);
- ROUND(ld,le,la,lb,lc,F2,K2,in[4],6);
- ROUND(rd,re,ra,rb,rc,F4,KK2,0,13);
- ROUND(lc,ld,le,la,lb,F2,K2,0,8);
- ROUND(rc,rd,re,ra,rb,F4,KK2,in[3],15);
- ROUND(lb,lc,ld,le,la,F2,K2,in[1],13);
- ROUND(rb,rc,rd,re,ra,F4,KK2,in[7],7);
- ROUND(la,lb,lc,ld,le,F2,K2,0,11);
- ROUND(ra,rb,rc,rd,re,F4,KK2,in[0],12);
- ROUND(le,la,lb,lc,ld,F2,K2,in[6],9);
- ROUND(re,ra,rb,rc,rd,F4,KK2,0,8);
- ROUND(ld,le,la,lb,lc,F2,K2,0,7);
- ROUND(rd,re,ra,rb,rc,F4,KK2,in[5],9);
- ROUND(lc,ld,le,la,lb,F2,K2,in[3],15);
- ROUND(rc,rd,re,ra,rb,F4,KK2,0,11);
- ROUND(lb,lc,ld,le,la,F2,K2,0,7);
- ROUND(rb,rc,rd,re,ra,F4,KK2,0x100u,7);
- ROUND(la,lb,lc,ld,le,F2,K2,in[0],12);
- ROUND(ra,rb,rc,rd,re,F4,KK2,0,7);
- ROUND(le,la,lb,lc,ld,F2,K2,0,15);
- ROUND(re,ra,rb,rc,rd,F4,KK2,0x80u,12);
- ROUND(ld,le,la,lb,lc,F2,K2,in[5],9);
- ROUND(rd,re,ra,rb,rc,F4,KK2,0,7);
- ROUND(lc,ld,le,la,lb,F2,K2,in[2],11);
- ROUND(rc,rd,re,ra,rb,F4,KK2,in[4],6);
- ROUND(lb,lc,ld,le,la,F2,K2,0x100u,7);
- ROUND(rb,rc,rd,re,ra,F4,KK2,0,15);
- ROUND(la,lb,lc,ld,le,F2,K2,0,13);
- ROUND(ra,rb,rc,rd,re,F4,KK2,in[1],13);
- ROUND(le,la,lb,lc,ld,F2,K2,0x80u,12);
- ROUND(re,ra,rb,rc,rd,F4,KK2,in[2],11);
- ROUND(ld,le,la,lb,lc,F3,K3,in[3],11);
- ROUND(rd,re,ra,rb,rc,F3,KK3,0,9);
- ROUND(lc,ld,le,la,lb,F3,K3,0,13);
- ROUND(rc,rd,re,ra,rb,F3,KK3,in[5],7);
- ROUND(lb,lc,ld,le,la,F3,K3,0x100u,6);
- ROUND(rb,rc,rd,re,ra,F3,KK3,in[1],15);
- ROUND(la,lb,lc,ld,le,F3,K3,in[4],7);
- ROUND(ra,rb,rc,rd,re,F3,KK3,in[3],11);
- ROUND(le,la,lb,lc,ld,F3,K3,0,14);
- ROUND(re,ra,rb,rc,rd,F3,KK3,in[7],8);
- ROUND(ld,le,la,lb,lc,F3,K3,0,9);
- ROUND(rd,re,ra,rb,rc,F3,KK3,0x100u,6);
- ROUND(lc,ld,le,la,lb,F3,K3,0x80u,13);
- ROUND(rc,rd,re,ra,rb,F3,KK3,in[6],6);
- ROUND(lb,lc,ld,le,la,F3,K3,in[1],15);
- ROUND(rb,rc,rd,re,ra,F3,KK3,0,14);
- ROUND(la,lb,lc,ld,le,F3,K3,in[2],14);
- ROUND(ra,rb,rc,rd,re,F3,KK3,0,12);
- ROUND(le,la,lb,lc,ld,F3,K3,in[7],8);
- ROUND(re,ra,rb,rc,rd,F3,KK3,0x80u,13);
- ROUND(ld,le,la,lb,lc,F3,K3,in[0],13);
- ROUND(rd,re,ra,rb,rc,F3,KK3,0,5);
- ROUND(lc,ld,le,la,lb,F3,K3,in[6],6);
- ROUND(rc,rd,re,ra,rb,F3,KK3,in[2],14);
- ROUND(lb,lc,ld,le,la,F3,K3,0,5);
- ROUND(rb,rc,rd,re,ra,F3,KK3,0,13);
- ROUND(la,lb,lc,ld,le,F3,K3,0,12);
- ROUND(ra,rb,rc,rd,re,F3,KK3,in[0],13);
- ROUND(le,la,lb,lc,ld,F3,K3,in[5],7);
- ROUND(re,ra,rb,rc,rd,F3,KK3,in[4],7);
- ROUND(ld,le,la,lb,lc,F3,K3,0,5);
- ROUND(rd,re,ra,rb,rc,F3,KK3,0,5);
- ROUND(lc,ld,le,la,lb,F4,K4,in[1],11);
- ROUND(rc,rd,re,ra,rb,F2,KK4,0x80u,15);
- ROUND(lb,lc,ld,le,la,F4,K4,0,12);
- ROUND(rb,rc,rd,re,ra,F2,KK4,in[6],5);
- ROUND(la,lb,lc,ld,le,F4,K4,0,14);
- ROUND(ra,rb,rc,rd,re,F2,KK4,in[4],8);
- ROUND(le,la,lb,lc,ld,F4,K4,0,15);
- ROUND(re,ra,rb,rc,rd,F2,KK4,in[1],11);
- ROUND(ld,le,la,lb,lc,F4,K4,in[0],14);
- ROUND(rd,re,ra,rb,rc,F2,KK4,in[3],14);
- ROUND(lc,ld,le,la,lb,F4,K4,0x80u,15);
- ROUND(rc,rd,re,ra,rb,F2,KK4,0,14);
- ROUND(lb,lc,ld,le,la,F4,K4,0,9);
- ROUND(rb,rc,rd,re,ra,F2,KK4,0,6);
- ROUND(la,lb,lc,ld,le,F4,K4,in[4],8);
- ROUND(ra,rb,rc,rd,re,F2,KK4,in[0],14);
- ROUND(le,la,lb,lc,ld,F4,K4,0,9);
- ROUND(re,ra,rb,rc,rd,F2,KK4,in[5],6);
- ROUND(ld,le,la,lb,lc,F4,K4,in[3],14);
- ROUND(rd,re,ra,rb,rc,F2,KK4,0,9);
- ROUND(lc,ld,le,la,lb,F4,K4,in[7],5);
- ROUND(rc,rd,re,ra,rb,F2,KK4,in[2],12);
- ROUND(lb,lc,ld,le,la,F4,K4,0,6);
- ROUND(rb,rc,rd,re,ra,F2,KK4,0,9);
- ROUND(la,lb,lc,ld,le,F4,K4,0x100u,8);
- ROUND(ra,rb,rc,rd,re,F2,KK4,0,12);
- ROUND(le,la,lb,lc,ld,F4,K4,in[5],6);
- ROUND(re,ra,rb,rc,rd,F2,KK4,in[7],5);
- ROUND(ld,le,la,lb,lc,F4,K4,in[6],5);
- ROUND(rd,re,ra,rb,rc,F2,KK4,0,15);
- ROUND(lc,ld,le,la,lb,F4,K4,in[2],12);
- ROUND(rc,rd,re,ra,rb,F2,KK4,0x100u,8);
- ROUND(lb,lc,ld,le,la,F5,K5,in[4],9);
- ROUND(rb,rc,rd,re,ra,F1,KK5,0,8);
- ROUND(la,lb,lc,ld,le,F5,K5,in[0],15);
- ROUND(ra,rb,rc,rd,re,F1,KK5,0,5);
- ROUND(le,la,lb,lc,ld,F5,K5,in[5],5);
- ROUND(re,ra,rb,rc,rd,F1,KK5,0,12);
- ROUND(ld,le,la,lb,lc,F5,K5,0,11);
- ROUND(rd,re,ra,rb,rc,F1,KK5,in[4],9);
- ROUND(lc,ld,le,la,lb,F5,K5,in[7],6);
- ROUND(rc,rd,re,ra,rb,F1,KK5,in[1],12);
- ROUND(lb,lc,ld,le,la,F5,K5,0,8);
- ROUND(rb,rc,rd,re,ra,F1,KK5,in[5],5);
- ROUND(la,lb,lc,ld,le,F5,K5,in[2],13);
- ROUND(ra,rb,rc,rd,re,F1,KK5,0x80u,14);
- ROUND(le,la,lb,lc,ld,F5,K5,0,12);
- ROUND(re,ra,rb,rc,rd,F1,KK5,in[7],6);
- ROUND(ld,le,la,lb,lc,F5,K5,0x100u,5);
- ROUND(rd,re,ra,rb,rc,F1,KK5,in[6],8);
- ROUND(lc,ld,le,la,lb,F5,K5,in[1],12);
- ROUND(rc,rd,re,ra,rb,F1,KK5,in[2],13);
- ROUND(lb,lc,ld,le,la,F5,K5,in[3],13);
- ROUND(rb,rc,rd,re,ra,F1,KK5,0,6);
- ROUND(la,lb,lc,ld,le,F5,K5,0x80u,14);
- ROUND(ra,rb,rc,rd,re,F1,KK5,0x100u,5);
- ROUND(le,la,lb,lc,ld,F5,K5,0,11);
- ROUND(re,ra,rb,rc,rd,F1,KK5,in[0],15);
- ROUND(ld,le,la,lb,lc,F5,K5,in[6],8);
- ROUND(rd,re,ra,rb,rc,F1,KK5,in[3],13);
- ROUND(lc,ld,le,la,lb,F5,K5,0,5);
- ROUND(rc,rd,re,ra,rb,F1,KK5,0,11);
- ROUND(lb,lc,ld,le,la,F5,K5,0,6);
- ROUND(rb,rc,rd,re,ra,F1,KK5,0,11);
- dgst[0]=0xefcdab89u+lc+rd;
- dgst[1]=0x98badcfeu+ld+re;
- dgst[2]=0x10325476u+le+ra;
- dgst[3]=0xc3d2e1f0u+la+rb;
- dgst[4]=0x67452301u+lb+rc;
- }
- #define BLOOM_GET_BIT(N)((bloom[(N)>>3]>>((N)&7))&1)
- #define BH05(N)(N[0]<<16|N[1]>>16)
- #define BH06(N)(N[1]<<16|N[2]>>16)
- #define BH07(N)(N[2]<<16|N[3]>>16)
- #define BH08(N)(N[3]<<16|N[4]>>16)
- #define BH09(N)(N[4]<<16|N[0]>>16)
- #define BH10(N)(N[0]<<8|N[1]>>24)
- #define BH11(N)(N[1]<<8|N[2]>>24)
- #define BH12(N)(N[2]<<8|N[3]>>24)
- #define BH13(N)(N[3]<<8|N[4]>>24)
- #define BH14(N)(N[4]<<8|N[0]>>24)
- #define BH15(N)(N[0]<<24|N[1]>> 8)
- #define BH16(N)(N[1]<<24|N[2]>> 8)
- #define BH17(N)(N[2]<<24|N[3]>> 8)
- #define BH18(N)(N[3]<<24|N[4]>> 8)
- #define BH19(N)(N[4]<<24|N[0]>> 8)
- uint
- bloom_chk_hash160(global const uchar*bloom,uint*h) {
- if(!BLOOM_GET_BIT(h[0])) {
- return 0;
- }
- if(!BLOOM_GET_BIT(h[1])) {
- return 0;
- }
- if(!BLOOM_GET_BIT(h[2])) {
- return 0;
- }
- if(!BLOOM_GET_BIT(h[3])) {
- return 0;
- }
- if(!BLOOM_GET_BIT(h[4])) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH05(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH06(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH07(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH08(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH09(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH10(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH11(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH12(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH13(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH14(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH15(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH16(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH17(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH18(h))) {
- return 0;
- }
- if(!BLOOM_GET_BIT(BH19(h))) {
- return 0;
- }
- return 1;
- }
- kernel void
- hash160_bloom(global const ulong(*pubkeys)[4],global const uchar*bloom,global const uint*privkey
- ) {
- const ushort gid0=get_global_id(0);
- const ushort gid1=get_global_id(1);
- const ushort gid2=get_global_id(2);
- const ushort gsz0=get_global_size(0);
- const ushort gsz1=get_global_size(1);
- const ushort gsz2=get_global_size(2);
- const ushort idx=gid2*gsz0*gsz1+gid1*gsz0+gid0;
- const ushort didx=idx*2;
- uint sha256_out[8];
- uint sha256_in[16];
- uint ripemd160_out[5];
- for(uchar i=0; i<4; i++) {
- uchar di=i*2;
- ulong pkx=pubkeys[didx][3-i];
- ulong pky=pubkeys[didx+1][3-i];
- sha256_in[di]=(uint)(pkx >> 32);
- sha256_in[di+1]=(uint)(pkx & 0xFFFFFFFF);
- sha256_in[di+8]=(uint)(pky >> 32);
- sha256_in[di+9]=(uint)(pky & 0xFFFFFFFF);
- }
- sha256_u((uchar*)sha256_in,sha256_out);
- ripemd160_transform(sha256_out,ripemd160_out);
- if(bloom_chk_hash160(bloom,ripemd160_out)) {
- printf("%08x%08x%08x%08x%08x:u:priv:%08x%08x%08x%08x%08x%08x%08x%08x+%#0x\n",bswap32(ripemd160_out[0]),bswap32(ripemd160_out[1]),bswap32(ripemd160_out[2]),bswap32(ripemd160_out[3]),bswap32(ripemd160_out[4]),bswap32(privkey[0]),bswap32(privkey[1]),bswap32(privkey[2]),bswap32(privkey[3]),bswap32(privkey[4]),bswap32(privkey[5]),bswap32(privkey[6]),bswap32(privkey[7]),idx);
- }
- sha256_c((uchar*)sha256_in,sha256_out);
- ripemd160_transform(sha256_out,ripemd160_out);
- if(bloom_chk_hash160(bloom,ripemd160_out)) {
- printf("%08x%08x%08x%08x%08x:c:priv:%08x%08x%08x%08x%08x%08x%08x%08x+%#0x\n",bswap32(ripemd160_out[0]),bswap32(ripemd160_out[1]),bswap32(ripemd160_out[2]),bswap32(ripemd160_out[3]),bswap32(ripemd160_out[4]),bswap32(privkey[0]),bswap32(privkey[1]),bswap32(privkey[2]),bswap32(privkey[3]),bswap32(privkey[4]),bswap32(privkey[5]),bswap32(privkey[6]),bswap32(privkey[7]),idx);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement