Hey all,
I stumbled upon a pretty intriguing case related to the Bitcoin address "1LN4yp6rQALjwg53SKsi44teq1fp2v5wqR", which reused the same nonce k in two separate transactions signed with the same private key.
Transaction 1: 65278a3cf6d4710bd5a556edeb6854e07de0324a5008569e33984da491df8c38
R = 00b42646001435ec60a40982735c4e73d31be13d0086be394eaf5ce10b0f38f689
S = 711a12a1a4db96159ec5760f2201beeb04043efc3d39e10ba17c9e66816ff9ad
Z = 91002245c37eba47e4f5764f0c4780b3cd9ba0f3ea709368cfd21717d82be496
Transaction 2: d87d1bc2d41ed867f0f4b7b7ee9915f09cb82477388e306acac8279146edacb8
R = 00b42646001435ec60a40982735c4e73d31be13d0086be394eaf5ce10b0f38f689
S = 5c55551c5a2348d32107f4c7174c9a90aa9621c927326f1e4294432192589f3d
Z = c47a2f11de95b92b65ee72082eda621ee681faf6e9abc64597325523f7d76202
The r value (identical in both signatures) is 00b42646001435ec60a40982735c4e73d31be13d0086be394eaf5ce10b0f38f689.
Seems like RFC 6979, which is the standard for deterministic k generation, wasn’t applied here. This address is kinda famous.
So I’m curious:
Can we figure out how k was created in this case (like if it was a weak PRNG, based on timestamps, or something else)? And is there a chance we could recreate the same k if we make the right assumptions?
how was k chosen in this case
2 replies 280 views
Unless r has an obvious value (eg. 1*G) it is going to be very difficult to guess how it was chosen.
The only method is to use a search engine to see where the address/transaction is mentioned and see the reason there.
In the past when any of these broken keys were found, the owner is asked what wallet they were using and by analyzing the behavior and/or looking at its source code the broken part was found. For example when the users said they were using blockchain.info the source code was analyzed and it was found that they were using random.org to generate the ephemeral key and the site was returning an error message which the app still used as input which ended up being the same for everyone!
Surprisingly the way to generate the k from 1LN4yp6rQALjwg53SKsi44teq1fp2v5wqR doesn't seems weak.
This my method to say that
Step 1 :
recovered every tx signed by 1LN4yp6rQALjwg53SKsi44teq1fp2v5wqR (total sent136 BTC!!!!)
Step2 :
identified the two input where r==b42646001435ec60a40982735c4e73d31be13d0086be394eaf5ce10b0f38f689
Step 3:
recovered k for this two input with nonce reused formula
this is the secret recovered:
But 1 sample of k is too low to see a patern or some biased entropy so I made the assumption that every k was generate with the same (probably) weak RNG.
Step 4:
recovered every k for 1LN4yp6rQALjwg53SKsi44teq1fp2v5wqR (priv = 28608884601749819904852249207473436882265395560722309163084982020290971201593) with this formula
there is 675 different k for 1LN4yp6rQALjwg53SKsi44teq1fp2v5wqR
removed the one of the two b42646001435ec60a40982735c4e73d31be13d0086be394eaf5ce10b0f38f689 duplicate ( not to false entropy)
Step 5 : used a bunch of rng testing statiscal test from this google github repo on the list of k:
http://[code]https://github.com/google/paranoid_crypto[/code]
this is the result of the tests (p values)
(0.7526555431379823, 'Frequency')
(0.8922205625150528, 'LongestRuns')
(0.17401029065157583, 'Runs')
(0.09841635668060003, 'BinaryMatrixRank')
(0.133636, 'LargeBinaryMatrixRank_64_*_64')
(0.711212, 'LargeBinaryMatrixRank_128_*_128')
(0.711212, 'LargeBinaryMatrixRank_256_*_256')
(0.13004210277109796, 'OverlappingTemplateMatching')
(0.9204344990860858, 'UniversalImpl1')
(0.7418997106144236, 'UniversalImpl2')
(0.9851583654051379, 'LinearComplexity_dist')
(0.32331377641368286, 'LinearComplexity_extreme')
(0.5797307681237995, 'ApproximateEntropy_0')
(0.7235022428413989, 'ApproximateEntropy_1')
(0.6577288253868533, 'ApproximateEntropy_2')
(0.49821641104893855, 'ApproximateEntropy_3')
(0.6156687031532114, 'ApproximateEntropy_4')
(0.45974516471567906, 'ApproximateEntropy_5')
(0.21884604607320576, 'ApproximateEntropy_6')
(0.2414807578348784, 'ApproximateEntropy_7')
(0.15020972293729182, 'ApproximateEntropy_8')
(0.18459092265541552, 'Spectral')
(0.4303553446832167, 'RandomWalk_0')
(0.7000550793665439, 'RandomWalk_1')
(0.7229207109153853, 'LatticeFindBias')
!! A bad p_value indicating a weakness had to very low (for ex 10e-7)
this is not the case here.. :
NB:The latest test is the more important and perform a Lattice Reduction with samples of k. It is very powerful to identify a bias in a lcg and in a lot of weak prng (according to this docs of the library :https://github.com/google/paranoid_crypto/blob/main/docs/ecdsa_signature_tests.md
Related topics
- Bitcoin Core displaying coins (UTXOs) in a new tab 13
- Are you in favor of BIP-110? Let's get a Bitcoin poll going. 0
- Erlay seems to have some issues here’s a better proposal for a bitcoin protocol without invites 3
- New Optional Hourglass Implementation is Live 3
- Ways to earn some sats by contributing to bitcoin core development 5
- Exploring the Potential and Challenges of a Kardashev-Scale Bitcoin Network 3