Advertisement
Guest User

Untitled

a guest
Sep 7th, 2014
313
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.41 KB | None | 0 0
  1. # This is a proposal to eliminate the need for OP_RETURN to relay
  2.  
  3. # First lets take an utxo that we own and try to send it to a stealth address.
  4.  
  5. # Info of utxo:
  6.  
  7. prev_hash = 'f3ebd0b3534518c23f439aac836ff207d6414b6530aecf1e0fff1d413774f994'
  8. vout = '06' # The 7th output.
  9. amount = 0.03170609 # in BTC
  10.  
  11. # The address I am using to send from in this example is 1FHxvwCfFz3B1VZSAQa71qWGyDbxdfamh4
  12.  
  13.  
  14. # Normally, this is where we would generate an ephemeral pubkey.
  15. # But instead, the sender, having entered the password for signature, reveals the private key
  16. # to the above address.
  17.  
  18. privkey = Decrypt(encrypted_privkey) # lets assume privkey is in bigint format.
  19.  
  20. shared_secret = ECmultiply(privkey, scan_pubkey) # scan_pubkey of recipient
  21. shared_secret_priv = sha256(shared_secret)
  22. shared_secret_pub = ECmultiply(shared_secret_priv, SECP256k1_generator_point)
  23.  
  24. # We have in effect, used the senders key as the ephemeral key. Since the pubkey must be
  25. # included in the ScriptSig, the recipient can know the shared secret without
  26. # the tx looking obviously like a stealth transaction.
  27.  
  28. # Here is where I thought: Oh, but if I send more bitcoins from the same address to the
  29. # same stealth address... the resulting send_to address will be the same! address reuse! OMG
  30.  
  31. # Now comes the solution. We take the hash of concatenated scan_pubkey, prev_hash and vout
  32. # This becomes the privkey for a 3rd point.
  33.  
  34.  
  35. vout_priv = sha256((scan_pubkey + prev_hash + vout).decode('hex'))
  36. vout_pub = ECmultiply(vout_priv, SECP256k1_generator_point)
  37.  
  38.  
  39. # Now we have 3 points: Scan_pubkey, shared_secret_pub, and vout_pub.
  40. # Add all three together.
  41.  
  42. address_point = ECaddition(ECaddition(scan_pubkey, shared_secret_pub), vout_pub)
  43. # As ECadd is communicative, order of addition doesnt matter
  44.  
  45. send_to_address = Base58CheckEncode(ripemd160(sha256(address_point)))
  46.  
  47. # create the output sending to the above address. Sending is finished.
  48.  
  49.  
  50. # For the recipient:
  51. # First, lets assume he knows what tx is to him from some outside source.
  52. # (I will mention the search method later)
  53.  
  54. # He searches the ScriptSig of each input for any pubkeys, and tries them in order.
  55. # (normal p2kh will have 1 pubkey per input)
  56.  
  57. # He notices the pubkey of the first input (which is prev_hash)
  58.  
  59. pubkey = '0309430d1bea1b90a59523f2892cd26084808394ce5cc7ea4b6ecbec0a63480c8c'
  60.  
  61. shared_secret = ECmultiply(scan_privkey, pubkey) # pubkey from ScriptSig x scan_privkey
  62. shared_secret_priv = sha256(shared_secret)
  63.  
  64. # Then he looks at the vout index and prevhash used in the input.
  65.  
  66. vout_priv = sha256((scan_pubkey + prev_hash + vout).decode('hex'))
  67.  
  68. send_to_address_priv = (scan_privkey + shared_secret_priv + vout_priv) % N # Mod order of the curve.
  69.  
  70. send_to_address_pub = ECmultiply(send_to_address_priv, SECP256k1_generator_point)
  71.  
  72. send_to_address_test = Base58CheckEncode(ripemd160(sha256(address_point)))
  73.  
  74. assert send_to_address_test == send_to_address
  75.  
  76. # If the addresses are equal, then you now have the private key,
  77. # and the only information necessary was the txid.
  78.  
  79.  
  80.  
  81. """
  82. Lets talk about performance:
  83.  
  84. If we look at the procedures for send and receive with the old OP_RETURN
  85. method (I left out simple things like adding bigints and modding the order of the curve etc.)
  86.  
  87. Old send   : ECmult > sha256 > ECmult > ECadd > sha256 > ripemd160
  88. ECmult x 2
  89. ECadd x 1
  90. sha256 x 2
  91. ripemd160 x 1
  92.  
  93. Old receive: ECmult > sha256 > ECmult > sha256 > ripemd160
  94. ECmult x 2
  95. sha256 x 2
  96. ripemd160 x 1
  97.  
  98.  
  99. Looking at the New method I explained above and comparing:
  100.  
  101. New send   : ECmult > sha256 > ECmult > sha256 > ECmult > ECadd > ECadd > sha256 > ripemd160
  102. ECmult x 3
  103. ECadd x 2
  104. sha256 x 3
  105. ripemd160 x 1
  106. Compare: Increase of 1 of each (ECmult, ECadd, sha256)
  107.  
  108. New receive: ECmult > sha256 > sha256 > ECmult > sha256 > ripemd160
  109. ECmult x 2
  110. sha256 x 3
  111. ripemd160 x 1
  112. Compare: Increase of 1 sha256
  113.  
  114. The heavy lifting is on the receiving end (as you must now iterate through every single ScriptSig
  115. and compare against all output addresses.) but luckily the receiving calculcations only increased by one sha256.
  116.  
  117. To narrow down the txes you need to search... I was wondering if the input that was used to generate the address
  118. could change the sequence (the one that is normally 0xffffffff at the end of each input) to hash to the prefix...
  119. or even match the sequence msb bits to the prefix bits etc.
  120.  
  121.  
  122.  
  123. I would like to hear any comments / questions.
  124.  
  125. - dabura667
  126.  
  127. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement