Wednesday, March 12, 2014

Setup of the ASIC Erupter Blade V2 (Part 3)

Before we begin the configuration of the stratum proxy software, now would be a good time to summarize the progress we have made so far:

At this point we should have an assembled ASIC rig with 1-10 boards seated and configured for our backend network.  Each board should feature a unique IP address that is of the form 192.168.2.x where x is a value greater than or equal to 200 and a netmask value of 255.255.255.0.

Each of our boards should be connected via Ethernet cable to a multiport switch large enough to accommodate all of our mining boards plus an Ethernet connection coming from our stratum proxy host's _second_ Ethernet port.  From our stratum proxy host, this interface should have an IP address of the form 192.168.2.2 (or anything less than 200 and greater than or equal to 2 really) with a netmask of 255.255.255.0. 

The first Ethernet port on our stratum proxy host should be connected to our internet accessible home network. This interface should have an IP address and netmask that is compatible with the settings of the internet router.

On the stratum proxy host, the first interface will generally be the device eth0 and the second interface the device eth1, however depending upon your particular hardware configuration, your mileage may vary.  For instance, should you choose to use a laptop as your stratum proxy host, you might use wlan0 (the wireless device) as one of your interfaces.  In the end, the important feature is that the stratum proxy host should have two interfaces so that it can sit comfortably on two networks acting as the bridge between your mining network and your internet connected network.  This will enable the proxy to 'talk' privately to the boards in your mining rig, while exchanging data with whichever pool you bind your processing to.

With these pieces in place, we can move on to configuring the stratum proxy host:

Configuring the Stratum Proxy Host:


Configuration of the stratum proxy host begins with downloading and installing the BFGminer program.  This program is responsible for requesting work from the mining pool as well as aggregating and passing along the results from our ASIC mining rig.

You may find the latest version of BFGMiner here.

In fairness there are other programs that provide this function, however once built, I found BFGminer to be the easiest to use and the most stable.   If you have adapted these instructions to work under Windows, you can use the precompiled windows binary (32 bit, 64 bit).  If (as is the case with the author) you are using Linux as your mining platform,  depending upon your distribution, you may need to build and install it from source code first.

If you are using a supported Linux distribution (as shown on the BFGminer web page) HOORAY! Simply follow the simple instructions provided to get your distribution's package manager to install the software for you and skip past the painful process that I'm about to detail below.  If you find that you're going to have to build the package from its source code, buckle up and we will go through it step by step and hope for the best.  In short, this is the painful part! However, I'm an old pro, and I'm sure that you're an attentive reader, so we'll struggle through it together although I can't help but to recall a saying that a dear friend once shared with me concerning such circumstances:

Nobody rides for free...

And with that let's build us a BFGMiner stratum proxy package!

Building and Installing the BFGMiner Software Package:


If you have built software from source code before, much of what follows may seem like an exercise in worshipping at the Temple of the Obvious.  If you can or have already built BFGMiner, you may skip to the section on configuration.  If you are unfamiliar with building Unix software packages from source code, the first step will be to insure that you have all of the program development tools loaded into your operating system.  Typically these tools will include your C compiler and linker as well as any libraries you may need to have installed prior to building the package.

The package manager (software for installing software) will vary depending upon your Linux distribution.  If you are attempting this via BSD*nix, it may be different altogether (the differences of which lie far beyond the scope of this article).  Generally amongst Linux distributions, the flavors are roughly divided between the Debian and Redhat based distributions.  As a result, where applicable, you can expect your package manager to be either APT or YUM respectively.  Armed with the appropriate package manager, knowledge of the actual package names is the only remaining thing required to setup the build environment we'll need to compile BFGMiner.

To install the build environment using APT on a Debian based system, AS THE ROOT USER use the command:

apt-get install build-essential

To install the build environment using YUM on a RedHat based system, AS THE ROOT USER use the command:

yum groupinstall "Development Tools"

For their respective distributions, these commands will typically install the C compiler, libraries, and include files needed to compile most computer software packages from source code.  Unfortunately, BFGMiner is not so average in that we will need to install additional libraries before we'll be able to successfully compile this package.  From the README file included with the source code package these are (Debian):
autoconf automake libtool pkg-config libcurl4-gnutls-dev libjansson-dev uthash-dev libncursesw5-dev libudev-dev libusb-1.0-0-dev libevent-dev libmicrohttpd-dev hidapi

Install packages under Debian based distributions as follows:

apt-get install autoconf automake libtool pkg-config libcurl4-gnutls-dev\ libjansson-dev uthash-dev libncursesw5-dev libudev-dev libusb-1.0-0-dev\ libevent-dev libmicrohttpd-dev hidapi

For RedHat based distributions, the names will be slightly different (of course, nothing can be easy right?):

autoconf automake libtool pkg-config libcurl libcurl4 uthash ncurses\ ncurses-devel libudev libusb libevent libmicrohttpd hidapi

Install packages under RedHat based distributions as follows:

yum install autoconf automake libtool pkg-config libcurl libcurl4 uthash ncurses ncurses-devel libudev libusb libevent libmicrohttpd hidapi

It is important that all of these packages be installed prior to attempting to build BFGMiner from source code, especially libmicrohttpd which we will use to enable proxy service.  Once the prerequisite software has been installed, we are clear to extract the source code from the BFGMiner package we downloaded earlier using the following commands:

mkdir bfg
cd bfg
unzip /path/to/downloaded/source_code.zip
./configure

If everything configures without error (it is of utmost importance that everything does prior to attempting the next step), you'll be ready to build the software package using the command:

make

What follows should be screens and screens of compiler output.  If you see the message "Warning" at this stage, you may ignore it.  Discrepancies between Linux distributions occasionally show up as slight differences between the include library files used to compile and link executable files.  On the other hand, if you see "Error" messages, you'll have to revisit checking to see that all of the prerequisite software is installed, followed by potentially re-running the ./configure command.

Unfortunately, this part of the process involves some level of trial and error.  To the extent that you find yourself unable to build BFGMiner from its sources, the problem will almost always be a case of missing prerequisites, either in the form of missing libraries or libraries that are present but of incompatible versions.

