Skip to content

Instantly share code, notes, and snippets.

@tevador
Last active December 13, 2024 04:07
Show Gist options
  • Save tevador/23a84444df2419dd658cba804bf57f1a to your computer and use it in GitHub Desktop.
Save tevador/23a84444df2419dd658cba804bf57f1a to your computer and use it in GitHub Desktop.

[Draft] Zero-cost post-quantum mitigations for Seraphis

This draft presents post-quantum mitigations for Monero's next transaction protocol Seraphis. These mitigations are "zero-cost" in the sense that they only involve changes to the way private keys and blinding factors are calculated, which is transparent to blockchain verifiers. Mitigated keys will be compatible with a future hard-fork that can be put in place to ensure monetary soundness and security of the protocol even against a quantum computer.

While these mitigations do not prevent a quantum adversary from breaking the privacy of past transactions, they protect Monero from a total collapse that would result from an undetectable money supply inflation or the theft of users' funds.

1. Introduction

In 2020, Monero performed a post-quantum security audit that confirmed severe vulnerabilities of the transaction protocol against quantum algorithms [1]. In descending order of severity, a quantum adversary (QA) would be able to:

  • undetectably inflate the money supply,
  • steal users' funds,
  • deanonymize the transaction graph.

While the audit mostly focused on Monero's current transaction protocol RingCT, the above issues also apply to the next transaction protocol Seraphis [2]. In addition, Seraphis is also vulnerable to a double-spending attack because its key images are not perfectly bound to the output keys. Double-spending would also enable a QA to undetectably inflate the money supply.

The following mitigations are proposed for Seraphis:

  1. Embedding ElGamal commitments into Pedersen commitments. ElGamal commitments are pefectly binding and prevent a QA from opening the commitment to arbitrary values.
  2. Using hash-based commitments to prove the correctness of key images, preventing a QA from double-spending.
  3. Embedding a quantum-resistant public key into the private spend key to prevent a QA from stealing outputs they don't own.

1.1 Preliminaries

We use the additive notation for elliptic curve operations. Lowercase letters usually refer to the elements of Zq, where q is the prime order of the main subgroup of the ed25519 elliptic curve. Uppercase letters usually refer to group elements (elliptic curve points). G is the generator of the elliptic curve and H, J, X, U are four additional generators with a (presently) unknown discrete logarithm relationship to G.

The function Hq() refers to a hash function {0,1}* -> Zq. The function H32() refers to a hash function {0,1}* -> {0,1}256. The concatenation operator is denoted by ||.

Domain-separation tags are denoted with a capital letter T.

2. Seraphis basics

2.1 Amount commitments

Similarly to RingCT, transaction amounts in Seraphis are hidden with Pedersen commitments. Pedersen commitment C to a value v using a blinding factor r is derived as:

C = r G + v H (2.1.1)

Rewritten in terms of logG, the commitment becomes:

c = r + v*h (2.1.2)

where H = h G. This is an equation with 2 variables, so anyone who learns h can open the commitment to an arbitrary value of v by calculating the corresponding blinding factor as r = c - v*h.

2.2 Output keys

In Seraphis, the public spend key has the form of:

Ks = kvb X + ks U (2.2.1)

where kvb is the private view key and ks is the private spend key.

Public address keys have the form of:

Kaddr = Ks + kaddr_x X + kaddr_u U (2.2.2)

where kaddr_x and kaddr_u are private key extensions derived from a secret key sga and the address index j:

kaddr_x = Hq(sga || Taddr_x || j) (2.2.3)

kaddr_u = Hq(sga || Taddr_u || j) (2.2.4)

One-time output keys have the form of:

Ko = Kaddr + ksender_x X + ksender_u U (2.2.5)

where Kaddr is the public key of the address the output was sent to and ksender_x and ksender_u are address extensions generated by the sender from the shared secret sshared and the amount commitment C:

ksender_x = Hq(Tsender_x || sshared || C) (2.2.6)

ksender_u = Hq(Tsender_u || sshared || C) (2.2.7)

2.3 Key images

A Seraphis one-time output key has the form of:

Ko = kx X + ku U (2.3.1)

where

kx = kvb + kaddr_x + ksender_x (2.3.2)

ku = ks + kaddr_u + ksender_u (2.3.3)

The corresponding key image is:

Ki = (ku / kx) U (2.3.4)

We can rewrite Eq. 2.3.1 in terms of logU as:

ko = kx*x + ku (2.3.5)

where X = x U. An adversary who knows x can produce an arbitrary number of different valid key images for every Ko, allowing unlimited double spending.

3. Proposed constructions

3.1 Amount commitments

While Pedersen commitments do not bind a QA to the original amount, ElGamal commitments are a different form of homomorphic commitments that are pefectly binding.

3.1.1 ElGamal commitments

An ElGamal commitment to a value v with a blinding factor r consists of two group elements C, D calculated as:

C = r G + v H

D = r J

There are three problems with ElGamal commitments:

  1. The range proofs are less efficient than for Pedersen commitments.
  2. They do not hide the value v from a QA, who can learn r by calculating the discrete log of D.
  3. They require twice the blockchain space of Pedersen commitments.

The first problem can be solved by treating an ElGamal commitment as if it was a Pedersen commitment, ignoring the value of D. This is the main idea behind "switch commitments" [3]. Keeping D allows past amounts to be validated in the future if the danger of quantum computers arises.

The second problem can be solved by defining a switch commitment as the pair (C, d), where d = H32(D).

3.1.2 Zero-cost solution

Finally, an even more efficient solution was proposed in the Mimblewimble mailing list [4]. A switch commitment can be constructed by simply tweaking the blinding factor r. It works as follows:

  1. Generate a random blinding factor r'.
  2. Construct an ElGamal commitment with C' = r' G + v H and D' = r' J (3.1.2.1)
  3. Calculate a new blinding factor r = r' + Hq(Telgamal || C' || D').
  4. Output a Pedersen commitment C = r G + v H.

This construction removes all the disadvantages of ElGamal commitments, while still allowing the post-quantum validation protocol (Ch. 4) to verify that the commitment is being open to the original value.

3.2 Wallet keys

To prevent a QA from directly learning wallet seeds by calculating a discrete logarithm, each wallet must be derived from a secret seed m that is never directly used as an elliptic curve private key.

3.2.1 Private view key

The private view key kvb must be constructed independently of the spend key as:

kvb = Hq(m || Tvb) (3.2.1.1)

The associated public view key is defined as:

Kvb = kvb X (3.2.1.2)

This public key does not need to be published in the Seraphis protocol, but it is needed in the post-quantum protocol.

3.2.2 Auxiliary spend key

Instead of directly deriving the private spend key from m, we derive an auxiliary spend key as:

ks' = Hq(m || Taux_spend) (3.2.2.1)

The associated public auxiliary spend key is defined as:

Ks' = ks' U (3.2.2.2)

3.2.3 Quantum-resistant key pair

Before the wallet can construct the Seraphis spend key, a quantum-resistant key pair (zqr, Zqr) is generated using the following seed mqr:

mqr = H32(Tqr || m) (3.2.3)

Two possible quantum-resistant signature algorithms are listed in Chapter 5.

3.2.4 Auxiliary key image

The wallet can construct an auxiliary key image as:

Ki' = (ks' / kvb) U (3.2.4)

This key image has a similar format as the output key image (Eq. 2.3.4).

3.2.5 Key image proofs

To ensure that the auxiliary key image Ki' is correctly constructed according to Eq. (3.2.4), the wallet must construct two proofs:

  1. σki = (e1, s1) - a proof of knowledge of the discrete logarithm of Ki' with respect to the generator U.
  2. πki = (e2, s2) - a discrete logarithm equality proof showing the knowledge of a private key kvb such that kvb X = Kvb and kvb Ki' = Ks' (these relations hold from Eq. 3.2.1.2, 3.2.2.2 and 3.2.4).

The proofs σki and πki are standard Fiat-Shamir proofs discribed in the literature [5].

3.2.5 Private spend key

The Seraphis private spend key is finally constructed as:

ks = ks' + kΩ (3.2.5.1)

where kΩ is defined as:

kΩ = Hq(Tspend || Ω) (3.2.5.2)

and Ω is the following tuple:

Ω = (Kvb, Ks', Zqr, Ki', σki, πki) (3.2.5.3)

Since the hash function Hq() is irreversible even for a QA, the constuction proves that the tuple Ω had existed before the public spend key Ks was created.

3.3 Output keys

3.3.1 Address key extensions

Rather than using Eq. 2.2.3 and 2.2.4, address key extensions must be constructed as:

kaddr_x = Hq(Taddr_x || Ks || saddr) (3.3.1.1)

kaddr_u = Hq(Taddr_u || Ks || kaddr_x || saddr) (3.3.1.2)

where Ks is the wallet public spend key (Eq. 2.2.1) and

saddr = H32(sga || Taddr_inner || j) (3.3.1.3)

The irreversibility of Hq() proves that the spend key Ks had existed before the address extension kaddr_x and that kaddr_x was created before kaddr_u.

3.3.2 One-time address extensions

Rather than using Eq. 2.2.6 and 2.2.7, sender key extensions must be constructed as:

ksender_x = Hq(Tsender_x || Kaddr || ssender) (3.3.2.1)

ksender_u = Hq(Tsender_u || Kaddr || ksender_x || ssender) (3.3.2.2)

where Kaddr is the address public key and

ssender = H32(Tsender_inner || sshared || C) (3.3.2.3)

The irreversibility of Hq() proves that the address key Kaddr had existed before the sender extension ksender_x and that ksender_x was created before ksender_u.

3.4 Key images

The Seraphis key image (Eq. 2.3.4) can be equivalently expressed as:

Ki = Kxs + (kΩ + kaddr_u + ksender_u) Kxu (3.4.1)

where the public keys Kxs and Kxu meet the following three discrete logarithm relationships:

kx Kxs = Ks' (3.4.2)

kx Kxu = U (3.4.3)

kx Ki' = Ksi (3.4.4)

The public key Ksi is defined as:

Ksi = Ks' + kaddr_x Ki' + ksender_x Ki' (3.4.5)

Substituting for Ki', Ks' and Ksi into Eq. 3.4.4 yields:

