Pages:
Author

Topic: Check if your BTC-key is vulnerable (Read 18272 times)

full member
Activity: 233
Merit: 102
June 28, 2015, 09:50:37 PM
#55
I've fixed the code to loop through the offset (ie get >50 Txs), but the code isn't flagging 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm as a bad key when it's the address IDd as being a bad address.

any idea why?

Code:

Code:

#!/usr/bin/python

#https://gist.github.com/a8fecbfc619e2c72893d
#################################################################################
#                                                                               #
#.______               _______.  ______     ___      .__   __.                  #
#|   _  \             /       | /      |   /   \     |  \ |  |                  #
#|  |_)  |    ______ |   (----`|  ,----'  /  ^  \    |   \|  |                  #
#|      /    |______| \   \    |  |      /  /_\  \   |  . `  |                  #
#|  |\  \----.    .----)   |   |  `----./  _____  \  |  |\   |                  #
#| _| `._____|    |_______/     \______/__/     \__\ |__| \__|  v0.2.0          #
#                                                                               #
#GNU PL - 2015 - ca333  (modified by simcity4242)     #
#                                                                               #
#USE AT OWN RISK!                                                               #
#################################################################################

import json
import urllib2
import time
import sys

#for some reason blockchain.info api-chain is 59711 blocks short..
#blockstart = 170399
#blockstart += 59711
#blockcount = urllib2.urlopen("https://blockchain.info/en/q/getblockcount").read()

def rscan(addr):
"""Check address for duplicated r values."""
# TODO: add BCI API check address

print "WELCOME TO R-scan v0.1.2!"
print "ADDRESS-R-SCAN: "

urladdr = 'https://blockchain.info/address/%s?format=json&offset=%s'

###control api-url
#print str(urladdr[:-22] % addr)

addrdata = json.load(urllib2.urlopen(urladdr % (addr, '0')))
ntx = addrdata['n_tx']
print "Data for pubkey: " + str(addr) + " has " + str(addrdata['n_tx']).center(6) + "Tx%s" % 's'[ntx==1:]
#print "number of txs: " + str(addrdata['n_tx'])

#tx-details:

txs = []
for i in range(0, ntx//50 + 1):
sys.stderr.write("Fetching Txs from offset\t%s\n" % str(i*50))
jdata = json.load(urllib2.urlopen(urladdr % (addr, str(i*50))))
txs.extend(jdata['txs'])

assert len(txs) == ntx
addrdata['txs'] = txs


y = 0
inputs = []
while y < ntx:
#print "#################################################################################"
#print "TX nr :" + str(y+1)
#print "hash: " + str(addrdata['txs'][y]['hash'])
#print "number of inputs: " + str(addrdata['txs'][y]['vin_sz'])
#only if
#if addrdata['txs'][y]['vin_sz'] > 1:
zy = 0
while zy < addrdata['txs'][y]['vin_sz']:
#print "Input-ScriptNR " + str(zy+1) + " :" + str(addrdata['txs'][y]['inputs'][zy]['script'])
inputs.append(addrdata['txs'][y]['inputs'][zy]['script'])
zy += 1
y += 1

xi = 0
zi = 1
lenx = len(inputs)
alert = 0

bad = []
#compare the sig values in each input script
while xi < lenx-1:
x = 0
while x < lenx-zi:
if inputs[xi][10:74] == inputs[x+zi][10:74]:
#print "In Input NR: " + str(xi) + "[global increment] " + str(inputs[xi])
#print('\a')
print "Resued R-Value: "
print inputs[x+zi][10:74]
bad.append((int(x), str(inputs[x+zi][10:74])))
alert += 1
x += 1
zi += 1
xi += 1

#check duplicates
#alert when everything ok

if alert < 1:
print "Good pubKey. No problems."
else:
print "Address %s has %d reused R value%s!" % (addr, len(bad), "s"[len(bad)==1:])
return bad

if __name__ == '__main__':
from sys import argv
print """python rscan.py 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm"""
if len(argv) == 1:
addr = raw_input("Enter Bitcoin address eg 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm")
elif len(argv) == 2 and isinstance(argv[1], basestring):
addr = str(argv[1])
rscan(addr)

# 9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1


 
full member
Activity: 122
Merit: 100
June 24, 2015, 10:37:22 PM
#54
hero member
Activity: 521
Merit: 522
Developer - EthicHacker - BTC enthusiast
June 21, 2015, 03:10:22 AM
#53
[...]

The script working good but some problem more then a 50 transaction it not process

address: 1szVke6ThJtfdUTi6Y5AAMDMePM4Ha8vK

output

Resued R-Value: 262e481b6d8905b5adba67aff05eb8261501b0a9434c0b7f043d00cf8d23c91b
----------------------------------------------------------------------------------------------------------------------
if address: 1QCRoj5dPAsADvzd2o7NBy6kywBEkfC1Xh

output

compare:

Good pubKey. No problems.
------------------------------------------------------------------------------------------------------------------------
if address: 1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm

output

TX nr :51
Traceback (most recent call last):
  File "C:\master\identical-r-check.py", line 61, in
    print "hash: " + str(addrdata['txs'][y]['hash'])
IndexError: list index out of range
------------------------------------------------------------------------------------------------------------------------
1BFhrfTTZP3Nw4BNy4eX4KFLsn9ZeijcMm -> this address reused r value but the script give error how to solve , if any solved script available

you must use offset to load ALL data.
I posted on previous page:

interesting feedback from person on reddit when I shared this script (I wrote an article on my own site to archive this script and talk about it and share it with others who aren't on here)  and it goes like:

Quote
There's a problem with either the script or the blockchain.info api where the number of tx field doesn't match the actual number of tx sent.
In other words,
Code:
assert( len(addrdata['txs']) < addrdata['n_tx'] )
fails.


The script only works for keys with up to 50 tx. If your key got more than 50 tx you have to add some lines (add loop and use optional API-parameters limit and offset to parse through all transactions [50+]).

yes but i writed this in the first post (see above comment), so its only for max 50 tx. when it s more you must adapt the script because it takes the information from blockchain.info and example its more 50 tx, but only loading 50 tx data from bc.info API, then it parses outside range of loaded data. this is the error. i hope you understand. when you need adaption of script write me. i am happy to help you anytime.
thank you.
 Yea I'd like to see the for loop if possible to choose trx size

hello sory i don't see yours reply so waited so long. excuse me.
ok i post pseudocode hope you can add it with python in fact only little work:
full script i write in coming weeks. #EDIT: overload with RL-work. will sit on extension soon.

Code:
x=0
y=0
z = getTXnr(); //get total number of transactions
n = z%50 //modulo operater so we know the number of tx in last page [b]when its < 50 TX[/b]
m = (z-n)/50 //this is so we know HOW MANY TIMES we have A FULL PAGE (50 tx)

//also we need adapt the urladdr because now we take MORE THAN 50 txs. so we use offset parameter for going through pages.
for y < m:
      compare(loadData("https://blockchain.info/de/rawaddr/" + str(addr) + "&offset="+ x)) //now it load the TX begining @x tx.      
      x+=50; //now we go to NEXT 50 tx.. offset=50 means we ingnore first 50 txs.. or we start @TX NR 51..
      y+=1;

compare(loadData("https://blockchain.info/de/rawaddr/" + str(addr) + "&offset="+ x)); //now it take the LAST TXs from the LAST PAGE
//IMPORTANT: in the compare section of the script you MUST ONLY PARSE n transactions


This is the example of above pseudocode with REAL values in it. so you see every loops job and what is happening here exact:


Code:
//now REAL example with value: so we think for a [b]tx with 138 TXs[/b]
x = 0 //first offset we start @tx NR. 0
y = 0 //our counter for increment
z = 138 //number of total TX
n = 38  //138 modulo 50 = 38 rest
m = 2  //number of FULL pages with 50 TXs

//1st run of loop:

for 0 < 2:
     compare(loadData(blockchain_data(offset=0))); //we start at TX 0 and get data until TX nr. 50
     x=50

//2nd run of loop:

for 1 < 2:
     compare(loadData(blockchain_data(offset=50))); //we start at TX 50 and get data until TX nr. 100
     x=100

//now we leave foor-loop and compare the LAST txs (n)

compare(loadData(blockchain_data(offset=100))); // here its only important so you PARSE ONLY n transaction in the compare-part of the script.
//so for this is the n needed.



have a good sunday evening.
thank you.
ca333


I write again: THIS SCRIPT ONLY WORK FOR MAX 50tx. If you want more, you must use algorithm from above i published in previous page.
Please read all posting in this thread. then its all clear.

thank you,
ca333





It looks like addrdata isn't large enough, simply a buffer overflow.  Does print "number of txs: " + str(addrdata['n_tx'])  output a value larger than 50? I suggest printing y, addrdata['n_tx'] and the other values. It's a multidimensional array and one of them is out of range, meaning the array is not large enough to store values there.

yes because data is NOT LOADED from blockchain. so script parses out of range ==> "overflow" (from array)
hero member
Activity: 672
Merit: 508
LOTEO
June 12, 2015, 06:22:21 AM
#52
sr. member
Activity: 381
Merit: 250
June 12, 2015, 06:21:25 AM
#51
omg, this is really interesting and i didnt saw it before, ty so much for share it man!!

i will try it as soon as i come to my house.
newbie
Activity: 16
Merit: 1
June 12, 2015, 05:50:43 AM
#50
sr. member
Activity: 271
Merit: 250
June 08, 2015, 06:02:56 AM
#49
thanks very much for sharing....
very interesting..
hero member
Activity: 672
Merit: 508
LOTEO
June 04, 2015, 04:15:07 AM
#48
Interesting script, going to have a closer look at this later. You probably want to do this line of code in two steps:
Code:
addrdata = json.load(urllib2.urlopen(urladdr))
to verify that data is received. But as you said it's beta version Smiley

An improvement would be an auto checker, that simply extracts the bitcoin addresses from the wallet files at runtime and uses them as input.
hero member
Activity: 521
Merit: 522
Developer - EthicHacker - BTC enthusiast
June 04, 2015, 04:07:44 AM
#47
This software is great, but does not provide any value to the users.
I am pretty sure, that reused R values will be detected within milliseconds and the private keys emptied immediately.
So if your funds are gone, you have reused a R value ;-)

not "any" because low balance keys are not interested for bad guys. i provided this for testing/educational purposes.
if i find out it makes harm to users/btc-community i will delete all. also the services i finded out have rng vuln i directly
imported balance and contacted developers. i think nobody with exsisting btc-service have rng issue anymore. also all pubkeys with more 50BTC or more balance are secured.

and i extra only provided a lightweight script. so with this technology (json request http) no chance to scan fast. if ported into ansic and used on highend server with own blockchain i can scan/compare all chain inputs in no time. but i think this people who are able to do this, have a moral compass and do not do this... badguys most cases are not very inteligent.


also if anybody interested in more things i start soon release my scriptbase and software on github. (ca333)
it s all for btc-security and some cryptocurrencies security.

thank you.



Hats off to you for not being like most others. Many others with your skillset would use their talent for malicious intentions, it takes a real human to use their talents for honesty.

thank you for positive feedback. i think we, as human, and as technical skilled community, must try to make it better place, RL and virtual world. and only when "you behave like you want also other to behave" (= form of categorical imperative from Immanuel Kant) the society and community we living in, will move into good ("moral and ethical correct") direction... for my opinion we must fight bad malicious things and not make more harm for others.. karma is existent.

thank you
ca333
legendary
Activity: 1051
Merit: 1000
https://r.honeygain.me/XEDDM2B07C
June 03, 2015, 06:16:12 AM
#46
This software is great, but does not provide any value to the users.
I am pretty sure, that reused R values will be detected within milliseconds and the private keys emptied immediately.
So if your funds are gone, you have reused a R value ;-)

