Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TRC102: Hierarchical Deterministic Wallets #102

Closed
Federico2014 opened this issue Oct 28, 2019 · 4 comments
Closed

TRC102: Hierarchical Deterministic Wallets #102

Federico2014 opened this issue Oct 28, 2019 · 4 comments

Comments

@Federico2014
Copy link
Contributor

Federico2014 commented Oct 28, 2019

TIP: 102
Title: Hierarchical Deterministic Wallets
Author: federico<federico.zhen@tron.network>
discussions-to: https://github.com/tronprotocol/tips/issues/102
status: draft
type: Standards Track
category: TRC
Created: 2019-10-22

Simple Summary

This proposal defines a mechanism for extending hierarchical deterministic wallets, as described in BIP32
and BIP44, to support both Tron's transparent and shielded addresses.

Abstract

BIP32 and BIP44 are the standard mechanism by which wallets for Bitcoin and its derivatives generate keys and addresses deterministically.
However, they only support the transparent address generation. This specification will provide support for the hierarchically shielded addresses derivation in a similar way as BIP32, which can offer users better privacy protection.

Motivation

At present, Tron network has scheduled to support the shielded addresses by ZK-SNARKs, so it is necessary to provide the standard compatibility for shielded hierarchical deterministic wallets.

Specification

In this specification, transparent address indicates the address which is public in the transaction, while the shielded address stands for the address which
is not available from the transaction.

Wallet Key Path

Existing HD wallets all use BIP44 to organize their derived keys. In order to
improve existing user experiences, we broadly follow BIP 44's design here. However, we have
altered the design where it makes sense to leverage features of shielded addresses.

m / purpose' / coin_type' / account' / transparent' / change / address_index

Apostrophe in the path indicates that BIP32 hardened derivation is used.

  • m: a seed generated by the mnemonic codes to generate the master key.

  • purpose: a constant set to 102' (or 0x80000066) following the BIP43 recommendation. It indicates that
    the subtree of this node is used according to this specification.

  • coin_type: a constant identifying the cybercoin that this subtree's keys are used with. For Tron, coin_type is 195 as assigned in SLIP44.

  • account: numbered from index 0 in sequentially increasing manner. Defined as in BIP44.

  • transparent: for transparent addresses, transparent is set 1; for the shielded addresses, transparent is set 0;

  • change: for transparent addresses, constant 0 is used for external chain and constant 1 for internal chain (also known as change addresses) as in BIP44;
    for shielded addresses, change field is omitted, because shielded addresses are never publicly visible in transactions.

  • address_index: numbered from index 0 in sequentially increasing manner. Defined as in BIP44.

Mnemonic Codes

BIP39 should be used to derive binary seed from a mnemonic code.

We strongly recommend using 24 word mnemonic (256 bits of entropy).

Transparent Multi-Account Hierarchy for Deterministic Wallets

We adapt BIP44 for generating transparent address, except an extra transparent field is added. This is an upgrade of TIP001. We will focus on the shielded addresses derivation in the following section.

Hierarchical Derivation for Shielded Addresses

The shielded addresses derivation process described here are mainly based on the ZIP32 standard proposed by Zcash team.

Conventions

Most of the notation and functions used in this TIP are defined here for convenience:

  • truncatek(S) means the sequence formed from the first k elements of S.

  • a || b means the concatenation of sequences a then b.

  • [k] P means scalar multiplication of the elliptic curve point P by the scalar k.

  • LEOS2IPl (S) is the integer in range {0..2l -1} represented in little-endian order
    by the byte sequence S of length l/8.

  • I2LEBSPl (k) is the sequence of l bits representing k in little-endian order.

  • LEBS2OSPl (B) is defined as follows when l is a multiple of 8: convert each group of 8 bits
    in B to a byte value with the least significant bit first, and concatenate the resulting bytes in the
    same order as the groups.

  • reprJ (P) is the representation of the Jubjub elliptic curve point P as a bit sequence.

  • BLAKE2b-256(p, x) refers to unkeyed BLAKE2b-256 in sequential mode, with an output digest length of
    32 bytes, 16-byte personalization string p, and input x.

  • BLAKE2b-512(p, x) refers to unkeyed BLAKE2b-512 in sequential mode, with an output digest length of
    64 bytes, 16-byte personalization string p, and input x.

  • PRFexpand (sk, t) := BLAKE2b-512("Tron_ExpandSeed", sk || t )

  • ToScalar(x) := LEOS2IP512 (x) (mod rJ ), where rJ is the order
    of the Jubjub large prime subgroup.

  • DiversifyHash(d) maps a diversifier d to a base point on the Jubjub elliptic curve, or to ⊥ if the
    diversifier is invalid.

