bsip-1203: Detailed deterministic offset computation.

This commit is contained in:
Christopher Sanborn 2018-10-03 13:40:22 -04:00
parent 87525f2496
commit 4383ef74a7

View file

@ -4,7 +4,7 @@
Status: Draft
Type: Protocol
Created: 2018-01-29
Discussion: <url>
Discussion: https://github.com/bitshares/bsips/issues/91
## Abstract
@ -78,11 +78,71 @@ The dual-key format separates the duties of spending a commitment from those of
#### Procedure for single-key stealth addresses (CT-style)
We assume the address encodes public key _A_, and that the wallet owner is in posession of (_A_, _a_), where _a_ is the corresponding private key.
Recognizability depends on there being a deterministic relationship between the AuthKey that authorizes expenditure of a particular cTXO, the one-time key (OTK) that the sender generated randomly for the cTXO, and the recipient's Address key (or keys).
We assume that the stealth address encodes public keys corresponding to two purposes: discovery, and expenditure. When an address encodes only one public key, that key is used for both purposes. We refer to the key for discovery as the "view" key, and denote the private, public pair as _(v, ViewKey)_. For spending, we denote the key pair as _(s, SpendKey)_.
The AuthKey for a cTXO is an EC point summation of the address's SpendKey and an EC point "offset," which, for present purposes we will denote by the private, public pair _(o, Offset)_, with _Offset = o*G_.
&nbsp; _AuthKey &nbsp;=&nbsp; SpendKey &nbsp;+&nbsp; Offset_
Anonymity is preserved so long as only the sender and the receiver are able to compute _o_ and _Offset_. The algorithm for computing _Offset_ is a deterministic function of the OTK and ViewKey only, (and not the SpendKey). This allows the the recipient to recover the SpendKey by simple subtraction of _Offset_ from the AuthKey and compare against a list of SpendKeys that the wallet may have used to generate an address family with a common ViewKey. (See _[address-per-invoice](#utility-of-dual-key-addresses)_ below.)
Algorithm | Description / Specification
:---:|:---------------------------
_Shared(a,B)&nbsp;&rarr;&nbsp;secret <br> Shared(A,b) &rarr; secret_ | This yields a "shared secret" between public keys _A_ and _B_ computable only by parties possessing at least one of the private keys _a_ and _b_.<br><br>&nbsp; _secret = SHA512(P<sub>X</sub>)_; &nbsp; &nbsp; _P = aB = Ab_<br><br>For BitShares Stealth, the secret is a byte buffer (64 bytes) computed from the SHA512 hash of the encoded _X_ coordinate (32 bytes) of EC point _P_. (c.f. [EC Diffie-Hellman](https://en.wikipedia.org/wiki/Elliptic-curve_DiffieHellman).)
_ChildOffset(B,index)&nbsp;&rarr;&nbsp;offset_ | This yields an integer-valued private key _offset_ that generates the keypair _(offset, Offset = offset*G)_. The offset is considered to be a "child" of key _B_, and the parameter _index_ is a byte buffer.<br><br>&nbsp; _child = BigInteger(SHA256(Compressed(B)_ &vert;&vert; _index))_<br><br>_Compressed(B)_ refers to the SEC1 "compressed" representation of public key _B_. The &vert;&vert; symbol refers to concatenation.
**Sending:**
The sender's procedure for computing the offset and generating the AuthKey for the cTXO is detailed as follows:
<ol>
<li> Compute a "shared secret" between between the sender and receiver:
_secret = Shared(otk, ViewKey)_
</li>
<li> Compute the OffsetKey as a child of the ViewKey, indexed by the shared secret:
_offset = ChildOffset(ViewKey,secret)_<br>
_OffsetKey = offset*G_
</li>
<li> Compute the AuthKey by summing SpendKey and OffsetKey:
_AuthKey = SpendKey + OffsetKey_
</li>
</ol>
**Receiving:**
The receiver, having acquired a list of cTXO metadata that includes _OTK_ and _AuthKey_, goes through the following process to test for ownership:
<ol>
<li> Compute a "shared secret" between between the sender and receiver:
_secret = Shared(OTK, viewpriv)_
</li>
<li> Compute the OffsetKey as a child of the ViewKey, indexed by the shared secret:
_offset = ChildOffset(ViewKey,secret)_<br>
_OffsetKey = offset*G_
</li>
<li> Recover the public SpendKey by subtracting OffsetKey from AuthKey:
_SpendKey = AuthKey - OffsetKey_
</li>
<li> Compare the recovered SpendKey against all wallet SpendKeys that may have been used with the ViewKey to generate an address. If one matches, then the cTXO is "recognized." To later spend the cTXO, the wallet computes the private authorization key as:
_authpriv = spendpriv + offset_
</li>
</ol>
Thus, a wallet may undertake to periodically download and scan the metadata for Stealth transactions and test for outputs that can recover a wallet's public SpendKey from knowledge of the private ViewKey.
##### Embedding recognizability data in the transaction
For the recipient to recognize a cTXO as their own, the cTXO need only to encode two items: 1.) The one-time PubKey (OTK) that the sender generated for shared-secret generation, and, 2.) the authorization PubKey (AuthKey) of the cTXO. Because the AuthKey is computed deterministically from _Shared(OTK,AddrKey)_, it stands that if the recipient can generate the same AuthKey, then the cTXO belongs to them.
For the recipient to have the practical ability to recognize a cTXO as their own, the cTXO, as recorded on the blockchain, must include the following two items: 1.) The one-time PubKey (OTK) that the sender generated for shared-secret generation, and, 2.) the authorization PubKey (AuthKey) of the cTXO. Because the AuthKey is computed deterministically from _Shared(OTK,AddrKey)_, it stands that if the recipient can generate the same AuthKey, and thereby determine that the cTXO belongs to them.
The structure of a cTXO is as follows:
@ -109,12 +169,6 @@ _Field_ | _Purpose_
_(TODO: How is this serialized? Do omitted fields "take up space"? Can fields be chosen a la carte? How hard will it be to extend this memo format, for, say, multiple assets in the case of CA? See fc::raw::pack.)_
#### Procedure for dual-key stealth addresses (CryptoNote-style)
##### Embedding recognizability data in the transaction
##### Detecting inbound transaction (dual-key)
### API Requirements to Allow Detection of Inbound Commitments