Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/q9f/secp256k1.cr
a native library implementing secp256k1 purely for the crystal language.
https://github.com/q9f/secp256k1.cr
bitcoin bitcoin-addresses byte checksum compressed crystal crystal-language ec ecdh ecdsa ethereum ethereum-addresses native-library secp256k1
Last synced: about 2 months ago
JSON representation
a native library implementing secp256k1 purely for the crystal language.
- Host: GitHub
- URL: https://github.com/q9f/secp256k1.cr
- Owner: q9f
- License: apache-2.0
- Created: 2019-12-20T12:28:03.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-07-13T01:16:59.000Z (12 months ago)
- Last Synced: 2024-02-01T15:49:59.922Z (5 months ago)
- Topics: bitcoin, bitcoin-addresses, byte, checksum, compressed, crystal, crystal-language, ec, ecdh, ecdsa, ethereum, ethereum-addresses, native-library, secp256k1
- Language: Crystal
- Homepage: https://q9f.github.io/secp256k1.cr/
- Size: 685 KB
- Stars: 49
- Watchers: 5
- Forks: 9
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Lists
- awesome-crystal - secp256k1.cr - Elliptic curve used in the public-private-key cryptography (Blockchain)
- awesome-crystal - secp256k1.cr - Elliptic curve used in the public-private-key cryptography (Blockchain)
README
# secp256k1.cr
[![Build Status](https://img.shields.io/github/actions/workflow/status/q9f/secp256k1.cr/spec.yml?branch=main)](https://github.com/q9f/secp256k1.cr/actions)
[![Code Coverage](https://codecov.io/gh/q9f/secp256k1.cr/branch/main/graph/badge.svg?token=ngxRs9HdJA)](https://codecov.io/gh/q9f/secp256k1.cr)
[![Documentation](https://img.shields.io/badge/docs-html-black)](https://q9f.github.io/secp256k1.cr/)
[![Release](https://img.shields.io/github/v/release/q9f/secp256k1.cr?include_prereleases&color=black)](https://github.com/q9f/secp256k1.cr/releases/latest)
[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)
[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg?color=black)](LICENSE)A library implementing the `Secp256k1` elliptic curve natively in pure Crystal.
`Secp256k1` is the elliptic curve used in the public-private-key cryptography required by `Bitcoin`, `Ethereum`, and `Polkadot`.This library allows for:
* providing a `Secp256k1` cryptographic context, see `Secp256k1::Context`
* managing `Secp256k1` signatures and verification, see `Secp256k1::Signature`
* managing private-public keypairs, see `Secp256k1::Key`
* generating public keys, see `Secp256k1::Point`
* generating private keys, see `Secp256k1::Num`# Installation
Add the `Secp256k1` library to your `shard.yml`
```yaml
dependencies:
secp256k1:
github: q9f/secp256k1.cr
version: "~> 0.5"
```# Usage
Import and expose the `Secp256k1` module.
```crystal
require "secp256k1"
```This library exposes the following modules and classes (in logical order):
* `Secp256k1`: necessary constants and data structures, including:
- `Secp256k1::Num`: for managing big numerics (private keys)
- `Secp256k1::Point`: for handling of elliptic curve points (public keys)
- `Secp256k1::Key`: for managing private-public keypairs (accounts)
- `Secp256k1::Signature`: for handling ECDSA signatures (r, s, v)
* `Secp256k1::Context`: providing a cryptographic context for signing and verification
* `Secp256k1::Curve`: the entire core mathematics behind the elliptic curve cryptography
* `Secp256k1::Util`: binding of various hashing algorithms for convenienceBasic usage:
```crystal
# generates a new, random keypair
key = Secp256k1::Key.new
# => #,
# @public_key=#,
# @y=#>># gets the private key
key.private_hex
# => "3ccf84820c20d5e8c536ba84c52ba410375b29b1812b5f7e722445c969a0fb30"# gets the compressed public key with prefix
key.public_hex_compressed
# => "02cd4a8712ee6efc15b5abe37c0dbfa979d89c427d3fe24b076008decefe94dba2"
```Signature generation and verification:
```crystal
# sign a message with a private key
ctx = Secp256k1::Context.new
priv = Secp256k1::Num.new "1f0c122d41ff536b19bfd83537c0dfc290e45cd3c375a43237c8b8fff7ac8af7"
key = Secp256k1::Key.new priv
hash = Secp256k1::Util.sha256 "Henlo, Wordl"
sig = ctx.sign key, hash
# => #,
# @s=#,
# @v=#># verify a signature with a public key
r = Secp256k1::Num.new "c4079db44240b7afe94985c69fc89602e33629fd9b8623d711c30ce6378b33df"
s = Secp256k1::Num.new "6842c1b63c94bdb8e4f5ae88fb65f7a98b77b197c8323004fb47ef57fab29053"
v = Secp256k1::Num.new "00"
sig = Secp256k1::Signature.new r, s, v
hash = Secp256k1::Util.sha256 "Henlo, Wordl"
publ = Secp256k1::Point.new "0416008a369439f1a8a75cf974860bed5b10180518d6b1dd3ac847f423fd375d6aa29474394f0cd79d2ea543507d069e97339284f01bdbfd27392daec0ec553816"
ctx.verify sig, hash, publ
# => true
```There are example scripts for generating `Bitcoin` and `Ethereum` accounts in `src/bitcoin.cr` and `src/ethereum.cr`.
# Documentation
The full library documentation can be found here: [q9f.github.io/secp256k1.cr](https://q9f.github.io/secp256k1.cr/)
Generate a local copy with:
```shell
crystal docs
```# Testing
The library is entirely specified through tests in `./spec`; run:
```shell
crystal spec --verbose
```# Understand
Private keys are just scalars (`Secp256k1::Num`) and public keys are points (`Secp256k1::Point`) with `x` and `y` coordinates.
Bitcoin public keys can be uncompressed `p|x|y` or compressed `p|x`. both come with a prefix `p` which is useless for uncompressed keys but necessary for compressed keys to recover the `y` coordinate on the `Secp256k1` elliptic curve field.
Ethereum public keys are uncompressed `x|y` without any prefix. The last 20 bytes slice of the `y` coordinate is actually used as address without any checksum. A checksum was later added in EIP-55 using a `keccak256` hash and indicating character capitalization.
Neither Bitcoin nor Ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.
# Known issues
_Note: this library should not be used in production without proper auditing. It should be considered slow and insecure._
* This library is not constant time and might be subject to side-channel attacks. ([#4](https://github.com/q9f/secp256k1.cr/issues/4))
* This library does unnecessary big-integer math and should someday rather correctly implement the `Secp256k1` prime field ([#5](https://github.com/q9f/secp256k1.cr/issues/5))
* This library is slow in recovering signatures. Future versions should respect the recovery ID to quickly identify the correct public key from a signature.Found any other issue? Report it: [github.com/q9f/secp256k1.cr/issues](https://github.com/q9f/secp256k1.cr/issues)
# Contribute
Create a pull request, and make sure tests and linter pass.
This pure crystal implementation is based on the python implementation [wobine/blackboard101](https://github.com/wobine/blackboard101) which is also used as reference to write tests against. It's a complete rewrite of the abandoned [packetzero/bitcoinutils](https://github.com/packetzero/bitcoinutils) for educational purposes.
Honerable mention for the [bitcoin wiki](https://en.bitcoin.it/wiki/Main_Page) and the [ethereum stackexchange](https://ethereum.stackexchange.com/) for providing so many in-depth resources that supported this project in reimplementing everything.
License: Apache License v2.0
Contributors: [**@q9f**](https://github.com/q9f/), [@cserb](https://github.com/cserb), [MrSorcus](https://github.com/MrSorcus)