X11 Possible Nonce Vulnerability...

darrenturn90

New Member
Dec 13, 2014
3
1
3
verters com slash blockcheck

tl;dr - it seems that 90% or more of blocks have a nonce value divisible by 256. Can this be confirmed? If so, it essentially means that only mining nonce values divisible by 256 will yield a far greater chance of finding blocks.
 
  • Like
Reactions: GilAlexander

crowning

Well-known Member
May 29, 2014
1,415
1,997
183
Alpha Centauri Bc
verters com slash blockcheck

tl;dr - it seems that 90% or more of blocks have a nonce value divisible by 256. Can this be confirmed? If so, it essentially means that only mining nonce values divisible by 256 will yield a far greater chance of finding blocks.
No idea if that's true, however I've a script running right now which checks this.

Will probably run the complete night to parse the complete blockchain, but I'll report back tomorrow.

Gotta catch some sleep now :)
 

darrenturn90

New Member
Dec 13, 2014
3
1
3
No probs.
Remember, to account for blocks that have a very low difficulty - as they throw the equation off.
 

UdjinM6

Official Dash Dev
Dash Core Team
Moderator
May 20, 2014
3,639
3,537
1,183
did a check for the last 50K blocks
http://pastebin.com/zeUSNLN6
~2% for Darkcoin

EDIT: for anyone interested, here is fixed code (using correct port/library)

PHP:
<?php
// this code uses EasyBitcoin a PHP Wrapper API for the JSON RPC interface
require_once('easybitcoin.php');
$coin = new Bitcoin('darkcoind','password','localhost','9998');
$blockCount = $coin->getblockcount();
$blockHistory = array();
$i = 0;

for($blockID=$blockCount; $blockID>$blockCount-50000; $blockID--) {
    // get block hash
    $blockHash = $coin->getblockhash($blockID);

    // get block
    $block = $coin->getblock($blockHash);
    $blockHistory[$blockID] = $block["nonce"];
}

file_put_contents(dirname(__FILE__) . "/nonce2.json",json_encode($blockHistory));

?>
PHP:
<?php
$nonceDB = json_decode(file_get_contents(dirname(__FILE__) . "/nonce2.json"),true);
$groups3 = array();

foreach($nonceDB as $height => $nonce) {
    $val = $nonce % 256;
    if (!isset($groups3[$val])) $groups3[$val] = 0;
    $groups3[$val]++;
}

asort($groups3);

print_r($groups3);
?>
you'll need this also
Code:
wget https://raw.githubusercontent.com/aceat64/EasyBitcoin-PHP/master/easybitcoin.php
and curl lib for php
Code:
sudo apt-get install php5-curl
 
Last edited by a moderator:

darrenturn90

New Member
Dec 13, 2014
3
1
3
So the nonces are more divisible by 256... but not by much relative to the entire batch. However, there is still a slight pattern there.
 

crowning

Well-known Member
May 29, 2014
1,415
1,997
183
Alpha Centauri Bc
So the nonces are more divisible by 256... but not by much relative to the entire batch. However, there is still a slight pattern there.
I did the same test for the last 10000 Bitcoin blocks, and here nonces divisible by 256 are also leading, but with 0.47% way closer to the theoretically expected value. Darkcoin has 2.748%.
 

maky

Member
Nov 14, 2014
71
32
58
How it can be a problem? We all will be using nonce divisible by 256 and chances for all will be equall again. ;)
 
  • Like
Reactions: vertoe

crowning

Well-known Member
May 29, 2014
1,415
1,997
183
Alpha Centauri Bc
Yeah, but only if someone notices the community about that pattern.... oh wait! *recompiles his miners*
Also thought about this...but you'd have to solo-mine.

The pools just count the number of your shares, not their quality, so most of the (already small) advantage will go away.
 

UdjinM6

Official Dash Dev
Dash Core Team
Moderator
May 20, 2014
3,639
3,537
1,183
Yeah, but only if someone notices the community about that pattern.... oh wait! *recompiles his miners*
Also thought about this...but you'd have to solo-mine.

The pools just count the number of your shares, not their quality, so most of the (already small) advantage will go away.
I agree with this but it would be interesting to see mh/s comparison of two versions though - will be there any boost in share calculation?
//Still thinking of CPU/GPU internal hardware optimizations nonce like this could hit...//
 

crowning

Well-known Member
May 29, 2014
1,415
1,997
183
Alpha Centauri Bc
I agree with this but it would be interesting to see mh/s comparison of two versions though - will be there any boost in share calculation?
//Still thinking of CPU/GPU internal hardware optimizations nonce like this could hit...//
For the shits and giggles I just build a miner which only uses "nonce mod 256 = 0" nonces, the pool seems to accept them, but I can't see a change in the hash-rate at the pool (and that's what counts).

I'll let it run over night and see what happens...
 
  • Like
Reactions: UdjinM6

moocowmoo

Bovine Bit-flipper
Foundation Member
Jun 15, 2014
483
603
263
masternode.me
Dash Address
XmoocowYfrPKUR6p6M5aJZdVntQe71irCX
ran the numbers. not seeing it.

Low diff or high diff, the numbers don't show an exploitable skew.
Code:
for all 186118 blocks, if nonce mod 'power of 2' == 0, increment value below:
2: 102581,
4: 60053,
8: 39145,
16: 27066,
32: 20272,
64: 13299,
128: 8389,
256: 5120,
512: 2616,
1024: 1382,
2048: 767,
4096: 450,
8192: 294,
16384: 237,
32768: 221,
65536: 214,
131072: 99,
262144: 57,
524288: 25,
1048576: 13,
2097152: 6,
4194304: 4,
8388608: 3,
16777216: 2,
33554432: 2

the code I used: (qnd)

Code:
(echo "[" ; for blocks in `seq 1 \`darkcoind getblockcount\`` ; do echo -n '{' ; darkcoind getblock $(darkcoind getblockhash $blocks) | egrep 'height|difficulty|nonce' | tr "\n" " " | sed -e 's/, $//g' ;  echo '},' ; done ; echo "]" ) | tee nonce_values.json
then I edited nonce_values.json to remove the last trailing comma, then ran this.

Code:
#!/usr/bin/python

import json
from pprint import pprint

modulii = dict()
mod_values = list(map((lambda x: 2**x), range(1,32)))


def parse_nonce(nonce):
    results = []
    for mod in mod_values:
        if nonce < mod:
            continue
        remainder = nonce % mod
        if remainder == 0:
            modulii[mod] = modulii.get(mod, 0) + 1
        results.append((mod,remainder))
    return results


with open('nonce_values.json') as f:
    j= json.load(f)

results=[]
count = 0
for nonce in j:
    count += 1
    results.append(parse_nonce(nonce['nonce']))

pprint(count)
pprint(modulii)
quit()
(results array has the full mod/remainder breakdown if anybody's interested in further analysis.)

Happy hacking! :)

EDIT: updated the source extraction for easier adding of difficulty exclusions
 
Last edited by a moderator: