Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ecdsa Laravel Package

starkbank/ecdsa

Pure-PHP ECDSA implementation compatible with OpenSSL. Fast signing/verification using Jacobian coordinates and optimized scalar multiplication. Security features include RFC6979 deterministic nonces, low-S normalization, on-curve validation, and hash truncation. Supports secp256k1 and P-256; requir...

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require starkbank/ecdsa
    

    Ensure ext-gmp is enabled in your PHP environment (php -m | grep gmp).

  2. First Use Case: Sign a message with a generated key pair:

    use EllipticCurve\PrivateKey;
    use EllipticCurve\Ecdsa;
    
    $privateKey = new PrivateKey(); // Generates secp256k1 by default
    $message = "Hello, Laravel!";
    $signature = Ecdsa::sign($message, $privateKey);
    $publicKey = $privateKey->publicKey();
    
    // Verify
    $isValid = Ecdsa::verify($message, $signature, $publicKey);
    
  3. Key Sources:

    • Generate new keys: new PrivateKey().
    • Load from PEM:
      $privateKey = PrivateKey::fromPem(file_get_contents('key.pem'));
      

Where to Look First

  • Documentation: Focus on the README’s "Sample Code" section for signing/verification workflows.
  • Curves: Check EllipticCurve\CurveFp for supported curves (secp256k1, prime256v1) and how to add custom ones.
  • Security Features: Review RFC 6979 and BIP-62 compliance in the README.

Implementation Patterns

Core Workflows

1. Signing Data

// Sign a JSON payload (e.g., for API requests)
$message = json_encode(['user_id' => 123, 'amount' => 100]);
$signature = Ecdsa::sign($message, $privateKey);
$base64Sig = $signature->toBase64(); // For API headers/body

2. Verification

// Validate a signature (e.g., in a Laravel middleware)
$publicKey = PublicKey::fromPem($request->header('public-key'));
$isValid = Ecdsa::verify($request->getContent(), $signature, $publicKey);

3. Key Rotation

// Rotate keys periodically (e.g., in a Laravel job)
$oldPrivateKey = PrivateKey::fromPem($oldKeyPem);
$newPrivateKey = new PrivateKey();
$oldPublicKey = $oldPrivateKey->publicKey();
$newPublicKey = $newPrivateKey->publicKey();

// Re-sign data with new key
$resignedSig = Ecdsa::sign($message, $newPrivateKey);

4. Interoperability with OpenSSL

// Convert OpenSSL-generated keys to this library
$opensslPrivateKey = file_get_contents('private.pem');
$privateKey = PrivateKey::fromPem($opensslPrivateKey);

// Use existing OpenSSL signatures (DER format)
$derSig = file_get_contents('signature.der');
$signature = Signature::fromDer($derSig);

Laravel-Specific Patterns

Service Provider

// config/app.php
'providers' => [
    App\Providers\EcdsaServiceProvider::class,
],

// app/Providers/EcdsaServiceProvider.php
namespace App\Providers;
use EllipticCurve\PrivateKey;
use Illuminate\Support\ServiceProvider;

class EcdsaServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('ecdsa.private-key', function () {
            return PrivateKey::fromPem(config('ecdsa.private_key'));
        });
    }
}

Middleware for Signature Validation

// app/Http/Middleware/ValidateSignature.php
namespace App\Http\Middleware;
use EllipticCurve\Ecdsa;
use EllipticCurve\PublicKey;
use Closure;

class ValidateSignature
{
    public function handle($request, Closure $next)
    {
        $publicKey = PublicKey::fromPem($request->header('public-key'));
        $signature = Signature::fromBase64($request->header('signature'));
        if (!Ecdsa::verify($request->getContent(), $signature, $publicKey)) {
            abort(403, 'Invalid signature');
        }
        return $next($request);
    }
}

Artisan Command for Key Management

// app/Console/Commands/GenerateEcdsaKeys.php
namespace App\Console\Commands;
use EllipticCurve\PrivateKey;
use Illuminate\Console\Command;

class GenerateEcdsaKeys extends Command
{
    protected $signature = 'ecdsa:generate';
    protected $description = 'Generate ECDSA key pair';

    public function handle()
    {
        $privateKey = new PrivateKey();
        $publicKey = $privateKey->publicKey();
        $this->info("Private Key:\n" . $privateKey->toPem());
        $this->info("Public Key:\n" . $publicKey->toPem());
    }
}

Storing Keys in Laravel

// config/ecdsa.php
return [
    'private_key' => env('ECDSA_PRIVATE_KEY'),
    'public_key'  => env('ECDSA_PUBLIC_KEY'),
    'curve'       => 'secp256k1', // or 'prime256v1'
];

Integration Tips

  1. Hashing Messages: Use hash() or hash_hmac() before signing to ensure deterministic outputs:

    $hashedMessage = hash('sha256', $message, true);
    $signature = Ecdsa::sign($hashedMessage, $privateKey);
    
  2. Compressed Public Keys: Reduce storage/bandwidth for public keys:

    $compressedKey = $publicKey->toCompressed(); // e.g., "02..."
    $publicKey = PublicKey::fromCompressed($compressedKey);
    
  3. Custom Curves: Add support for ed25519 or other curves:

    $ed25519Curve = new CurveFp(
        '0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed',
        '0x5866666666666666666666666666666666666666666666666666666666666666',
        // ... other params
        'ed25519'
    );
    CurveFp::add($ed25519Curve);
    
  4. Batch Verification: For high-throughput APIs, preload public keys and verify in bulk:

    $publicKeys = collect($request->public_keys)->map(fn($key) => PublicKey::fromPem($key));
    $signatures = collect($request->signatures)->map(fn($sig) => Signature::fromBase64($sig));
    $messages = $request->messages;
    
    $results = $publicKeys->zip($signatures)->zip($messages)
        ->map(fn($tuple) => Ecdsa::verify(...$tuple));
    
  5. Caching Signatures: Cache verified signatures for repeated requests (e.g., webhooks):

    $cacheKey = "ecdsa:verify:{$request->id}";
    if (!cache()->has($cacheKey)) {
        $isValid = Ecdsa::verify($request->content, $signature, $publicKey);
        cache()->put($cacheKey, $isValid, now()->addHours(1));
    }
    

Gotchas and Tips

Pitfalls

  1. GMP Extension Missing:

    • Error: FatalError: Uncaught Error: Call to undefined function gmp_init().
    • Fix: Enable ext-gmp in php.ini or use a Docker image with GMP (e.g., php:8.2-gmp).
    • Workaround: If GMP is unavailable, consider falling back to ext-openssl or a polyfill like php-gmp.
  2. Nonce Reuse:

    • Risk: Reusing nonces leaks private keys (even with RFC 6979).
    • Fix: Always use Ecdsa::sign() (which implements RFC 6979) instead of manual key generation.
  3. Curve Mismatch:

    • Error: Invalid curve parameter when verifying signatures.
    • Fix: Ensure the curve used for signing matches the curve in the public key (e.g., secp256k1 vs. prime256v1).
  4. Signature Malformation:

    • Error: Signature malformed during verification.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony