Bitcoin Forum
May 05, 2024, 11:29:10 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 »  All
  Print  
Author Topic: What is the status of the stealth addresses?  (Read 2797 times)
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
April 30, 2014, 01:11:13 PM
Last edit: April 30, 2014, 01:30:00 PM by piotr_n
 #1

I'm kind of bored recently and even though I was never very enthusiastic about the stealth addresses, it still seems to be the most exciting feature to add to my wallet software.
I know that there are all kind of mailing lists with less and more outdated specs flying around, but since I don't monitor them, could anyone please update me on the most recent status?

Today I have been playing with DarkWallet a bit and from what I see each wallet there has by default one stealth address assigned to it.
I also figured out what this address represents.
For all I know, there are two public keys - one is to encrypt the message (nonce or whatever it is called), while the other one is there to calculate the actual destination for the coins that are being spent.

So, for instance, I got an address vJmyoyfHgvkW2fRbqpANQircWiWDFMHtzyUxbcGsnUCX6z1jEjfArypDBNMeQdmsczkLVoSwYRZ5pS8 YAxxQY7Q2m8SUXB2sZWjB6q - it decodes to:
Code:
2a - version
00 - options
03b5ca63d7bda5b8f70a68864fafa0587e446c52be23150da2b95ad9d6f3e6f71f - scan_pubkey
01 - number of spend keys
0351bec154c01c4f26794da8b0a3019b163b633ea933387f48288ed35cbc833f53 - spend pubkey 1
01 - number sigs
00 - prefix_length
b3fe7b1a - standard checksum of the address

Now, I want to extend my wallet so it would be able to send coins to such an address.
How do I build the transaction?

Is there any spec that I can read?
Any actually working code that makes a transaction which sends money to such an address?

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
1714908550
Hero Member
*
Offline Offline

Posts: 1714908550

View Profile Personal Message (Offline)

Ignore
1714908550
Reply with quote  #2

1714908550
Report to moderator
"Bitcoin: the cutting edge of begging technology." -- Giraffe.BTC
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1714908550
Hero Member
*
Offline Offline

Posts: 1714908550

View Profile Personal Message (Offline)

Ignore
1714908550
Reply with quote  #2

1714908550
Report to moderator
sickpig
Legendary
*
Offline Offline

Activity: 1260
Merit: 1008


View Profile
April 30, 2014, 07:42:17 PM
 #2

I'm kind of bored recently and even though I was never very enthusiastic about the stealth addresses, it still seems to be the most exciting feature to add to my wallet software.
I know that there are all kind of mailing lists with less and more outdated specs flying around, but since I don't monitor them, could anyone please update me on the most recent status?

Today I have been playing with DarkWallet a bit and from what I see each wallet there has by default one stealth address assigned to it.
I also figured out what this address represents.
For all I know, there are two public keys - one is to encrypt the message (nonce or whatever it is called), while the other one is there to calculate the actual destination for the coins that are being spent.

So, for instance, I got an address vJmyoyfHgvkW2fRbqpANQircWiWDFMHtzyUxbcGsnUCX6z1jEjfArypDBNMeQdmsczkLVoSwYRZ5pS8 YAxxQY7Q2m8SUXB2sZWjB6q - it decodes to:
Code:
2a - version
00 - options
03b5ca63d7bda5b8f70a68864fafa0587e446c52be23150da2b95ad9d6f3e6f71f - scan_pubkey
01 - number of spend keys
0351bec154c01c4f26794da8b0a3019b163b633ea933387f48288ed35cbc833f53 - spend pubkey 1
01 - number sigs
00 - prefix_length
b3fe7b1a - standard checksum of the address

Now, I want to extend my wallet so it would be able to send coins to such an address.
How do I build the transaction?

Is there any spec that I can read?
Any actually working code that makes a transaction which sends money to such an address?

https://en.bitcoin.it/wiki/Sx/Stealth
http://sx.dyne.org/

Bitcoin is a participatory system which ought to respect the right of self determinism of all of its users - Gregory Maxwell.
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
April 30, 2014, 09:05:01 PM
 #3

I tried that today but cannot get this sx tool to build on my Ubuntu.
So I cannot execute these commands.

Also I'm curious about the encryption part and how the actual transaction looks inside.
I guess there is some extra null output with this encrypted nonce.

I'm asking about a format of a stealth payment transaction - is such thing even defined yet?

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
Abdussamad
Legendary
*
Offline Offline

Activity: 3612
Merit: 1564



View Profile
May 01, 2014, 04:29:45 AM
 #4

I tried that today but cannot get this sx tool to build on my Ubuntu.
So I cannot execute these commands.

Yeah, common problem. Try this script instead:

https://github.com/mastercoin-MSC/install-msc/blob/master/res/install-sx.sh

Ref: https://bitcointalk.org/index.php?topic=259999.msg6099554#msg6099554
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 01, 2014, 09:03:47 AM
Last edit: May 01, 2014, 03:43:07 PM by piotr_n
 #5

I tried that today but cannot get this sx tool to build on my Ubuntu.
So I cannot execute these commands.

Yeah, common problem. Try this script instead:

https://github.com/mastercoin-MSC/install-msc/blob/master/res/install-sx.sh

Ref: https://bitcointalk.org/index.php?topic=259999.msg6099554#msg6099554
Thanks, but this one didn't solve it.
Other issues. Seems to need boost 1.49 when my OS has 1.46. After changing the script to use 1.46, still crashes on building getx_responder.lo

EDIT:
nvm, took me a few hours, but somehow managed to build it already.
but it doesn't even seem to support the "New stuff" so it doesn't really help me.

EDIT2:
Found it: https://wiki.unsystem.net/index.php/DarkWallet/Stealth
Smiley

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 01, 2014, 07:40:32 PM
 #6

OK. It seems that I have a proof of concept software that I am able to run and use as a reference.
Now, if someone could please advise me...
This function (that's javascrip from the darkwallet):
Code:
// Simple NAF (Non-Adjacent Form) multiplication algorithm
// TODO: modularize the multiplication algorithm
function pointFpMultiply(k) {
    if(this.isInfinity()) return this;
    if(k.signum() == 0) return this.curve.getInfinity();

    var e = k;
    var h = e.multiply(new BigInteger("3"));

    var neg = this.negate();
    var R = this;

    var i;
    for(i = h.bitLength() - 2; i > 0; --i) {
R = R.twice();

var hBit = h.testBit(i);
var eBit = e.testBit(i);

if (hBit != eBit) {
   R = R.add(hBit ? this : neg);
}
    }

    return R;
}

It seems to multiply this(x,y,z) point, by a big int k - to return R(x,y,z)

Non-Adjacent Form - right, that explains a lot! Wink
Except that I have no idea what it means Smiley

Anyway, such a function had not been used for anything else in Bitcoin before - had it?
I mean, I need to code it in, if I want my wallet to be able to send coins to stealth addresses - right?

Is there some simpler (less optimized) version of such a function?
One that would operate solely on big-int arithmetic, instead of this for/if/bit/add stuff?
Just so I'd be able to understand what it actually does and the actual math behind it.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
caedes
Newbie
*
Offline Offline

Activity: 44
Merit: 0


View Profile
May 02, 2014, 03:30:36 PM
 #7

The sx implementation uses an old spec, we just published some more information about how we do it in darkwallet:

https://bitcointalk.org/index.php?topic=592518.0

We have some test vectors in our unit tests, check the above link, i can provide you test vectors in a different format if you so prefer.

I would say is the status now is need to make a spec but it should be production ready (the stealth address idea), we have it working in real world and seems to work as advertised.
caedes
Newbie
*
Offline Offline

Activity: 44
Merit: 0


View Profile
May 02, 2014, 03:33:10 PM
 #8

OK. It seems that I have a proof of concept software that I am able to run and use as a reference.

Anyway, such a function had not been used for anything else in Bitcoin before - had it?
I mean, I need to code it in, if I want my wallet to be able to send coins to stealth addresses - right?

Is there some simpler (less optimized) version of such a function?
One that would operate solely on big-int arithmetic, instead of this for/if/bit/add stuff?
Just so I'd be able to understand what it actually does and the actual math behind it.

That's elliptic curve point multiplication, you should have a library in your language of preference taking care of that.
caedes
Newbie
*
Offline Offline

Activity: 44
Merit: 0


View Profile
May 02, 2014, 05:05:38 PM
 #9

Also, bip32 code may be doing similar calculations.
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 03, 2014, 10:44:31 AM
Last edit: May 03, 2014, 02:17:47 PM by piotr_n
 #10

That's elliptic curve point multiplication, you should have a library in your language of preference taking care of that.
That is what I had initially thought, but the thing is that for the example test vector:
Code:
X = f46a67e20804f956a1ce64566d96a42658a9a7a4c9a0be924615bef881a4a3f2
Y = 3a8218cdf4156c60585f5721189289cc89500eab79480a109eb1d0684e560996
k = 84e5f7d329c3dab1160dbf9cb0b1a3c82e6058c06260f4101b1660b865ce98c5

... the JS function returns:
Code:
x = eb8d6a5c12e70b0d5e05336e9103318e89ca4445004afc3640d3e47e488a4d0f
y = 8fabd090eade40104431906d3bc0c25d988270aa017bfa8ce3707c0d72649571

while the EC multiplication k*(x,y) that I have here would return:
Code:
x = 61537944f9b1245a76be6bf1d49e5ea0aa44a9a4da657c7b04598c702b440db8
y = f96de684e701f3bc48ef2e86a2e9e0be122b741331b926023ab346a82e81b8e9

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 03, 2014, 02:17:36 PM
Last edit: May 06, 2014, 08:31:23 AM by piotr_n
 #11

That's elliptic curve point multiplication, you should have a library in your language of preference taking care of that.
That is what I had initially thought, but the thing is that for the example test vector:
[...]

sorry, never mind - I was printing wrong values.
didn't realize that pub.x.x is not the actual x.
what a sucker I am Smiley

now everythign makes much more sense.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
caedes
Newbie
*
Offline Offline

Activity: 44
Merit: 0


View Profile
May 04, 2014, 05:04:48 AM
 #12


now everythign makes much more sense.

Cool, keep us updated!
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 05, 2014, 02:34:42 PM
Last edit: May 05, 2014, 03:05:16 PM by piotr_n
 #13

I'm still a bit confused, to be honest.
I wanted to use DW to send some money to my own stealth addresses, just to see how it works.
But my transactions have been pending for days already, so I am now trying to send it myself, using my own s/w.

Anyway, please explain me one thing. I have a stealth address with two public keys: scanKey and spendKey - I want to send some coins there.
So what I would do is:

1. I pick up a secret C - some random 32 bytes

2. Do I have to do anything with C here???

3. I calculate C*scanKey - and put it inside the first null-ouptut, like this:
Code:
6a2606 <4_random_bytes> <compressed(C*scanKey)>

4. I calculate C*spenKey - and use it in the next output (one that actually spends the coins):
Code:
76a914 <hash160(C*spenKey)> 88ac

5. I sign and broadcast the transaction.


In general it seems pretty clear, but the devil is in the details.
Obviously I want my txs to be compatible with the existing solution (not just with my own), so I have these questions:
1. Do I need to do anything with my random C, between point 1 and 3?
2. You have this StealthDH() function that takes X from a result of EC multiplication, prefixes it with 03 and then does sha256 on it - at which point is it actually used?
3. The 4 random bytes in point 3 - are they just random, or what?

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
dabura667
Sr. Member
****
Offline Offline

Activity: 475
Merit: 252


View Profile
May 05, 2014, 07:13:41 PM
Last edit: May 05, 2014, 07:27:43 PM by dabura667
 #14

I'm still a bit confused, to be honest.
I wanted to use DW to send some money to my own stealth addresses, just to see how it works.
But my transactions have been pending for days already, so I am now trying to send it myself, using my own s/w.

Anyway, please explain me one thing. I have a stealth address with two public keys: scanKey and spendKey - I want to send some coins there.
So what I would do is:

1. I pick up a secret C - some random 32 bytes

2. Do I have to do anything with C here???

3. I calculate C*scanKey - and put it inside the first null-ouptut, like this:
Code:
6a2606 <4_random_bytes> <compressed(C*scanKey)>

4. I calculate C*spenKey - and use it in the next output (one that actually spends the coins):
Code:
76a914 <hash160(C*spenKey)> 88ac

5. I sign and broadcast the transaction.


In general it seems pretty clear, but the devil is in the details.
Obviously I want my txs to be compatible with the existing solution (not just with my own), so I have these questions:
1. Do I need to do anything with my random C, between point 1 and 3?
2. You have this StealthDH() function that takes X from a result of EC multiplication, prefixes it with 03 and then does sha256 on it - at which point is it actually used?
3. The 4 random bytes in point 3 - are they just random, or what?


You are getting mixed up.

First let's see what you have to do first to send to a stealth address:

1. check the checksum! (convert from base58 to hex, strip last 4 bytes, SHA256 twice, compare first 4 bytes with checksum, if match then continue)
2. check if mainnet
3. check version byte (not used)
4. check N (number of keys for multisig)
5. check required number of sigs (for multisig)

6. create a new pub/priv keypair (lets call its pubkey "ephemkey" and privkey "e")
7. IF there is a prefix in the stealth address, brute force a nonce such that SHA256(nonce.concate(ephemkey)) first 4 bytes are equal to the prefix. IF NOT, then just run through the loop once and pickup a random nonce. (probably make the while condition include "or prefix = null" or something to that nature.
8. Once you have the nonce and the ephemkey, you can create the first output, which is
Code:
OP_RETURN <nonce:4bytes> <ephemkey:33bytes>
9. Now use ECC multiplication to calculate e*Q where Q = scan_pubkey and e = privkey to ephemkey and then hash it.
10. That hash is now "c". use ECC multiplication and addition to calculate D + (c*G) where D = spend_pubkey, and G is the reference point for secp256k1. This will give you a new pubkey. (we'll call it D')
11. Create a normal P2KH output spending to D' as public key.
12. make the tx with the two outputs from #8 and #11 and broadcast it. (Don't forget to create any change outputs you need!)

Edit: I forgot to say, if it is multisig, then repeat #10 for every spend_pubkey, A becomes A' B becomes B' etc... then take all the pubkeys from A' B' C' D' etc etc. and make a p2sh multisig address. Then in step 11 create normal P2SH output to multisig. so with multisig only #10 and #11 will change. everything else is same.

My Tip Address:
1DXcHTJS2DJ3xDoxw22wCt11FeAsgfzdBU
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 05, 2014, 08:03:07 PM
 #15

That's very useful - thanks!

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 06, 2014, 12:17:45 AM
 #16

I think it works. Smiley

Just one more question.

When you say "brute force a nonce such that SHA256(nonce.concate(ephemkey)) first 4 bytes are equal to the prefix" - what if the prefix is not 4 bytes long?

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
dabura667
Sr. Member
****
Offline Offline

Activity: 475
Merit: 252


View Profile
May 06, 2014, 02:56:45 AM
Last edit: May 06, 2014, 04:06:32 AM by dabura667
 #17

I think it works. Smiley

Just one more question.

When you say "brute force a nonce such that SHA256(nonce.concate(ephemkey)) first 4 bytes are equal to the prefix" - what if the prefix is not 4 bytes long?
If it is not than 4. The only difference is the first x bytes must match the prefix of a length x / 8 rounded up.

Also remember that prefix_length is in bits, so to get the number of bytes to compare you must take x / 8 rounded up.

Edit: sorry for all the edits, i just woke up...

Sorry last edit I swear.

Here's the function for comparing the hash with the prefix.

https://github.com/darkwallet/darkwallet/blob/42bb91761555c078f386be2ff6f61f7c033c60f0/js/util/stealth.js
Stealth.checkPrefix is the function.

The function at the very bottom is the loop to brute force the prefix.

My Tip Address:
1DXcHTJS2DJ3xDoxw22wCt11FeAsgfzdBU
genjix
Legendary
*
expert
Offline Offline

Activity: 1232
Merit: 1072


View Profile
May 06, 2014, 04:39:25 AM
 #18

https://wiki.unsystem.net/index.php/Install_entire_toolchain

https://wiki.unsystem.net/index.php/Sx/Stealth

https://wiki.unsystem.net/index.php/DarkWallet/Stealth
piotr_n (OP)
Legendary
*
Offline Offline

Activity: 2053
Merit: 1354


aka tonikt


View Profile WWW
May 06, 2014, 08:30:36 AM
Last edit: May 06, 2014, 09:00:59 AM by piotr_n
 #19

@dabura667
cheers.
so the prefix length cannot be bigger than 32 bits?
and if it was all 32 bits, but I could not find a matching nonce - what then? pick up a different "ephemkey"?


@genjix
yeah, I had gone through these specs.
none of them was even close to be as useful as one post from dabura667 Smiley

btw, building the tools on my old ubuntu 12.04 was a real fight.
first I needed gcc 4.7 (I had 4.6)
then leveldb version was apparently too old
and libbboost - I also had to upgrade this one to 1.49.
the biggest problem was that the errors I saw did not help much to diagnose the problems.
the second biggest: this version of ubuntu would not just upgrade any of these packages in a simple way.

Check out gocoin - my original project of full bitcoin node & cold wallet written in Go.
PGP fingerprint: AB9E A551 E262 A87A 13BB  9059 1BE7 B545 CDF3 FD0E
ShadowOfHarbringer
Legendary
*
Offline Offline

Activity: 1470
Merit: 1005


Bringing Legendary Har® to you since 1952


View Profile
May 06, 2014, 09:14:10 AM
 #20

I'm kind of bored recently and even though I was never very enthusiastic about the stealth addresses, it still seems to be the most exciting feature to add to my wallet software.
I know that there are all kind of mailing lists with less and more outdated specs flying around, but since I don't monitor them, could anyone please update me on the most recent status?

Today I have been playing with DarkWallet a bit and from what I see each wallet there has by default one stealth address assigned to it.
I also figured out what this address represents.
For all I know, there are two public keys - one is to encrypt the message (nonce or whatever it is called), while the other one is there to calculate the actual destination for the coins that are being spent.

So, for instance, I got an address vJmyoyfHgvkW2fRbqpANQircWiWDFMHtzyUxbcGsnUCX6z1jEjfArypDBNMeQdmsczkLVoSwYRZ5pS8 YAxxQY7Q2m8SUXB2sZWjB6q - it decodes to:
Code:
2a - version
00 - options
03b5ca63d7bda5b8f70a68864fafa0587e446c52be23150da2b95ad9d6f3e6f71f - scan_pubkey
01 - number of spend keys
0351bec154c01c4f26794da8b0a3019b163b633ea933387f48288ed35cbc833f53 - spend pubkey 1
01 - number sigs
00 - prefix_length
b3fe7b1a - standard checksum of the address

Now, I want to extend my wallet so it would be able to send coins to such an address.
How do I build the transaction?

Is there any spec that I can read?
Any actually working code that makes a transaction which sends money to such an address?

Offtopic: It is nice to finally see you taking matter in your own hands instead of walking around and complaining.

Respect.

Pages: [1] 2 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!