[N4] Post-Quantum Cryptography
Research and integration of quantum-resistant primitives to ensure long-term security.
Propose research and initial integration of quantum-resistant cryptographic primitives to ensure long-term security of the Neo blockchain. The goal is to evaluate suitable post-quantum algorithms and determine the necessary protocol and implementation changes for cross-compatibility across all Neo clients.
Motivation:
Quantum computing poses a potential long-term threat to existing elliptic curve cryptography. Integrating post-quantum primitives now ensures Neo’s cryptographic resilience and interoperability across all supported languages and clients.
Tasks:
- [ ] Research NIST-recommended post-quantum algorithms (e.g., CRYSTALS-Kyber, Dilithium, Falcon) suitable for blockchain usage.
- [ ] Evaluate if hash size should be increased to 512 bits (e.g., SHA3-512 or BLAKE2b-512) to maintain quantum resistance.
- [ ] Assess compatibility of proposed algorithms with neo-go and python toolchains.
- [ ] Define upgrade paths and potential backward compatibility strategy.
- [ ] Implement prototype support in core and SDKs for testing interoperability.
- [ ] Document findings and prepare a NEP draft specifying algorithm selection and integration details.
Related PRs
- #4291
Draft for 1:
1.1 The CRYSTALS-Kyber is not a signature algorithm, so we cannot use it.
The Dilithium(ML-DSA, FIPS 204). MS has a package to suport it(https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.mldsa). But the private key has a big private key size:
Method Public key size Private key size Signature size Security level
------------------------------------------------------------------------------------------------------
Crystals Dilithium 2 1,312 2,528 2,420 1 (128-bit)
Crystals Dilithium 3 1,952 4,000 3,293 3 (192-bit)
Crystals Dilithium 5 2,592 4,864 4,595 5 (256-bit)
1.2 The Falcon(FN-DSA, FIPS 206, BouncyCastle supports it) has smaller key and signature size, but slower(about 1/30 ~ 1/80 speed of ML-DSA). it.
Method Public key size Private key size Signature size Security level
------------------------------------------------------------------------------------------------------
Falcon 512 897 1,281 690 1 (128-bit)
Falcon 1024 1,793 2,305 1,330 5 (256-bit)
1.3 SL-DSA has too large signature size, so cannot use it.
1.4
Recommend Falcon 512
ECC256 KeyPair -> Falcon512 Keypair.
syscall CheckSig -> syscall CheckFN512Sig.
Draft for 2. 256bit hash has 128bit security level for PQC, and too many compatible issues if increasing hash size.
So increasing the hash size is not absolutely necessary.
But neo can change the hash algorithms.
For example:
PublicKey -> Address: TruncateTo160(Sha256(Sha3_512(public-key)))
Private key size is the small issue I think, it's the easier change that we can have
Private key size is the small issue I think, it's the easier change that we can have
Signature size is critical.
PublicKey -> Address: TruncateTo160(Sha256(Sha3_512(private-key)))
If we don't increase the size, the collision could be easier
Private key size is the small issue I think, it's the easier change that we can have
Signature size is critical.
Signature yes, but private it's internal
PublicKey -> Address: TruncateTo160(Sha256(Sha3_512(private-key)))
If we don't increase the size, the collision could be easier
128-bit security level is good enough, I think.
Draft for 3. C#, Go, Python have packages to support PQC. C#: BouncyCastle and MS packages. Go: https://github.com/cloudflare/circl. Python: many packages.
Auggestion: PQC is necessary/important but not urgent, so neo can take action after other more well-known projects have taken action.
Before this, neo can provide a draft design, but not implement it.,
and some features like signing and verification can be provided first in CryptoLib.
For reference: Dilithium can be further extended into Threshold Dilithium in the future, enabling support for aggregated (multi-party) signatures.
Private key size is the small issue I think, it's the easier change that we can have
Signature size is critical.
Signature yes, but private it's internal
The signature size is 10 to 60 times larger.
It's a problem.
Uint512 type could be required, could you also create it?
Uint512type could be required, could you also create it?
Does hash size readlly need to be increased to 512 bits?
Uint512type could be required, could you also create it?Does hash size readlly need to be increased to 512 bits?
If we create a new kind of wallet, with new kind of verification, it could use a longer hash size, preserving the current ones.
Uint512type could be required, could you also create it?Does hash size readlly need to be increased to 512 bits?
If we create a new kind of wallet, with new kind of verification, it could use a longer hash size, preserving the current ones.
Why is larger hash size necessary?
Uint512type could be required, could you also create it?Does hash size readlly need to be increased to 512 bits?
If we create a new kind of wallet, with new kind of verification, it could use a longer hash size, preserving the current ones.
Why is larger hash size necessary?
UInt160 is very small for PC, so we will need to be able to choose a different one for signing, why not allow 512 if we will allow 256?
Uint512type could be required, could you also create it?Does hash size readlly need to be increased to 512 bits?
If we create a new kind of wallet, with new kind of verification, it could use a longer hash size, preserving the current ones.
Why is larger hash size necessary?
UInt160 is very small for PC, so we will need to be able to choose a different one for signing, why not allow 512 if we will allow 256?
The UInt160 is generated from twice hash, so neo can use larger first hash size, for example: SHA3-512.
Account will be generated from Hash160(Hash512(public-key)), for example:
TruncateTo160(SHA256(SHA3_512(public-key))).
Even if PC can break the first hash160, it would be difficult to break the second hash512.
If neo change the account size, tooooo many compatible issues.
Uint512type could be required, could you also create it?
The task is completed. Submit a PR now?
Uint512type could be required, could you also create it?Does hash size readlly need to be increased to 512 bits?
If we create a new kind of wallet, with new kind of verification, it could use a longer hash size, preserving the current ones.
Why is larger hash size necessary?
UInt160 is very small for PC, so we will need to be able to choose a different one for signing, why not allow 512 if we will allow 256?
The UInt160 is generated from twice hash, so neo can use larger first hash size, for example: SHA3-512. Account will be generated from Hash160(Hash512(public-key)), for example:
TruncateTo160(SHA256(SHA3_512(public-key))).Even if PC can break the first hash160, it would be difficult to break the second hash512.
If neo change the account size, tooooo many compatible issues.
agree.
Uint512 and ML-DSA are supported. Submit the PR now, or wait to finalize the solution?
Uint512 and ML-DSA are supported. Submit the PR now, or wait to finalize the solution?
I think is good to have it, we can do bencharks and tests
As @Wi1l-B0t said, Kyber is for message encryption, it is currently in use on Signal, for example.
In need to face, initially, the decision between Dilithium and Falcon, but Falcon requires delicate floating-point arithmetic, which can not be perfect for decentralized networks with different machines specification.
@Wi1l-B0t , in your description you said that BouncyCastle Supports Falcon, but it looks like that it supports CRYSTALS-Dilithium (ML-DSA) instead. Can you confirm?
Dilithium can be further extended into Threshold Dilithium in the future, enabling support for aggregated (multi-party) signatures.
For reference:
https://csrc.nist.gov/csrc/media/events/2025/sixth-pqc-standardization-conference/efficient%20threshold%20ml-dsa%20up%20to%206%20parties.pdf
https://csrc.nist.gov/csrc/media/presentations/2025/efficient-threshold-ml-dsa-up-to-6-parties/efficient_threshold-niot_2.13.pdf
@Wi1l-B0t , in your description you said that BouncyCastle Supports Falcon, but it looks like that it supports CRYSTALS-Dilithium (ML-DSA) instead. Can you confirm?
It supports CRYSTALS-Dilithium (ML-DSA), and partly supports Falcon.
As @Wi1l-B0t said, Kyber is for message encryption, it is currently in use on Signal, for example.
In need to face, initially, the decision between Dilithium and Falcon, but Falcon requires delicate floating-point arithmetic, which can not be perfect for decentralized networks with different machines specification.
Yes. This might be a problem.
Another important perspective is related to Hardware Wallets... perhaps the choice here that has largest support is the best one, because this can even make it unfeasible for migration. I think I've seen some discussions on these for Dilithium, not for Falcon, but just to consider this point before it's too late :)