(kx * ks' / kvb) U = ks' U + (kaddr_x * ks' / kvb) U + (ksender_x * ks' / kvb) U

kx * ks' / kvb = ks' + kaddr_x * ks' / kvb + ksender_x * ks' / kvb

kx * ks' = kvb * ks' + kaddr_x * ks' + ksender_x * ks'

kx = kvb + kaddr_x + ksender_x

which matches the definition of kx (Eq. 2.3.2).

Rearranging Eq. 3.4.2 and 3.4.3 yields:

Kxs = (ks' / kx) U (3.4.6)

Kxu = (1 / kx) U (3.4.7)

Substituting for Kxs and Kxu into Eq. 3.4.1 shows that it's equivalent to Eq. 2.3.4.

4. Post-quantum validation protocol

This proposal does not modify any Seraphis consensus rules, but offers a secondary quantum-resistant protocol that can be activated by a hard fork.

4.1 Input validation

Spending a Seraphis e-note (Ko, C) in the post-quantum protocol requires the transaction to reveal the following:

  1. The hidden ElGamal commitment (C', D') (Eq. 3.1.2.1)
  2. A range proof for the commitment.
  3. The tuple Ω (Eq. 3.2.5.2)
  4. The secret key saddr (Eq. 3.3.1.3)
  5. The secret key ssender (Eq. 3.3.2.3)
  6. The public key Kxs (Eq. 3.4.6)
  7. The public key Kxu (Eq. 3.4.7)
  8. The discrete logarithm equality proof πx = (e3, s3) for the pairs (Kxs, Ks'), (Kxu, U) and (Ki', Ksi) (Eq. 3.4.2-3.4.4)
  9. A quantum-resistant signature with the private key zqr (Ch. 3.2.3). This signature should sign all transaction outputs.

To validate the spend, consensus needs to perform the following steps:

  1. Validate C ?= C' + Hq(Telgamal || C' || D') G
  2. Validate the range proof
  3. Validate the proofs σki and πki from Ω
  4. Calculate kΩ = Hq(Tspend || Ω)
  5. Calculate Ks = Kvb + Ks' + kΩ U
  6. Calculate kaddr_x = Hq(Taddr_x || Ks || saddr)
  7. Calculate kaddr_u = Hq(Taddr_u || Ks || kaddr_x || saddr)
  8. Calculate Kaddr = Ks + kaddr_x X + kaddr_u U
  9. Calculate ksender_x = Hq(Tsender_x || Kaddr || ssender)
  10. Calculate ksender_u = Hq(Tsender_u || Kaddr || ksender_x || ssender)
  11. Validate Ko ?= Kaddr + ksender X + ksender_u U
  12. Validate the proof πx
  13. Calculate the key image Ki = Kxs + (kΩ + kaddr_u + ksender_u) Kxu
  14. Validate that Ki is not spent.
  15. Validate the quantum-resistant signature with Zqr.

4.2 Output validation

All transaction outputs must contain ElGamal commitments with valid range proofs. The component-wise sum of the output commitments must be equal to the component-wise sum of the input commitments.

This protocol does not put any other restrictions on the output format, so it can be used to migrate Seraphis outputs to a new quantum-secure privacy protocol.

4.3 Privacy caveats

The quantum-resistant protocol makes the input e-notes provably spent, which may reduce the privacy of past transactions that used the e-notes as decoys.

All migrated outputs that belong to the same wallet share the same tuple Ω, which links them together.

5. Post-quantum signature algorithms

In July 2022, NIST has announced 3 post-quantum digital signature algorithms that have been selected for standardization [6]:

  1. CRYSTALS-Dilithium
  2. Falcon
  3. SPHINCS+

These algorithms have survived at least 6 years of cryptanalysis and offer acceptable size and performance to be practically usable. Falcon is patented [7], so that leaves just two possible candidates to be used by Monero.

5.1 CRYSTALS-Dilithium

CRYSTALS-Dilithium is lattice-based signature scheme. It offers decently sized public keys and signatures and relatively fast key generation (with comparable performance to elliptic curves).

variant security level public key size signature size keygen (Intel Skylake)
Dilithium2 128-bit 1 312 2 420 ~100 μs
Dilithium3 192-bit 1 952 3 293 ~200 μs

The major disadvantage of lattice-based systems is that they rely on new hardness assumptions, which may be broken in the future.

5.1.1 Hardware wallets

The generation of a CRYSTALS-Dilithium public key requires approximately 10 KB of RAM and takes around 50 ms on ARM Cortex M4.

5.2 SPHINCS+

SPHINCS+ is hash-based digital signature scheme. It's the most conservative choice because it only relies on the preimage resistance of hash functions.

The disadvantages of SPHINCS+ are relatively large signatures and slow key generation.

variant security level public key size signature size keygen (Intel Haswell)
SPHINCS+-SHA-256-128s-simple 128-bit 32 7 856 ~100 ms
SPHINCS+-SHA-256-128s-robust 128-bit 32 7 856 ~200 ms
SPHINCS+-SHA-256-128f-simple 128-bit 32 17 088 ~1.5 ms
SPHINCS+-SHA-256-128f-robust 128-bit 32 17 088 ~3 ms
SPHINCS+-SHA-256-192s-simple 192-bit 48 16 224 ~150 ms
SPHINCS+-SHA-256-192s-robust 192-bit 48 16 224 ~300 ms
SPHINCS+-SHA-256-192f-simple 192-bit 48 35 664 ~3 ms
SPHINCS+-SHA-256-192f-robust 192-bit 48 35 664 ~6 ms

5.2.1 Hardware wallets

The generation of a SPHINCS+ public key requires approximately 2 KB of RAM and takes around 0.5 seconds on ARM Cortex M4 for the "f-simple" variants and around 10-20 seconds for the "s-simple" variants. The "robust" variants are twice slower.

6. Summary

Incorporating this protocol into Seraphis requires the following 4 wallet-side functions:

  1. MakeCommit(r', v), returns (C, r) (Ch. 3.1.2)
  2. MakeWallet(m), returns (kvb, ks) (Ch. 3.2)
  3. MakeAddressExt(Ks, sga, j), returns (kaddr_x, kaddr_u) (Ch. 3.3.1)
  4. MakeSenderExt(Kaddr, sshared, C), returns (ksender_x, ksender_u) (Ch. 3.3.2)

These functions enable a backwards-compatible post-quantum protocol to be activated eiher as an emergency hard-fork or as part of a post-quantum migration process.

While it's possible that the post-quantum protocol may not be needed in the foreseeable future, the "zero-cost" nature of this proposal makes it a very cheap mitigation for a possible disaster.

References

[1] https://github.com/insight-decentralized-consensus-lab/post-quantum-monero/blob/master/writeups/technical_note.pdf

[2] https://github.com/UkoeHB/Seraphis/blob/master/Seraphis-0-0-16.pdf

[3] https://eprint.iacr.org/2017/237.pdf

[4] https://lists.launchpad.net/mimblewimble/msg00479.html

[5] https://crypto.ethz.ch/publications/files/CamSta97b.pdf

[6] https://csrc.nist.gov/projects/post-quantum-cryptography/selected-algorithms-2022

[7] https://csrc.nist.gov/csrc/media/Projects/post-quantum-cryptography/documents/selected-algos-2022/final-ip-statements/Falcon-Statements-final.pdf

@kayabaNerve
Copy link

We don't have a requirement to support multiple messages, right? Would a traditional WOTS(+) signature achieve smaller sizes compared to SPHINCS+?

The overall idea sounds great and generally trivial to implement as needed during a pre-quantum setting.

@tevador
Copy link
Author

tevador commented Sep 5, 2022

Yes, WOTS might work. That would require each wallet to migrate all of its Seraphis outputs in a single transactions, which could be doable.

I'd prefer to avoid lattice-based crypto if possible.

@kayabaNerve
Copy link

Considering Seraphis would already have been deprecated AND they'd share the same root key... I don't see why we wouldn't migrate in a single TX simply in the name of efficiency. There's no privacy distinction here. Removing the tree removes a lot of complexity and should also reduce the signature size.

@WooolJuuun
Copy link

A good summary. However, the two post-quantum signature algorithms mentioned in the article are released by NIST. How can we ensure that they do not have any backdoors?

@kayabaNerve
Copy link

Hash-based signatures (as proposed here) are dead simple to understand and can directly inherit the security of the hash function (I'd have to double check security arguments around non-single-use signatures).

We'd just instantiate it with a hash function we already trust.

Also, all of the PQ algorithms were scrutinized for backdoors and they accordingly frequently used NUMS, nothing up my sleeves, methods for constants. They've also had wide review by the community. I would not be concerned about explicit backdoors (though I would be potentially concerned about security claims of some of the algorithms, which is why we'd make a conservative decision).

@chaserene
Copy link

this isn't directly relevant to this mitigation scheme (especially since SPHINCS+ seems to have the stronger support), rather a reaction to the following sentiment:

These algorithms have survived at least 6 years of cryptanalysis

all of the PQ algorithms were scrutinized for backdoors

them being chosen by NIST as finalists and being accepted by a majority doesn't necessarily mean that they are the best/good options.

Daniel J Bernstein (contributor to most of the cryptographic schemes and curves we use today, and a staunch advocate against up-my-sleeves crypto) has been criticizing the process a lot on his blog http://blog.cr.yp.to/index.html, from 2022.08.05 on. he went as far as suing the US government again (he has already done that once in the 90s).

the NIST PQ process does look botched. it took awful long and there were many published attacks after each round of approved candidates. the "best" part was probably where the sole candidate for a whole algo famly was broken the same month that NIST announced it as a target for standardization.

although it's a PKE and not a signature algorithm, here's an example of a project going forward with a non-NIST PQ scheme: https://simplex.chat/blog/20240314-simplex-chat-v5-6-quantum-resistance-signal-double-ratchet-algorithm.html#adding-quantum-resistance-to-signal-double-ratchet-algorithm

@kayabaNerve
Copy link

  1. I do appreciate djb's efforts for transparency, even if I don't appreciate all their commentary, and won't claim the process perfect.
  2. That SIDH commentary includes how there were not known attacks and ended up with a groundbreaking new attack. While I won't claim that's likely for ECs, or other well worked with items, I'm forced to note that could happen to a variety of cryptographic constructions. Regardless, we discussed constructions meant to be robust against this sort of commentary.
  3. I generally don't support Kyber anywhere as it's patented, and truly hope there's an IETF NTRU spec. SimpleX attacks the Kyber spec for lines 304-314. 309-314 is the removal of a hash call which is completely justified in context, and was argued for elsewhere. It was literally referred to as the "hash of shame" in some circles. It's far from critical.

Then lines 304-308 are about a distinct topic (though also a hash) justified as:

Hashing the (hash of the) ciphertext into the final shared key does
not help at all with any formal security property or with proofs. On
the contrary, hashing the hash of the ciphertext into the final key
complicates QROM proofs as pointed out in
https://eprint.iacr.org/2021/708.pdf.

Accordingly, I don't really care for SimpleX's thoughts on this matter.

I vote we stay on the topic of the actual candidates for us, not if every candidate by NIST makes the most sense or if Kyber was wrongfully given first place, not second (or third, or whatever the argument would be).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment