UTXO Cryptography
Panther's UTXO encryption/decryption model
TL;DR
Spender encrypts a message to recipient that is published on-chain
All zAccount holders scan the chain for UTXO commitments and attempt to read the message
Only the intended recipient, the account holding the cryptographic key, may read the message and assume spend rights to a UTXO
Introduction
An essential requirement of Pantherβs Shielded Pools is to ensure the untracability of transactions to stakeholders who do not hold the correct keys. To achieve this, the mainnet beta Protocol supports non-interactive transactions. That is, the spender can pass assets to the receiver's zAccount using the receiverβs public read key and the public root spending key available on a public lookup registry maintained by the smart contract.
Every zAsset UTXO has one βownerβ or zAccount able to spend it. This is achieved by including a unique public (spending) key in the generation of the UTXO commitment, for which the corresponding private (spending) key is only known by the recipient.
In order to spend a UTXO the owner needs to prove (in Zero-Knowledge) that they hold the spending private key.
High-level overview of Panther's UTXO cryptography
The following conventions are applied to formulae:
lowercase letters in formulae bellow denote prime field elements ("scalars") - i.e. private keys
capital letters denote points on the elliptic curve - i.e. the public keys
'*' denotes the multiplication of an elliptic curve point by a scalar, i.e. scalar multiplication
The Protocol uses a shared symmetric key for encryption/decryption of messages with secrets
Secrets.
M
are UTXOβs "opening values" for recipients and data for spenders to track past transactionsMessages passed to the smart contract are encrypted:
spender to receiver
spender to self
Sender publishes the Ephemeral key,
E
and ciphertextM'
on-chain β formalizing a transactionRecipient scans chain to extract
M
(fromM'
usingE
) to take ownership of a UTXOSpender can re-create history by decrypting messages to self,
M'
Although spender knows the UTXOβs public key, only the recipient who holds the root spending private key may spend the UTXO
Next, letβs take a closer look at how the cryptography behind this Protocol is implemented.
Panther Protocol keys
A "key pair" is a pair composed of a private key and its corresponding public key.
The private key is a big integer ("scalar") from the prime field defined by the Baby Jubjub elliptic curve.
The public key, P
corresponding to the private key, p
is a point on the curve, such that the following equation holds:
P
=p
*G
Where, P
and p
are the public and private keys, and G
is the generator of the group of elliptic curve points.
The so-called Base8
point is used as the generator. This point generates a "commutative group" of curve points that cryptographers call the "Baby Jubjub subgroup".
The ECDH key agreement protocol (over the Baby Jubjub elliptic curve) is used to share the symmetric key and to derive the spending keys of UTXOs.
The following key pairs are essential to the transfer of zAssets in the form of UTXO updates:
Recipient reading key pair (
w
,W
=w
*G
): allows the recipient to decode messages with opening values of UTXOs, i.e. knowledge of the private key is needed to decrypt a message.Root spending key pair (
s
,S
=s
*G
): enables spending of a UTXO by the owner, i.e., no matter who generates a UTXO, only the holder of the private key may spend the UTXO.
The term "root" applies as spending keys for UTXOs are "derived" from this key pair.
Nullifier key (
n
,N
=n
*G
): required in order to generate the nullifiers for UTXOs.
This key enables compliance, by encoding the nullifier so that information in the Data Safe may reveal whether the UTXO has been spent.
Next, let's consider how spending and encryption keys are derived.
Creating a new UTXO
When a zAsset is spent, an output, i.e. a new UTXO is created.
Spender selects two randoms,
r
ande
, to derive the spending and message encryption keys.Spender derives the spending public key
S'
for the new UTXO from the recipient's root spending public keyS
and the randomr
:
S'
=r
*S
Spender creates an ephemeral key using the random (
e
) from Step 1:
E
=e
*G
Spender creates the shared key,
K
to encrypt the message to the recipient with, based on the recipientβs public reading key,W
and the random,e
:
K
=e
*W
Spender composes the message to the recipient,
M
and encrypts the message into the ciphertext,M'
.
5.1 Message composition. The message,
M
contains the information needed to spend the UTXO: random,r
required for the recipient to generate the spending key,S'
and other opening values (such aszAssetId
and the value the UTXO represents).5.2 Message encryption. The spender encrypts the message to the recipient with the shared key,
K
applying the symmetric encryption (applying the methodAES-128-cbc
):M'
= Enc(M
,K
)
Spender calls the Shielded Pool contract to publish the new UTXO as well as the encrypted message to the recipient.
6.1 Publishes the ephemeral key,
E
and the ciphertextM'
.6.2 Using the same encryption key derivation method, but with own reading key instead of the recipient's reading key, the spender encrypts the message "to self". This encrypted message (which only the spender may decrypt) contains data required to reconstruct an audit trail of the spender's transactions.
Taking ownership of a UTXO
The following steps detail how a recipient is able to take ownership of the input UTXO.
1. Scan chain for ciphertexts
Each zAccount holder behaves as it is a potential recipient and scans the chain for ciphertexts, M'
and ephemeral keys, E
.
2. Attempt to decrypt every ciphertext
2.1 Compute the shared key, K
K
=w
*E
Note, if the spender encrypted the message with the recipientβs public reading key (i.e. the message is intended for the recipient), the recipient derives the same shared key that the spender used:
K
=w
*E
=w
* (e
*G
) =e
* (w
*G
) =e
*W
2.2 Decrypt the ciphertext using that key
M
= Dec(M'
,K
)
2.3 Analyze whether the decrypted message, M
is meaningful
If an encrypted message (i.e. the ciphertext and the ephemeral key) was intended for a different recipient, and thus the non-recipient computed the wrong encryption key, the decryption algorithm still returns some random (meaningless) decrypted text. However, the true recipient can easily distinguish if the decrypted text, M
contains properly formed or meaningless data.
So, IF
M
is invalid, message is ignored. IFM
is valid, recipient extracts fromM
the random,r
and other opening values required to spend the UTXO.
2.4 Derive the private spending key for the UTXO
The recipient derives the private spending key for the UTXO:
s'
=r
βs
here, 'β' denotes multiplication of integers (in the prime field).
Note, that the private spending key derived this way indeed corresponds to its public key that the spender derived:
S'
= (r
βs
) *G
=r
* (s
*G
) =r
*S
This method provides an efficient encryption/decryption mechanism and a unique spending public key that is unlinkable to other transactions by the same recipient, even given that E is publicly accessible on-chain.
What next?
Learn how UTXOs represent assets locked in the Panther vault, zAssets
Understand how users enter a Shielded Pool to create a zAccount and transact with other account holders and the wider DeFi ecosystem
Last updated