https://telegra.ph/Recovering-private-keys-using-weak-signatures-from-the-blockchain-04-06 Recovering private keys using weak signatures from the blockchain Lets have a look at this transaction: transaction: 9ec4bc49e828d924af1d1029cacf709431abbde46d59554b62bc270e3b29c4b1 input script 1: 30440220d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1022044e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e0104dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff input script 2: 30440220d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad102209a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab0104dbd0c61532279cf72981c3584fc32216e0127699635c2789f549e0730c059b81ae133016a69c21e23f1859a95f06d52b7bf149a8f2fe4e8535c8a829b449c5ff This transactions contains two inputs and one output. You will notice there are equal bytes at the start and at the end. The bytes at the end is the hex-encoded public key of the address spending the coins - nothing wrong with that. But, the first half of the script is the actual signature (r, s): r1: d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1 r2: d47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1 s1: 44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e s2: 9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab You can see, r1 equals r2. This is quite a problem because now we are able to recover the private key to this public key: private key = (z1*s2 - z2*s1)/(r*(s1-s2)) Yes, its that easy. We setup our sage notebook like this: p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 r = 0xd47ce4c025c35ec440bc81d99834a624875161a26bf56ef7fdc0f5d52f843ad1 s1 = 0x44e1ff2dfd8102cf7a47c21d5c9fd5701610d04953c6836596b4fe9dd2f53e3e s2 = 0x9a5f1c75e461d7ceb1cf3cab9013eb2dc85b6d0da8c3c6e27e3a5a5b3faa5bab z1 = 0xc0e2d0a89a348de88fda08211c70d1d7e52ccef2eb9459911bf977d587784c6e z2 = 0x17b0f41c8c337ac1e18c98759e83a8cccbc368dd9d89e5f03cb633c265fd0ddc p is just the order of G, a parameter of the secp256k1 curve used by Bitcoin. We create a field for the calculations: K = GF(p) Converted into a more suitable format: hex: c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96 WIF: 5KJp7KEffR7HHFWSFYjiCUAntRSTY69LAQEX1AUzaSBHHFdKEpQ Now we import it to your favourite Bitcoin wallet. It’ll calculate the correct bitcoin address and we’ll be able to spend coins sent to this address. The reason why this works? ECDSA requires a random number for each signature. If this random number is ever used twice within the same private key it can be recovered. This transaction was generated by a hardware bitcoin wallet using a pseudo-random number generator that was returning the same “random” number every time. I wrote a little script dec 2019, but this "feature" is still quite untapped. It parses the blockchain, looking for conspicuous inputscripts containing those weak signatures I described. You may want to download it here: https://sharebox.ai/54375c70353ead96cecbb216a2933cd8 Have fun!