From 9be719c0a80d94b91f95fcf9a7e87b447524bdf9 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Fri, 16 Jan 2026 21:55:18 -0500 Subject: [PATCH 01/12] Create XXXX-falcon-signature-precompile.md --- proposals/XXXX-falcon-signature-precompile.md | 495 ++++++++++++++++++ 1 file changed, 495 insertions(+) create mode 100644 proposals/XXXX-falcon-signature-precompile.md diff --git a/proposals/XXXX-falcon-signature-precompile.md b/proposals/XXXX-falcon-signature-precompile.md new file mode 100644 index 000000000..f8f03b76c --- /dev/null +++ b/proposals/XXXX-falcon-signature-precompile.md @@ -0,0 +1,495 @@ +--- +simd: 'XXXX' +title: Precompile for Falcon-512 Signature Verification +authors: + - TBD +category: Standard +type: Core +status: Draft +created: 2026-01-16 +feature: (fill in with feature key and github tracking issues once accepted) +--- + +## Summary + +Adding a precompile to support the verification of Falcon-512 signatures, +providing post-quantum cryptographic security for Solana transactions. +This enables quantum-resistant signature verification as an alternative +to the existing Ed25519 signatures. + +## Motivation + +Cryptographically Relevant Quantum Computers (CRQCs) pose a significant +threat to the security of current elliptic curve and RSA-based +cryptographic systems. When sufficiently powerful quantum computers become +available, Shor's algorithm will be able to break Ed25519, secp256k1, and +other elliptic curve signatures currently used by Solana and other +blockchains. + +NIST has standardized several post-quantum cryptographic algorithms +as part of their Post-Quantum Cryptography Standardization process. +Falcon (FN-DSA) was selected for standardization as draft FIPS 206, +with final publication expected in late 2026 or early 2027. Falcon was +chosen for its compact signature size relative to other lattice-based +schemes, making it particularly suitable for blockchain applications +where transaction size directly impacts costs and throughput. + +By adding Falcon-512 signature verification as a precompile, Solana can: + +1. **Future-proof the network**: Enable users to protect high-value + accounts and critical infrastructure against future quantum attacks. + +2. **Support hybrid security models**: Allow applications to require both + classical (Ed25519) and post-quantum (Falcon) signatures for + defense-in-depth. + +3. **Enable gradual migration**: Provide a migration path for the + ecosystem to transition to quantum-resistant cryptography before + quantum computers become a practical threat. + +4. **Maintain competitive positioning**: Other blockchain networks + (Ethereum via EIP-8052, etc.) are also preparing post-quantum + solutions. Solana should not fall behind in cryptographic security. + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", +"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this +document are to be interpreted as described in RFC 2119. + +## Dependencies + +This proposal depends on the following previously accepted proposals: + +- **[SIMD-0152]: Precompiles** + + This SIMD follows the unified precompile behavior defined in SIMD-0152. + +[SIMD-0152]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md + +## New Terminology + +- **Falcon / FN-DSA**: A lattice-based digital signature algorithm + selected by NIST for standardization (draft FIPS 206). Based on the + "Fast Fourier Lattice-based Compact Signatures over NTRU" scheme. + +- **Falcon-512**: The smaller parameter set of Falcon, providing + approximately 128 bits of classical security and targeting NIST + Security Level I (equivalent to AES-128). + +- **NTRU lattice**: The algebraic structure underlying Falcon, based on + polynomial rings modulo q = 12289. + +- **Post-quantum cryptography (PQC)**: Cryptographic algorithms believed + to be secure against attacks by both classical and quantum computers. + +## Detailed Design + +The precompile's purpose is to verify Falcon-512 signatures in accordance +with draft FIPS 206 (FN-DSA). + +### Falcon-512 Parameters + +The following parameters define Falcon-512: + +| Parameter | Value | +|-----------|-------| +| n (degree) | 512 | +| q (modulus) | 12289 | +| Public key size | 897 bytes | +| Signature size | <= 666 bytes | +| Security level | NIST Level I (~128 bits classical) | + +### Program + +ID: `Fa1con512SigVerify11111111111111111111111111` + +In accordance with [SIMD-0152], the program's `verify` instruction MUST +accept the following data: + +``` +struct Falcon512SigVerifyInstruction { + num_signatures: uint8 LE, // Number of signatures to verify + padding: uint8 LE, // Single byte padding + offsets: Array, // Array of offset structs + additionalData?: Bytes, // Optional additional data +} + +struct Falcon512SignatureOffsets { + signature_offset: uint16 LE, // Offset to signature + signature_length: uint16 LE, // Length of signature (variable) + signature_instruction_index: uint16 LE, // Instruction index to signature + public_key_offset: uint16 LE, // Offset to public key + public_key_instruction_index: uint16 LE, // Instruction index to public key + message_offset: uint16 LE, // Offset to start of message data + message_length: uint16 LE, // Size of message data + message_instruction_index: uint16 LE, // Instruction index to message +} +``` + +Note: Unlike Ed25519 and secp256k1/r1 which have fixed signature sizes, +Falcon signatures have variable length due to compression. The +`signature_length` field is required to handle this variability. The +maximum compressed signature size is 666 bytes as specified in draft +FIPS 206. This value may change in the final specification; implementations +MUST be updated to match the final FIPS 206 before activation. + +The padding byte MUST be ignored and MAY contain any value. + +### Signature Format + +Falcon-512 signatures MUST be in the compressed format as specified in +draft FIPS 206 Section 3.5. The signature consists of: + +1. A header byte (0x39 for Falcon-512 compressed, computed as 0x30 + logn) +2. A 40-byte random salt (nonce) +3. The compressed signature polynomial s2 + +The precompile MUST reject signatures that: +- Exceed the maximum allowed signature size (666 bytes) +- Have an invalid header byte +- Fail decompression +- Have coefficients outside the valid range + +### Public Key Format + +Public keys MUST be in the format specified in draft FIPS 206 Section 3.3: + +1. A header byte (0x09 for Falcon-512, computed as 0x00 + logn where logn = 9) +2. The 896-byte encoding of the public key polynomial h + +Total public key size: 897 bytes + +The precompile MUST reject public keys that: +- Have an invalid header byte +- Have an incorrect length +- Fail decoding + +### Verification Algorithm + +The verification follows draft FIPS 206 Algorithm 18 (Verify): + +1. Decode the public key h from the encoded format +2. Decode the signature (salt, s2) from the compressed format +3. Compute c = HashToPoint(salt || message) +4. Compute s1 = c - s2 * h (mod q) +5. Verify that ||(s1, s2)||^2 <= bound^2 + +The HashToPoint function uses SHAKE-256 as specified in draft FIPS 206 +to hash the message into a polynomial in Z_q[x]/(x^n + 1). + +### Behavior + +In accordance with [SIMD-0152], the behavior of the precompile MUST be: + +1. If instruction `data` is empty, return error. +2. The first byte of `data` is the number of signatures `num_signatures`. +3. If `num_signatures` is 0, return error. +4. If `num_signatures` > 8, return error (MAX_ALLOWED_PRECOMPILE_SIGNATURES). +5. Expect enough bytes of `data` for `num_signatures` instances of + `Falcon512SignatureOffsets`. +6. The second byte (padding) MUST be ignored and MAY contain any value. +7. Iterate `num_signatures` times: + a. Read `offsets`: an instance of `Falcon512SignatureOffsets` + b. Based on the `offsets`, retrieve `signature`, `public_key`, and + `message` bytes. If any of the three fails, return error. + c. Validate signature length is within bounds [41, 666]. The minimum + of 41 bytes accounts for the header byte (1) plus salt (40). Note + that decode failures during verification supersede length checks. + d. Invoke the Falcon-512 verification function. If it fails, return error. + +All arithmetic operations (offset + length, num_signatures * struct_size, +data_start_position increments) MUST use overflow-checked arithmetic. +If overflow occurs, return error. + +``` +/// Pseudocode for verification + +SERIALIZED_OFFSET_STRUCT_SIZE = 16 // 8 uint16 fields +PUBLIC_KEY_LENGTH = 897 +MAX_SIGNATURE_LENGTH = 666 +MIN_SIGNATURE_LENGTH = 41 // header (1) + salt (40) + +function verify() { + if length_of_data == 0 { + return Error + } + + num_signatures = data[0] + + if num_signatures == 0 { + return Error + } + + if num_signatures > 8 { + return Error + } + + // Check for overflow before arithmetic + required_length = checked_add( + checked_mul(num_signatures, SERIALIZED_OFFSET_STRUCT_SIZE), + 2 + ) + if required_length == OVERFLOW || length_of_data < required_length { + return Error + } + + all_tx_data = { data, instruction_datas } + data_start_position = 2 + + // Iterate num_signatures times + for i in 0 to num_signatures (exclusive) { + offsets = (Falcon512SignatureOffsets) + all_tx_data.data[data_start_position.. + data_start_position + SERIALIZED_OFFSET_STRUCT_SIZE] + data_start_position += SERIALIZED_OFFSET_STRUCT_SIZE + + // Validate signature length + if offsets.signature_length < MIN_SIGNATURE_LENGTH || + offsets.signature_length > MAX_SIGNATURE_LENGTH { + return Error + } + + signature = get_data_slice(all_tx_data, + offsets.signature_instruction_index, + offsets.signature_offset, + offsets.signature_length) + if !signature { + return Error + } + + public_key = get_data_slice(all_tx_data, + offsets.public_key_instruction_index, + offsets.public_key_offset, + PUBLIC_KEY_LENGTH) + if !public_key { + return Error + } + + message = get_data_slice(all_tx_data, + offsets.message_instruction_index, + offsets.message_offset, + offsets.message_length) + if !message { + return Error + } + + result = falcon512_verify(signature, public_key, message) + if result != Success { + return Error + } + } + return Success +} + +// This function is re-used across precompiles in accordance with SIMD-0152 +fn get_data_slice(all_tx_data, instruction_index, offset, length) { + if instruction_index == 0xFFFF { + instruction_data = all_tx_data.data + } else { + if instruction_index >= num_instructions { + return Error + } + instruction_data = all_tx_data.instruction_datas[instruction_index] + } + + start = offset + // Check for overflow before arithmetic + end = checked_add(offset, length) + if end == OVERFLOW || end > length(instruction_data) { + return Error + } + + return instruction_data[start..end] +} +``` + +### Compute Cost +(**Tentative**) + +Falcon-512 verification is computationally more expensive than Ed25519 +due to the polynomial arithmetic involved. Benchmarking MUST be performed +on representative hardware to determine appropriate compute costs. + +Based on preliminary estimates from reference implementations: +- Falcon-512 verification: approximately 0.5-1ms on modern hardware +- This translates to approximately 15,000-30,000 CUs per verification + +Final compute costs MUST be determined through benchmarking in accordance +with established Solana compute unit pricing conventions (33ns/CU). + +The maximum number of Falcon signatures per transaction is 8, consistent +with the limit defined in SIMD-0152 for all precompiles. + +## Alternatives Considered + +### 1. Other Post-Quantum Signature Schemes + +**Dilithium (ML-DSA):** +- Pros: Larger security margins, simpler implementation +- Cons: Significantly larger signatures (~2,420 bytes for Dilithium2 vs + ~666 bytes for Falcon-512), making it less suitable for blockchain use + +**SPHINCS+:** +- Pros: Hash-based, very conservative security assumptions +- Cons: Very large signatures (~17KB-49KB), impractical for blockchain + +**Falcon-1024:** +- Pros: Higher security level (NIST Level V) +- Cons: Larger signatures (~1,280 bytes) and keys (~1,793 bytes), + higher computational cost + +Falcon-512 provides the best balance of security, signature size, and +verification performance for blockchain applications. + +### 2. Syscall Instead of Precompile + +Similar to the discussion in SIMD-0048/0075, implementing as a syscall +would ease integration for developers by avoiding instruction +introspection. However, precompiles are the established pattern for +signature verification in Solana, and following this pattern ensures +consistency. + +### 3. On-chain BPF Implementation + +Implementing Falcon verification in BPF would consume excessive compute +units due to the complex polynomial arithmetic involved, making it +impractical without precompile support. + +### 4. Hash Function Variants + +EIP-8052 proposes two variants: one using SHAKE-256 (NIST-compliant) and +one using Keccak256 (EVM-optimized). For Solana, we recommend only the +NIST-compliant SHAKE-256 variant to: +- Maintain compliance with draft FIPS 206 +- Avoid unnecessary complexity +- Ensure interoperability with other draft FIPS 206 implementations + +## Impact + +### For dApp Developers + +- New precompile available for post-quantum signature verification +- Larger signature and public key sizes require adjustments to account + data structures and transaction layouts +- SDK updates will be needed to support Falcon key generation and signing + +### For Validators + +- Additional precompile to implement and maintain +- Higher computational cost per Falcon signature verification +- No impact on existing transaction processing + +### For Core Contributors + +- Implementation of Falcon-512 verification following draft FIPS 206 +- Integration with existing precompile infrastructure per SIMD-0152 +- Development of comprehensive test suites for cross-client compatibility + +## Security Considerations + +### Algorithm Security + +Falcon-512 targets NIST Security Level I, providing approximately 128 +bits of classical security and resistance against known quantum attacks. +The security is based on the hardness of the NTRU problem and the Short +Integer Solution (SIS) problem over NTRU lattices. + +### Implementation Security + +1. **Constant-time implementation**: The verification algorithm SHOULD be + implemented in constant time where feasible to prevent timing attacks, + though verification is inherently less sensitive than signing. + +2. **Input validation**: All inputs (signatures, public keys) MUST be + thoroughly validated before processing to prevent malformed input + attacks. + +3. **Signature uniqueness**: Unlike ECDSA, Falcon signatures are + inherently non-malleable due to the use of a random salt (nonce) in + the signing process. Each signing operation produces a unique + signature. + +### Cross-Client Consistency + +As with other precompiles, it is imperative that there is bit-level +reproducibility between implementations across different validator +clients. Any discrepancy could cause network forks. + +Recommendations: +- Development of a comprehensive test suite including NIST test vectors +- Active communication between client teams during implementation +- Use of well-audited reference implementations where possible + +### Migration Considerations + +This precompile does NOT replace Ed25519 for transaction signing. It +provides an additional verification capability that applications can +choose to use. A full migration of Solana's core transaction signatures +to post-quantum algorithms would require a separate, more comprehensive +proposal. + +## Drawbacks + +1. **Larger data sizes**: Falcon-512 public keys (897 bytes) and + signatures (~666 bytes) are significantly larger than Ed25519 (32 + bytes and 64 bytes respectively), increasing transaction sizes and + storage costs. + +2. **Higher computational cost**: Falcon verification is more expensive + than Ed25519, potentially reducing transaction throughput if widely + adopted. + +3. **Complexity**: Falcon's lattice-based cryptography is more complex + than elliptic curve cryptography, potentially increasing the attack + surface and maintenance burden. + +4. **Uncertain timeline**: The threat from quantum computers remains + uncertain, and this capability may not be needed for many years. + +5. **Ecosystem immaturity**: Post-quantum cryptography tooling and + libraries are less mature than classical cryptography. + +6. **Draft specification**: FIPS 206 is not yet finalized. If the final + specification differs from the current draft, this precompile may + require updates before activation. The implementation SHOULD track + the NIST standardization process and incorporate any changes from + the final FIPS 206 specification. + +## Backwards Compatibility + +Transactions using the Falcon precompile instruction cannot be processed +on Solana versions that do not implement this feature. A feature gate +MUST be used to enable this feature when the majority of the cluster is +running the required version. + +Transactions that do not use this feature are not impacted. + +Existing Ed25519 signatures and other precompiles (secp256k1, secp256r1) +continue to function unchanged. + +## Scope + +This precompile provides **signature verification only**. Key generation +and signing are out of scope and must be performed off-chain. Note that +Falcon signing is more complex than Ed25519 signing, requiring discrete +Gaussian sampling over lattices. Implementers should use well-audited +cryptographic libraries for signing operations. + +## Test Vectors + +Implementations MUST pass the Known Answer Tests (KATs) provided by NIST +for FN-DSA. Additional test vectors will be derived from: +- NIST ACVP (Automated Cryptographic Validation Protocol) test vectors +- Falcon reference implementation test suite +- Wycheproof project test vectors (when available) + +A comprehensive test suite will be developed and maintained to ensure +cross-client compatibility. + +## References + +- [Draft FIPS 206: FN-DSA (Falcon)](https://csrc.nist.gov/pubs/fips/206/ipd) - NIST Post-Quantum Signature Standard (Initial Public Draft) +- [EIP-8052: Falcon Signature Precompile](https://eips.ethereum.org/EIPS/eip-8052) +- [SIMD-0152: Precompiles](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md) +- [SIMD-0075: Precompile for secp256r1](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0075-precompile-for-secp256r1-sigverify.md) +- [Falcon Reference Implementation](https://falcon-sign.info/) +- [NIST PQC Standardization](https://csrc.nist.gov/projects/post-quantum-cryptography) From e349a4fa62876cb39fe4da6016e8c6dab0565bcd Mon Sep 17 00:00:00 2001 From: zz-sol Date: Tue, 20 Jan 2026 08:43:50 -0500 Subject: [PATCH 02/12] address david's comments --- proposals/XXXX-falcon-signature-precompile.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/proposals/XXXX-falcon-signature-precompile.md b/proposals/XXXX-falcon-signature-precompile.md index f8f03b76c..cd80bc238 100644 --- a/proposals/XXXX-falcon-signature-precompile.md +++ b/proposals/XXXX-falcon-signature-precompile.md @@ -390,14 +390,18 @@ NIST-compliant SHAKE-256 variant to: Falcon-512 targets NIST Security Level I, providing approximately 128 bits of classical security and resistance against known quantum attacks. -The security is based on the hardness of the NTRU problem and the Short -Integer Solution (SIS) problem over NTRU lattices. +The security is based on the hardness of the **NTRU problem**, which +relates to finding short vectors (**SVP**) in NTRU lattices. Without +knowledge of the trapdoor (private key), an attacker cannot find the +short signature vectors that satisfy the verification equation. ### Implementation Security -1. **Constant-time implementation**: The verification algorithm SHOULD be - implemented in constant time where feasible to prevent timing attacks, - though verification is inherently less sensitive than signing. +1. **Constant-time implementation**: Constant-time implementation is NOT + required for verification. Unlike signing (which involves secret key + operations), verification only processes public data (public key, + message, signature) and does not leak secret information through + timing variations. 2. **Input validation**: All inputs (signatures, public keys) MUST be thoroughly validated before processing to prevent malformed input From 0d56ad1d6acd6811dc290436c568f73e4963fc63 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Tue, 27 Jan 2026 08:20:47 -0500 Subject: [PATCH 03/12] clarify padding mechanism --- proposals/XXXX-falcon-signature-precompile.md | 70 ++++++++++--------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/proposals/XXXX-falcon-signature-precompile.md b/proposals/XXXX-falcon-signature-precompile.md index cd80bc238..0030e7225 100644 --- a/proposals/XXXX-falcon-signature-precompile.md +++ b/proposals/XXXX-falcon-signature-precompile.md @@ -95,12 +95,14 @@ The following parameters define Falcon-512: | n (degree) | 512 | | q (modulus) | 12289 | | Public key size | 897 bytes | -| Signature size | <= 666 bytes | +| Signature size | 666 bytes (padded, fixed) | | Security level | NIST Level I (~128 bits classical) | ### Program -ID: `Fa1con512SigVerify11111111111111111111111111` +ID: `Fa1con512SigVerify11111111111111111111111111` (placeholder) +The final program ID MUST be assigned via the standard precompile +program deployment process. In accordance with [SIMD-0152], the program's `verify` instruction MUST accept the following data: @@ -115,7 +117,6 @@ struct Falcon512SigVerifyInstruction { struct Falcon512SignatureOffsets { signature_offset: uint16 LE, // Offset to signature - signature_length: uint16 LE, // Length of signature (variable) signature_instruction_index: uint16 LE, // Instruction index to signature public_key_offset: uint16 LE, // Offset to public key public_key_instruction_index: uint16 LE, // Instruction index to public key @@ -125,28 +126,28 @@ struct Falcon512SignatureOffsets { } ``` -Note: Unlike Ed25519 and secp256k1/r1 which have fixed signature sizes, -Falcon signatures have variable length due to compression. The -`signature_length` field is required to handle this variability. The -maximum compressed signature size is 666 bytes as specified in draft -FIPS 206. This value may change in the final specification; implementations -MUST be updated to match the final FIPS 206 before activation. +Note: This proposal uses the fixed-length (padded) Falcon-512 signature +encoding. Signatures MUST be exactly 666 bytes. This value is specified +in draft FIPS 206 and may change in the final specification; this +document and implementations MUST be updated to match the final FIPS +206 before activation. -The padding byte MUST be ignored and MAY contain any value. +The padding byte MUST be ignored and MAY contain any value. It is +reserved for alignment/forward compatibility with SIMD-0152. ### Signature Format -Falcon-512 signatures MUST be in the compressed format as specified in -draft FIPS 206 Section 3.5. The signature consists of: +Falcon-512 signatures MUST be in the fixed-length (padded) format as +specified in draft FIPS 206. The signature consists of: -1. A header byte (0x39 for Falcon-512 compressed, computed as 0x30 + logn) +1. A header byte (as specified in draft FIPS 206 for Falcon-512 padded) 2. A 40-byte random salt (nonce) -3. The compressed signature polynomial s2 +3. The padded encoding of the signature polynomial s2 The precompile MUST reject signatures that: -- Exceed the maximum allowed signature size (666 bytes) +- Have a length other than 666 bytes - Have an invalid header byte -- Fail decompression +- Fail decoding - Have coefficients outside the valid range ### Public Key Format @@ -168,13 +169,22 @@ The precompile MUST reject public keys that: The verification follows draft FIPS 206 Algorithm 18 (Verify): 1. Decode the public key h from the encoded format -2. Decode the signature (salt, s2) from the compressed format +2. Decode the signature (salt, s2) from the padded format 3. Compute c = HashToPoint(salt || message) 4. Compute s1 = c - s2 * h (mod q) 5. Verify that ||(s1, s2)||^2 <= bound^2 The HashToPoint function uses SHAKE-256 as specified in draft FIPS 206 to hash the message into a polynomial in Z_q[x]/(x^n + 1). +The `bound` value is the Falcon-512 norm bound parameter defined in +draft FIPS 206; implementations MUST use that exact value for +verification. +This document MUST be updated with the exact numeric bound once the +final FIPS 206 value is published. +Domain separation for HashToPoint MUST follow the draft FIPS 206 +definition for Falcon-512. If Solana-specific domain separation is +desired, it MUST be applied by the caller to the message bytes before +invoking the precompile. ### Behavior @@ -191,9 +201,8 @@ In accordance with [SIMD-0152], the behavior of the precompile MUST be: a. Read `offsets`: an instance of `Falcon512SignatureOffsets` b. Based on the `offsets`, retrieve `signature`, `public_key`, and `message` bytes. If any of the three fails, return error. - c. Validate signature length is within bounds [41, 666]. The minimum - of 41 bytes accounts for the header byte (1) plus salt (40). Note - that decode failures during verification supersede length checks. + c. Validate signature length is exactly 666 bytes. Decode failures + during verification supersede length checks. d. Invoke the Falcon-512 verification function. If it fails, return error. All arithmetic operations (offset + length, num_signatures * struct_size, @@ -203,10 +212,9 @@ If overflow occurs, return error. ``` /// Pseudocode for verification -SERIALIZED_OFFSET_STRUCT_SIZE = 16 // 8 uint16 fields +SERIALIZED_OFFSET_STRUCT_SIZE = 14 // 7 uint16 fields PUBLIC_KEY_LENGTH = 897 -MAX_SIGNATURE_LENGTH = 666 -MIN_SIGNATURE_LENGTH = 41 // header (1) + salt (40) +SIGNATURE_LENGTH = 666 function verify() { if length_of_data == 0 { @@ -242,16 +250,10 @@ function verify() { data_start_position + SERIALIZED_OFFSET_STRUCT_SIZE] data_start_position += SERIALIZED_OFFSET_STRUCT_SIZE - // Validate signature length - if offsets.signature_length < MIN_SIGNATURE_LENGTH || - offsets.signature_length > MAX_SIGNATURE_LENGTH { - return Error - } - signature = get_data_slice(all_tx_data, offsets.signature_instruction_index, offsets.signature_offset, - offsets.signature_length) + SIGNATURE_LENGTH) if !signature { return Error } @@ -407,10 +409,10 @@ short signature vectors that satisfy the verification equation. thoroughly validated before processing to prevent malformed input attacks. -3. **Signature uniqueness**: Unlike ECDSA, Falcon signatures are - inherently non-malleable due to the use of a random salt (nonce) in - the signing process. Each signing operation produces a unique - signature. +3. **Signature uniqueness and malleability**: The random salt (nonce) + makes honest signatures unique across signings of the same message. + Non-malleability relies on the verification rule, including the + tight norm bound check, which should reject transformed signatures. ### Cross-Client Consistency From e58c219a3da9df23039fea99cce1100b7356d9e4 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Sun, 1 Feb 2026 10:48:08 -0500 Subject: [PATCH 04/12] adding simd number --- ...ture-precompile.md => 0461-falcon-signature-precompile.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename proposals/{XXXX-falcon-signature-precompile.md => 0461-falcon-signature-precompile.md} (99%) diff --git a/proposals/XXXX-falcon-signature-precompile.md b/proposals/0461-falcon-signature-precompile.md similarity index 99% rename from proposals/XXXX-falcon-signature-precompile.md rename to proposals/0461-falcon-signature-precompile.md index 0030e7225..0a1e1f58e 100644 --- a/proposals/XXXX-falcon-signature-precompile.md +++ b/proposals/0461-falcon-signature-precompile.md @@ -1,8 +1,8 @@ --- -simd: 'XXXX' +simd: '0461' title: Precompile for Falcon-512 Signature Verification authors: - - TBD + - ZZ category: Standard type: Core status: Draft From 029c036160eeb261721d3f35d04d201bb76aca25 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Sun, 1 Feb 2026 10:54:33 -0500 Subject: [PATCH 05/12] fix linter --- proposals/0461-falcon-signature-precompile.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/proposals/0461-falcon-signature-precompile.md b/proposals/0461-falcon-signature-precompile.md index 0a1e1f58e..e5af63b85 100644 --- a/proposals/0461-falcon-signature-precompile.md +++ b/proposals/0461-falcon-signature-precompile.md @@ -145,6 +145,7 @@ specified in draft FIPS 206. The signature consists of: 3. The padded encoding of the signature polynomial s2 The precompile MUST reject signatures that: + - Have a length other than 666 bytes - Have an invalid header byte - Fail decoding @@ -160,6 +161,7 @@ Public keys MUST be in the format specified in draft FIPS 206 Section 3.3: Total public key size: 897 bytes The precompile MUST reject public keys that: + - Have an invalid header byte - Have an incorrect length - Fail decoding @@ -305,6 +307,7 @@ fn get_data_slice(all_tx_data, instruction_index, offset, length) { ``` ### Compute Cost + (**Tentative**) Falcon-512 verification is computationally more expensive than Ed25519 @@ -312,6 +315,7 @@ due to the polynomial arithmetic involved. Benchmarking MUST be performed on representative hardware to determine appropriate compute costs. Based on preliminary estimates from reference implementations: + - Falcon-512 verification: approximately 0.5-1ms on modern hardware - This translates to approximately 15,000-30,000 CUs per verification @@ -326,15 +330,18 @@ with the limit defined in SIMD-0152 for all precompiles. ### 1. Other Post-Quantum Signature Schemes **Dilithium (ML-DSA):** + - Pros: Larger security margins, simpler implementation - Cons: Significantly larger signatures (~2,420 bytes for Dilithium2 vs ~666 bytes for Falcon-512), making it less suitable for blockchain use **SPHINCS+:** + - Pros: Hash-based, very conservative security assumptions - Cons: Very large signatures (~17KB-49KB), impractical for blockchain **Falcon-1024:** + - Pros: Higher security level (NIST Level V) - Cons: Larger signatures (~1,280 bytes) and keys (~1,793 bytes), higher computational cost @@ -361,6 +368,7 @@ impractical without precompile support. EIP-8052 proposes two variants: one using SHAKE-256 (NIST-compliant) and one using Keccak256 (EVM-optimized). For Solana, we recommend only the NIST-compliant SHAKE-256 variant to: + - Maintain compliance with draft FIPS 206 - Avoid unnecessary complexity - Ensure interoperability with other draft FIPS 206 implementations @@ -421,6 +429,7 @@ reproducibility between implementations across different validator clients. Any discrepancy could cause network forks. Recommendations: + - Development of a comprehensive test suite including NIST test vectors - Active communication between client teams during implementation - Use of well-audited reference implementations where possible @@ -484,6 +493,7 @@ cryptographic libraries for signing operations. Implementations MUST pass the Known Answer Tests (KATs) provided by NIST for FN-DSA. Additional test vectors will be derived from: + - NIST ACVP (Automated Cryptographic Validation Protocol) test vectors - Falcon reference implementation test suite - Wycheproof project test vectors (when available) @@ -493,7 +503,10 @@ cross-client compatibility. ## References -- [Draft FIPS 206: FN-DSA (Falcon)](https://csrc.nist.gov/pubs/fips/206/ipd) - NIST Post-Quantum Signature Standard (Initial Public Draft) +- [Draft FIPS 206: FN-DSA (Falcon)][fips-206] - NIST Post-Quantum Signature + Standard (Initial Public Draft) + +[fips-206]: https://csrc.nist.gov/pubs/fips/206/ipd - [EIP-8052: Falcon Signature Precompile](https://eips.ethereum.org/EIPS/eip-8052) - [SIMD-0152: Precompiles](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md) - [SIMD-0075: Precompile for secp256r1](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0075-precompile-for-secp256r1-sigverify.md) From 681312be0193ba0a6048faf4eb1466d8625d8030 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Sun, 1 Feb 2026 11:04:43 -0500 Subject: [PATCH 06/12] fix CI --- proposals/0461-falcon-signature-precompile.md | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/proposals/0461-falcon-signature-precompile.md b/proposals/0461-falcon-signature-precompile.md index e5af63b85..d577c1296 100644 --- a/proposals/0461-falcon-signature-precompile.md +++ b/proposals/0461-falcon-signature-precompile.md @@ -1,11 +1,11 @@ --- simd: '0461' -title: Precompile for Falcon-512 Signature Verification +title: Falcon-512 Signature Precompile authors: - ZZ category: Standard type: Core -status: Draft +status: Idea created: 2026-01-16 feature: (fill in with feature key and github tracking issues once accepted) --- @@ -505,10 +505,13 @@ cross-client compatibility. - [Draft FIPS 206: FN-DSA (Falcon)][fips-206] - NIST Post-Quantum Signature Standard (Initial Public Draft) - -[fips-206]: https://csrc.nist.gov/pubs/fips/206/ipd -- [EIP-8052: Falcon Signature Precompile](https://eips.ethereum.org/EIPS/eip-8052) -- [SIMD-0152: Precompiles](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md) -- [SIMD-0075: Precompile for secp256r1](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0075-precompile-for-secp256r1-sigverify.md) +- [EIP-8052: Falcon Signature Precompile][eip-8052] +- [SIMD-0152: Precompiles][simd-0152] +- [SIMD-0075: Precompile for secp256r1][simd-0075] - [Falcon Reference Implementation](https://falcon-sign.info/) - [NIST PQC Standardization](https://csrc.nist.gov/projects/post-quantum-cryptography) + +[fips-206]: https://csrc.nist.gov/pubs/fips/206/ipd +[eip-8052]: https://eips.ethereum.org/EIPS/eip-8052 +[simd-0152]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md +[simd-0075]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0075-precompile-for-secp256r1-sigverify.md From dd4fe044ac96deef8e0b4526957718b3dd8de42c Mon Sep 17 00:00:00 2001 From: zz-sol Date: Sun, 1 Feb 2026 11:35:31 -0500 Subject: [PATCH 07/12] Update 0461-falcon-signature-precompile.md --- proposals/0461-falcon-signature-precompile.md | 1 - 1 file changed, 1 deletion(-) diff --git a/proposals/0461-falcon-signature-precompile.md b/proposals/0461-falcon-signature-precompile.md index d577c1296..0394f5e9e 100644 --- a/proposals/0461-falcon-signature-precompile.md +++ b/proposals/0461-falcon-signature-precompile.md @@ -513,5 +513,4 @@ cross-client compatibility. [fips-206]: https://csrc.nist.gov/pubs/fips/206/ipd [eip-8052]: https://eips.ethereum.org/EIPS/eip-8052 -[simd-0152]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md [simd-0075]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0075-precompile-for-secp256r1-sigverify.md From 01b3da888ccbbe9cb01f829bdf4be778a5e9a9a6 Mon Sep 17 00:00:00 2001 From: zz-sol Date: Thu, 5 Feb 2026 19:36:40 -0500 Subject: [PATCH 08/12] refactor into a syscall --- ...le.md => 0461-falcon-signature-syscall.md} | 275 +++++++----------- 1 file changed, 100 insertions(+), 175 deletions(-) rename proposals/{0461-falcon-signature-precompile.md => 0461-falcon-signature-syscall.md} (63%) diff --git a/proposals/0461-falcon-signature-precompile.md b/proposals/0461-falcon-signature-syscall.md similarity index 63% rename from proposals/0461-falcon-signature-precompile.md rename to proposals/0461-falcon-signature-syscall.md index 0394f5e9e..e637525e7 100644 --- a/proposals/0461-falcon-signature-precompile.md +++ b/proposals/0461-falcon-signature-syscall.md @@ -1,6 +1,6 @@ --- simd: '0461' -title: Falcon-512 Signature Precompile +title: Falcon-512 Signature Syscall authors: - ZZ category: Standard @@ -12,7 +12,7 @@ feature: (fill in with feature key and github tracking issues once accepted) ## Summary -Adding a precompile to support the verification of Falcon-512 signatures, +Adding a syscall to support the verification of Falcon-512 signatures, providing post-quantum cryptographic security for Solana transactions. This enables quantum-resistant signature verification as an alternative to the existing Ed25519 signatures. @@ -34,7 +34,7 @@ chosen for its compact signature size relative to other lattice-based schemes, making it particularly suitable for blockchain applications where transaction size directly impacts costs and throughput. -By adding Falcon-512 signature verification as a precompile, Solana can: +By adding Falcon-512 signature verification as a syscall, Solana can: 1. **Future-proof the network**: Enable users to protect high-value accounts and critical infrastructure against future quantum attacks. @@ -57,13 +57,7 @@ document are to be interpreted as described in RFC 2119. ## Dependencies -This proposal depends on the following previously accepted proposals: - -- **[SIMD-0152]: Precompiles** - - This SIMD follows the unified precompile behavior defined in SIMD-0152. - -[SIMD-0152]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0152-precompiles.md +None. ## New Terminology @@ -83,7 +77,7 @@ This proposal depends on the following previously accepted proposals: ## Detailed Design -The precompile's purpose is to verify Falcon-512 signatures in accordance +The syscall's purpose is to verify Falcon-512 signatures in accordance with draft FIPS 206 (FN-DSA). ### Falcon-512 Parameters @@ -98,43 +92,28 @@ The following parameters define Falcon-512: | Signature size | 666 bytes (padded, fixed) | | Security level | NIST Level I (~128 bits classical) | -### Program +### Syscall -ID: `Fa1con512SigVerify11111111111111111111111111` (placeholder) -The final program ID MUST be assigned via the standard precompile -program deployment process. +We propose a new syscall that verifies a single Falcon-512 signature per call: -In accordance with [SIMD-0152], the program's `verify` instruction MUST -accept the following data: - -``` -struct Falcon512SigVerifyInstruction { - num_signatures: uint8 LE, // Number of signatures to verify - padding: uint8 LE, // Single byte padding - offsets: Array, // Array of offset structs - additionalData?: Bytes, // Optional additional data -} - -struct Falcon512SignatureOffsets { - signature_offset: uint16 LE, // Offset to signature - signature_instruction_index: uint16 LE, // Instruction index to signature - public_key_offset: uint16 LE, // Offset to public key - public_key_instruction_index: uint16 LE, // Instruction index to public key - message_offset: uint16 LE, // Offset to start of message data - message_length: uint16 LE, // Size of message data - message_instruction_index: uint16 LE, // Instruction index to message -} +```rust +define_syscall!(fn sol_falcon512_verify( + signature_addr: *const u8, // 666 bytes, fixed-length padded signature + public_key_addr: *const u8, // 897 bytes + message_addr: *const u8, + message_len: u64, + result_addr: *mut u8 // 1 = valid, 0 = invalid +) -> u64); ``` +Programs can batch verifications by invoking the syscall multiple times. + Note: This proposal uses the fixed-length (padded) Falcon-512 signature encoding. Signatures MUST be exactly 666 bytes. This value is specified in draft FIPS 206 and may change in the final specification; this document and implementations MUST be updated to match the final FIPS 206 before activation. -The padding byte MUST be ignored and MAY contain any value. It is -reserved for alignment/forward compatibility with SIMD-0152. - ### Signature Format Falcon-512 signatures MUST be in the fixed-length (padded) format as @@ -144,9 +123,10 @@ specified in draft FIPS 206. The signature consists of: 2. A 40-byte random salt (nonce) 3. The padded encoding of the signature polynomial s2 -The precompile MUST reject signatures that: +The syscall MUST treat signatures as invalid if they: -- Have a length other than 666 bytes +- Are provided with insufficient buffer length (the syscall always reads + exactly 666 bytes) - Have an invalid header byte - Fail decoding - Have coefficients outside the valid range @@ -160,10 +140,11 @@ Public keys MUST be in the format specified in draft FIPS 206 Section 3.3: Total public key size: 897 bytes -The precompile MUST reject public keys that: +The syscall MUST treat public keys as invalid if they: +- Are provided with insufficient buffer length (the syscall always reads + exactly 897 bytes) - Have an invalid header byte -- Have an incorrect length - Fail decoding ### Verification Algorithm @@ -186,125 +167,37 @@ final FIPS 206 value is published. Domain separation for HashToPoint MUST follow the draft FIPS 206 definition for Falcon-512. If Solana-specific domain separation is desired, it MUST be applied by the caller to the message bytes before -invoking the precompile. +invoking the syscall. ### Behavior -In accordance with [SIMD-0152], the behavior of the precompile MUST be: - -1. If instruction `data` is empty, return error. -2. The first byte of `data` is the number of signatures `num_signatures`. -3. If `num_signatures` is 0, return error. -4. If `num_signatures` > 8, return error (MAX_ALLOWED_PRECOMPILE_SIGNATURES). -5. Expect enough bytes of `data` for `num_signatures` instances of - `Falcon512SignatureOffsets`. -6. The second byte (padding) MUST be ignored and MAY contain any value. -7. Iterate `num_signatures` times: - a. Read `offsets`: an instance of `Falcon512SignatureOffsets` - b. Based on the `offsets`, retrieve `signature`, `public_key`, and - `message` bytes. If any of the three fails, return error. - c. Validate signature length is exactly 666 bytes. Decode failures - during verification supersede length checks. - d. Invoke the Falcon-512 verification function. If it fails, return error. - -All arithmetic operations (offset + length, num_signatures * struct_size, -data_start_position increments) MUST use overflow-checked arithmetic. -If overflow occurs, return error. +The syscall MUST: -``` -/// Pseudocode for verification - -SERIALIZED_OFFSET_STRUCT_SIZE = 14 // 7 uint16 fields -PUBLIC_KEY_LENGTH = 897 -SIGNATURE_LENGTH = 666 - -function verify() { - if length_of_data == 0 { - return Error - } - - num_signatures = data[0] - - if num_signatures == 0 { - return Error - } - - if num_signatures > 8 { - return Error - } - - // Check for overflow before arithmetic - required_length = checked_add( - checked_mul(num_signatures, SERIALIZED_OFFSET_STRUCT_SIZE), - 2 - ) - if required_length == OVERFLOW || length_of_data < required_length { - return Error - } - - all_tx_data = { data, instruction_datas } - data_start_position = 2 - - // Iterate num_signatures times - for i in 0 to num_signatures (exclusive) { - offsets = (Falcon512SignatureOffsets) - all_tx_data.data[data_start_position.. - data_start_position + SERIALIZED_OFFSET_STRUCT_SIZE] - data_start_position += SERIALIZED_OFFSET_STRUCT_SIZE - - signature = get_data_slice(all_tx_data, - offsets.signature_instruction_index, - offsets.signature_offset, - SIGNATURE_LENGTH) - if !signature { - return Error - } - - public_key = get_data_slice(all_tx_data, - offsets.public_key_instruction_index, - offsets.public_key_offset, - PUBLIC_KEY_LENGTH) - if !public_key { - return Error - } - - message = get_data_slice(all_tx_data, - offsets.message_instruction_index, - offsets.message_offset, - offsets.message_length) - if !message { - return Error - } - - result = falcon512_verify(signature, public_key, message) - if result != Success { - return Error - } - } - return Success -} - -// This function is re-used across precompiles in accordance with SIMD-0152 -fn get_data_slice(all_tx_data, instruction_index, offset, length) { - if instruction_index == 0xFFFF { - instruction_data = all_tx_data.data - } else { - if instruction_index >= num_instructions { - return Error - } - instruction_data = all_tx_data.instruction_datas[instruction_index] - } - - start = offset - // Check for overflow before arithmetic - end = checked_add(offset, length) - if end == OVERFLOW || end > length(instruction_data) { - return Error - } - - return instruction_data[start..end] -} -``` +1. Read exactly 666 bytes at `signature_addr` and 897 bytes at + `public_key_addr`. +2. Read `message_len` bytes at `message_addr`. +3. Write the verification result to `result_addr` as a single byte: + `1` for valid, `0` for invalid. + +The syscall MUST treat any signature or public key that fails decoding +or format validation as invalid, and MUST return success with +`result_addr` set to `0` (i.e., invalid signature is not a fatal error). + +The syscall returns `0` on successful execution (regardless of signature +validity) after writing `result_addr`. Non-zero return values are +reserved for internal errors. + +The syscall MUST abort the virtual machine if any of the following are +true: + +- The VM memory ranges `[signature_addr, signature_addr + 666)` or + `[public_key_addr, public_key_addr + 897)` are not readable. +- The VM memory range `[message_addr, message_addr + message_len)` is + not readable. +- The VM memory range `[result_addr, result_addr + 1)` is not writable. +- `message_len` exceeds `MAX_FALCON_MESSAGE_LEN`. +- Any pointer + length arithmetic overflows. +- Compute budget is exceeded. ### Compute Cost @@ -322,8 +215,41 @@ Based on preliminary estimates from reference implementations: Final compute costs MUST be determined through benchmarking in accordance with established Solana compute unit pricing conventions (33ns/CU). -The maximum number of Falcon signatures per transaction is 8, consistent -with the limit defined in SIMD-0152 for all precompiles. +Because the verification hashes `message_len` bytes via SHAKE-256, the +syscall MUST meter compute cost for hashing work proportionally to +`message_len`, or enforce a maximum `message_len` to cap total cost. +This proposal specifies both: + +- `MAX_FALCON_MESSAGE_LEN`: maximum allowed `message_len` (bytes). Calls + with larger values MUST abort the VM. +- `falcon_hash_bytes_per_cu`: bytes per CU charged for hashing work. + +Compute cost MUST be charged as: + +``` +falcon_verify_base ++ ceil(message_len / falcon_hash_bytes_per_cu) +``` + +Where `falcon_verify_base` and `falcon_hash_bytes_per_cu` are runtime +parameters set by benchmarking. `MAX_FALCON_MESSAGE_LEN` is a fixed +constant defined by this SIMD and enforced by the feature gate. +**Tentative**: `MAX_FALCON_MESSAGE_LEN = 65_535`. +Cost calculation MUST use overflow-checked arithmetic. + +Programs can invoke the syscall multiple times to verify multiple +signatures within a single instruction; the total compute budget will +apply across all invocations. + +### Syscall Integration + +- The syscall MUST be feature-gated and unavailable prior to activation. +- The syscall MUST be registered in the runtime syscall table under the + name `sol_falcon512_verify`. +- The ABI MUST follow existing syscall conventions: + - `0` return value indicates successful execution (validity is conveyed + only via `result_addr`). + - Non-zero return values indicate internal errors. ## Alternatives Considered @@ -349,19 +275,19 @@ with the limit defined in SIMD-0152 for all precompiles. Falcon-512 provides the best balance of security, signature size, and verification performance for blockchain applications. -### 2. Syscall Instead of Precompile +### 2. Precompile Instead of Syscall -Similar to the discussion in SIMD-0048/0075, implementing as a syscall -would ease integration for developers by avoiding instruction -introspection. However, precompiles are the established pattern for -signature verification in Solana, and following this pattern ensures -consistency. +Following the existing signature verification pattern (Ed25519 and +secp256k1) via precompiles would keep consistency with established +native programs. However, a syscall avoids instruction introspection, +is simpler for program developers, and aligns with other cryptographic +operations already exposed via syscalls. ### 3. On-chain BPF Implementation Implementing Falcon verification in BPF would consume excessive compute units due to the complex polynomial arithmetic involved, making it -impractical without precompile support. +impractical without syscall support. ### 4. Hash Function Variants @@ -377,21 +303,21 @@ NIST-compliant SHAKE-256 variant to: ### For dApp Developers -- New precompile available for post-quantum signature verification +- New syscall available for post-quantum signature verification - Larger signature and public key sizes require adjustments to account data structures and transaction layouts - SDK updates will be needed to support Falcon key generation and signing ### For Validators -- Additional precompile to implement and maintain +- Additional syscall to implement and maintain - Higher computational cost per Falcon signature verification - No impact on existing transaction processing ### For Core Contributors - Implementation of Falcon-512 verification following draft FIPS 206 -- Integration with existing precompile infrastructure per SIMD-0152 +- Integration with the syscall interface and compute budget accounting - Development of comprehensive test suites for cross-client compatibility ## Security Considerations @@ -424,7 +350,7 @@ short signature vectors that satisfy the verification equation. ### Cross-Client Consistency -As with other precompiles, it is imperative that there is bit-level +As with other syscalls, it is imperative that there is bit-level reproducibility between implementations across different validator clients. Any discrepancy could cause network forks. @@ -436,7 +362,7 @@ Recommendations: ### Migration Considerations -This precompile does NOT replace Ed25519 for transaction signing. It +This syscall does NOT replace Ed25519 for transaction signing. It provides an additional verification capability that applications can choose to use. A full migration of Solana's core transaction signatures to post-quantum algorithms would require a separate, more comprehensive @@ -464,14 +390,14 @@ proposal. libraries are less mature than classical cryptography. 6. **Draft specification**: FIPS 206 is not yet finalized. If the final - specification differs from the current draft, this precompile may + specification differs from the current draft, this syscall may require updates before activation. The implementation SHOULD track the NIST standardization process and incorporate any changes from the final FIPS 206 specification. ## Backwards Compatibility -Transactions using the Falcon precompile instruction cannot be processed +Transactions using the Falcon syscall cannot be processed on Solana versions that do not implement this feature. A feature gate MUST be used to enable this feature when the majority of the cluster is running the required version. @@ -483,7 +409,7 @@ continue to function unchanged. ## Scope -This precompile provides **signature verification only**. Key generation +This syscall provides **signature verification only**. Key generation and signing are out of scope and must be performed off-chain. Note that Falcon signing is more complex than Ed25519 signing, requiring discrete Gaussian sampling over lattices. Implementers should use well-audited @@ -506,7 +432,6 @@ cross-client compatibility. - [Draft FIPS 206: FN-DSA (Falcon)][fips-206] - NIST Post-Quantum Signature Standard (Initial Public Draft) - [EIP-8052: Falcon Signature Precompile][eip-8052] -- [SIMD-0152: Precompiles][simd-0152] - [SIMD-0075: Precompile for secp256r1][simd-0075] - [Falcon Reference Implementation](https://falcon-sign.info/) - [NIST PQC Standardization](https://csrc.nist.gov/projects/post-quantum-cryptography) From 6594157629c132133a01e0af1e60343ff32ffa5b Mon Sep 17 00:00:00 2001 From: zz-sol Date: Fri, 6 Feb 2026 10:59:10 -0500 Subject: [PATCH 09/12] address comments --- proposals/0461-falcon-signature-syscall.md | 23 ++++++---------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/proposals/0461-falcon-signature-syscall.md b/proposals/0461-falcon-signature-syscall.md index e637525e7..7df053956 100644 --- a/proposals/0461-falcon-signature-syscall.md +++ b/proposals/0461-falcon-signature-syscall.md @@ -101,8 +101,7 @@ define_syscall!(fn sol_falcon512_verify( signature_addr: *const u8, // 666 bytes, fixed-length padded signature public_key_addr: *const u8, // 897 bytes message_addr: *const u8, - message_len: u64, - result_addr: *mut u8 // 1 = valid, 0 = invalid + message_len: u64 ) -> u64); ``` @@ -176,16 +175,14 @@ The syscall MUST: 1. Read exactly 666 bytes at `signature_addr` and 897 bytes at `public_key_addr`. 2. Read `message_len` bytes at `message_addr`. -3. Write the verification result to `result_addr` as a single byte: - `1` for valid, `0` for invalid. The syscall MUST treat any signature or public key that fails decoding -or format validation as invalid, and MUST return success with -`result_addr` set to `0` (i.e., invalid signature is not a fatal error). +or format validation as invalid. -The syscall returns `0` on successful execution (regardless of signature -validity) after writing `result_addr`. Non-zero return values are -reserved for internal errors. +Return values: + +- `0`: signature is valid +- `1`: signature is invalid (including any decoding or format failure) The syscall MUST abort the virtual machine if any of the following are true: @@ -194,7 +191,6 @@ true: `[public_key_addr, public_key_addr + 897)` are not readable. - The VM memory range `[message_addr, message_addr + message_len)` is not readable. -- The VM memory range `[result_addr, result_addr + 1)` is not writable. - `message_len` exceeds `MAX_FALCON_MESSAGE_LEN`. - Any pointer + length arithmetic overflows. - Compute budget is exceeded. @@ -246,10 +242,6 @@ apply across all invocations. - The syscall MUST be feature-gated and unavailable prior to activation. - The syscall MUST be registered in the runtime syscall table under the name `sol_falcon512_verify`. -- The ABI MUST follow existing syscall conventions: - - `0` return value indicates successful execution (validity is conveyed - only via `result_addr`). - - Non-zero return values indicate internal errors. ## Alternatives Considered @@ -404,9 +396,6 @@ running the required version. Transactions that do not use this feature are not impacted. -Existing Ed25519 signatures and other precompiles (secp256k1, secp256r1) -continue to function unchanged. - ## Scope This syscall provides **signature verification only**. Key generation From fbcffb1529b3ef39dfeae01ad6a633fd31f3ccad Mon Sep 17 00:00:00 2001 From: zz-sol Date: Fri, 6 Feb 2026 16:42:43 -0500 Subject: [PATCH 10/12] update reference links --- proposals/0461-falcon-signature-syscall.md | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/proposals/0461-falcon-signature-syscall.md b/proposals/0461-falcon-signature-syscall.md index 7df053956..db2c7ba7c 100644 --- a/proposals/0461-falcon-signature-syscall.md +++ b/proposals/0461-falcon-signature-syscall.md @@ -78,7 +78,7 @@ None. ## Detailed Design The syscall's purpose is to verify Falcon-512 signatures in accordance -with draft FIPS 206 (FN-DSA). +with the Falcon specification (v1.2). ### Falcon-512 Parameters @@ -108,15 +108,13 @@ define_syscall!(fn sol_falcon512_verify( Programs can batch verifications by invoking the syscall multiple times. Note: This proposal uses the fixed-length (padded) Falcon-512 signature -encoding. Signatures MUST be exactly 666 bytes. This value is specified -in draft FIPS 206 and may change in the final specification; this -document and implementations MUST be updated to match the final FIPS -206 before activation. +encoding. Signatures MUST be exactly 666 bytes, as specified in the +Falcon v1.2 specification. ### Signature Format Falcon-512 signatures MUST be in the fixed-length (padded) format as -specified in draft FIPS 206. The signature consists of: +specified in the Falcon v1.2 specification. The signature consists of: 1. A header byte (as specified in draft FIPS 206 for Falcon-512 padded) 2. A 40-byte random salt (nonce) @@ -132,7 +130,8 @@ The syscall MUST treat signatures as invalid if they: ### Public Key Format -Public keys MUST be in the format specified in draft FIPS 206 Section 3.3: +Public keys MUST be in the format specified in the Falcon v1.2 +specification: 1. A header byte (0x09 for Falcon-512, computed as 0x00 + logn where logn = 9) 2. The 896-byte encoding of the public key polynomial h @@ -148,7 +147,7 @@ The syscall MUST treat public keys as invalid if they: ### Verification Algorithm -The verification follows draft FIPS 206 Algorithm 18 (Verify): +The verification follows the Falcon v1.2 verification algorithm: 1. Decode the public key h from the encoded format 2. Decode the signature (salt, s2) from the padded format @@ -156,14 +155,12 @@ The verification follows draft FIPS 206 Algorithm 18 (Verify): 4. Compute s1 = c - s2 * h (mod q) 5. Verify that ||(s1, s2)||^2 <= bound^2 -The HashToPoint function uses SHAKE-256 as specified in draft FIPS 206 +The HashToPoint function uses SHAKE-256 as specified in the Falcon v1.2 to hash the message into a polynomial in Z_q[x]/(x^n + 1). The `bound` value is the Falcon-512 norm bound parameter defined in -draft FIPS 206; implementations MUST use that exact value for -verification. -This document MUST be updated with the exact numeric bound once the -final FIPS 206 value is published. -Domain separation for HashToPoint MUST follow the draft FIPS 206 +the Falcon v1.2 specification; implementations MUST use that exact +value for verification. +Domain separation for HashToPoint MUST follow the Falcon v1.2 definition for Falcon-512. If Solana-specific domain separation is desired, it MUST be applied by the caller to the message bytes before invoking the syscall. @@ -381,11 +378,11 @@ proposal. 5. **Ecosystem immaturity**: Post-quantum cryptography tooling and libraries are less mature than classical cryptography. -6. **Draft specification**: FIPS 206 is not yet finalized. If the final - specification differs from the current draft, this syscall may - require updates before activation. The implementation SHOULD track - the NIST standardization process and incorporate any changes from - the final FIPS 206 specification. +6. **Specification alignment**: If future NIST standardization (FIPS 206) + diverges from the Falcon v1.2 specification referenced here, this + syscall may require updates before activation. The implementation + SHOULD track the NIST standardization process and incorporate any + changes needed for alignment. ## Backwards Compatibility @@ -418,13 +415,16 @@ cross-client compatibility. ## References -- [Draft FIPS 206: FN-DSA (Falcon)][fips-206] - NIST Post-Quantum Signature - Standard (Initial Public Draft) +- [Falcon Specification v1.2 (PDF)][falcon-spec] +- [FIPS 206: FN-DSA (Falcon) Presentation][fips-206] - NIST CSRC presentation +- [FIPS 206 Status Update (PDF)][fips-206-pdf] - [EIP-8052: Falcon Signature Precompile][eip-8052] - [SIMD-0075: Precompile for secp256r1][simd-0075] - [Falcon Reference Implementation](https://falcon-sign.info/) - [NIST PQC Standardization](https://csrc.nist.gov/projects/post-quantum-cryptography) -[fips-206]: https://csrc.nist.gov/pubs/fips/206/ipd +[falcon-spec]: https://falcon-sign.info/falcon.pdf +[fips-206]: https://csrc.nist.gov/presentations/2025/fips-206-fn-dsa-falcon +[fips-206-pdf]: https://csrc.nist.gov/csrc/media/presentations/2025/fips-206-fn-dsa-%28falcon%29/images-media/fips_206-perlner_2.1.pdf [eip-8052]: https://eips.ethereum.org/EIPS/eip-8052 [simd-0075]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0075-precompile-for-secp256r1-sigverify.md From a57f4f6e1821137c2f5c0eb518e77f6de6588d4d Mon Sep 17 00:00:00 2001 From: zz-sol Date: Fri, 6 Feb 2026 17:17:56 -0500 Subject: [PATCH 11/12] address comments --- proposals/0461-falcon-signature-syscall.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/proposals/0461-falcon-signature-syscall.md b/proposals/0461-falcon-signature-syscall.md index db2c7ba7c..f0b1dbf5a 100644 --- a/proposals/0461-falcon-signature-syscall.md +++ b/proposals/0461-falcon-signature-syscall.md @@ -116,7 +116,7 @@ Falcon v1.2 specification. Falcon-512 signatures MUST be in the fixed-length (padded) format as specified in the Falcon v1.2 specification. The signature consists of: -1. A header byte (as specified in draft FIPS 206 for Falcon-512 padded) +1. A header byte (Falcon-512 padded: `0x39`) 2. A 40-byte random salt (nonce) 3. The padded encoding of the signature polynomial s2 @@ -153,7 +153,7 @@ The verification follows the Falcon v1.2 verification algorithm: 2. Decode the signature (salt, s2) from the padded format 3. Compute c = HashToPoint(salt || message) 4. Compute s1 = c - s2 * h (mod q) -5. Verify that ||(s1, s2)||^2 <= bound^2 +5. Verify that $$||(s1, s2)||^2 <= bound^2$$ The HashToPoint function uses SHAKE-256 as specified in the Falcon v1.2 to hash the message into a polynomial in Z_q[x]/(x^n + 1). @@ -202,7 +202,7 @@ on representative hardware to determine appropriate compute costs. Based on preliminary estimates from reference implementations: -- Falcon-512 verification: approximately 0.5-1ms on modern hardware +- Falcon-512 verification: approximately 10-20µs on modern hardware - This translates to approximately 15,000-30,000 CUs per verification Final compute costs MUST be determined through benchmarking in accordance @@ -228,7 +228,8 @@ Where `falcon_verify_base` and `falcon_hash_bytes_per_cu` are runtime parameters set by benchmarking. `MAX_FALCON_MESSAGE_LEN` is a fixed constant defined by this SIMD and enforced by the feature gate. **Tentative**: `MAX_FALCON_MESSAGE_LEN = 65_535`. -Cost calculation MUST use overflow-checked arithmetic. +Cost calculation MUST use saturating arithmetic and MUST NOT fail due to +overflow. Programs can invoke the syscall multiple times to verify multiple signatures within a single instruction; the total compute budget will From efe679b53e299820aedd9496fbba669f63fd96bf Mon Sep 17 00:00:00 2001 From: zz-sol Date: Fri, 6 Feb 2026 17:43:24 -0500 Subject: [PATCH 12/12] Update 0461-falcon-signature-syscall.md --- proposals/0461-falcon-signature-syscall.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0461-falcon-signature-syscall.md b/proposals/0461-falcon-signature-syscall.md index f0b1dbf5a..4f5277bb8 100644 --- a/proposals/0461-falcon-signature-syscall.md +++ b/proposals/0461-falcon-signature-syscall.md @@ -156,7 +156,7 @@ The verification follows the Falcon v1.2 verification algorithm: 5. Verify that $$||(s1, s2)||^2 <= bound^2$$ The HashToPoint function uses SHAKE-256 as specified in the Falcon v1.2 -to hash the message into a polynomial in Z_q[x]/(x^n + 1). +to hash the message into a polynomial in $$\mathbb{Z}_q[x]/(x^n + 1)$$. The `bound` value is the Falcon-512 norm bound parameter defined in the Falcon v1.2 specification; implementations MUST use that exact value for verification.