Once the make completes, the BFGMiner program will be ready to use.  Copy the BFGMiner executable into your /usr/local/bin directory.

At this point, to make your new setup easier to use, using 'vi' or your favorite text editor, you can copy the following lines into your own customizable shell script (This one works for slush):

#!/bin/sh

# slush.sh - script for configuring proxy host to mine with slush
 
/usr/local/bin/bfgminer -G --http-port 8334 -o stratum+tcp://stratum.bitcoin.cz:3333 -u your-worker -p your-password

The important parts of this script are the --http-port nnnn which is the place where our ASIC erupter boards will find our proxy, and the -o, -u, and -p options which identify the URL of the mining pool we want to work with, our worker's login id for the pool, and the worker's password associated with our login id.  Obviously, you may substitute other URLs in the -o option to mine for other pools.  The strength of this set up is that only the stratum proxy need know anything about the outside mining pool.  Our ASIC Erupter Blades only need to know about the proxy.  They could care less about the world beyond our stratum proxy host and are content to do their work without concern.

In the next and final installment of this series, we will bring everything we've covered together so that you can get up and mining.

Until next time,

DP
donation btc: 1HSFkXyLqPv1iHTjcRRw9DgiFb7SftiCxA

Monday, February 24, 2014

Setup of the ASIC Erupter Blade V2 (Part 2)


As long as you have all of the required parts, assembling your ASIC Erupter Blade mining rig is the easiest part of the process.  As stated in our previous article, when building a rig from Erupter blades, it is highly (extremely highly) recommended that you also purchase the matching backplane and power supply.  These two accessories can greatly simplify rig construction and have your blades up and running in minutes.  If you don't get one that includes the aesthetically pleasing cage, you can mount your backplane to most any surface just as long as you provide for protection from shorting out the underside of the backplane.  My rig was mounted to a wooden board, I used the plastic packaging material for this purpose.

Parts list:


1 Power Supply
1 ASIC Erupter Blade V2 Backplane (supports up to 10 blades)
1-10 ASIC Erupter Blades
1 4, 8, or 16 port Netgear (or equivalent) Ethernet switch*
1 Additional USB/PCI/PCMCIA Ethernet card for your proxy computer host 
3-12 CAT5 or CAT6 Ethernet cables 3FT*
1 Surge Protected 4 or 6 outlet plug strip
1 BFGMinger Software 
1+Fans for cooling**

* = Depends upon how many blades you will be installing
**= Depends upon which fans you select and how you mount them

Things you should already have:


1 Broadband Internet service via your telephone or cable company
1 Complete computer connected to the internet
2 Available electrical outlets and electrical service

 

Assembly:




If you purchased the bitcoin ASIC Erupter Blade open air case pictured above from a vendor like bitcoinrigs.org, you can mostly skip this step.  As you can see, this rig greatly simplifies connecting your backplane to a support.  It's definitely the most aesthetically pleasing option.  If you're tastes are a little bit more McGyver*, you can mount the backplane on an ordinary wooden board.  The one I used (because was unaware of the air case at the time I built my rig) measured 1'x4'x3/4".  Using the packing material that came with the backplane and the existing screw holes (please don't drill your backplane) I was able to secure it using appropriately sized drywall/wood screws.  One note of caution however:  Take care when fastening the board down not to unnecessarily flex/bend it.  Once your board is secured, you can attach the power supply to the connector on the far right side labelled "GND".  The label of the power supply should face to the right away from the backplane such that the bulk of the supply is not interfering the innermost board connector.

*For those who are more into the DIY thing, I highly recommend reading Dogie's Guide.

At this point, in the lower right corner of the backplane you will see a jumper labelled "Power Jumper".  This will essentially function as the on/off switch of the rig.  Once the backplane and power supply have been secured, you will be ready to add an Erupter blade.  I typically started from the inside and worked my way to the left leaving space between boards at first to allow for airflow around each one until filling the rig, but it probably doesn't matter.

With each blade, the backplane, and the power supply installed you will be ready to network the boards.  Originally, when I first networked my rig, I connected it to my wireless router alongside the rest of my network connected devices.  As obvious as it seemed at the time, what I didn't know was that these blades didn't necessarily "play nice" with some wireless routers.

In fairness, you can find instructions on the internet where people have had success with their wireless routers but your mileage may vary.  I chose a far more conservative approach and created an isolated backend network.  This was accomplished by dual homing the stratum proxy host (placing the computer/stratum proxy host on two networks, each network using its own network interface card) with one side of the host connected to the regular internet via my wireless router and the other side of the host connected to the ASIC erupter blades via an ethernet switch.  Although the Erupter Blades could interact with the internet themselves using getwork protocol, using a stratum proxy yielded a far more flexible solution.

Coupled with my own home grown ASIC Erupter tools,  this dual homed configuration made it easier to manage the boards both collectively and individually.  In my setup I am able to assign blades or groups of blades to different mining pools dynamically.





Once assembled and networked with the stratum proxy host (which via its other network interface should be already be connected to the internet via your wireless router) before activating your second interface, you'll need to properly configure the subnet masks on your ASIC blades. 

Erupter Blade Configuration:


Configuration of the mining rig from the point will involve configuring the stratum proxy host and each of the ASIC Erupter Blades.  Depending upon your operating system (usually Windows or some flavor of Unix), the procedure for manipulating your network interfaces will vary.  I used Ubuntu Linux for this setup, so those instructions will be included here.  Windows uses similar commands for configuring its network interface and if there is significant interest in updating this article to include them, I will.  Just leave your comments at the end of the article...

Since we will be configuring the Erupter Blades using the stratum proxy host, we will need to properly configure its network interface first.  If you dual homed the system as recommended, the procedure will be slightly tricky because of the default settings each blade comes typically initialized with.  ASIC Erupter Blades typically come setup to participate on subnet 192.168.1.x.  For many home internet private networks, this subnet also happens to be the default subnet assigned to many wireless routers.  In order to avoid the conflict, we must set the subnet mask of our backend network to 192.168.2.x*.

(*this step is only necessary if your wireless router uses 192.168.1.x as its default subnet, otherwise you may skip the next few steps)

