# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [2.0.0] - 2026-11-03
This release follows a review of the bindings, including the changes of
1.8.0. The raw constructors are hidden, the text instances use standard
encodings, and more values are validated when they are built. Several
changes are breaking; see Changed.
### Changed
- The raw constructors of `SecKey`, `PubKey`, `Sig`, `CompactSig`,
`SchnorrSig`, `Msg` and `Tweak`, and the `Ctx` constructor, are no longer
exported from `Crypto.Secp256k1`. Build values with `secKey`, `pubKey`,
`sig`, `compactSig`, `schnorrSig`, `msg`, `tweak` or the import functions.
The `get` field is still exported. The constructors remain available from
`Crypto.Secp256k1.Internal.Base`, without validation.
- `tweak` rejects numbers not below the curve order. `sig` rejects a zero
component. `Read` and `IsString` follow.
- `Show`, `Read` and `IsString` for `PubKey` use the compressed SEC1 encoding
in hex; `Read` and `IsString` also accept the uncompressed and hybrid
encodings. The same instances for `Sig` use the compact encoding in hex.
Before, they used the internal representation of libsecp256k1, which is not
portable between platforms or library versions.
- `normalizeSig` is total: `Ctx -> Sig -> Sig`. It returns the lower-S form of
any signature. Before, it returned `Nothing` for a signature that was
already in that form.
- `importSig` and `importCompactSig` return `Nothing` for a signature with a
zero component. libsecp256k1 parses a DER component that is not below the
curve order as zero while reporting success, and such a signature can never
verify.
- `tweakNegate` returns `Just` zero for a zero tweak.
- `combinePubKeys` raises an error for a raw key of the wrong length, as every
other function does, instead of returning `Nothing`.
- `signSchnorr`, `signSchnorrWithAux` and `signSchnorrIO` verify the signature
before returning it, as BIP-340 requires, and raise an error if that fails.
- The package requires libsecp256k1 0.2.0 or later through `pkg-config`. The
Schnorr bindings of 1.8.0 already needed that version to link.
### Added
- ECDSA public key recovery, in the new module `Crypto.Secp256k1.Recovery`:
`RecSig`, `recSig`, `signRecMsg`, `recover`, `convertRecSig`,
`importCompactRecSig` and `exportCompactRecSig`, bound to the `recovery`
module of libsecp256k1. `signRecMsg` gives the signatures of Bitcoin Core's
message signing, and `recover` is what its message verification does. The
package flag `recovery`, on by default, builds the module; turn it off for a
libsecp256k1 built without `--enable-module-recovery`.
- `signMsgLowR` grinds the nonce until r is below 2^255, with the same extra
nonce data as Bitcoin Core, so DER signatures are at most 70 bytes and are
byte-for-byte the same as Bitcoin Core's.
- `isLowS` and `isLowR`.
- `Show`, `Read` and `IsString` instances for `CompactSig`.
- `Arbitrary` instance for `Tweak`.
- Documentation of the thread-safety rule of `randomizeContext`, of what
`Show` prints for a `SecKey`, of the memory handling of secret keys, of the
lower-S requirement of `verifySig`, of the x-only representation of BIP-340
keys, and of the differences from Bitcoin Core.
### Fixed
- `importPubKey` and `exportPubKey` were documented as DER. The format is
SEC1.
- `tweakMulPubKey` was documented as adding a multiple of the generator.
- Removed the unused `unliftio-core` dependency and unused imports. The
library and the tests build with `-Wall` without warnings.
## [1.8.0] - 2026-11-03
### Added
- BIP-340 Schnorr signatures, built on the `schnorrsig` and `extrakeys`
modules of libsecp256k1, which it enables by default since version 0.2.0:
`SchnorrSig`, `schnorrSig`, `signSchnorr`, `signSchnorrWithAux`,
`signSchnorrIO` and `verifySchnorr`. No build flag is needed.
- `importXOnlyPubKey` and `exportXOnlyPubKey` convert between `PubKey` and
32-byte BIP-340 x-only public keys.
- `tweakAddXOnlyPubKey` and `tweakAddXOnlySecKey` add a BIP-341 Taproot tweak
to a public key and to its secret key.
### Fixed
- `secKey` rejects zero and numbers not lower than the curve order, as
`secp256k1_ec_seckey_verify` does. `Read` and `IsString` for `SecKey` follow.
- `pubKey` and `sig` reject bytes that are not a canonical internal
representation of a point on the curve or of a signature with both
components below the order. `Read` and `IsString` follow.
- An illegal argument no longer aborts the program. Contexts get a callback
that makes libsecp256k1 return failure, so a zero `PubKey` built with the
raw constructor gives `False`, `Nothing` or an exception.
- Functions raise an error for a `SecKey`, `PubKey`, `Sig`, `CompactSig`,
`Msg` or `Tweak` of the wrong length built with the raw constructor, instead
of letting libsecp256k1 read past the end of the buffer.
- `combinePubKeys` passes the key count as `size_t`, as the C function expects,
and returns `Nothing` when a key is not a valid point, since
`secp256k1_ec_pubkey_combine` does not check.
- Tweak functions write to a fresh buffer instead of mutating a `ByteString`
in place.
## [1.7.0] - 2026-10-31
### Added
- Reinstaded some functions removed by accident.
## [1.6.0] - 2026-10-31
### Removed
- No longer does this module expose the destroyContext function.
Context is now only destroyed safely by the garbage collector.
## [1.5.1] - 2026-10-31
### Fixed
- This package is now compatible with base16 version 2.0.
## [1.5.0] - 2026-08-12
### Fixed
- Use seckey instead of privkey aliases.
## [1.4.6] - 2025-05-09
### Removed
- Removed more unnecessary file boilerplate.
## [1.4.5] - 2025-05-09
### Removed
- Removed unnecessary file boilerplate.
## [1.4.4] - 2025-05-09
### Changed
- Simplify author name.
## [1.4.3] - 2025-05-08
### Changed
- New home in github.com/jprupp rather than github.com/haskoin.
## [1.4.2] - 2024-12-10
### Changed
- Relax all upper-bound version restrictions in `package.yaml`.
## [1.4.1] - 2024-12-10
### Changed
- Relax version restriction on QuickCheck.
## [1.4.0] - 2024-08-28
### Removed
- Removed BIP-340 support. Fedora’s version of secp256k1 libraries do not have required symbols.
## [1.3.0] - 2024-08-28
### Added
- Added BIP-340 support.
## [1.2.0] - 2023-03-14
### Changed
- Make compatible with latest upstream LTS Haskell.
## [1.1.0] - 2023-11-01
### Changed
- Use ForeignPtr to allow the garbage collector manage the context object (Ctx).
## [1.0.1] - 2023-09-20
### Changed
- Reworked the structure of the Internal modules to allow having add-on packages for optional libsecp256k1 features.
## [1.0.0] - 2023-07-28
### Changed
- Context data structure must be created and passed explicitly.
- Field selectors are now short and duplicates are allowed.
- Use DuplicateRecordFields and OverloadedRecordDot language extensions.
## [0.6.1] - 2022-04-18
### Changed
- Bump version and LTS Haskell.
- Update dependencies.
## [0.6.0] - 2021-08-27
### Changed
- Remove all use of CPP.
- Depend on base16 instead of the old base16-bytestring package.
- Target ghc-9.0.1 compiler.
### Fixed
- Do not crash on bytestrings that are backed by null C pointers.
## [0.5.0] - 2020-10-16
### Changed
- Include version boundaries and other changes submitted by Emily Pillmore.
## [0.4.0] - 2020-07-23
### Changed
- Remove fragile ForeignPtr implementation in favor of just storing ByteStrings.
- Reuse memory instead of copying when possible.
## [0.3.1] - 2020-07-03
### Fixed
- Use unsafe calls in FFI.
## [0.3.0] - 2020-06-13
### Fixed
- Compiles with all flags now.
### Added
- Script to compile with all flags.
### Removed
- Remove ECDH support.
- Remove Schnorr support.
- Remove Recovery support.
## [0.2.5] - 2020-06-13
### Changed
- Reuse context aggressively.
- Generate context in a single thread.
### Fixed
- Memory deallocation bug.
## [0.2.4] - 2020-06-12
### Changed
- Update Cabal and package version.
## [0.2.3] - 2020-06-07
### Changed
- Return meaningful error upon encountering weird ret status from upstream code.
### Added
- Test parallel signature creation and verification.
## [0.2.2] - 2020-04-14
### Removed
- Hide tweak negation behind a flag for compatibilidy with Debian 9.
### Fixed
- Correct code that was not compiling with some flags enabled.
## [0.2.1] - 2020-04-10
### Changed
- Do not depend on hardcoded DER signatures in tests.
## [0.2.0] - 2020-04-10
### Added
- Support for ECDH APIs.
- Support for Schnorr APIs.
### Removed
- Enabling key recovery APIs need a flag.
## [0.1.8] - 2020-01-15
### Added
- Add missing `NFData` instances for some types.
## [0.1.7] - 2020-01-15
### Added
- Add `NFData` instances for all types.
## [0.1.6] - 2019-12-26
### Added
- Use `pkgconfig` for C library dependency.
## [0.1.5] - 2019-09-19
### Added
- Flag for ECDH bindings.
## [0.1.4] - 2018-10-25
### Changed
- Constrain imports to avoid clashes with a QuickCheck function.
## [0.1.3] - 2018-10-13
### Added
- Hashable instances for various types.
## [0.1.2] - 2018-09-10
### Changed
- Separate dependencies between library and tests.
- Remove `hspec` default to prevent problems with Nix.
### Removed
- Dependency to `cryptohash` not needed.
## [0.1.1] - 2018-09-10
### Changed
- Update changelog to reflect name and version change.
- Update to LTS Haskell 12.9.
## [0.1.0] - 2018-09-10
### Changed
- Name of package change from `secp256k1` to `secp256k1-haskell` to avoid Nix conflicts.