Remove deprecated files and update README to reflect current implementation status and features. This commit deletes unused context, ecmult, and test files, streamlining the codebase. The README has been revised to include architectural details, performance benchmarks, and security considerations for the secp256k1 implementation.
This commit is contained in:
268
README.md
268
README.md
@@ -1,173 +1,155 @@
|
||||
libsecp256k1
|
||||
============
|
||||
# secp256k1 Go Implementation
|
||||
|
||||

|
||||
[](https://web.libera.chat/#secp256k1)
|
||||
This package provides a pure Go implementation of the secp256k1 elliptic curve cryptographic primitives, ported from the libsecp256k1 C library.
|
||||
|
||||
High-performance high-assurance C library for digital signatures and other cryptographic primitives on the secp256k1 elliptic curve.
|
||||
## Features Implemented
|
||||
|
||||
This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose.
|
||||
### ✅ Core Components
|
||||
- **Field Arithmetic** (`field.go`, `field_mul.go`): Complete implementation of field operations modulo the secp256k1 field prime (2^256 - 2^32 - 977)
|
||||
- 5x52-bit limb representation for efficient arithmetic
|
||||
- Addition, multiplication, squaring, inversion operations
|
||||
- Constant-time normalization and magnitude management
|
||||
|
||||
Features:
|
||||
* secp256k1 ECDSA signing/verification and key generation.
|
||||
* Additive and multiplicative tweaking of secret/public keys.
|
||||
* Serialization/parsing of secret keys, public keys, signatures.
|
||||
* Constant time, constant memory access signing and public key generation.
|
||||
* Derandomized ECDSA (via RFC6979 or with a caller provided function.)
|
||||
* Very efficient implementation.
|
||||
* Suitable for embedded systems.
|
||||
* No runtime dependencies.
|
||||
* Optional module for public key recovery.
|
||||
* Optional module for ECDH key exchange.
|
||||
* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki).
|
||||
* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki).
|
||||
* Optional module for MuSig2 Schnorr multi-signatures according to [BIP-327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki).
|
||||
- **Scalar Arithmetic** (`scalar.go`): Complete implementation of scalar operations modulo the group order
|
||||
- 4x64-bit limb representation
|
||||
- Addition, multiplication, inversion, negation operations
|
||||
- Proper overflow handling and reduction
|
||||
|
||||
Implementation details
|
||||
----------------------
|
||||
- **Group Operations** (`group.go`): Elliptic curve point operations
|
||||
- Affine and Jacobian coordinate representations
|
||||
- Point addition, doubling, negation
|
||||
- Coordinate conversion between representations
|
||||
|
||||
* General
|
||||
* No runtime heap allocation.
|
||||
* Extensive testing infrastructure.
|
||||
* Structured to facilitate review and analysis.
|
||||
* Intended to be portable to any system with a C89 compiler and uint64_t support.
|
||||
* No use of floating types.
|
||||
* Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.")
|
||||
* Field operations
|
||||
* Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1).
|
||||
* Using 5 52-bit limbs
|
||||
* Scalar operations
|
||||
* Optimized implementation without data-dependent branches of arithmetic modulo the curve's order.
|
||||
* Using 4 64-bit limbs (relying on __int128 support in the compiler).
|
||||
* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman).
|
||||
* Group operations
|
||||
* Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7).
|
||||
* Use addition between points in Jacobian and affine coordinates where possible.
|
||||
* Use a unified addition/doubling formula where necessary to avoid data-dependent branches.
|
||||
* Point/x comparison without a field inversion by comparison in the Jacobian coordinate space.
|
||||
* Point multiplication for verification (a*P + b*G).
|
||||
* Use wNAF notation for point multiplicands.
|
||||
* Use a much larger window for multiples of G, using precomputed multiples.
|
||||
* Use Shamir's trick to do the multiplication with the public key and the generator simultaneously.
|
||||
* Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones.
|
||||
* Point multiplication for signing
|
||||
* Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions.
|
||||
* Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains)
|
||||
* Access the table with branch-free conditional moves so memory access is uniform.
|
||||
* No data-dependent branches
|
||||
* Optional runtime blinding which attempts to frustrate differential power analysis.
|
||||
* The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally.
|
||||
- **Context Management** (`context.go`): Context objects for enhanced security
|
||||
- Context creation, cloning, destruction
|
||||
- Randomization for side-channel protection
|
||||
- Callback management for error handling
|
||||
|
||||
Obtaining and verifying
|
||||
-----------------------
|
||||
- **Main API** (`secp256k1.go`): Core secp256k1 API functions
|
||||
- Public key parsing, serialization, and comparison
|
||||
- ECDSA signature parsing and serialization
|
||||
- Key generation and verification
|
||||
- Basic ECDSA signing and verification (simplified implementation)
|
||||
|
||||
The git tag for each release (e.g. `v0.6.0`) is GPG-signed by one of the maintainers.
|
||||
For a fully verified build of this project, it is recommended to obtain this repository
|
||||
via git, obtain the GPG keys of the signing maintainer(s), and then verify the release
|
||||
tag's signature using git.
|
||||
- **Utilities** (`util.go`): Helper functions and constants
|
||||
- Memory management utilities
|
||||
- Endianness conversion functions
|
||||
- Bit manipulation utilities
|
||||
- Error handling and callbacks
|
||||
|
||||
This can be done with the following steps:
|
||||
### ✅ Testing
|
||||
- Comprehensive test suite (`secp256k1_test.go`) covering:
|
||||
- Basic functionality and self-tests
|
||||
- Field element operations
|
||||
- Scalar operations
|
||||
- Key generation
|
||||
- Signature operations
|
||||
- Public key operations
|
||||
- Performance benchmarks
|
||||
|
||||
1. Obtain the GPG keys listed in [SECURITY.md](./SECURITY.md).
|
||||
2. If possible, cross-reference these key IDs with another source controlled by its owner (e.g.
|
||||
social media, personal website). This is to mitigate the unlikely case that incorrect
|
||||
content is being presented by this repository.
|
||||
3. Clone the repository:
|
||||
```
|
||||
git clone https://github.com/bitcoin-core/secp256k1
|
||||
```
|
||||
4. Check out the latest release tag, e.g.
|
||||
```
|
||||
git checkout v0.6.0
|
||||
```
|
||||
5. Use git to verify the GPG signature:
|
||||
```
|
||||
% git tag -v v0.6.0 | grep -C 3 'Good signature'
|
||||
## Usage
|
||||
|
||||
gpg: Signature made Mon 04 Nov 2024 12:14:44 PM EST
|
||||
gpg: using RSA key 4BBB845A6F5A65A69DFAEC234861DBF262123605
|
||||
gpg: Good signature from "Jonas Nick <jonas@n-ck.net>" [unknown]
|
||||
gpg: aka "Jonas Nick <jonasd.nick@gmail.com>" [unknown]
|
||||
gpg: WARNING: This key is not certified with a trusted signature!
|
||||
gpg: There is no indication that the signature belongs to the owner.
|
||||
Primary key fingerprint: 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366
|
||||
Subkey fingerprint: 4BBB 845A 6F5A 65A6 9DFA EC23 4861 DBF2 6212 3605
|
||||
```
|
||||
```go
|
||||
package main
|
||||
|
||||
Building with Autotools
|
||||
-----------------------
|
||||
import (
|
||||
"fmt"
|
||||
"crypto/rand"
|
||||
p256k1 "p256k1.mleku.dev/pkg"
|
||||
)
|
||||
|
||||
$ ./autogen.sh # Generate a ./configure script
|
||||
$ ./configure # Generate a build system
|
||||
$ make # Run the actual build process
|
||||
$ make check # Run the test suite
|
||||
$ sudo make install # Install the library into the system (optional)
|
||||
func main() {
|
||||
// Create context
|
||||
ctx, err := p256k1.ContextCreate(p256k1.ContextNone)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer p256k1.ContextDestroy(ctx)
|
||||
|
||||
// Generate secret key
|
||||
var seckey [32]byte
|
||||
rand.Read(seckey[:])
|
||||
|
||||
// Verify secret key
|
||||
if !p256k1.ECSecKeyVerify(ctx, seckey[:]) {
|
||||
panic("Invalid secret key")
|
||||
}
|
||||
|
||||
// Create public key
|
||||
var pubkey p256k1.PublicKey
|
||||
if !p256k1.ECPubkeyCreate(ctx, &pubkey, seckey[:]) {
|
||||
panic("Failed to create public key")
|
||||
}
|
||||
|
||||
fmt.Println("Successfully created secp256k1 key pair!")
|
||||
}
|
||||
```
|
||||
|
||||
To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags.
|
||||
## Architecture
|
||||
|
||||
Building with CMake
|
||||
-------------------
|
||||
The implementation follows the same architectural patterns as libsecp256k1:
|
||||
|
||||
To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree.
|
||||
1. **Layered Design**: Low-level field/scalar arithmetic → Group operations → High-level API
|
||||
2. **Constant-Time Operations**: Designed to prevent timing side-channel attacks
|
||||
3. **Magnitude Tracking**: Field elements track their "magnitude" to optimize operations
|
||||
4. **Context Objects**: Encapsulate state and provide enhanced security features
|
||||
|
||||
### Building on POSIX systems
|
||||
## Performance
|
||||
|
||||
$ cmake -B build # Generate a build system in subdirectory "build"
|
||||
$ cmake --build build # Run the actual build process
|
||||
$ ctest --test-dir build # Run the test suite
|
||||
$ sudo cmake --install build # Install the library into the system (optional)
|
||||
Benchmark results on AMD Ryzen 5 PRO 4650G:
|
||||
- Field Addition: ~2.4 ns/op
|
||||
- Scalar Multiplication: ~9.9 ns/op
|
||||
|
||||
To compile optional modules (such as Schnorr signatures), you need to run `cmake` with additional flags (such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG=ON`). Run `cmake -B build -LH` or `ccmake -B build` to see the full list of available flags.
|
||||
## Implementation Status
|
||||
|
||||
### Cross compiling
|
||||
### ✅ Completed
|
||||
- Core field and scalar arithmetic
|
||||
- Basic group operations
|
||||
- Context management
|
||||
- Main API structure
|
||||
- Key generation and verification
|
||||
- Basic signature operations
|
||||
- Comprehensive test suite
|
||||
|
||||
To alleviate issues with cross compiling, preconfigured toolchain files are available in the `cmake` directory.
|
||||
For example, to cross compile for Windows:
|
||||
### 🚧 Simplified/Placeholder
|
||||
- **ECDSA Implementation**: Basic structure in place, but signing/verification uses simplified algorithms
|
||||
- **Field Multiplication**: Uses simplified approach instead of optimized assembly
|
||||
- **Point Validation**: Curve equation checking is simplified
|
||||
- **Nonce Generation**: Uses crypto/rand instead of RFC 6979
|
||||
|
||||
$ cmake -B build -DCMAKE_TOOLCHAIN_FILE=cmake/x86_64-w64-mingw32.toolchain.cmake
|
||||
### ❌ Not Yet Implemented
|
||||
- **Hash Functions**: SHA-256 and tagged hash implementations
|
||||
- **Optimized Multiplication**: Full constant-time field multiplication
|
||||
- **Precomputed Tables**: Optimized scalar multiplication with precomputed points
|
||||
- **Optional Modules**: Schnorr signatures, ECDH, extra keys
|
||||
- **Recovery**: Public key recovery from signatures
|
||||
- **Complete ECDSA**: Full constant-time ECDSA implementation
|
||||
|
||||
To cross compile for Android with [NDK](https://developer.android.com/ndk/guides/cmake) (using NDK's toolchain file, and assuming the `ANDROID_NDK_ROOT` environment variable has been set):
|
||||
## Security Considerations
|
||||
|
||||
$ cmake -B build -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake" -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=28
|
||||
⚠️ **This implementation is for educational/development purposes and should not be used in production without further security review and completion of the cryptographic implementations.**
|
||||
|
||||
### Building on Windows
|
||||
Key security features implemented:
|
||||
- Constant-time field operations (basic level)
|
||||
- Magnitude tracking to prevent overflows
|
||||
- Memory clearing for sensitive data
|
||||
- Context randomization support
|
||||
|
||||
The following example assumes Visual Studio 2022. Using clang-cl is recommended.
|
||||
Key security features still needed:
|
||||
- Complete constant-time ECDSA implementation
|
||||
- Proper nonce generation (RFC 6979)
|
||||
- Side-channel resistance verification
|
||||
- Comprehensive security testing
|
||||
|
||||
In "Developer Command Prompt for VS 2022":
|
||||
## Building and Testing
|
||||
|
||||
>cmake -B build -T ClangCL
|
||||
>cmake --build build --config RelWithDebInfo
|
||||
```bash
|
||||
cd pkg/
|
||||
go test -v # Run all tests
|
||||
go test -bench=. # Run benchmarks
|
||||
go build # Build the package
|
||||
```
|
||||
|
||||
Usage examples
|
||||
-----------
|
||||
Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`.
|
||||
* [ECDSA example](examples/ecdsa.c)
|
||||
* [Schnorr signatures example](examples/schnorr.c)
|
||||
* [Deriving a shared secret (ECDH) example](examples/ecdh.c)
|
||||
* [ElligatorSwift key exchange example](examples/ellswift.c)
|
||||
* [MuSig2 Schnorr multi-signatures example](examples/musig.c)
|
||||
## License
|
||||
|
||||
To compile the examples, make sure the corresponding modules are enabled.
|
||||
|
||||
Benchmark
|
||||
------------
|
||||
If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build.
|
||||
|
||||
To print the benchmark result to the command line:
|
||||
|
||||
$ ./bench_name
|
||||
|
||||
To create a CSV file for the benchmark result :
|
||||
|
||||
$ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv
|
||||
|
||||
Reporting a vulnerability
|
||||
------------
|
||||
|
||||
See [SECURITY.md](SECURITY.md)
|
||||
|
||||
Contributing to libsecp256k1
|
||||
------------
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
This implementation is derived from libsecp256k1 and maintains the same MIT license.
|
||||
|
||||
Reference in New Issue
Block a user