This will involve getting the stratum proxy host to talk to each of our ASIC blades using their default network, and then updating each blade's network settings to allow it to participate on our alternate 192.168.2.x network.  Since we will not need internet connectivity to configure the blades, we will first shut down the internet connected network interface on the stratum server.  To identify the proper network interface to shut down, we will use the 'ifconfig' command:

ifconfig -a

This command will give us the status of all the network interfaces present within the stratum proxy:


In this example, eth0 is the internet connected network interface while eth1 represents our backend network.  We can temporarily disable this interface using the 'ifdown' command as follows:

ifdown eth0

This will essentially disable our connection to the outside internet and free the network 192.168.1.x for us to use to configure each ASIC Erupter Blade.  It is important to note that from the factory, the default settings for each blade will be the same, so in order to avoid conflicts we will be configuring each board one at a time.

Physically this will mean that until all the boards have been given unique IP addresses, only ONE board should be plugged into the back plane at a time.  Once the board has been configured with its own unique IP address, the back plane should be powered down, the board removed, the next board inserted, and the configuration process (described below) repeated.

Step 1:

With our ASIC Erupter Blade and our stratum proxy host computer plugged into our ethernet switch, set the backend network interface to the default network factory setting for the ASIC using the 'ifconfig' command as follows:

ifconfig eth1 inet 192.168.1.2 netmask 255.255.255.0

This will assign our backend network to be the network that an ASIC Erupter Blade configured with factory default settings expects to see.  The configuration web server embedded on our Erupter Blade has a default URL address of:

http://192.168.1.254:8000

Step 2:

Using your favorite browser (I use firefox), navigate to the URL listed above. This should bring up a configuration page similar to:


 

Change the IP address to be 192.168.2.200, the Gateway to be 192.168.2.1, and the Primary DNS to be 192.168.2.1.  Lastly press the Update/Restart button to apply the changes.

At this point the ASIC Erupter Blade will be configured for operation but now incompatible with our current network settings.  Power the backplane off, remove the board and insert another board into its place.

Step 3:

Repeat this procedure, only substituting a unique IP address for each blade you configure.  In other words, give each new blade an address in the range of 192.168.2.2xx.  The will enable a greater number of ASIC Erupter Blades to coexist on the backend network without creating network conflicts with each another.

Between each configuration, remember to power off each board and disconnect it from the network.  Although powered off, each board will remember its configuration.  Once all the boards have been configured, you can plug them each into their shared backplane.  Plug everything together and power everything down including the network switch.  Our next step will be to reconfigure the stratum proxy server host.

Stratum Proxy Host Configuration


Now that our ASIC Erupter Blades are configured with unique IP addresses compatible with what will be our backend network subnet, it is time to reconfigure the backend network interface on the stratum proxy host.  We accomplish this by reusing the ifconfig command as follows:

ifconfig eth1 inet 192.168.2.2 netmask 255.255.255.0

This command will assign our second network interface with an IP address that is compatible with our intended backend network's subnet.  Once the interface has been configured, you can power on the ethernet switch followed by the ASIC Erupter Blades....

We may also reconnect our stratum proxy host to the internet through its eth0 network interface using the following:

ifup eth0

This will restore our internet connection just as if we had restarted the system.  In our next article, we will discuss the installation and configuration of the stratum proxy host's software.

Stay tuned!

DP
donation btc: 1HSFkXyLqPv1iHTjcRRw9DgiFb7SftiCxA

Saturday, February 1, 2014

Setup of the ASIC Erupter Blade V2



There is nothing obvious about Bitcoin mining.  With its own specialized hardware, software, and even lingo, the world of Bitcoin mining can appear at first to be a scary place for the Newbie  cryptocoin miner.  As with most new things, there is much to learn, and also much to get bitten by. While search engines are helpful, sometimes it can be challenging to find the particular information you need.  Nowhere else is this more true than when it comes to finding information to properly setup and configure the ASIC Erupter blade.

When I first purchased my blade, I came to the table as a  system administrator and a veteran programmer.  Having built both computer systems and the networks that connect them, I felt fairly comfortable that I could get my board "up and hashing" relatively quickly...  

I was wrong.  In the absence of *any* documentation, I ended up scratching my head for a week before I had my blade hashing and generating bitcoin.

After working with the hardware for a short time, I could tell that it was bleeding edge technology in that it behaved as a "right off the presses" product.  The HTML web interface was unpolished and syntactically incorrect (more on that in a later article).  The rig itself looked more like something that belonged in a research lab than on a consumer's desk.  In short, this was the "hard" of hardware.

Fortunately, I was not the first to travel this treacherous path, and now neither are you. After a week in the wilderness, Google searches and email exchanges with the vendor that I bought the board from finally yielded results. I encountered some very well done tutorials on the net (which I will include in the reference section of this series) and  found good advice via valuable conversation on bitcointalk.org.  For the most part, the bitcoin community has been both helpful and welcoming.  It is that spirit that I wish to uphold in these articles.

With that said, before we start down our yellow brick road together I would like to add the following advice:

While there is something both attractive and appealing about the DIY (do-it-yourself) aspects of putting together your own bitcoin mining rigs, resist the temptation to make life harder on yourself by trying to do too much.  Ultimately, I would guess that most of you bought your bitcoin rigs to make money by mining bitcoins. The more time you spend building or customizing your rig, the less time it will spend doing what you actually bought it for.  With the ASIC Erupter Blades version 2, I highly (highly) recommend that you also purchase the companion backplane and power supply.  They are matched to your hardware and are very easy to assemble.  If you are also a fan of aesthetics you can purchase the backplane and open air case available from http://bitcoinrigs.org.  I certainly do *not* recommend powering the boards from the top power connector and/or adapting a regular computer case and power supply to house them.  

For the first version of the boards (Version 1) this was required, the additional custom hardware that came as an option for Version 2 was definitely an improvement that will most likely lead to fewer short circuits and more reliable operation.  Going the McGyver route will almost surely (unless you are extremely careful) introduce future problems that may prove difficult to diagnose and resolve quickly.

In part 2 of this article we will get down to the business of assembling our rig.  Stay tuned.

