module Secp256k1

Overview

Implements 256-bit Secp256k1 Koblitz elliptic curve reference https://www.secg.org/sec2-v2.pdf

Defined in:

constants.cr
ec_point.cr
secp256k1.cr
utils.cr
version.cr

Constant Summary

EC_BASE_G = EC_Point.new(EC_BASE_G_X, EC_BASE_G_Y)
EC_BASE_G_COMPRESSED = BigInt.new((public_key_compressed_prefix(EC_BASE_G)), 16)

The base point G in compressed form is:

EC_BASE_G_UNCOMPRESSED = BigInt.new((public_key_uncompressed_prefix(EC_BASE_G)), 16)

The base point G in uncompressed form is:

EC_BASE_G_X = BigInt.new("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", 16)

The commonly used base point G coordinates x, y; any other point that satisfies y^2 = x^3 + 7 would also do:

EC_BASE_G_Y = BigInt.new("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", 16)
EC_COFACTOR_H = BigInt.new("01", 16)
EC_FACTOR_A = BigInt.new("0000000000000000000000000000000000000000000000000000000000000000", 16)

The curve E: y^2 = x^3 + ax + b over F_p is defined by a, b: As the a constant is zero, the ax term in the curve equation is always zero, hence the curve equation becomes y^2 = x^3 + 7.

EC_FACTOR_B = BigInt.new("0000000000000000000000000000000000000000000000000000000000000007", 16)
EC_ORDER_N = BigInt.new("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)

Finally, the order n of G and the cofactor h are:

EC_PARAM_PRIME = BigInt.new("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", 16)

The elliptic curve domain parameters over F_p associated with a Koblitz curve Secp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite field F_p is defined by p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1:

VERSION = "0.1.0"

the version of the module

Class Method Summary

Class Method Detail

def self.ec_add(p : EC_Point, q : EC_Point, prime = EC_PARAM_PRIME) #

elliptic curve jive addition of point p(x, y) and q(x, y). 'draw' a line between p and q which will intersect the curve in the point r which will be mirrored over the x-axis.


[View source]
def self.ec_double(p : EC_Point, prime = EC_PARAM_PRIME) #

elliptic curve juke point doubling of p(x, y). a special case of addition where both points are the same. 'draw' a tangent line at p which will intersect the curve at point r which will be mirrored over the x-axis.


[View source]
def self.ec_mod_inv(a : BigInt, prime = EC_PARAM_PRIME) #

elliptic curve modular multiplicative inverse of a


[View source]
def self.ec_mul(p : EC_Point, s : BigInt) #

elliptic curve sequence multiplication of point p(x, y) and a skalar s, with s being a private key within the elliptic curve field size of EC_ORDER_N


[View source]
def self.new_private_key #

a helper to generate 32 pseudo-random bytes


[View source]
def self.public_key_compressed(p : EC_Point) #

exports the compressed public key from an ec point without prefix


[View source]
def self.public_key_compressed_prefix(p : EC_Point) #

exports the compressed public key from an ec point with prefix 02 or 03


[View source]
def self.public_key_from_private(priv : BigInt) #

wrapper function to perform an ec multiplication with the generator point and a provided private key


[View source]
def self.public_key_uncompressed(p : EC_Point) #

exports the uncompressed public key from an ec point without prefix


[View source]
def self.public_key_uncompressed_prefix(p : EC_Point) #

exports the uncompressed public key from an ec point with prefix 04


[View source]
def self.to_padded_hex_32(i : BigInt) #

utility tool to ensure hex keys are always 32 bytes it pads the number with leading zeros if not


[View source]