not "any" because low balance keys are not interested for bad guys. i provided this for testing/educational purposes.
if i find out it makes harm to users/btc-community i will delete all. also the services i finded out have rng vuln i directly
imported balance and contacted developers. i think nobody with exsisting btc-service have rng issue anymore. also all pubkeys with more 50BTC or more balance are secured.

and i extra only provided a lightweight script. so with this technology (json request http) no chance to scan fast. if ported into ansic and used on highend server with own blockchain i can scan/compare all chain inputs in no time. but i think this people who are able to do this, have a moral compass and do not do this... badguys most cases are not very inteligent.


also if anybody interested in more things i start soon release my scriptbase and software on github. (ca333)
it s all for btc-security and some cryptocurrencies security.

thank you.



Hats off to you for not being like most others. Many others with your skillset would use their talent for malicious intentions, it takes a real human to use their talents for honesty.
newbie
Activity: 16
Merit: 1
June 02, 2015, 06:24:53 AM
#45
http://bitcoin.stackexchange.com/questions/37740/same-identical-r-value-of-all-transaction-not-provide-corresponding-privatekey

Same identical R value of all transaction not provide corresponding privatekey


https://blockchain.info/tx/9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1

transaction you get

R = d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1

S1 = 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e

S2 = 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab

Z1 = c0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e

Z2 = 17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc

z = 7a1a7e52797fc8caaa435d2a4dace39158504bf204fbe19f14dbb427faee50ae

private key = c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96

but the other transaction not providing corresponding private key

with same identical R value = d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1