DP

Friday, January 31, 2014

The Bounty (Conclusion)

In our first article we covered how to translate the single bit logical XOR (exclusive OR) function into its arithmetic equivalent.  In part 2 we discussed how to step through the individual bits of a multiple bit operand so that we could transform our original XOR function into a bitwise operation.  Lastly, in this article we will combine all of the information we've discussed so far in the previous two articles and synthesize it into the very programs that I submitted as my entries for the original challenge.

BEFORE WE BEGIN


Although I am fluent in a few computer languages, my quick and dirty language of choice is Perl.  For those interested in porting this example to other languages, the code should run equally well under Python with minor edits.  Furthermore, although this particular challenge called for an implementation of the XOR function, the principles used to translate the function into its arithmetic equivalent apply equally toward the translation of other logical functions.  In all such cases, the utility of the number (-1) will usually prove to be indispensable whether used to implement the logical function itself, or used as an alternate modulo 2 substitute.

 

PUTTING IT ALL TOGETHER

 

At this point we have investigated all of the elements that we'll use to complete our program.  We have developed arithmetic equivalents for our XOR function.  We have  implemented ways to step through each bit of  our operands to perform bitwise operations.  In short, we have assembled all of the ingredients; now it is time to bake this cake!

As you might imagine, despite our new understanding of the challenge, this program will be somewhat complicated to describe with plenty of room for typos.  For this reason, I we'll actually be employing the computer itself to generate the final equation.  Perl is well suited for this purpose although I suspect that Python would be an equally valid choice.

Given input variables $a and $b, we begin by breaking down each operand into its bitwise constitutents:

#!/usr/bin/perl

# our improvised %2 function: ((1-(-1)**$n)/2)

for ($i=0; $i<32; $i++)  # 32 bits
{
    $hash= sprintf("%02x", $i);
    $ai= "a".$hash; #hash for var containing rotate eq a.bit[i]
    $bi= "b".$hash; #hash for var containing rotate eq b.bit[i]
    $n= "\$a*2**(32-$i)%(2**32-1)";  # rotate to bit a.bit[i]
    $var{$ai}= "((1-(-1)**($n))/2)"; # assign hash for a.bit[i]
    $n= "\$b*2**(32-$i)%(2**32-1)";  # rotate to bit b.bit[i]
    $var{$bi}= "((1-(-1)**($n))/2)"; # assign hash for b.bit[i]
}

The above code will cycle through the 32 bits (0-31) of both operands and assign each hash in %var to be the equation necessary (given an input '$a' or input '$b' ) to rotate the bit at the position specified by $i to the one's position (2^0) and to evaluate the result as either being even (0) or odd(0).

First the code creates a hash using the name of the operand ('a' or 'b') concatenated to the hexidecimal value of $i.  Next, the variable $n is assigned to the equation representing the rotation of the bit at the position specified by $i to the one's position of the operand (2^0).  Lastly, the %var hash is assigned the equation representing our alternate modulo 2 function applied to the rotation in $n.  When all is said and done, in Perl terms, $var{'a12'} will be assigned to the equation required to rotate the bit found at the 18th position (because 12 in hexidecimal is 18 in decimal) to the one's position (also known as the least significant bit) and to evaluate it as being zero (0) or one (1).

Keeping these equations straight and typo-free is half the battle!  Using the computer to do it for us greatly simplifies the remaining programming ahead.

Armed with equations to evaluate each bit of both operands (a, b), we are now in the position to program our computer to give us our bitwise XOR function.  We accomplish this using the following code:

$formula= "";

for ($i=0; $i<32; $i++)
{
    $hash=sprintf("%02x", $i);
    $ai= "a".$hash;
    $bi= "b".$hash;
    $formula.="((1+((-1)**($var{$ai}+$var{$bi})+"
    $formula.="(-1)**(2-($var{$ai}+$var{$bi})))/(-2))/2)*2**$i+\n";
}

chop ($formula); # get rid of last newline
chop ($formula); # get rid of last (+) sign

$formula.=";";   # append semi-colon (:)

print "$formula\n" 

The final formula ends up being the addition of subsequent applications of our derived XOR function using $var{$ai} and $var{$bi} (as we defined them in the previous code segment) as inputs.  Using the variable $formula, we accumulate these repeated applications of our arithmetic XOR function by multiplying the output of each XOR operation by the power of 2 representing the output bit's position within the result.

When this program is executed, Perl's string substitution will faithfully reproduce the precedence and syntax of the simpler functions we needed to combine to create the complete equation.  We'll then use the output from this program as paste it into another separate program for evaluation:

