Skip to main content

Try it Live

Run SIWE examples in the interactive playground

Verification

Signature verification for SIWE messages.

verify

Verify SIWE message signature matches claimed address.

Signature

Parameters

  • message - BrandedMessage that was signed
  • signature - 65-byte signature (r + s + v)

Returns

true if signature valid and matches message.address false if signature invalid or address mismatch

Signature Format

Total: 65 bytesV normalization:
  • If v >= 27: recoveryId = v - 27
  • If v < 27: recoveryId = v
  • Valid recovery IDs: 0 or 1

Process

  1. Validate Message: Check structure with validate(message)
  2. Get Hash: Compute EIP-191 hash with getMessageHash(message)
  3. Extract Components: Parse r, s, v from signature
  4. Normalize V: Convert v to recovery ID (0 or 1)
  5. Recover Public Key: Use secp256k1 recovery
  6. Derive Address: Keccak-256(publicKey)[12:32]
  7. Compare: Check recovered address === message.address

Example

Common Patterns

Backend Verification

Instance Method

With Validation

Error Cases

Returns false for:
  • Invalid message structure
  • Signature length !== 65 bytes
  • Invalid v value (not 0, 1, 27, or 28)
  • Failed public key recovery
  • Address mismatch
  • Any exception during verification

Security Considerations

Constant-Time Comparison:
  • Address comparison loops through all 20 bytes
  • Prevents timing attacks
V Normalization:
  • Accepts both raw (0, 1) and EIP-155 (27, 28) formats
  • Rejects invalid v values
Public Key Recovery:
  • Uses secp256k1 curve (same as Ethereum)
  • Validates recovered point on curve
  • Rejects invalid signatures
No Malleability:
  • Signature uniqueness enforced by secp256k1
  • Low-s values recommended but not required

verifyMessage

Combined validation and signature verification.

Signature

Parameters

  • message - BrandedMessage to verify
  • signature - 65-byte signature
  • options.now - Current time for timestamp checks

Returns

ValidationResult:
  • { valid: true } - Structure valid AND signature verified
  • { valid: false, error: ValidationError } - Structure invalid OR signature mismatch

Process

  1. Validate Structure: Call validate(message, options)
  2. Return if Invalid: Early return with validation error
  3. Verify Signature: Call verify(message, signature)
  4. Return Result: { valid: true } or signature mismatch error

Example

Error Types

All validation errors plus:
  • signature_mismatch - Signature does not match address or verification failed

Common Patterns

Complete Verification

With Timestamp Check

Complete Auth Flow

Advantages Over Separate Calls

Convenience:
  • Single function call for complete verification
  • Structured error handling
  • Consistent return type
Efficiency:
  • Early return on validation failure
  • Skips expensive signature verification if structure invalid
Correctness:
  • Ensures validation always happens first
  • Prevents verification of malformed messages

Performance

Validation: O(1) - Fast structure checks Signature Verification: O(1) - secp256k1 recovery (expensive) Optimization: Always validates first to avoid wasting cycles on invalid messages

Factory API

Tree-shakeable factory pattern with explicit crypto dependencies.

Verify Factory

Dependencies:
  • keccak256: (data: Uint8Array) => Uint8Array - Keccak256 hash function
  • secp256k1RecoverPublicKey: (sig: {r, s, v}, hash: Uint8Array) => Uint8Array - secp256k1 public key recovery
  • addressFromPublicKey: (x: bigint, y: bigint) => Uint8Array - Address derivation from public key
Example:
Bundle size: Crypto only included if you import it.

VerifyMessage Factory

Same dependencies as Verify. Example:

GetMessageHash Factory

Dependencies:
  • keccak256: (data: Uint8Array) => Uint8Array - Keccak256 hash function
Example:

See Also