Difference between revisions of "Proof of work"

From Bitmessage Wiki
Jump to navigation Jump to search
(updated for Protocol V3)
 
Line 1: Line 1:
This page describes Bitmessage's Proof of work ("POW") mechanism as it currently exists. In this document, hash() means SHA512(). SHA512 was chosen as it is widely supported and so that Bitcoin POW hardware cannot trivially be used for Bitmessage POWs. The author acknowledges that they are essentially the same algorithm with a different key size.
+
This page describes Bitmessage's Proof of work ("POW") mechanism as it exists in Protocol Version 3. In this document, hash() means SHA512(). SHA512 was chosen as it is widely supported and so that Bitcoin POW hardware cannot trivially be used for Bitmessage POWs. The author acknowledges that they are essentially the same algorithm with a different key size.
  
averageProofOfWorkNonceTrialsPerByte is set by the owner of a Bitmessage address. The default and minimum is 320. (This is the same as difficulty 1. If the difficulty is 2, then this value is 640).
+
Both averageProofOfWorkNonceTrialsPerByte and payloadLengthExtraBytes are set by the owner of a Bitmessage address. The default and minimum for each is 1000. (This is the same as difficulty 1. If the difficulty is 2, then this value is 2000). The purpose of payloadLengthExtraBytes is to add some extra weight to small messages.
 
 
payloadLengthExtraBytes is set by the owner of a Bitmessage address. The default and minimum is 14000. The purpose of this value is to add some extra weight to small messages. If the user sets the small message difficulty to 2, then this value is doubled.  
 
  
 
=== Do a POW ===
 
=== Do a POW ===
Line 9: Line 7:
 
Let us use a msg message as an example.
 
Let us use a msg message as an example.
  
     payload = embeddedTime + encodedStreamNumber + encrypted
+
     payload = embeddedTime + encodedObjectVersion + encodedStreamNumber + encrypted
 +
 
 +
    payloadLength = the length of payload, in bytes, + 8 (to account for the nonce which we will append later)
 +
 
 +
    TTL = the number of seconds in between now and the object expiresTime.
  
     target = 2^64 / ((length of the payload in bytes  +  payloadLengthExtraBytes + 8) * averageProofOfWorkNonceTrialsPerByte)
+
     [[File:POW forumla 2.png|none|caption]]
  
 
     initialHash = hash(payload)
 
     initialHash = hash(payload)
Line 21: Line 23:
 
     while trialValue > target:
 
     while trialValue > target:
 
         nonce = nonce + 1
 
         nonce = nonce + 1
         resultHash = hash(hash( nonce + initialHash ))
+
         resultHash = hash(hash( nonce || initialHash ))
 
         trialValue = the first 8 bytes of resultHash, converted to an integer
 
         trialValue = the first 8 bytes of resultHash, converted to an integer
  
Line 36: Line 38:
 
     initialHash = hash(dataToCheck)
 
     initialHash = hash(dataToCheck)
  
     resultHash = hash(hash( nonce + initialHash ))
+
     resultHash = hash(hash( nonce || initialHash ))
  
 
     POWValue = the first eight bytes of resultHash converted to an integer
 
     POWValue = the first eight bytes of resultHash converted to an integer
  
     target = 2^64 / ((length of payload  + payloadLengthExtraBytes) * averageProofOfWorkNonceTrialsPerByte)
+
     TTL = the number of seconds in between now and the object expiresTime.
 +
 
 +
    [[File:POW forumla 2.png|none|caption]]
  
 
If POWValue is less than or equal to target, then the POW check passes.
 
If POWValue is less than or equal to target, then the POW check passes.

Latest revision as of 21:46, 17 October 2014

This page describes Bitmessage's Proof of work ("POW") mechanism as it exists in Protocol Version 3. In this document, hash() means SHA512(). SHA512 was chosen as it is widely supported and so that Bitcoin POW hardware cannot trivially be used for Bitmessage POWs. The author acknowledges that they are essentially the same algorithm with a different key size.

Both averageProofOfWorkNonceTrialsPerByte and payloadLengthExtraBytes are set by the owner of a Bitmessage address. The default and minimum for each is 1000. (This is the same as difficulty 1. If the difficulty is 2, then this value is 2000). The purpose of payloadLengthExtraBytes is to add some extra weight to small messages.

Do a POW

Let us use a msg message as an example.

   payload = embeddedTime + encodedObjectVersion + encodedStreamNumber + encrypted
   payloadLength = the length of payload, in bytes, + 8 (to account for the nonce which we will append later)
   TTL = the number of seconds in between now and the object expiresTime.
caption
   initialHash = hash(payload)

start with trialValue = 99999999999999999999

also start with nonce = 0 where nonce is 8 bytes in length and can be hashed as if it is a string.

   while trialValue > target:
       nonce = nonce + 1
       resultHash = hash(hash( nonce || initialHash ))
       trialValue = the first 8 bytes of resultHash, converted to an integer

When this loop finishes, you will have your 8 byte nonce value which you can prepend onto the front of the payload. The message is then ready to send.

Check a POW

Let us assume that 'payload' contains the payload for a msg message (the nonce down through the encrypted message data).

   nonce = the first 8 bytes of payload
   dataToCheck = the ninth byte of payload on down (thus it is everything except the nonce)
   initialHash = hash(dataToCheck)
   resultHash = hash(hash( nonce || initialHash ))
   POWValue = the first eight bytes of resultHash converted to an integer
   TTL = the number of seconds in between now and the object expiresTime.
caption

If POWValue is less than or equal to target, then the POW check passes.