((1+((-1)**(((1-(-1)**($a*2**(32-0)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-0)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-0)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-0)%(2**32-1)))/2))))/(-2))/2)*2**0+
((1+((-1)**(((1-(-1)**($a*2**(32-1)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-1)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-1)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-1)%(2**32-1)))/2))))/(-2))/2)*2**1+
((1+((-1)**(((1-(-1)**($a*2**(32-2)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-2)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-2)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-2)%(2**32-1)))/2))))/(-2))/2)*2**2+
((1+((-1)**(((1-(-1)**($a*2**(32-3)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-3)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-3)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-3)%(2**32-1)))/2))))/(-2))/2)*2**3+
((1+((-1)**(((1-(-1)**($a*2**(32-4)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-4)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-4)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-4)%(2**32-1)))/2))))/(-2))/2)*2**4+
((1+((-1)**(((1-(-1)**($a*2**(32-5)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-5)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-5)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-5)%(2**32-1)))/2))))/(-2))/2)*2**5+
((1+((-1)**(((1-(-1)**($a*2**(32-6)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-6)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-6)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-6)%(2**32-1)))/2))))/(-2))/2)*2**6+
((1+((-1)**(((1-(-1)**($a*2**(32-7)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-7)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-7)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-7)%(2**32-1)))/2))))/(-2))/2)*2**7+
((1+((-1)**(((1-(-1)**($a*2**(32-8)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-8)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-8)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-8)%(2**32-1)))/2))))/(-2))/2)*2**8+
((1+((-1)**(((1-(-1)**($a*2**(32-9)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-9)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-9)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-9)%(2**32-1)))/2))))/(-2))/2)*2**9+
((1+((-1)**(((1-(-1)**($a*2**(32-10)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-10)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-10)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-10)%(2**32-1)))/2))))/(-2))/2)*2**10+
((1+((-1)**(((1-(-1)**($a*2**(32-11)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-11)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-11)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-11)%(2**32-1)))/2))))/(-2))/2)*2**11+
((1+((-1)**(((1-(-1)**($a*2**(32-12)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-12)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-12)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-12)%(2**32-1)))/2))))/(-2))/2)*2**12+
((1+((-1)**(((1-(-1)**($a*2**(32-13)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-13)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-13)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-13)%(2**32-1)))/2))))/(-2))/2)*2**13+
((1+((-1)**(((1-(-1)**($a*2**(32-14)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-14)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-14)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-14)%(2**32-1)))/2))))/(-2))/2)*2**14+
((1+((-1)**(((1-(-1)**($a*2**(32-15)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-15)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-15)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-15)%(2**32-1)))/2))))/(-2))/2)*2**15+
((1+((-1)**(((1-(-1)**($a*2**(32-16)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-16)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-16)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-16)%(2**32-1)))/2))))/(-2))/2)*2**16+
((1+((-1)**(((1-(-1)**($a*2**(32-17)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-17)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-17)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-17)%(2**32-1)))/2))))/(-2))/2)*2**17+
((1+((-1)**(((1-(-1)**($a*2**(32-18)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-18)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-18)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-18)%(2**32-1)))/2))))/(-2))/2)*2**18+
((1+((-1)**(((1-(-1)**($a*2**(32-19)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-19)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-19)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-19)%(2**32-1)))/2))))/(-2))/2)*2**19+
((1+((-1)**(((1-(-1)**($a*2**(32-20)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-20)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-20)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-20)%(2**32-1)))/2))))/(-2))/2)*2**20+
((1+((-1)**(((1-(-1)**($a*2**(32-21)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-21)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-21)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-21)%(2**32-1)))/2))))/(-2))/2)*2**21+
((1+((-1)**(((1-(-1)**($a*2**(32-22)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-22)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-22)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-22)%(2**32-1)))/2))))/(-2))/2)*2**22+
((1+((-1)**(((1-(-1)**($a*2**(32-23)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-23)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-23)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-23)%(2**32-1)))/2))))/(-2))/2)*2**23+
((1+((-1)**(((1-(-1)**($a*2**(32-24)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-24)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-24)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-24)%(2**32-1)))/2))))/(-2))/2)*2**24+
((1+((-1)**(((1-(-1)**($a*2**(32-25)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-25)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-25)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-25)%(2**32-1)))/2))))/(-2))/2)*2**25+
((1+((-1)**(((1-(-1)**($a*2**(32-26)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-26)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-26)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-26)%(2**32-1)))/2))))/(-2))/2)*2**26+
((1+((-1)**(((1-(-1)**($a*2**(32-27)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-27)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-27)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-27)%(2**32-1)))/2))))/(-2))/2)*2**27+
((1+((-1)**(((1-(-1)**($a*2**(32-28)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-28)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-28)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-28)%(2**32-1)))/2))))/(-2))/2)*2**28+
((1+((-1)**(((1-(-1)**($a*2**(32-29)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-29)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-29)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-29)%(2**32-1)))/2))))/(-2))/2)*2**29+
((1+((-1)**(((1-(-1)**($a*2**(32-30)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-30)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-30)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-30)%(2**32-1)))/2))))/(-2))/2)*2**30+
((1+((-1)**(((1-(-1)**($a*2**(32-31)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-31)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-31)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-31)%(2**32-1)))/2))))/(-2))/2)*2**31;

Now that we have our equation (in a syntactically correct, Perl compatible format), we need only add a few additional Perl statements to create our finished program:

#!/usr/bin/perl

my $buf= <STDIN>;
my ($a, $b) = split /\s+/, $buf;

my $result=

