SIMD-0075

Precompile for verifying secp256r1 sig.

Author: Orion (Bunkr), Jstnw (Bunkr), Dean (Web3 Builders Alliance) · Category: Core Protocol GitHub →

Feature Gate Status

Mainnet Active E800
Testnet Active E770
Devnet Active E881

srremy31J5Y25FrAApwVb9kZcfXbusYMMsvTK9aWv5q

TL;DR

Adding a precompile to support the verification of signatures generated on the secp256r1 curve. Analogous to the support for secp256k1 and ed25519 signatures that already exists in form of the `KeccakSecp256k11111111111111111111111111111` and `Ed25519SigVerify111111111111111111111111111` precompiles. 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.

Summary

Adding a precompile to support the verification of signatures generated on the secp256r1 curve. Analogous to the support for secp256k1 and ed25519 signatures that already exists in form of the `KeccakSecp256k11111111111111111111111111111` and `Ed25519SigVerify111111111111111111111111111` precompiles. 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.

Motivation

Solana has the opportunity to leverage the secure element of users' existing mobile devices to support more user-friendly self-custodial security solutions. The status quo of air-gapping signing with a hardware wallet currently requires specialty hardware and still represents a single point of failure. Multi-signature wallets provide enhanced security through multi-party signing, however the UX is cumbersome due to the need to sign transactions multiple times and manage multiple seed phrases. A much more ergonomic approach combining the best of these two solutions on generalised mobile hardware could be achieved by adding support for secp256r1 signatures. There are already several standardised implementations of this, such as Passkeys and WebAuthn. These solutions leverage Apple's Secure Enclave and Android Keystore to enable users to save keypairs associated to different services natively on the secure element of their mobile devices. To authenticate with those services, the user uses their biometrics to sign a message with the stored private key. While originally intended to solve for password-less authentication in Web2 applications, WebAuthn and Passkeys also make an excellent candidate for on-chain second-factor authentication. Beyond simply securing funds, there are also many other potential beneficial abstractions that could make use of the simple UX they provide. Although WebAuthn supports the following curves: - P-256 - P-384 - P-521 - ed25519 P-256 is the only one supported by both Android & MacOS/iOS (MacOS/iOS being the more restrictive of the two), hence the goal being to implement secp256r1 signature verification General Documentation: [WebAuthn](https://webauthn.io/) [Passkeys](https://fidoalliance.org/passkeys/) **Note: P-256 / secp256r1 / prime256v1 are used interchangably in this document as they represent the same elliptic curve. The choice of nomenclature depends on what RFC or SEC document is being referenced.**

Key Changes

  • If instruction data is empty, return error.
  • The first byte of data is the number of signatures num_signatures.
  • If num_signatures is 0, return error.
  • Expect (enough bytes of data for) num_signatures instances of Secp256r1SignatureOffsets.
  • For each signature: a. Read offsets: an instance of Secp256r1SignatureOffsets b. Based on the offsets, retrieve signature, public_key, and message bytes. If any of the three fails, return error. c. Invoke the actual sigverify function. If it fails, return error.
  • Get the instruction_index-th instruction_data
  • The special value 0xFFFF means "current instruction"
  • If the index is invalid, return Error
  • Return length bytes starting from offset
  • If this exceeds the instruction_data length, return Error

Impact

Would enable the on-chain usage of Passkeys and the WebAuthn Standard, and turn the vast majority of modern smartphones into native hardware wallets. By extension, this would also enable the creation of account abstractions and forms of Two-Factor Authentication around those keypairs.

Backwards Compatibility

Transactions using the instruction could not be used on Solana versions which don't implement this feature. A Feature gate should be used to enable this feature when the majority of the cluster is using the required version. Transactions that do not use this feature are not impacted.

Security Considerations

The following security considerations must be made for the implementation of ECDSA over NIST P-256. ### Curve The curve parameters for NIST P-256/secp256r1/prime256v1 are outlined in the [SEC2](https://www.secg.org/SEC2-Ver-1.0.pdf#page=21) document in Section 2.7.2 ### Point Encoding/Decoding The precompile must accept SEC1 encoded points in compressed form. The encoding and decoding of these is outlined in sections `2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion` and `2.3.4 Octet-String-to-Elliptic-Curve-Point Conversion` found in [SEC1](https://www.secg.org/sec1-v2.pdf#page=16). The SEC1 encoded EC point P = (x_p, y_p) in compressed form consists of 33 bytes (octets). The first byte of 02_16 / 03_16 signifies a compressed point, as well as whether y_p is odd or even. The remaining 32 bytes represent x_p converted into a 32 octet string. While SEC1 encoded uncompressed points could also be used, due to their larger size of 65 bytes, the ease of transformation between uncompressed and compressed points, and the vast majority of applications exclusively making use of compressed points, it seems a reasonable consideration to save 32 bytes of instruction data with a protocol that only accepts compressed points. ### ECDSA / Signature Verification The precompile must implement the `Verifying Operation` outlined in [SEC1](https://www.secg.org/sec1-v2.pdf#page=52) in Section 4.1.4 as well as in the [Digital Signature Standard (DSS)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf#page=36) document in Section 6.4.2. A multitude of test vectors to verify correctness can be found in [RFC6979](https://datatracker.ietf.org/doc/html/rfc6979#appendix-A.2.5) in Section A.2.5 as well as at the [NIST CAVP](https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/digital-signatures#ecdsa2vs) (Cryptographic Algorithm Validation Program) ### General As multiple other clients are being developed, it is imperative that there is bit-level reproducibility between the precompile implementations, especially with regard to cryptographic operations. Any discrepancy between implementations could cause a fork and or a chain halt. As such we would propose the following: - Development of a thorough test suite that includes all test vectors as well as tests from the [Wycheproof Project](https://github.com/google/wycheproof#project-wycheproof) - Maintaining active communication with other clients to ensure parity and to support potential changes if they arise.