---
# System prepended metadata

title: Keys

---

# Keys

[TOC]

## BLS signatures

| Repository       | Struct       |   Content   | Type                            |
| --------         | ------------ | ----------- | ------------------------------- |
| bls12_381-sign   | `SecretKey`  | `BlsScalar` | BLS secret key                  |
| bls12_381-sign   | `PublicKey`  | `G2Affine`  | BLS public key                  |
| bls12_381-sign   | `APK`        | `PublicKey` | BLS apk (aggregated public key) |

https://github.com/dusk-network/bls12_381-sign/tree/main/rust/bls12_381-sign/src/keys

### Use

- **Consensus**: everyone involved in the consensus (the stakers) signs the block (with these signatures we identify the participants), and we use BLS signatures because we can aggregate them (so, we only include a single signature in the block).
- **Stake Contract**: Stakers are identified by a given BLS public key, and all operations with the stake contract must contain a signature proving ownership of said key.


### Questions

- Why do we use BLS keys, since there's mathematically no difference between one (Jubjub) and the other (BLS)? If we used Jubjub keys for this, users should only mantain one public key and not two (one for Phoenix and another one for consensus).
    - **Answer:** we want to aggregate the signatures used in the consensus. This requires a pairing-based signature scheme.[^1] Therefore, we must instantiate the signature scheme in a pairing-friendly elliptic curve, which rules out Jubjub.
    - **Follow-up question**: the secret key is also different? Could they both derive from a common seed?
- Why do we use the G2 for PublicKeys instead of G1? It's a bigger group than G1, and operations are more expensive.


### Notes

- **APK:** the aggregated public key is computed as a linear combination of a bunch of public keys $\{pk_i\}$, using their hashes as coefficients:
$APK = \sum_{i=1}^n H(x_i) pk_i$.
Is it $x_i = pk_i$, or all the accumulated keys up to $i$, or all keys in a different order?


## JubJub keys

| Repository  | Struct            |   Content                               | Type                       | Alternate Name  |
| ----------  | ----------------- | --------------------------------------- | -------------------------- | --------------- |
| dusk-pki    | `SecretKey`       | `JubJubScalar`                          | JubJub Secret Key          | Note-Secret Key |
| dusk-pki    | `PublicKey`       | `JubJubExtended`                        | JubJub Public Key          | Note-Public Key |
| dusk-pki    | `SecretSpendKey`  | `a: JubJubScalar`   `b: JubJubScalar`   | JubJub Secret "Spend" Key  | Secret Key      |
| dusk-pki    | `PublicSpendKey`  | `A: JubJubExtended` `B: JubJubExtended` | JubJub Public "Spend" Key  | Public Key      |
| dusk-pki    | `StealthAddress`  | `R: JubJubExtended` `pk_r: PublicKey`   | Stealth Address            | N/A             |
| dusk-pki    | `ViewKey`         | `a: JubJubScalar`   `B: JubJubExtended` | View Key                   | N/A             |

https://github.com/dusk-network/dusk-pki/tree/master/src

### Use

These keys are used for Phoenix.

- The JubJub secret and public "Spend" keys are the user's static keys (called public/private key in the Phoenix document).
- The stealth address is the note public key and the `R` that allows the recipient to spend the note.
- The Jubjub secret key is actually the note's secret key.
- The Jubjub public key is `pk_r` (that is, the note's public key).
- The ViewKey is the pair `(SecretSpendKey[0], PublicSpendKey[1])`.
- PublicKey is used twice with different generators $$G, G'$$ to produce two keys.
- SecretKey is used to sign Schnorr signatures, which is then verified by the two keys from the previous comment.

### Notes

- `JubJubExtended` is another representation of `JubJubAffine` that contains additional elements that speed up computations.


## Others?

- `DeriveKey`: found [here](https://github.com/dusk-network/rusk/blob/d62411299bc088cf9f8032ed6179f59eb7f8fda4/circuits/transfer/src/types.rs) and used [here](https://github.com/dusk-network/rusk/blob/d62411299bc088cf9f8032ed6179f59eb7f8fda4/circuits/transfer/src/send_to_contract_obfuscated.rs). We do not think that this is a key in the cryptographic sense.

## What to do with key nomenclature

### The current situation

Currently, `dusk-pki` contains structs for all types of Jubjub keys that are used in Phoenix. Some of the names reflect their role in Phoenix, which is a bit misleading because this should not be tied to Phoenix. Moreover, it is not just the names but the functionality. For example, a`SecretKey` is computed [here](https://github.com/dusk-network/dusk-pki/blob/master/src/keys/spend/secret.rs#L53) as $H(aR)+b$, which is kinda Phoenix-specific. Thus, `dusk-pki` is entangled with Phoenix.

### The ideal situation

The ideal situation would be to have structs for all keys in `dusk-pki`, and these should not be directly tied in name or functionality to their instantiations, e.g. in Phoenix. Conceptually, there are only two types of Jubjub keys:
- Secret keys, where some randomness is processed in the right way and then used to generate a uniformly random `JubJubScalar`.[^2]
- Public keys, where a secret key is multiplied by a fixed Jubjub generator to produce a `JubJubExtended`.
 
These esentially correspond to `SecretKey` and `PublicKey` above, respectively. The rest are just combinations of these, but it would still be okay to have explicit structs for them, derived from `SecretKey` and `PublicKey`, for convenience.

Then, in Phoenix (or potentially other places where these keys are instantiated), the concrete instances of these keys would have names that reflect their role within the transaction protocol, and in accordance to the Phoenix documentation. For example, the instance in Phoenix of `SecretKey` would be the `Note secret key`, and the two instances of `PublicKey` with respect to generators $G, G'$ would be the `Note public key` and `Nullification key`.

Making this happen, however, entails substantial changes in the code. A potentially simpler alternative would be to accept the entanglement with Phoenix and just move the keys to Phoenix.





[^1]: In this case, we use [BLS signatures](https://hovav.net/ucsd/dist/sigs.pdf) on the [BLS12-381 curve](https://eprint.iacr.org/2002/088.pdf). Note that the fact that both signature scheme and curve are called BLS is basically a coincidence, as only one of the authors overlap.

[^2]: The specifics should be left to the particular use case, e.g. Phoenix. A (static) user secret key won't be computed in the same way as a (ephemeral) note public key.