((1+((-1)**(((1-(-1)**($a*2**(32-0)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-0)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-0)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-0)%(2**32-1)))/2))))/(-2))/2)*2**0+
((1+((-1)**(((1-(-1)**($a*2**(32-1)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-1)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-1)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-1)%(2**32-1)))/2))))/(-2))/2)*2**1+
((1+((-1)**(((1-(-1)**($a*2**(32-2)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-2)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-2)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-2)%(2**32-1)))/2))))/(-2))/2)*2**2+
((1+((-1)**(((1-(-1)**($a*2**(32-3)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-3)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-3)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-3)%(2**32-1)))/2))))/(-2))/2)*2**3+
((1+((-1)**(((1-(-1)**($a*2**(32-4)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-4)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-4)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-4)%(2**32-1)))/2))))/(-2))/2)*2**4+
((1+((-1)**(((1-(-1)**($a*2**(32-5)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-5)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-5)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-5)%(2**32-1)))/2))))/(-2))/2)*2**5+
((1+((-1)**(((1-(-1)**($a*2**(32-6)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-6)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-6)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-6)%(2**32-1)))/2))))/(-2))/2)*2**6+
((1+((-1)**(((1-(-1)**($a*2**(32-7)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-7)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-7)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-7)%(2**32-1)))/2))))/(-2))/2)*2**7+
((1+((-1)**(((1-(-1)**($a*2**(32-8)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-8)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-8)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-8)%(2**32-1)))/2))))/(-2))/2)*2**8+
((1+((-1)**(((1-(-1)**($a*2**(32-9)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-9)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-9)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-9)%(2**32-1)))/2))))/(-2))/2)*2**9+
((1+((-1)**(((1-(-1)**($a*2**(32-10)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-10)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-10)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-10)%(2**32-1)))/2))))/(-2))/2)*2**10+
((1+((-1)**(((1-(-1)**($a*2**(32-11)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-11)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-11)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-11)%(2**32-1)))/2))))/(-2))/2)*2**11+
((1+((-1)**(((1-(-1)**($a*2**(32-12)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-12)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-12)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-12)%(2**32-1)))/2))))/(-2))/2)*2**12+
((1+((-1)**(((1-(-1)**($a*2**(32-13)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-13)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-13)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-13)%(2**32-1)))/2))))/(-2))/2)*2**13+
((1+((-1)**(((1-(-1)**($a*2**(32-14)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-14)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-14)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-14)%(2**32-1)))/2))))/(-2))/2)*2**14+
((1+((-1)**(((1-(-1)**($a*2**(32-15)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-15)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-15)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-15)%(2**32-1)))/2))))/(-2))/2)*2**15+
((1+((-1)**(((1-(-1)**($a*2**(32-16)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-16)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-16)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-16)%(2**32-1)))/2))))/(-2))/2)*2**16+
((1+((-1)**(((1-(-1)**($a*2**(32-17)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-17)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-17)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-17)%(2**32-1)))/2))))/(-2))/2)*2**17+
((1+((-1)**(((1-(-1)**($a*2**(32-18)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-18)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-18)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-18)%(2**32-1)))/2))))/(-2))/2)*2**18+
((1+((-1)**(((1-(-1)**($a*2**(32-19)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-19)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-19)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-19)%(2**32-1)))/2))))/(-2))/2)*2**19+
((1+((-1)**(((1-(-1)**($a*2**(32-20)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-20)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-20)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-20)%(2**32-1)))/2))))/(-2))/2)*2**20+
((1+((-1)**(((1-(-1)**($a*2**(32-21)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-21)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-21)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-21)%(2**32-1)))/2))))/(-2))/2)*2**21+
((1+((-1)**(((1-(-1)**($a*2**(32-22)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-22)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-22)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-22)%(2**32-1)))/2))))/(-2))/2)*2**22+
((1+((-1)**(((1-(-1)**($a*2**(32-23)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-23)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-23)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-23)%(2**32-1)))/2))))/(-2))/2)*2**23+
((1+((-1)**(((1-(-1)**($a*2**(32-24)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-24)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-24)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-24)%(2**32-1)))/2))))/(-2))/2)*2**24+
((1+((-1)**(((1-(-1)**($a*2**(32-25)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-25)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-25)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-25)%(2**32-1)))/2))))/(-2))/2)*2**25+
((1+((-1)**(((1-(-1)**($a*2**(32-26)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-26)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-26)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-26)%(2**32-1)))/2))))/(-2))/2)*2**26+
((1+((-1)**(((1-(-1)**($a*2**(32-27)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-27)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-27)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-27)%(2**32-1)))/2))))/(-2))/2)*2**27+
((1+((-1)**(((1-(-1)**($a*2**(32-28)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-28)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-28)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-28)%(2**32-1)))/2))))/(-2))/2)*2**28+
((1+((-1)**(((1-(-1)**($a*2**(32-29)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-29)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-29)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-29)%(2**32-1)))/2))))/(-2))/2)*2**29+
((1+((-1)**(((1-(-1)**($a*2**(32-30)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-30)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-30)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-30)%(2**32-1)))/2))))/(-2))/2)*2**30+
((1+((-1)**(((1-(-1)**($a*2**(32-31)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-31)%(2**32-1)))/2))+(-1)**(2-(((1-(-1)**($a*2**(32-31)%(2**32-1)))/2)+((1-(-1)**($b*2**(32-31)%(2**32-1)))/2))))/(-2))/2)*2**31;

print "$result\n";

We're DONE!  This program was submitted as a solution to the original challenge.  At this time of this writing I have not been contacted by the original poster concerning the bounty, but I am confident that we have a working program.  Bounty or not, it was an interesting challenge (although I would prefer to collect the bounty :-) ) and a nice creative problem solving exercise.  I'll post updates here when I get them.

We now resume our ASIC Erupter Blade discussion already in progress, thanks for reading...

DP
donation btc: 1HSFkXyLqPv1iHTjcRRw9DgiFb7SftiCxA

UPDATE: I won!  Thanks Evil-Knievel!!!

 

Wednesday, January 29, 2014

The Bounty (Part 2)

In our last article, we discussed how to re-implement the XOR function using standard arithmetic operations and the properties of negative one (-1).  Because negative one (-1) when used as a base and combined with an exponent yields only two values, it was perfectly suited to be adapted for use with a logical function.

Now, we need to step through the individual bits of each of our 32 bit operands in order to feed our XOR function.  Normally we would accomplish this via a RIGHT SHIFT operation implemented either as a logical function ">>" or as division by a power of 2.  In this way we could then move bits of interest to the right  most (2**0) position where determinations of their value could be made by testing whether the resulting operand was even (0) or odd (1).   The TRAP that must be avoided is that without access to integer math, division becomes unavailable as a means to implement our RIGHT SHIFT operation. This is because in floating point math, our discarded bits can never be discarded.  As a part of floating point numbers, whenever we divide our operand to shift its bits to the right, they continue to persist as decimal fractions.  We must find another way.

Programmers are creatures of habit just like everyone else.  While they might be far more likely to attempt right shifting their way through each of the individual bits of our operands, rotate operations are just as valid and easy to program.  The less obvious difference simply that your bits of interest have to be rotated to the ones (2**0) position from the left vs shifted (or rotated) toward the right.

For instance, if you think about a rotate operation across a 4 bit word, take the number 5 (0101) in binary for example... To rotate across a 4 bit word you have to make use of the number 2**4-1, or 15.  Most programmers seeking to test the second bit position (2**1) would prefer to shift right 1 bit by doing an integer divide by 2, yielding 5/2 or 2 (0010).   This moves the 2nd bit to the 2**0 position where it could be tested for eveness or oddness.

The counter-intuitive part is that we can also get the second bit into the last position where we need it using a left rotate.  To accomplish this, we first multiply our operand by 8 (2**3), to shift everything 3 bits to the left:

5*8= 0101 << 3 = 0101000 (40)  
(Because we are shifting left, we must shift 4-1 or 3 bits to the left...)

Next recognize that for a 4 bit word, 2**4= 1 (mod 2**4-1). This means that for every multiple of 2**4 we encounter (basically everything left of the 4th bit position), we are adding 1 (mod 2^4-1) or in other terms, that multiple multiplied by 1 (mod 2**4-1). Thus the number left of the word size accounts for the value of the bits left of 2^4 (mod 2**4-1), while all the bits right of 2**4 are either less than 2**4-1 OR 2**4-1 itself.  (If all the bits right of 2**4 are 1, you can think of that as the same as 0 (mod 2**4-1))

To get the complete modulus (mod 2**4-1), we must first add the multiple of 2**4 (the number to the left of our 4 bit word) to everything mod 2**4  (the number to the right of our 4 bit word or rather our operand & 2**4-1).  In other words:

(40 >> 4) + (40 & 15) = 2+8 = 10 = 1010.

If we check that against the actual 40%(2**4-1) or 40%15 we also get 10.  We have rotated the bit we were interested in to the 2**0 position from the left just as we would have preferred to right shift our way there.  The difference is that opposed to our disposable bit being eaten by integer division, it has appeared at the left of our 4 bit word.

Please note that although the actual value of the word has changed, it doesn't matter from the standpoint of evaluating the now least most significant bit of the operand as being even (0) or odd (1). For this challenge, this means that we can now  step through each bit of both operands to evaluate the xor function in a bitwise fashion.

This part of the problem was potentially the biggest stumbling block because it required programmers to approach its solution from an unconventional direction (left rotates) vs. the approach programmers are most likely acquainted with (right shifts).  Shift left (<< | *2) and shift right (>> | /2) two of the most commonly used tools in the programmer tool box, but sometimes when all you think you have is a hammer, everything else tends to resemble a nail.  

Whether he knew it or not, the original poster gave us the actual tool that we needed; force of habit was probably the reason that many of us (myself included) didn't recognize it as such at first.  In part 3 of this article we will put all of this information together into the program that was finally submitted for the challenge.

Stay tuned.

DP
donation btc: 1HSFkXyLqPv1iHTjcRRw9DgiFb7SftiCxA

Tuesday, January 28, 2014

The Bounty...




This past weekend while reading through the bitcointalk forums, I came across an interesting programming challenge.  It read:

Hello Guys,

What you get:
Bounty of 200$ (either in BTC or wire transfer)

What you need to solve:
Simple (or less simple) algrebraic-only expression of the bitwise XOR operator. Allowed operators: powers, *, /, + and -. Also modulo (2^32-1) is allowed.
During calculation, the numerical limits of 32bit may be exceeded.
Your formula should be applicable to two unsigned integers of 32 bits.

Let the game begin Grin 

Evil-Knievel


XOR, known formally as "eXclusive OR", has always been one of several useful coding tools that programmers over the years could (for the most part) rely upon.   Typically available as a  logical operator in most modern programming languages, long gone have been the days of needing to actually understand the mathematical foundations of the computer logic that powers it.  For most of us, it's usually been sufficient to know "what" our logical functions do versus the "how" they work.

One need not know how a car works to drive it proficiently...

There's certainly nothing wrong with that.  Whether driving your car to work or employing a common logical operator in your own computer programs, one could easily make the case that there are better ways for programmers to spend their time than to figure out the mathematical foundations of the "truth tables" they all learn when first starting to code.  Busy, competitive, and results driven, our world often encourages us to reach our destinations without regard to the "hows" involved.

However, for those who enjoy cars on a level beyond driving them and for those that allow themselves to be as impressed by a tool as by its function, there is both a challenge and a pleasure associated with investigating the "hows" of the tools we take for granted.  There is the opportunity to learn, to accomplish, to challenge oneself and to come to appreciate the problem solving abilities of those who came before us.  Most importantly, (at least in terms of this particular challenge) there is also the opportunity to make $200!

 (Hey, nothing about digital coin mining is cheap and every bit helps!)

In this article we will temporarily interrupt our regularly scheduled blog to discuss the solution I found for this particular programming challenge.  If there is one thing that I've missed from my college years, it's been the analysis and discussion of computer programs and computer programming as a science.  This challenge involved as much math and science as one could ever want to tease their brain with.  In the end, it was a problem that proved to be pleasurable in its resolution.  As of this writing, I haven't gotten paid  (will update here if it happens) but for those who are interested, I have the details below:

The Problem:

To implement a 32 bit XOR function using only the arithmetic operators +,-,/,*,^ and a single modulo operation: mod 2^31-1.

 

The XOR function:

 

Simply stated, the XOR function is a logical operation that accepts 2 binary digits (1 or 0) as input and outputs a single result according to the following truth table:

X Y   xor(X,Y)
0  0       0
1  0       1
0  1       1
1  1       0

One way to think of this table is in the manner that programmers learn to "sound it it out" namely the phrase "X OR Y but not BOTH".  This means that where either input is a 1, and the other input is a 0, the result of the function will be 1, however where the inputs equal each other (X=Y: 1=1 or 0=0) the result of the function will be 0.

In most computer programming languages, we can express this with a simple statement:

X^Y

For a programmer, one doesn't get to be much more spoiled that that!  Using the "^" (exclusive OR) operator, most compilers and interpreters will do a bitwise XOR operation using the variables X and Y.   However to contemplate the distasteful, what if the "^" operator isn't available in the language that you've chosen to program your machine with?  What is a poor programmer to do?

Well before you get that look that people familiar only with driving automatic transmission equipped cars  get just before they get thrown behind the wheel of a manual 5 speed vehicle, I'll tell you exactly what we do:

We go back to the BASICS. We dust off our high school level arithmetic, and boldly march into battle!

If you contemplate high school level arithmetic, by the time most of us graduated, we knew about addition, subtraction, multiplication, division, exponentiation, and remainders.  We learned about numbers with special properties such as 1, 0, and -1.  We learned special identities for each of the mathematical operations.  We learned about undefined numbers and the special circumstances where we might expect to encounter them.  We learned about alternative numbering systems and we learned about how to combine all of these elements into functions such as...

