> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# P256

> secp256r1 (P-256) signature verification precompile for WebAuthn and secure hardware

## Overview

The P256 precompile provides native support for verifying secp256r1 (P-256) elliptic curve signatures, implementing EIP-7212. This enables smart contracts to verify signatures from WebAuthn authenticators, secure hardware modules, and other systems using the P-256 curve.

**Address**: `0x0000000000000000000000000000000000000100`

## Gas Costs

Fixed cost: **3,450 gas**

## Method

### Signature Verification

The precompile exposes a single unnamed function that verifies P-256 signatures.

**Input Format** (160 bytes):

* Bytes 0-31: `message_hash` (32 bytes) - The hash of the message
* Bytes 32-63: `r` (32 bytes) - The r component of the signature
* Bytes 64-95: `s` (32 bytes) - The s component of the signature
* Bytes 96-127: `x` (32 bytes) - The x coordinate of the public key
* Bytes 128-159: `y` (32 bytes) - The y coordinate of the public key

**Output Format** (32 bytes):

* Returns `0x0000...0001` (1) if signature is valid
* Returns `0x0000...0000` (0) if signature is invalid

### Example Usage

<CodeGroup>
  ```solidity Solidity theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  // P256 signature verification
  address constant P256_PRECOMPILE = 0x0000000000000000000000000000000000000100;

  function verifyP256Signature(
      bytes32 messageHash,
      bytes32 r,
      bytes32 s,
      bytes32 x,
      bytes32 y
  ) external view returns (bool) {
      bytes memory input = abi.encodePacked(messageHash, r, s, x, y);
      
      (bool success, bytes memory result) = P256_PRECOMPILE.staticcall(input);
      
      if (!success || result.length != 32) {
          return false;
      }
      
      return uint256(bytes32(result)) == 1;
  }
  ```

  ```javascript Ethers.js theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
  const ethers = require('ethers');

  // P256 precompile address
  const P256_ADDRESS = '0x0000000000000000000000000000000000000100';

  async function verifyP256Signature(provider, messageHash, r, s, x, y) {
      // Encode the input data
      const input = ethers.utils.concat([
          messageHash,
          r,
          s,
          x,
          y
      ]);
      
      // Call the precompile
      const result = await provider.call({
          to: P256_ADDRESS,
          data: input
      });
      
      // Check if signature is valid (result should be 0x00...01)
      return result === '0x' + '00'.repeat(31) + '01';
  }
  ```
</CodeGroup>

## Implementation Details

### Curve Parameters

The precompile uses the secp256r1 (NIST P-256) elliptic curve with the following parameters:

* Field prime: `p = 2^256 - 2^224 + 2^192 + 2^96 - 1`
* Curve equation: `y² = x³ + ax + b` where:
  * `a = -3`
  * `b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b`

### Input Validation

The precompile performs the following validations:

1. Input must be exactly 160 bytes
2. Public key coordinates (x, y) must be valid points on the curve
3. Signature components (r, s) must be within the valid range \[1, n-1] where n is the curve order

### Security Considerations

* The precompile only verifies that a signature is mathematically valid for the given public key
* Applications must implement additional checks such as:
  * Public key authentication (e.g., WebAuthn credential verification)
  * Message format validation
  * Replay attack prevention

## Use Cases

### WebAuthn Integration

The P256 precompile enables smart contracts to verify WebAuthn assertions, allowing for:

* Passwordless authentication
* Hardware security key support
* Biometric authentication via compatible devices

### Secure Hardware Modules

Many secure elements and hardware security modules use P-256 for signing operations:

* Apple Secure Enclave
* Android Keystore (when configured for P-256)
* TPM 2.0 modules
* Smart cards

### Example: WebAuthn Verification

```solidity theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
contract WebAuthnWallet {
    using bytes for bytes;
    
    struct Credential {
        bytes32 credentialId;
        uint256 publicKeyX;
        uint256 publicKeyY;
    }
    
    mapping(address => Credential) public credentials;
    
    function verify(
        bytes calldata authenticatorData,
        bytes calldata clientDataJSON,
        bytes32 r,
        bytes32 s
    ) external view returns (bool) {
        Credential memory cred = credentials[msg.sender];
        
        // Compute challenge hash according to WebAuthn spec
        bytes32 clientDataHash = sha256(clientDataJSON);
        bytes32 messageHash = sha256(abi.encodePacked(authenticatorData, clientDataHash));
        
        // Verify P-256 signature
        bytes memory input = abi.encodePacked(
            messageHash,
            r,
            s,
            bytes32(cred.publicKeyX),
            bytes32(cred.publicKeyY)
        );
        
        (bool success, bytes memory result) = address(0x100).staticcall(input);
        return success && result.length == 32 && uint256(bytes32(result)) == 1;
    }
}
```

## Gas Optimization

Since the gas cost is fixed at 3,450, optimizations should focus on:

* Minimizing the number of signature verifications
* Batch processing where possible
* Caching verification results when appropriate
