SkillAgentSearch skills...

Secp256k1.Net

Cross platform C# wrapper for the native secp256k1 lib (netstandard2.0)

Install / Use

/learn @zone117x/Secp256k1.Net
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Secp256k1.Net

NuGet NuGet CI codecov

Cross platform C# wrapper for the native bitcoin-core/secp256k1 C library.

dotnet add package Secp256k1.Net

Platform Support

Pre-compiled binaries are bundled for the following platforms:

| OS | x64 | x86 | arm64 | |----|:---:|:---:|:-----:| | Windows | ✓ | ✓ | ✓ | | Linux (glibc) | ✓ | ✓ | ✓ | | Linux (musl/Alpine) | ✓ | | ✓ | | macOS | ✓ | | ✓ |

This library targets netstandard2.0 and net8.0, supporting a wide-range of .NET deployments: .NET Core 2.0+, .NET Framework 4.6.1+, Mono 5.4+, etc. Conditional compilation is used to enable optimized native library interop features available on modern targets (net8.0 and above).


Quick Start

using Secp256k1Net;
using System.Security.Cryptography;
using System.Text;

// Generate a key pair
var (secretKey, publicKey) = Secp256k1.CreateKeyPair(compressed: true);

// Sign a message (ECDSA)
byte[] message = SHA256.HashData(Encoding.UTF8.GetBytes("Hello, secp256k1!"));
byte[] signature = Secp256k1.Sign(message, secretKey);
bool isValid = Secp256k1.Verify(signature, message, publicKey);

// Schnorr signatures (BIP-340)
var (xOnlyPubKey, _) = Secp256k1.CreateXOnlyPublicKey(secretKey);
byte[] schnorrSig = Secp256k1.SignSchnorr(message, secretKey);
bool schnorrValid = Secp256k1.VerifySchnorr(schnorrSig, message, xOnlyPubKey);

// ECDH shared secret
var (aliceSecret, alicePublic) = Secp256k1.CreateKeyPair(compressed: true);
var (bobSecret, bobPublic) = Secp256k1.CreateKeyPair(compressed: true);
byte[] sharedSecret1 = Secp256k1.ComputeSharedSecret(bobPublic, aliceSecret);
byte[] sharedSecret2 = Secp256k1.ComputeSharedSecret(alicePublic, bobSecret);
// sharedSecret1 == sharedSecret2

See the examples project for more complete working examples.

API Reference

Full API Documentation

The Secp256k1 class exposes static functions that are idiomatic C#, using a thread-safe internal context:

Key Generation & Validation

  • CreateSecretKey() - Generate a cryptographically secure random secret key (example)
  • CreatePublicKey(secretKey, compressed) - Derive a serialized public key from a secret key (example)
  • CreateXOnlyPublicKey(secretKey) - Derive an x-only public key and parity for BIP-340 (example)
  • CreateKeyPair(compressed) - Generate a new secret key and public key pair (example)
  • IsValidSecretKey(secretKey) - Validate a secret key (example)
  • IsValidPublicKey(publicKey) - Validate a serialized public key (example)

Public Key Operations

  • CompressPublicKey(publicKey) - Convert a public key to 33-byte compressed format (example)
  • DecompressPublicKey(publicKey) - Convert a public key to 65-byte uncompressed format (example)
  • NegatePublicKey(publicKey, compressed) - Negate a public key (example)
  • CombinePublicKeys(publicKeys, compressed) - Add multiple public keys together (example)

ECDSA Signing & Verification

  • Sign(messageHash, secretKey) - Create a 64-byte compact ECDSA signature (example)
  • Verify(signature, messageHash, publicKey) - Verify an ECDSA signature (example)
  • SignRecoverable(messageHash, secretKey) - Create a recoverable signature with recovery ID (example)
  • RecoverPublicKey(signature, recoveryId, messageHash, compressed) - Recover public key from signature (example)

DER Signature Format

  • SignatureToDer(compactSignature) - Convert compact signature to DER format (example)
  • SignatureFromDer(derSignature) - Convert DER signature to compact format (example)
  • VerifyDer(derSignature, messageHash, publicKey) - Verify a DER-encoded signature (example)

Signature Normalization

  • NormalizeSignature(signature) - Normalize signature to lower-S form (example)
  • IsNormalizedSignature(signature) - Check if signature is in lower-S form (example)

Schnorr Signatures (BIP-340)

  • SignSchnorr(messageHash, secretKey, auxRand) - Create a Schnorr signature (example)
  • VerifySchnorr(signature, message, publicKey) - Verify a Schnorr signature (example)

ECDH Key Agreement

  • ComputeSharedSecret(publicKey, secretKey) - Compute ECDH shared secret (example)

Key Tweaking (BIP-32 HD Wallets)

  • TweakSecretKeyAdd(secretKey, tweak) - Add a tweak to a secret key (example)
  • TweakPublicKeyAdd(publicKey, tweak, compressed) - Add a tweak to a public key (example)
  • TweakSecretKeyMul(secretKey, tweak) - Multiply a secret key by a tweak (example)
  • TweakPublicKeyMul(publicKey, tweak, compressed) - Multiply a public key by a tweak (example)
  • NegateSecretKey(secretKey) - Negate a secret key (example)

Hashing

  • TaggedHash(tag, message) - Compute a BIP-340 tagged hash (example)

Advanced Usage

The Secp256k1 class also provides instance methods that are direct wrappers for the native C library, with near one-to-one API mapping. These offer more control over memory allocation and access to additional features:

Benchmarks

Secp256k1.Net is consistently 5-10x faster than the next best library (NBitcoin) and 20-100x faster than pure managed implementations like BouncyCastle, Nethereum, and StarkBank.


BenchmarkDotNet v0.15.8, macOS Sequoia 15.7.1 (24G231) [Darwin 24.6.0]
Apple M3 Max, 1 CPU, 14 logical and 14 physical cores
.NET SDK 10.0.102
  [Host]     : .NET 10.0.2 (10.0.2, 10.0.225.61305), Arm64 RyuJIT armv8.0-a
  DefaultJob : .NET 10.0.2 (10.0.2, 10.0.225.61305), Arm64 RyuJIT armv8.0-a


| Method | Categories | Mean | Error | StdDev | Ratio | RatioSD | |------------- |--------------------- |-------------:|-----------:|-----------:|-------:|--------:| | Secp256k1Net | Ecdh | 22.964 μs | 0.1813 μs | 0.1607 μs | 1.00 | 0.01 | | NBitcoin | Ecdh | 167.133 μs | 0.6087 μs | 0.5694 μs | 7.28 | 0.05 | | Nethereum | Ecdh | 500.696 μs | 3.4009 μs | 3.1812 μs | 21.80 | 0.20 | | BouncyCastle | Ecdh | 503.882 μs | 6.4419 μs | 6.0257 μs | 21.94 | 0.29 | | | | | | | | | | Secp256k1Net | EcdsaRecover | 36.042 μs | 0.1504 μs | 0.1333 μs | 1.00 | 0.01 | | NBitcoin | EcdsaRecover | 268.565 μs | 1.1492 μs | 1.0187 μs | 7.45 | 0.04 | | Nethereum | EcdsaRecover | 1,977.580 μs | 14.0846 μs | 12.4856 μs | 54.87 | 0.39 | | BouncyCastle | EcdsaRecover | 2,270.418 μs | 27.8990 μs | 26.0967 μs | 62.99 | 0.74 | | | | | | | | | | Secp256k1Net | EcdsaSign | 15.231 μs | 0.0491 μs | 0.0436 μs | 1.00 | 0.00 | | NBitcoin | EcdsaSign | 133.297 μs | 0.5326 μs | 0.4721 μs | 8.75 | 0.04 | | Nethereum | EcdsaSign | 319.805 μs | 2.8822 μs | 2.6960 μs | 21.00 | 0.18 | | BouncyCastle | EcdsaSign

View on GitHub
GitHub Stars46
CategoryDevelopment
Updated7d ago
Forks14

Languages

C#

Security Score

90/100

Audited on Mar 23, 2026

No findings