https://blockchain.info/tx/47106ff70bf779efc32230f5ca956d0fc563f35a3c4395d1977fc38995327fe1

https://blockchain.info/tx/00b4dea9266283d93f35240f34b871b55e59c3d4a7705aa08d5745af398d9046

https://blockchain.info/tx/d6f071e082ebb8c7c7721a9019d7478489e3fd423cae6acabdbd2ffd28f5c300

https://blockchain.info/tx/83415dded4757181c6e1c55104e2742a6f8cff05a9a46fbf029ae47b0054d511

https://blockchain.info/tx/2bd15366f5bcc2046c480db4d6ad82450893f2a3370935ddee753325f1a7c6cc

https://blockchain.info/tx/e96feca9744b95533a5a3f657c346d7772a5004a76f4bc8de810b7ad015f6440

https://blockchain.info/tx/5a994f485039ebd83a0ed22cae943f0c792d85d218884f4cd80bd7cccdd75aae
legendary
Activity: 1974
Merit: 1077
^ Will code for Bitcoins
April 23, 2015, 01:44:30 AM
#44
how to get ( sop1 & sop2 ) these two value,
any formula or any script available...........

Not too easy. You should have good lib for bitcoin transactions to create "a template" and take a sha256d () of it.
Here is a piece of my code. But it will be useless for you. Just a pseudo-code

Code:
const MyKey32 Transaction::getRawHash ( const int n, const QByteArray& scr ) const
{
  MyByteArray ret;                                     // create empty array
  Stream stream ( s );                               
  ret.putInt32 ( stream.readU32 ( ) );                 // version
  ret.putVarInt ( stream.readVar ( ) );                // input count
  for ( int i ( 0 ); i < inputs; i++ )                 // copy all inputs
  {
    ret.append ( stream.readHash ( ) );                // copy 32 byte hash as is
    ret.putInt32 ( stream.readU32 ( ) );               // copy 4 bytes index
    stream.skipVarData ( );                            // skip original script
    ret.putPrefixedCond ( i ^ n, scr );                // script replacement
    ret.putInt32 ( stream.readU32 ( ) );
  }
  ret.putVarInt ( stream.readVar ( ) );                // output count
  for ( int i ( 0 ); i < outputs; i++ )                // copy all outputs byte-by-byte
  {
    ret.putInt64 ( stream.readU64 ( ) );
    ret.putPrefixed ( stream.readVarData ( ) );
  }
  ret.putInt32 ( stream.readU32 ( ) );                 // lock
  ret.putInt32 ( SIGHASH_ALL );                        // append hashcode
  return MyKey32 ( ret.constData ( ), ret.size ( ) );  // create hash256 of array
}

Thank you

http://bitcoin.stackexchange.com/questions/25387/how-to-get-the-z-value-aka-hash-of-the-outputs-to-be-signed

http://bitcoin.stackexchange.com/questions/25814/ecdsa-signature-and-the-z-value

http://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx

here i get explanation, i almost understand but not clear, i need step by step explanation please...

After this things will be clearer:

https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/
newbie
Activity: 16
Merit: 1
April 22, 2015, 09:07:46 PM
#43
how to get ( sop1 & sop2 ) these two value,
any formula or any script available...........

Not too easy. You should have good lib for bitcoin transactions to create "a template" and take a sha256d () of it.
Here is a piece of my code. But it will be useless for you. Just a pseudo-code

Code:
const MyKey32 Transaction::getRawHash ( const int n, const QByteArray& scr ) const
{
  MyByteArray ret;                                     // create empty array
  Stream stream ( s );                               
  ret.putInt32 ( stream.readU32 ( ) );                 // version
  ret.putVarInt ( stream.readVar ( ) );                // input count
  for ( int i ( 0 ); i < inputs; i++ )                 // copy all inputs
  {
    ret.append ( stream.readHash ( ) );                // copy 32 byte hash as is
    ret.putInt32 ( stream.readU32 ( ) );               // copy 4 bytes index
    stream.skipVarData ( );                            // skip original script
    ret.putPrefixedCond ( i ^ n, scr );                // script replacement
    ret.putInt32 ( stream.readU32 ( ) );
  }
  ret.putVarInt ( stream.readVar ( ) );                // output count
  for ( int i ( 0 ); i < outputs; i++ )                // copy all outputs byte-by-byte
  {
    ret.putInt64 ( stream.readU64 ( ) );
    ret.putPrefixed ( stream.readVarData ( ) );
  }
  ret.putInt32 ( stream.readU32 ( ) );                 // lock
  ret.putInt32 ( SIGHASH_ALL );                        // append hashcode
  return MyKey32 ( ret.constData ( ), ret.size ( ) );  // create hash256 of array
}

Thank you

http://bitcoin.stackexchange.com/questions/25387/how-to-get-the-z-value-aka-hash-of-the-outputs-to-be-signed

http://bitcoin.stackexchange.com/questions/25814/ecdsa-signature-and-the-z-value

http://bitcoin.stackexchange.com/questions/3374/how-to-redeem-a-basic-tx

here i get explanation, i almost understand but not clear, i need step by step explanation please...
legendary
Activity: 1260
Merit: 1019
April 22, 2015, 03:06:19 AM
#42
how to get ( sop1 & sop2 ) these two value,
any formula or any script available...........

Not too easy. You should have good lib for bitcoin transactions to create "a template" and take a sha256d () of it.
Here is a piece of my code. But it will be useless for you. Just a pseudo-code

Code:
const MyKey32 Transaction::getRawHash ( const int n, const QByteArray& scr ) const
{
  MyByteArray ret;                                     // create empty array
  Stream stream ( s );                               
  ret.putInt32 ( stream.readU32 ( ) );                 // version
  ret.putVarInt ( stream.readVar ( ) );                // input count
  for ( int i ( 0 ); i < inputs; i++ )                 // copy all inputs
  {
    ret.append ( stream.readHash ( ) );                // copy 32 byte hash as is
    ret.putInt32 ( stream.readU32 ( ) );               // copy 4 bytes index
    stream.skipVarData ( );                            // skip original script
    ret.putPrefixedCond ( i ^ n, scr );                // script replacement
    ret.putInt32 ( stream.readU32 ( ) );
  }
  ret.putVarInt ( stream.readVar ( ) );                // output count
  for ( int i ( 0 ); i < outputs; i++ )                // copy all outputs byte-by-byte
  {
    ret.putInt64 ( stream.readU64 ( ) );
    ret.putPrefixed ( stream.readVarData ( ) );
  }
  ret.putInt32 ( stream.readU32 ( ) );                 // lock
  ret.putInt32 ( SIGHASH_ALL );                        // append hashcode
  return MyKey32 ( ret.constData ( ), ret.size ( ) );  // create hash256 of array
}
newbie
Activity: 16
Merit: 1
April 22, 2015, 12:55:50 AM
#41
p    = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
r    = 0xd47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1
s1   = 0x44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e
s2   = 0x9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab

sop1 = 0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e
sop2 = 0x17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc

how to get ( sop1 & sop2 ) these two value,

any formula or any script available...........
hero member
Activity: 521
Merit: 522
Developer - EthicHacker - BTC enthusiast
April 09, 2015, 08:33:16 AM
#40
Wow, I didn't think it would be possible to calculate the private key just from a reused value. So when transactions are normally cast, is the r value recalculated?

Yes.
CMIIW I believe the latest wallets (eg. core 0.10) are all using deterministic signatures to make sure the R values are unique for each transaction.


yes it s possible when you use redundant signature values. but its new libsecp256k1 library from sipa (Pieter Wuille) use deterministic generation of k value. so its sure signing value is unique. this is updated 13 day ago: https://github.com/bitcoin/bitcoin/commit/223d8630b0bf1809d29660004255237ad9d15f86

you can read the details for the BIP 0032 here with full explanation: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
also must mention Gregory Maxwell gave advice for BIP extension: http://www.archivum.info/mailcatch/2013-08/00364/(Bitcoin-development)-BIP-32.5.html
hero member
Activity: 882
Merit: 1000
Exhausted
April 09, 2015, 07:08:19 AM
#39
Wow, I didn't think it would be possible to calculate the private key just from a reused value. So when transactions are normally cast, is the r value recalculated?

Yes.
CMIIW I believe the latest wallets (eg. core 0.10) are all using deterministic signatures to make sure the R values are unique for each transaction.
legendary
Activity: 1540
Merit: 1001
Crypto since 2014
April 09, 2015, 06:11:00 AM
#38
Wow, I didn't think it would be possible to calculate the private key just from a reused value. So when transactions are normally cast, is the r value recalculated?
legendary
Activity: 1140
Merit: 1000
The Real Jude Austin
April 03, 2015, 06:37:12 PM
#37
Does anyone have a version that can handle more than 50 transactions?

I am working on it now lol
member
Activity: 87
Merit: 10
March 18, 2015, 08:43:44 PM
#36
Thank you for providing this tool it is very useful.
Pages:
Jump to: