Popularity
7.6
Declining
Activity
0.0
Declining
48
5
9

Description

a native library implementing secp256k1 purely for the crystal language. `secp256k1` is the elliptic curve used in the public-private-key cryptography required by bitcoin and ethereum.

this library allows for key generation of:

* private keys (from secure random within the elliptic curve field size)

* mini private keys (short 30-char base-57 keys)

* wallet import format (checksummed private keys)

* public keys, prefixed, compressed (from private)

* public keys, unprefixed and prefixed, uncompressed (from private)

* conversion between the different public key formats

this library allows for address generation of:

* bitcoin address, compressed and uncompressed (from private or public key)

* any other bitcoin-based address by passing a `version` byte

* ethereum address, checksummed and unchecksummed (from private or public key)

* any other ethereum-based address

furthermore, this library allows for:

* signing `(r, s)` and verification of arbitrary messages and message-hashes (with key pairs)

* managing `enode` addresses as per `devp2p` specification for ethereum nodes

Programming language: Crystal
License: Apache License 2.0
Tags: Blockchain     Cryptography     Hashing     Bitcoin     Ethereum     Secp256k1     Ecdsa    
Latest version: v0.3.4

secp256k1.cr alternatives and similar shards

Based on the "Blockchain" category.
Alternatively, view secp256k1.cr alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of secp256k1.cr or a related project?

Add another 'Blockchain' Shard

README

secp256k1.cr

Build Status Documentation Release Language [License](LICENSE)

a native library implementing secp256k1 purely for the crystal language. secp256k1 is the elliptic curve used in the public-private-key cryptography required by bitcoin and ethereum.

this library allows for key generation of:

  • private keys (from secure random within the elliptic curve field size)
  • mini private keys (short 30-char base-56 keys)
  • wallet import format (checksummed base-58 private keys)
  • public keys, prefixed, compressed (from private)
  • public keys, unprefixed and prefixed, uncompressed (from private)
  • conversion between the different public key formats

this library allows for address generation of:

  • bitcoin address, compressed and uncompressed (from private or public key)
  • any other bitcoin-based address by passing a version byte
  • ethereum address, checksummed and unchecksummed (from private or public key)
  • any other ethereum-based address

furthermore, this library allows for:

  • signing (r, s) and verification of arbitrary messages and message-hashes (with key pairs)
  • managing enode addresses as per devp2p specification for ethereum nodes

installation

add the secp256k1 library to your shard.yml

dependencies:
  secp256k1:
    github: q9f/secp256k1.cr
    version: "~> 0.3"

usage

tl;dr, check out [crystal run ./try.cr](./try.cr)!

# import secp256k1
require "secp256k1"

this library exposes the following modules (in logical order):

  • Secp256k1: necessary constants and data structures, including:
    • Secp256k1::Keypair: for managing private-public key-pairs
    • Secp256k1::ECPoint: for handling of secp256k1 elliptic curve points (public keys)
    • Secp256k1::ECDSASignature: for secp256k1 ecdsa signatures
  • Secp256k1::Core: the entire core mathematics behind the elliptic curve cryptography
  • Secp256k1::Util: all tools for the handling of private-public key-pairs
  • Secp256k1::Hash: implementation of various hashing algorithms for convenience
  • Secp256k1::Signature: allows for signing messages and verifying signatures
  • Secp256k1::Bitcoin: for the generation of bitcoin addresses, including:
    • Secp256k1::Bitcoin::Account: for bitcoin account management
  • Secp256k1::Ethereum: for the generation of ethereum addresses, including
    • Secp256k1::Ethereum::Account: for ethereum account management
    • Secp256k1::Ethereum::Enode: for devp2p enode address management

basic usage:

# generates a new keypair
key = Secp256k1::Keypair.new
# => #<Secp256k1::Keypair:0x7f8be5611d80>

# gets the private key
key.get_secret
# => "53d77137b39427a35d8c4b187f532d3912e1e7135985e730633e1e3c1b87ce97"

# gets the compressed public key with prefix
compressed = Secp256k1::Util.public_key_compressed_prefix key.public_key
# => "03e097fc69f0b92f711620511c07fefdd648e469df46b1e4385a00a1786f6bc55b"

generate a compressed bitcoin mainnet address:

# generates a new keypair
key = Secp256k1::Keypair.new
# => #<Secp256k1::Keypair:0x7f8be5611d80>

# generates a compressed bitcoin account from the keypair
btc = Secp256k1::Bitcoin::Account.new key, "00", true
# => #<Secp256k1::Bitcoin::Account:0x7f81ef21ab80>

# gets the wallet-import format (checksummed private key)
btc.wif
# => "Kz2grUzxEAxNopiREbNpVbjoitAGQVXnUZY4n8pNdmWdVqub99qu"

# gets the compressed bitcoin addresss
btc.address
# => "1Q1zbmPZtS2chwxpviqz6qHgoM8UUuviGN"

generate a checksummed ethereum address:

# generates a new keypair
key = Secp256k1::Keypair.new
# => #<Secp256k1::Keypair:0x7f81ef21ad00>

# generates an ethereum account from the keypair
eth = Secp256k1::Ethereum::Account.new key
# => #<Secp256k1::Ethereum::Account:0x7f81ef1faac0>

# gets the private key
eth.get_secret
# => "53d77137b39427a35d8c4b187f532d3912e1e7135985e730633e1e3c1b87ce97"

# gets the ethereum addresss
eth.address
# => "0x224008a0F3d3cB989c807F568c7f99Bf451328A6"

documentation

the full library documentation can be found here: q9f.github.io/secp256k1.cr

generate a local copy with:

crystal docs

testing

the library is entirely specified through tests in ./spec; run:

crystal spec --verbose

understand

private keys are just scalars and public keys are points 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.

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.

  • this library is not constant time and might be subject to side-channel attacks. (#4)
  • this library does unnecessary big-integer math and should someday rather correctly implement the secp256k1 prime field (#5)

found another issue? report it: github.com/q9f/secp256k1.cr/issues

contribute

create a pull request, and make sure tests and linter passes.

this pure crystal implementation is based on the python implementation wobine/blackboard101 which is also used as reference to write tests against. it's a complete rewrite of the abandoned packetzero/bitcoinutils for educational purposes.

honerable mention for the bitcoin wiki and the ethereum stackexchange for providing so many in-depth resources that supported this project in reimplementing everything.

license: apache license v2.0

contributors: @q9f, @cserb, MrSorcus


*Note that all licence references and agreements mentioned in the secp256k1.cr README section above are relevant to that project's source code only.