xor(a,b)= (((-1)*((-1)**(a+b)+(-1)**(2-(a+b))) +2)/4

Remember that for logical functions, we make use of the binary number system where the only available digits are zero (0) and one (1).  As a result, we can assume that the only values that the variables a or b will ever contain will be either  0 or 1.  Enumerating all the possible combinations of a and b we can see that the sum of a+b constitutes  a simple OR function:

a  b  a+b  | (or)
0  0   0    0
1  0   1    1
0  1   1    1
1  1   2    1

In other words, the sum of a+b is non zero in all cases except where a=0 and b=0.  We may also notice that the column "a+b" resembles half of the XOR truth table in that when a=0, and b=0, our result becomes 0 (just like our XOR table).  What about the other half of our XOR table where a=1 and b=1 returns an output of 0?  That's a little bit trickier but easily reversed by subtracting the sum of a+b from the number 2.  This will give us a new column in our table where the 0 output we need for our XOR function will appear at the bottom:

a  b  a+b  2-(a+b)
0  0   0       2
1  0   1       1
0  1   1       1
1  1   2       0

This new table is much closer to our target XOR function, but we still need to transform it into a binary compatible output..  By "binary compatible output", our function needs to generate only two values... one or zero.  To accomplish this, we turn to the number (-1).  Looking closely at our revised table, we see not only zeroes in the positions where we need them, but we also see even and the odd numbers in the positions where we might need them.  This is where we can employ the number negative one (-1).  Negative one (-1) is special in that when used as a base, all exponents applied to it yield one of two values depending upon whether the exponent is even or odd.  In the event that the exponent is even, (-1) raised to an even power yields one (1).  Where the exponent is an odd, (-1) raised to an odd power yields negative one (-1).  Applying this understanding, we can revise our table again:

a  b  (-1)**(a+b)  (-1)**(2-(a+b)) sum((-1)**(a+b)+(-1)**(2-(a+b)))
0  0       1            1                         2
1  0      -1           -1                        -2
0  1      -1           -1                        -2
1  1       1            1                         2

Adding the last column which represents the sum of of (-1) raised to the power (a+b) and (-1) raised to the power (2-(a+b)) gives us a function where positive  (+2) represents the cases where either a <> b, and (-2) represents the cases where a=b.  At this point,  we are very close to our desired output.  Multiplying by the last column (-1) and adding 2 we can transform this table again:

a  b (-1)**(a+b) (-1)**(2-(a+b)) (-1)*sum((-1)**(a+b)+(-1)**(2-(a+b))+2
0  0     1           1                    (-1)*(+2)=(-2)+2= 0
1  0    -1          -1                    (-1)*(-2)=(+2)+2= 4
0  1    -1          -1                    (-1)*(-2)=(+2)+2= 4
1  1     1           1                    (-1)*(+2)=(+2)+2= 0

We are now much closer to our desired result.  The only thing left to do to transform this latest output into a binary compatible format (one or zero) is to divide the last column by 4.

a  b  (-1)**(a+b) (-1)**(2-(a+b)) (-1)*sum((-1)**(a+b)+(-1)**(2-(a+b))+2 col+2)/4
0  0      1           1                0/4= 0
1  0     -1          -1                4/4= 1
0  1     -1          -1                4/4= 1
1  1      1           1                0/4= 0

In terms of implementing the XOR function, we're done!  We aren't finished with the entire challenge as given, but we now have the equation that we need to implement the full solution. 

 

The Bitwise XOR:

 

Up until now we have discussed the basic XOR function in which we created a logical function equivalent that could take two binary inputs and output the value we would expect to see from the XOR truth table that we provided at the beginning of the article. We have used addition, multiplication, exponentiation and the properties of (-1) to approximate and manipulate digital values.

In fact, if we were only interested in single bit numbers, we'd be finished.

Our problem however specified that our XOR function would need to work with unsigned 32 bit numbers. Expressed in binary, these are the numbers 2**0 - 2**32-1.  So given that our XOR function only works with single binary digit numbers, how can we go about XOR'ing much larger 32 bit numbers?

We convert our 32 bit inputs to their binary form and XOR their component digits in pairs.  This is most commonly referred to as a bitwise XOR. To state it in simpler terms, the bitwise XOR is nothing more than the binary digits of the input numbers XOR'ed in pairs.

A  : 00000001111011101111000011110000 
B  : 11111111000011100000110000011110
XOR: 11111110111000001111110011101110

In the second part of this article, we'll visit how a programmer typically steps through the individual bits of inputs A and B, then I'll describe how I did it so as to fit within the constraints of the original challenge.

Stay tuned...

DP
donation btc: 1HSFkXyLqPv1iHTjcRRw9DgiFb7SftiCxA

Friday, January 24, 2014

When All Else Fails, Follow the Directions...

When I was a young teenager in high school, my computer science teacher Mr. Wright had a sign in his classroom which he prominently displayed within the plain view of his students.  It read:  "When all else fails, follow the directions."  At the time, those instructions were probably wasted on the classrooms full of 15 year olds he taught, most of whom thought they already knew everything.  In retrospect I go back and forth as to whether Mr. Wright was a quixotic optimist or a wise older sage but as it turned out, my classmates and I really didn't know everything.

Fast forward a few years (ok, more than a few years...) to a newbie bitcoin enthusiast waiting for a recently purchased ASIC Erupter Blade to arrive in the mail.   Rated at 10.7 gigahashes per second, I couldn't wait to install and get it working.  When the blade finally arrived, it was all there: the circuit board, the power adapter, the static bag, and... no instructions.  I'd seen ASIC Eruputer Blades priced from as low as $220 to as much as $600 but never had it occurred to me that such an esoteric technology might come without directions.

Sometimes, life is irony.

Thank goodness for search engines and the internet!  Two weeks, many Google searches and several resolved challenges later, the ASIC Erupter Blade was mining happily, hashing away as advertised.

The focus of this blog is therefore to document my mining adventures with the ASIC Erupter Blade alongside any other mining equipment of interest that I come across.  I also hope to assist you the reader in getting up and running faster by directing you past some of the pitfalls I encountered along the way.  There will be equipment reviews and analyses of my costs and rewards since starting mining. In some cases, I'll even be sharing my programming expertise and some of the code I developed to make my mining rig run more autonomously.

Stay tuned...

DP
donation btc: 1HSFkXyLqPv1iHTjcRRw9DgiFb7SftiCxA