The following FPE algorithm standardized is used:

  • FF1-AES256.Encrypt(key, tweak, x) refers to the FF1 encryption algorithm using AES with a
    256-bit key, and parameters radix = 2, minlen = 88, maxlen = 88. It will be used only with
    the empty string "" as the tweak. x is a sequence of 88 bits, as is the output.

We also define the following conversion function:

  • I2LEOSPl (k) is the byte sequence S of length l/8 representing in little-endian order the
    integer k in range {0..2l -1}. It is the reverse operation of LEOS2IPl (S).

We adapt the path notation of BIP32 to describe shielded HD paths, using apostrophes to
indicate hardened derivation (i' = i + 231 ) as in BIP44:

  • CDKsk(CDKsk(CDKsk(m, a'), b), c) is written as m / a' / b / c
  • CDKfvk(CDKfvk(CDKfvk(M, a), b), c) is written as M / a / b / c

Specification: Key Derivation

Extended Keys

BIP 32 defines a method to derive a number of child keys from a parent key. In order to prevent these from
depending solely on the parent key itself, both the private and public keys are extended with a 32-byte chain
code. We similarly extend Sapling keys with a chain code here. However, the concepts of "private" and "public"
keys in BIP 32 do not map cleanly to shielded key components. We take the following approach:

  • We derive child expanded spending keys, rather than spending keys. This enables us to
    implement both hardened and non-hardened derivation modes.

  • We do not derive public keys directly, as this would prevent the use of diversified addresses.
    Instead, we derive full viewing keys, from which payment addresses can be generated. This maintains
    the trust semantics of BIP 32: someone with access to a BIP 32 extended public key is able to view all
    transactions involving that address, which a full viewing key also enables.

We represent a extended spending key as (ask, nsk, ovk, dk, c), where (ask, nsk, ovk)
is the normal expanded spending key, dk is a diversifier key, and c is the chain code.

We represent a extended full viewing key as (ak, nk, ovk, dk, c), where (ak, nk, ovk)
is the normal full viewing key, dk is the same diversifier key as above, and c is the chain code.

The helper functions

Define EncodeExtSKParts(ask, nsk, ovk, dk) := I2LEOSP256 (ask) || I2LEOSP256 (nsk) || ovk || dk.

Define EncodeExtFVKParts(ak, nk, ovk, dk) := LEBS2OSP256 (reprJ (ak)) || LEBS2OSP256 (reprJ (nk)) || ovk || dk.

Master Key Generation

Let pathi= m / xx' / 195' / i' / 0', i denotes the i-th account. Let skpathi, pkpathi, cpathi
denotes the private key, public key and chain code at pathi derived by BIP32.

  • Calculate I = BLAKE2b-512 ("TronIP102", skpathi || pkpathi || cpathi ).

  • Split I into two 32-byte sequences, IL and IR .

  • Use IL as the master spending key skm , and IR as the master chain code
    cm.

  • Calculate askm , nskm , and ovkm via the standard derivation function:

    • askm = ToScalar(PRFexpand (skm , [0x00]))
    • nskm = ToScalar(PRFexpand (skm , [0x01]))
    • ovkm = truncate32 (PRFexpand (skm , [0x02]))
  • Calculate dkm similarly:

    • dkm = truncate32 (PRFexpand (skm , [0x10]))
  • Return (askm , nskm , ovkm , dkm , cm ) as the
    master extended spending key m.

Child Key Derivation

As in BIP 32, the method for deriving a child extended key, given a parent extended key and an index i,
depends on the type of key being derived, and whether this is a hardened or non-hardened derivation.

Deriving a child extended spending key

CDKsk((askpar , nskpar , ovkpar , dkpar , cpar ), i) →
(aski , nski , ovki , dki , ci )

  • Check whether i ≥ 231 (whether the child is a hardened key).

    • If so (hardened child): let I = PRFexpand (cpar , [0x11] || EncodeExtSKParts(askpar , nskpar , ovkpar , dkpar ) || I2LEOSP32 (i))
    • If not (normal child): let I = PRFexpand (cpar , [0x12] || EncodeExtFVKParts(akpar , nkpar , ovkpar , dkpar ) || I2LEOSP32 (i))
      where (nkpar , akpar , ovkpar ) is the full viewing key derived from
      (askpar , nskpar , ovkpar ).
  • Split I into two 32-byte sequences, IL and IR .

  • Let Iask = ToScalar(PRFexpand (IL , [0x13]))

  • Let Insk = ToScalar(PRFexpand (IL , [0x14]))

  • Return:

    • aski = Iask + askpar
    • nski = Insk + nskpar
    • ovki = truncate32 (PRFexpand (IL , [0x15] || ovkpar ))
    • dki = truncate32 (PRFexpand (IL , [0x16] || dkpar ))
    • ci = IR

Deriving a child extended full viewing key

Let G and H be the base point in elliptic curve.

CDKfvk((akpar , nkpar , ovkpar , dkpar , cpar ), i) →
(aki , nki , ovki , dki , ci )

  • Check whether i ≥ 231 (whether the child is a hardened key).

    • If so (hardened child): return failure
    • If not (normal child): let I = PRFexpand (cpar , [0x12] || EncodeExtFVKParts(akpar , nkpar , ovkpar , dkpar ) || I2LEOSP32 (i))
  • Split I into two 32-byte sequences, IL and IR .

  • Let Iask = ToScalar(PRFexpand (IL , [0x13]))

  • Let Insk = ToScalar(PRFexpand (IL , [0x14]))

  • Return:

    • aki = [Iask] G + akpar
    • nki = [Insk] H + nkpar
    • ovki = truncate32 (PRFexpand (IL , [0x15] || ovkpar ))
    • dki = truncate32 (PRFexpand (IL , [0x16] || dkpar ))
    • ci = IR

Diversifier derivation

The 88-bit diversifiers for a extended key are derived from its diversifier key dk. To prevent the
diversifier leaking how many diversified addresses have already been generated for an account, we make the
sequence of diversifiers pseudorandom and uncorrelated to that of any other account. In order to reach the
maximum possible diversifier range without running into repetitions due to the birthday bound, we use
FF1-AES256 as a Pseudo-Random Permutation as follows:

  • Let j be the index of the desired diversifier, in the range 0 .. 288 -1.
  • dj = FF1-AES256.Encrypt(dk, "", I2LEBSP88 (j)).

A valid diversifier dj is one for which DiversifyHash(dj) ≠ ⊥.
For a given dk, approximately half of the possible values of j yield valid diversifiers.

The default diversifier for an extended key is defined to be dj , where j is the
least nonnegative integer yielding a valid diversifier.

Fingerprints and Tags

Full Viewing Key Fingerprints and Tags

A full viewing key fingerprint with raw encoding FVK is given by:

BLAKE2b-256("TronFVFP", FVK)

It MAY be used to uniquely identify a particular full viewing key.

A "full viewing key tag" is the first 4 bytes of the corresponding full viewing key
fingerprint. It is intended for optimizing performance of key lookups, and MUST NOT be assumed to
uniquely identify a particular key.

Key Encodings

The following encodings are analogous to the xprv and xpub encodings defined
in BIP 32 for transparent keys and addresses. Each key type has a raw representation
and a Bech32 encoding.

Extended Spending Keys

An extended spending key (ask, nsk, ovk, dk, c), at some path,
with parent full viewing key tag parent_fvk_tag and child number i, is
represented as a byte sequence:

I2LEOSP8 (depth) || parent_fvk_tag || I2LEOSP32 (i) || c || EncodeExtSKParts(ask, nsk, ovk, dk)

For the master extended spending key, depth is 0, parent_fvk_tag is 4 zero bytes,
and i is 0.

When encoded as Bech32, the Human-Readable Part is secret-extended-key-main
for the production network, or secret-extended-key-test for the test network.

Extended full viewing keys

A extended full viewing key (ak, nk, ovk, dk, c), at depth depth,
with parent full viewing key tag parent_fvk_tag and child number i, is
represented as a byte sequence:

I2LEOSP8 (depth) || parent_fvk_tag || I2LEOSP32 (i) || c || EncodeExtFVKParts(ak, nk, ovk, dk)

For the master extended full viewing key, depth is 0, parent_fvk_tag is 4 zero bytes,
and i is 0.

When encoded as Bech32, the Human-Readable Part is txviews for the production
network, or txviewtest for the test network.

Rationale

Based on BIP32, BIP44 and ZIP32, We provide a standard mechanism for both transparent and shielded hierarchical deterministic wallets for Tron.

Implementation

None

Reference

@Federico2014 Federico2014 changed the title TRC: Tron Hierarchical Deterministic Wallets TRC102: Tron Hierarchical Deterministic Wallets Oct 29, 2019
@Federico2014 Federico2014 changed the title TRC102: Tron Hierarchical Deterministic Wallets TRC102: Hierarchical Deterministic Wallets Nov 1, 2019
@Rovak
Copy link

Rovak commented Nov 7, 2019

Add https://github.com/zcash/zips/blob/master/zip-0032.rst as a reference because that is where most of the text is copied from

@Federico2014
Copy link
Contributor Author

Add https://github.com/zcash/zips/blob/master/zip-0032.rst as a reference because that is where most of the text is copied from

We have provided the reference zip32 in the text. The main difference lies in the the wallet key path and master key generation.

@ha1i1uya
Copy link

Will this HD wallet initially be used on wallet-cli ?and when will it be realized?

@Federico2014
Copy link
Contributor Author

Will this HD wallet initially be used on wallet-cli ?and when will it be realized?
This TIP is currently still a draft and will be realized after comprehensive discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants