# BLSCT Cryptography¶

This section will describe the cryptography behind BLSCT, the novel protocol which we used to build NavCoin’s new private token xNAV.

For a wallet to create and receive BLSCT transactions, it needs to own a set of BLS keys. Let \(KDF(k, p)\) be a key derivation function where `k`

is a BLS private key and `p`

a derivation path, and `m`

the wallet’s master secret key. We use `G1`

from the pairing-friendly elliptic curve BLS12-381 and let `g`

be a `G1`

generator. Let `H`

be a secure hash function whose output is of 256-bit length and `HG1`

a hash function whose output is mapped as a `G1`

element.

The first steps are to calculate:

- A master blinding key: \(bmk = KDF(m, 130'/1')\)
- A master view key: \(vmk = KDF(m, 130'/0'/0')\)
- A master spend key: \(smk = KDF(m, 130'/0'/1')\)

A wallet can then generate the needed keys to construct an arbitrary number of addresses where coins can be received. Wallets generate their `SAi`

-th address \(SAi = (0,1,2,...)\) in their `Ai`

-th account \(Ai = (0,1,2,...)\) as a pair of public keys `(C, D)`

where:

Wallets must store `D`

in the wallet’s database registered to the index `(Ai, SAi)`

as an integer pair. Addresses are a Base58Check representation of the keys `(C, D)`

using `73`

and `33`

as mainnet Version bytes. When a wallet wants to send funds to an address, it must:

- Decode and extract
`(C, D)`

from the address.- Maintain an incremental counter of blinding addresses
`Bi`

.- Generate an ephemeral private key \(e = KDF(bmk, Bi++)\)
- Calculate the ephemeral public key \(E = e*g\)
- Generate the output’s public key \(R = e*D\)
- Generate the spending key \(P = H(e*C)*g+D\)
- Generate a shared secret \(S = e*C\)

The wallet must construct a per-output range-proof `bp`

to prove that the hidden amount `v`

is positive and within the allowed range. It is allowed to attach an encrypted message `memo`

limited to 54 bytes only viewable by the transaction’s recipient. Some of the scalars used in the proof creation are calculated from the shared secret `S`

.

The commitment’s secret key gamma will sign the message `BLSCTBALANCE`

to create a signature `BPSO`

, which will serve to prove later that the transaction creates no new coins. Constructing the signature using the basic scheme and a constant message is secure against a rogue public-key attack combined with a valid Bulletproofs range-proof. An attacker can not create it without knowledge of the secret key gamma.

The output’s ephemeral key `e`

will sign the output’s hash to create a signature `BSO`

using the augmented scheme.

The range proof `bp`

and the public keys `E`

, `R`

, and `P`

will be attached to a transaction’s output when it targets a private address. Transactions that include a BLSCT output have their version bit `10`

set to `1`

. Both public and BLSCT outputs can combine in the same transaction.

When a client sees this output, he will determine whether it belongs to him or not by performing the following checks:

- Calculate \(D' = P - H(vmk*R)*g\) and check if its wallet’s database has it registered to an index
`(Ai', SAi')`

.- Calculate \(S' = vmk * R\)
- Derive
`alpha`

,`rho`

,`tau1`

and`tau2`

and`gamma'`

from`S'`

.- Verify if the range proof
`bp`

is valid.- Calculate \(ex = (mu - rho*x) - alpha\) and \(ex2 = ((taux - tau2*x^2 - gamma*z^2) * x^{-1}) - tau1\)
- Extract the amount as \(v' = ex \& 0xFFFFFFFFFFFFFFFF\)
- Extract the encrypted message as \(memo' = ex2 || ex >> 64\)
- Check if the range-proof value’s commitment equals to \(gamma'*g + v'*HG1(g||"bulletproof"||0)\)

When the client wants to spend this output, it must set the spending transaction’s version bit `11`

to `1`

. It can calculate the output’s private spending key as \(p = H(vmk*R) + smk + H("SubAddress"||vmk||Ai'||SAi')\). The private key `p`

will sign the transaction input hash using the augmented scheme to produce the signature `BSI`

.

The extracted commitment’s secret key `gamma'`

will sign the message `BLSCTBALANCE`

to create a signature `BPSI`

.

The wallet will store the aggregation of all of the transaction’s `BSI`

s and `BSO`

s in its BLS transaction signature field as `BS`

. The transaction’s BLS balance signature will result from aggregating all the `BPSI`

s and `BPSO`

s signatures as `BPS`

.

Every transaction must include an output with a transparent amount whose script is the provably unspendable `OP_RETURN`

representing the sender’s fee. Transactions are not allowed to combine public and private inputs.

A validator can determine if a transaction is correct:

- By verifying that
`BPS`

is a valid signature by defining`pkBal`

as, for each transaction’s input`prevOut`

, the sum of \(prevOut.bp.v\) if it is private or \(prevOut.amount*HG1(g||"bulletproof"||0)\) if it is public, minus the sum of, for each transaction’s output`out`

, \(out.bp.v\) if it is private or \(out.amount*HG1(g||"bulletproof"||0)\) if it is public, and using`pkBal`

as the signer’s public key and`BLSCTBALANCE`

as the message of the basic scheme,- by verifying that
`BS`

is a valid signature using the augmented scheme with`P, H(tx_in)`

for each transaction’s input as inputs to the verify signature function, and`E, H(tx_out)`

from each transaction’s output,- and by verifying that for each output, its range proof
`bp`

is validated correctly.