From daab72765575394afe56db565af1cf5b17392c33 Mon Sep 17 00:00:00 2001 From: /raw PONG _GHMoaCXLT <58883403+q9f@users.noreply.github.com> Date: Mon, 6 Jan 2020 15:13:29 +0100 Subject: [PATCH 1/3] update docs --- docs/Secp256k1.html | 10 +++++----- docs/Secp256k1/Bitcoin.html | 26 +++++++++++++------------- docs/Secp256k1/Core.html | 10 +++++----- docs/Secp256k1/ECDSA_Signature.html | 12 ++++++------ docs/Secp256k1/EC_Point.html | 12 ++++++------ docs/Secp256k1/Ethereum.html | 10 +++++----- docs/Secp256k1/Hash.html | 26 +++++++++++++------------- docs/Secp256k1/Signature.html | 8 ++++---- docs/Secp256k1/Util.html | 20 ++++++++++---------- docs/index.html | 12 ++++++++++++ docs/index.json | 2 +- docs/search-index.js | 2 +- 12 files changed, 81 insertions(+), 69 deletions(-) diff --git a/docs/Secp256k1.html b/docs/Secp256k1.html index 8caa1a3..09fbec5 100644 --- a/docs/Secp256k1.html +++ b/docs/Secp256k1.html @@ -141,35 +141,35 @@

- + bitcoin.cr
- + constants.cr
- + structs.cr
- + version.cr
- + secp256k1.cr diff --git a/docs/Secp256k1/Bitcoin.html b/docs/Secp256k1/Bitcoin.html index 12c6210..eade21b 100644 --- a/docs/Secp256k1/Bitcoin.html +++ b/docs/Secp256k1/Bitcoin.html @@ -141,7 +141,7 @@

- + bitcoin.cr @@ -288,7 +288,7 @@


- [View source] + [View source]
@@ -310,7 +310,7 @@


- [View source] + [View source]
@@ -331,7 +331,7 @@


- [View source] + [View source]
@@ -352,7 +352,7 @@


- [View source] + [View source]
@@ -373,7 +373,7 @@


- [View source] + [View source]
@@ -394,7 +394,7 @@


- [View source] + [View source]
@@ -415,7 +415,7 @@


- [View source] + [View source]
@@ -436,7 +436,7 @@


- [View source] + [View source]
@@ -457,7 +457,7 @@


- [View source] + [View source]
@@ -478,7 +478,7 @@


- [View source] + [View source]
@@ -499,7 +499,7 @@


- [View source] + [View source]
@@ -520,7 +520,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/Core.html b/docs/Secp256k1/Core.html index ffbce34..e53f186 100644 --- a/docs/Secp256k1/Core.html +++ b/docs/Secp256k1/Core.html @@ -142,7 +142,7 @@

- + core.cr @@ -235,7 +235,7 @@


- [View source] + [View source]
@@ -259,7 +259,7 @@


- [View source] + [View source]
@@ -280,7 +280,7 @@


- [View source] + [View source]
@@ -303,7 +303,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/ECDSA_Signature.html b/docs/Secp256k1/ECDSA_Signature.html index 8cb7484..e34e7e9 100644 --- a/docs/Secp256k1/ECDSA_Signature.html +++ b/docs/Secp256k1/ECDSA_Signature.html @@ -143,7 +143,7 @@

- + structs.cr @@ -264,7 +264,7 @@


- [View source] + [View source]
@@ -299,7 +299,7 @@


- [View source] + [View source]
@@ -320,7 +320,7 @@


- [View source] + [View source]
@@ -341,7 +341,7 @@


- [View source] + [View source]
@@ -362,7 +362,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/EC_Point.html b/docs/Secp256k1/EC_Point.html index 8800035..dd3e629 100644 --- a/docs/Secp256k1/EC_Point.html +++ b/docs/Secp256k1/EC_Point.html @@ -143,7 +143,7 @@

- + structs.cr @@ -264,7 +264,7 @@


- [View source] + [View source]
@@ -299,7 +299,7 @@


- [View source] + [View source]
@@ -320,7 +320,7 @@


- [View source] + [View source]
@@ -341,7 +341,7 @@


- [View source] + [View source]
@@ -362,7 +362,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/Ethereum.html b/docs/Secp256k1/Ethereum.html index 6f7e743..fc3c089 100644 --- a/docs/Secp256k1/Ethereum.html +++ b/docs/Secp256k1/Ethereum.html @@ -141,7 +141,7 @@

- + ethereum.cr @@ -232,7 +232,7 @@


- [View source] + [View source]
@@ -253,7 +253,7 @@


- [View source] + [View source]
@@ -274,7 +274,7 @@


- [View source] + [View source]
@@ -295,7 +295,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/Hash.html b/docs/Secp256k1/Hash.html index c48dad0..cd68e16 100644 --- a/docs/Secp256k1/Hash.html +++ b/docs/Secp256k1/Hash.html @@ -141,7 +141,7 @@

- + hash.cr @@ -320,7 +320,7 @@


- [View source] + [View source]
@@ -341,7 +341,7 @@


- [View source] + [View source]
@@ -362,7 +362,7 @@


- [View source] + [View source]
@@ -383,7 +383,7 @@


- [View source] + [View source]
@@ -404,7 +404,7 @@


- [View source] + [View source]
@@ -425,7 +425,7 @@


- [View source] + [View source]
@@ -446,7 +446,7 @@


- [View source] + [View source]
@@ -467,7 +467,7 @@


- [View source] + [View source]
@@ -488,7 +488,7 @@


- [View source] + [View source]
@@ -509,7 +509,7 @@


- [View source] + [View source]
@@ -530,7 +530,7 @@


- [View source] + [View source]
@@ -551,7 +551,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/Signature.html b/docs/Secp256k1/Signature.html index d2aec3c..eb763bb 100644 --- a/docs/Secp256k1/Signature.html +++ b/docs/Secp256k1/Signature.html @@ -142,7 +142,7 @@

- + signature.cr @@ -228,7 +228,7 @@


- [View source] + [View source]
@@ -251,7 +251,7 @@


- [View source] + [View source]
@@ -272,7 +272,7 @@


- [View source] + [View source]
diff --git a/docs/Secp256k1/Util.html b/docs/Secp256k1/Util.html index 93e09ee..bc88be2 100644 --- a/docs/Secp256k1/Util.html +++ b/docs/Secp256k1/Util.html @@ -141,7 +141,7 @@

- + util.cr @@ -267,7 +267,7 @@


- [View source] + [View source]
@@ -288,7 +288,7 @@


- [View source] + [View source]
@@ -309,7 +309,7 @@


- [View source] + [View source]
@@ -331,7 +331,7 @@


- [View source] + [View source]
@@ -352,7 +352,7 @@


- [View source] + [View source]
@@ -373,7 +373,7 @@


- [View source] + [View source]
@@ -394,7 +394,7 @@


- [View source] + [View source]
@@ -415,7 +415,7 @@


- [View source] + [View source]
@@ -437,7 +437,7 @@


- [View source] + [View source]
diff --git a/docs/index.html b/docs/index.html index abf1d16..6d6f905 100644 --- a/docs/index.html +++ b/docs/index.html @@ -184,6 +184,18 @@

# > "0x2Ef1f605AF5d03874eE88773f41c1382ac71C239" +

+ +documentation

+ +

can be found here: https://q9f.github.io/secp256k1.cr/

+ +

generate a local copy with:

+ +
crystal docs
+

The base point G in compressed form is:

"},{"id":"EC_BASE_G_UNCOMPRESSED","name":"EC_BASE_G_UNCOMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_uncompressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in uncompressed form is:","summary":"

The base point G in uncompressed form is:

"},{"id":"EC_BASE_G_X","name":"EC_BASE_G_X","value":"BigInt.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\", 16)","doc":"The commonly used base point G coordinates x, y;\nany other point that satisfies y^2 = x^3 + 7 would also do:","summary":"

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

"},{"id":"EC_BASE_G_Y","name":"EC_BASE_G_Y","value":"BigInt.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\", 16)","doc":null,"summary":null},{"id":"EC_COFACTOR_H","name":"EC_COFACTOR_H","value":"BigInt.new(\"01\", 16)","doc":null,"summary":null},{"id":"EC_FACTOR_A","name":"EC_FACTOR_A","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000000\", 16)","doc":"The curve E: y^2 = x^3 + ax + b over F_p is defined by a, b:\nAs the a constant is zero, the ax term in the curve equation is always zero,\nhence the curve equation becomes y^2 = x^3 + 7.","summary":"

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.

"},{"id":"EC_FACTOR_B","name":"EC_FACTOR_B","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000007\", 16)","doc":null,"summary":null},{"id":"EC_ORDER_N","name":"EC_ORDER_N","value":"BigInt.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", 16)","doc":"Finally, the order n of G and the cofactor h are:","summary":"

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

"},{"id":"EC_PARAM_PRIME","name":"EC_PARAM_PRIME","value":"BigInt.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\", 16)","doc":"The elliptic curve domain parameters over F_p associated with a Koblitz curve\nSecp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite\nfield F_p is defined by p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1:","summary":"

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:

"},{"id":"VERSION","name":"VERSION","value":"\"0.2.0\"","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":"expose the secp256k1 module","summary":"

expose the secp256k1 module

","class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Bitcoin","path":"Secp256k1/Bitcoin.html","kind":"module","full_name":"Secp256k1::Bitcoin","name":"Bitcoin","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the bitcoin address space","summary":"

implements the bitcoin address space

","class_methods":[{"id":"address_from_private(priv:String,version="00",compressed=true)-class-method","html_id":"address_from_private(priv:String,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_private","doc":"generates a bitcoin address from a private key","summary":"

generates a bitcoin address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(priv : String, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L231","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p, version, compressed)\n"}},{"id":"address_from_public_key(pub:String,version="00")-class-method","html_id":"address_from_public_key(pub:String,version=&quot;00&quot;)-class-method","name":"address_from_public_key","doc":"generates a bitcoin address for any public key; compressed and uncompressed\nversion 0x00 = btc mainnet; pass different versions for different networks","summary":"

generates a bitcoin address for any public key; compressed and uncompressed version 0x00 = btc mainnet; pass different versions for different networks

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"args_string":"(pub : String, version = "00")","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L163","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (pub.size === 130) || (pub.size === 66)\n sha2 = Hash.sha256(pub)\n ripe = Hash.ripemd160(sha2)\n ripe_versioned = \"#{version}#{ripe}\"\n hashed = Hash.sha256(ripe_versioned)\n hashed_twice = Hash.sha256(hashed)\n binary = \"#{ripe_versioned}#{hashed_twice[0, 8]}\"\n return Hash.base58_encode(binary)\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point,version="00",compressed=true)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_public_point","doc":"generates a bitcoin address from an public key ec point","summary":"

generates a bitcoin address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(p : Secp256k1::EC_Point, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L195","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed_prefix(p)\nif compressed\n pub = Secp256k1::Util.public_key_compressed_prefix(p)\nend\nreturn address_from_public_key(pub, version)\n"}},{"id":"address_from_wif(wif:String)-class-method","html_id":"address_from_wif(wif:String)-class-method","name":"address_from_wif","doc":"gets a bitcoin address from a wif key","summary":"

gets a bitcoin address from a wif key

","abstract":false,"args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"args_string":"(wif : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L205","def":{"name":"address_from_wif","args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if wif_is_valid?(wif)\n vers = version_byte_from_wif(wif)\n vers = vers.to_i(16)\n vers = vers - 128\n vers = Secp256k1::Util.to_padded_hex_01(vers)\n priv = private_key_from_wif(wif)\n comp = is_wif_compressed?(wif)\n return address_from_private(priv, vers, comp)\nelse\n raise(\"invalid wallet import format (invalid wif: #{wif})\")\n return \"-999\"\nend"}},{"id":"is_wif_compressed?(w:String)-class-method","html_id":"is_wif_compressed?(w:String)-class-method","name":"is_wif_compressed?","doc":"checks if it's compressed or uncompressed wallet import format","summary":"

checks if it's compressed or uncompressed wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L111","def":{"name":"is_wif_compressed?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned.size === 76\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"new_mini_private_key-class-method","html_id":"new_mini_private_key-class-method","name":"new_mini_private_key","doc":"generates a new mini private key (30 characters, base-57)","summary":"

generates a new mini private key (30 characters, base-57)

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L18","def":{"name":"new_mini_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"valid = false\nkey = String.new\nwhile !valid\n i = 1\n key = \"S\"\n while i < 30\n i = i + 1\n r = Random.rand(57)\n key = key + (Hash.base57_char(r))\n end\n checksum = Hash.sha256_string(\"#{key}?\")\n valid = checksum[0, 2] === \"00\"\n priv = private_key_from_mini(key)\n valid = valid && priv > 0\n valid = valid && (priv === (priv % Secp256k1::EC_ORDER_N))\nend\nreturn key\n"}},{"id":"private_key_from_mini(m:String)-class-method","html_id":"private_key_from_mini(m:String)-class-method","name":"private_key_from_mini","doc":"gets a private key from a mini key","summary":"

gets a private key from a mini key

","abstract":false,"args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"args_string":"(m : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L47","def":{"name":"private_key_from_mini","args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"private_key = Hash.sha256_string(m)\nreturn BigInt.new(private_key, 16)\n"}},{"id":"private_key_from_wif(w:String)-class-method","html_id":"private_key_from_wif(w:String)-class-method","name":"private_key_from_wif","doc":"gets a private key from a wallet import format","summary":"

gets a private key from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L80","def":{"name":"private_key_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nif (checksum_key.size == 74) || (checksum_key.size == 76)\n private_key = BigInt.new(checksum_key[2, 64], 16)\n return Secp256k1::Util.to_padded_hex_32(private_key)\nelse\n raise(\"invalid wallet import format (invalid wif size: #{checksum_key.size})\")\n return \"-999\"\nend\n"}},{"id":"version_byte_from_wif(w:String)-class-method","html_id":"version_byte_from_wif(w:String)-class-method","name":"version_byte_from_wif","doc":"gets the version byte from a wallet import format","summary":"

gets the version byte from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L96","def":{"name":"version_byte_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned[0, 2]\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"wif_compressed_from_private(k:BigInt,version="80")-class-method","html_id":"wif_compressed_from_private(k:BigInt,version=&quot;80&quot;)-class-method","name":"wif_compressed_from_private","doc":"to indicate a compressed key to be used, append a \"01\" byte","summary":"

to indicate a compressed key to be used, append a \"01\" byte

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"args_string":"(k : BigInt, version = "80")","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L75","def":{"name":"wif_compressed_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return wif_from_private(k, version, \"01\")"}},{"id":"wif_from_private(k:BigInt,version="80",compr="")-class-method","html_id":"wif_from_private(k:BigInt,version=&quot;80&quot;,compr=&quot;&quot;)-class-method","name":"wif_from_private","doc":"gets a base-58 wallet import format from private key","summary":"

gets a base-58 wallet import format from private key

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"args_string":"(k : BigInt, version = "80", compr = "")","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L53","def":{"name":"wif_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = Secp256k1::Util.to_padded_hex_32(k)\nversioned = \"#{version}#{priv}#{compr}\"\nhashed = Hash.sha256(versioned)\nhashed_twice = Hash.sha256(hashed)\nbinary = \"#{versioned}#{hashed_twice[0, 8]}\"\nreturn Hash.base58_encode(binary)\n"}},{"id":"wif_is_valid?(w:String)-class-method","html_id":"wif_is_valid?(w:String)-class-method","name":"wif_is_valid?","doc":"validates wether a wif has a correct checksum","summary":"

validates wether a wif has a correct checksum

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L126","def":{"name":"wif_is_valid?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nvalid = (checksum_key.size === 74) || (checksum_key.size === 76)\nif valid\n private_key = private_key_from_wif(w)\n valid = (valid && (private_key != \"-999\")) && (private_key.size === 64)\n versioned = checksum_key[0, 66]\n wif_checksum = checksum_key[66, 8]\n if checksum_key.size === 76\n versioned = checksum_key[0, 68]\n wif_checksum = checksum_key[68, 8]\n end\n hashed = Hash.sha256(versioned)\n hashed_twice = Hash.sha256(hashed)\n pk_checksum = hashed_twice[0, 8]\n valid = valid && (wif_checksum === pk_checksum)\nend\nreturn valid\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Core","path":"Secp256k1/Core.html","kind":"module","full_name":"Secp256k1::Core","name":"Core","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"core.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit Secp256k1 Koblitz elliptic curve\nreference https://www.secg.org/sec2-v2.pdf","summary":"

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

","class_methods":[{"id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_add","doc":"elliptic curve jive addition of point p(x, y) and q(x, y).\n'draw' a line between p and q which will intersect the\ncurve in the point r which will be mirrored over the x-axis.","summary":"

elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, q : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L43","def":{"name":"ec_add","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x_delta = q.x - p.x\nx_inv = ec_mod_inv(x_delta)\ny_delta = q.y - p.y\nm = (y_delta * x_inv) % prime\nx = (((m * m) - p.x) - q.x) % prime\ny = ((m * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_double","doc":"elliptic curve juke point doubling of p(x, y).\na special case of addition where both points are the same.\n'draw' a tangent line at p which will intersect the curve\nat point r which will be mirrored over the x-axis.","summary":"

elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L59","def":{"name":"ec_double","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"lam_numer = ((3 * p.x) * p.x) + EC_FACTOR_A\nlam_denom = 2 * p.y\nlam_inv = ec_mod_inv(lam_denom)\nlam = (lam_numer * lam_inv) % prime\nx = ((lam * lam) - (2 * p.x)) % prime\ny = ((lam * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","name":"ec_mod_inv","doc":"elliptic curve modular multiplicative inverse of a","summary":"

elliptic curve modular multiplicative inverse of a

","abstract":false,"args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(a : BigInt, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L19","def":{"name":"ec_mod_inv","args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"m_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nreturn m_low % prime\n"}},{"id":"ec_mul(p:EC_Point,s:BigInt)-class-method","html_id":"ec_mul(p:EC_Point,s:BigInt)-class-method","name":"ec_mul","doc":"elliptic curve sequence multiplication of point p(x, y) and\na skalar s, with s being a private key within the elliptic\ncurve field size of EC_ORDER_N","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(p : EC_Point, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L74","def":{"name":"ec_mul","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (s === 0) || s >= EC_ORDER_N\n raise(\"invalid private key: outside of ec field size.\")\n exit(1)\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = ec_double(q)\n if char === '1'\n q = ec_add(q, p)\n end\nend\nreturn q\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/EC_Point","path":"Secp256k1/EC_Point.html","kind":"class","full_name":"Secp256k1::EC_Point","name":"EC_Point","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":18,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"A point in the two-dimensional space of an elliptic curve","summary":"

A point in the two-dimensional space of an elliptic curve

","class_methods":[],"constructors":[{"id":"new(x:BigInt,y:BigInt)-class-method","html_id":"new(x:BigInt,y:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(x : BigInt, y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L25","def":{"name":"new","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"x:BigInt-instance-method","html_id":"x:BigInt-instance-method","name":"x","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L20","def":{"name":"x","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@x"}},{"id":"x=(x:BigInt)-instance-method","html_id":"x=(x:BigInt)-instance-method","name":"x=","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"args_string":"(x : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L20","def":{"name":"x=","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@x = x"}},{"id":"y:BigInt-instance-method","html_id":"y:BigInt-instance-method","name":"y","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L23","def":{"name":"y","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@y"}},{"id":"y=(y:BigInt)-instance-method","html_id":"y=(y:BigInt)-instance-method","name":"y=","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L23","def":{"name":"y=","args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@y = y"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/ECDSA_Signature","path":"Secp256k1/ECDSA_Signature.html","kind":"class","full_name":"Secp256k1::ECDSA_Signature","name":"ECDSA_Signature","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":30,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"an ecdsa signature","summary":"

an ecdsa signature

","class_methods":[],"constructors":[{"id":"new(r:BigInt,s:BigInt)-class-method","html_id":"new(r:BigInt,s:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(r : BigInt, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L37","def":{"name":"new","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(r, s)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"r:BigInt-instance-method","html_id":"r:BigInt-instance-method","name":"r","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L32","def":{"name":"r","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@r"}},{"id":"r=(r:BigInt)-instance-method","html_id":"r=(r:BigInt)-instance-method","name":"r=","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"args_string":"(r : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L32","def":{"name":"r=","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@r = r"}},{"id":"s:BigInt-instance-method","html_id":"s:BigInt-instance-method","name":"s","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L35","def":{"name":"s","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@s"}},{"id":"s=(s:BigInt)-instance-method","html_id":"s=(s:BigInt)-instance-method","name":"s=","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L35","def":{"name":"s=","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@s = s"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Ethereum","path":"Secp256k1/Ethereum.html","kind":"module","full_name":"Secp256k1::Ethereum","name":"Ethereum","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"ethereum.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the Ethereum address space","summary":"

implements the Ethereum address space

","class_methods":[{"id":"address_checksum(adr:String)-class-method","html_id":"address_checksum(adr:String)-class-method","name":"address_checksum","doc":"returns a checksummed ethereum address as per eip-55","summary":"

returns a checksummed ethereum address as per eip-55

","abstract":false,"args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"args_string":"(adr : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L18","def":{"name":"address_checksum","args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"adr = adr.downcase\nif adr.size === 42\n adr = adr[2, 40]\nend\nif adr.size === 40\n keccak = Hash.keccak256_string(adr)\n address = \"0x\"\n i = 0\n while i < adr.size\n k = keccak[i].to_i(16)\n if k >= 8\n address = address + \"#{adr[i]}\".upcase\n else\n address = address + \"#{adr[i]}\"\n end\n i = i + 1\n end\n return address\nelse\n raise(\"malformed ethereum address (invalid size: #{adr.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_private(priv:String)-class-method","html_id":"address_from_private(priv:String)-class-method","name":"address_from_private","doc":"generates an ethereum address from a private key","summary":"

generates an ethereum address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"args_string":"(priv : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L75","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p)\n"}},{"id":"address_from_public_key(pub:String)-class-method","html_id":"address_from_public_key(pub:String)-class-method","name":"address_from_public_key","doc":"generates an ethereum address for an uncompressed public key","summary":"

generates an ethereum address for an uncompressed public key

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L53","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 128\n keccak = Hash.keccak256(pub)\n return address_checksum(keccak[24, 40])\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","name":"address_from_public_point","doc":"generates an ethereum address from an public key ec point","summary":"

generates an ethereum address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"args_string":"(p : Secp256k1::EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L68","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed(p)\nreturn address_from_public_key(pub)\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Hash","path":"Secp256k1/Hash.html","kind":"module","full_name":"Secp256k1::Hash","name":"Hash","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"hash.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"BASE_57","name":"BASE_57","value":"\"23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-57 alphabet (for mini private keys)","summary":"

the base-57 alphabet (for mini private keys)

"},{"id":"BASE_58","name":"BASE_58","value":"\"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-58 alphabet (for bitcoin)","summary":"

the base-58 alphabet (for bitcoin)

"}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"wraps various hashing functions for convenience","summary":"

wraps various hashing functions for convenience

","class_methods":[{"id":"base57_char(i:Int32)-class-method","html_id":"base57_char(i:Int32)-class-method","name":"base57_char","doc":"get a character from the base-57 alphabet at position i","summary":"

get a character from the base-57 alphabet at position i

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L120","def":{"name":"base57_char","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"i = i % 57\nreturn BASE_57[i]\n"}},{"id":"base58_decode(s:String)-class-method","html_id":"base58_decode(s:String)-class-method","name":"base58_decode","doc":"decode a hex string from base-58","summary":"

decode a hex string from base-58

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L70","def":{"name":"base58_decode","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"index = 0\ndecimal = BigInt.new(0)\nwhile index < s.size\n b58_char = s[index]\n position = BASE_58.index(b58_char)\n if !position.nil?\n decimal = (decimal * 58) + position\n index = index + 1\n else\n raise(\"cannot decode, invalid base58 character: '#{s[index]}'\")\n return \"-999\"\n end\nend\nhex = decimal.to_s(16)\nleading = 0\nwhile s[leading] === '1'\n leading = leading + 1\n hex = \"00#{hex}\"\nend\nreturn hex\n"}},{"id":"base58_encode(h:String)-class-method","html_id":"base58_encode(h:String)-class-method","name":"base58_encode","doc":"encode a hex string as base-58","summary":"

encode a hex string as base-58

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L97","def":{"name":"base58_encode","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = BigInt.new(h, 16)\nadr = String.new\nwhile pub > 0\n pub, rem = pub.divmod(58)\n adr = adr + BASE_58[rem]\nend\ni, s = 0, 2\ncurrent_byte = h[i, s]\nwhile (current_byte.to_i(16)) === 0\n adr = \"#{adr}1\"\n i = i + s\n current_byte = h[i, s]\nend\nreturn adr.reverse\n"}},{"id":"bin_to_hex(b:Bytes)-class-method","html_id":"bin_to_hex(b:Bytes)-class-method","name":"bin_to_hex","doc":"helper function to convert byte arrays to hex strings","summary":"

helper function to convert byte arrays to hex strings

","abstract":false,"args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"args_string":"(b : Bytes)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L126","def":{"name":"bin_to_hex","args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return b.hexstring"}},{"id":"hex_to_bin(s:String)-class-method","html_id":"hex_to_bin(s:String)-class-method","name":"hex_to_bin","doc":"helper function to convert hex strings to byte arrays","summary":"

helper function to convert hex strings to byte arrays

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L131","def":{"name":"hex_to_bin","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return s.hexbytes"}},{"id":"keccak256(h:String)-class-method","html_id":"keccak256(h:String)-class-method","name":"keccak256","doc":"operating a keccak-256 hash on the byte array","summary":"

operating a keccak-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L40","def":{"name":"keccak256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nb = hex_to_bin(h)\nreturn (keccak.update(b)).hexdigest\n"}},{"id":"keccak256_string(h:String)-class-method","html_id":"keccak256_string(h:String)-class-method","name":"keccak256_string","doc":"operating a keccak-256 hash on the actual string literal","summary":"

operating a keccak-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L47","def":{"name":"keccak256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nreturn (keccak.update(h)).hexdigest\n"}},{"id":"ripemd160(h:String)-class-method","html_id":"ripemd160(h:String)-class-method","name":"ripemd160","doc":"operating a ripemd-160 hash on the byte array","summary":"

operating a ripemd-160 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L64","def":{"name":"ripemd160","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"RIPEMD160\")).update(b)).hexdigest\n"}},{"id":"sha256(h:String)-class-method","html_id":"sha256(h:String)-class-method","name":"sha256","doc":"operating a sha2-256 hash on the byte array","summary":"

operating a sha2-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L53","def":{"name":"sha256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"SHA256\")).update(b)).hexdigest\n"}},{"id":"sha256_string(h:String)-class-method","html_id":"sha256_string(h:String)-class-method","name":"sha256_string","doc":"operating a sha2-256 hash on the actual string literal","summary":"

operating a sha2-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L59","def":{"name":"sha256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return ((OpenSSL::Digest.new(\"SHA256\")).update(h)).hexdigest"}},{"id":"sha3(h:String)-class-method","html_id":"sha3(h:String)-class-method","name":"sha3","doc":"operating a sha3-256 hash on the byte array","summary":"

operating a sha3-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L27","def":{"name":"sha3","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nb = hex_to_bin(h)\nreturn (sha3.update(b)).hexdigest\n"}},{"id":"sha3_string(h:String)-class-method","html_id":"sha3_string(h:String)-class-method","name":"sha3_string","doc":"operating a sha3-256 hash on the actual string literal","summary":"

operating a sha3-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L34","def":{"name":"sha3_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nreturn (sha3.update(h)).hexdigest\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"module","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"signature.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements ecdsa signature generation and verification for secp256k1\nref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages","summary":"

implements ecdsa signature generation and verification for secp256k1 ref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages

","class_methods":[{"id":"sign(msg:String,priv:BigInt)-class-method","html_id":"sign(msg:String,priv:BigInt)-class-method","name":"sign","doc":"the ecdsa signing algorithm (rfc 6979) takes as input a message `msg`\nand a private key `priv`. It produces as output a signature, which\nconsists of pair of integers `(r, s)`.","summary":"

the ecdsa signing algorithm (rfc 6979) takes as input a message msg and a private key priv.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(msg : String, priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr#L21","def":{"name":"sign","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nk = Util.new_private_key\nr = (Core.ec_mul(EC_BASE_G, k)).x % EC_ORDER_N\nk_inv = Core.ec_mod_inv(k, EC_ORDER_N)\ns = ((hash + (r * priv)) * k_inv) % EC_ORDER_N\nsig = ECDSA_Signature.new(r, s)\nreturn sig\n"}},{"id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify","doc":"the algorithm to verify an ecdsa signature takes as input the signed message `msg`\nand the signature `(r, s)` produced from self.sign and the public key `pub`,\ncorresponding to the signer's private key. The result is boolean.","summary":"

the algorithm to verify an ecdsa signature takes as input the signed message msg and the signature (r, s) produced from self.sign and the public key pub, corresponding to the signer's private key.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(msg : String, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr#L42","def":{"name":"verify","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nreturn verify_hash(hash, sig, pub)\n"}},{"id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify_hash","doc":"same as self.verify, just using the hashed message directly","summary":"

same as self.verify, just using the hashed message directly

","abstract":false,"args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(hash : BigInt, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr#L49","def":{"name":"verify_hash","args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"s_inv = Core.ec_mod_inv(sig.s, EC_ORDER_N)\np0 = Core.ec_mul(EC_BASE_G, (hash * s_inv) % EC_ORDER_N)\np1 = Core.ec_mul(pub, (sig.r * s_inv) % EC_ORDER_N)\np = Core.ec_add(p0, p1)\nreturn sig.r === p.x\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"util.cr","line_number":22,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"a collection of utilities for secp256k1 key management","summary":"

a collection of utilities for secp256k1 key management

","class_methods":[{"id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","html_id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","name":"decode_compressed_public_key","doc":"decodes a public key as ec point from a compressed public key string","summary":"

decodes a public key as ec point from a compressed public key string

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(pub : String, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L76","def":{"name":"decode_compressed_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 66\n prefix = pub[0, 2]\n if (prefix === \"02\") || (prefix === \"03\")\n x = BigInt.new(pub[2, 64], 16)\n a = (x ** 3) % prime\n a = (a + 7) % prime\n e = ((prime + 1) // 4) % prime\n y = BigInt.new\n LibGMP.mpz_powm_sec(y, a, e, prime)\n parity = prefix.to_i - 2\n if (y % 2) != parity\n y = (-y) % prime\n end\n return EC_Point.new(x, y)\n else\n raise(\"invalid prefix for compressed public key: #{prefix}\")\n end\nelse\n raise(\"malformed compressed public key (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"new_private_key-class-method","html_id":"new_private_key-class-method","name":"new_private_key","doc":"a helper to generate 32 pseudo-random bytes","summary":"

a helper to generate 32 pseudo-random bytes

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L43","def":{"name":"new_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"key = -999\nwhile !key > 0\n key = Random::Secure.hex(32)\n key = BigInt.new(key, 16)\nend\nreturn key % EC_ORDER_N\n"}},{"id":"public_key_compressed_prefix(p:EC_Point)-class-method","html_id":"public_key_compressed_prefix(p:EC_Point)-class-method","name":"public_key_compressed_prefix","doc":"exports the compressed public key from an ec point with prefix 02 or 03","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L58","def":{"name":"public_key_compressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"prefix = (p.y % 2) === 1 ? \"03\" : \"02\"\nreturn \"#{prefix}#{public_key_compressed(p)}\"\n"}},{"id":"public_key_from_private(priv:BigInt)-class-method","html_id":"public_key_from_private(priv:BigInt)-class-method","name":"public_key_from_private","doc":"wrapper function to perform an ec multiplication with\nthe generator point and a provided private key","summary":"

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

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L141","def":{"name":"public_key_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return Core.ec_mul(EC_BASE_G, priv)"}},{"id":"public_key_uncompressed(p:EC_Point)-class-method","html_id":"public_key_uncompressed(p:EC_Point)-class-method","name":"public_key_uncompressed","doc":"exports the uncompressed public key from an ec point without prefix","summary":"

exports the uncompressed public key from an ec point without prefix

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L64","def":{"name":"public_key_uncompressed","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x = to_padded_hex_32(p.x)\ny = to_padded_hex_32(p.y)\nreturn \"#{x}#{y}\"\n"}},{"id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","html_id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","name":"public_key_uncompressed_prefix","doc":"exports the uncompressed public key from an ec point with prefix 04","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L71","def":{"name":"public_key_uncompressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return \"04#{public_key_uncompressed(p)}\""}},{"id":"restore_public_key(pub:String)-class-method","html_id":"restore_public_key(pub:String)-class-method","name":"restore_public_key","doc":"detects public key type and tries to restore the ec point from it","summary":"

detects public key type and tries to restore the ec point from it

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L126","def":{"name":"restore_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"case pub.size\nwhen 130, 128\n return decode_uncompressed_public_key(pub)\nwhen 66\n return decode_compressed_public_key(pub)\nelse\n raise(\"unknown public key format (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"to_padded_hex_01(i:Int32)-class-method","html_id":"to_padded_hex_01(i:Int32)-class-method","name":"to_padded_hex_01","doc":"generic tool to encode single hex bytes as strings, e.g., \"07\"","summary":"

generic tool to encode single hex bytes as strings, e.g., \"07\"

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L24","def":{"name":"to_padded_hex_01","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 2\n hex = '0' + hex\nend\nreturn hex\n"}},{"id":"to_padded_hex_32(i:BigInt)-class-method","html_id":"to_padded_hex_32(i:BigInt)-class-method","name":"to_padded_hex_32","doc":"utility tool to ensure hex keys are always 32 bytes\nit pads the number with leading zeros if not","summary":"

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

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"args_string":"(i : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L34","def":{"name":"to_padded_hex_32","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 64\n hex = '0' + hex\nend\nreturn hex\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]}]}} \ No newline at end of file +{"repository_name":"github.com/q9f/secp256k1.cr","body":"# secp256k1.cr\n\n\n[![Badge](https://github.com/q9f/secp256k1.cr/workflows/Nightly/badge.svg)](https://github.com/q9f/secp256k1.cr/actions)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg)](LICENSE)\n\na 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.\n\nthis library allows for key generation of:\n* private keys (from secure random within the elliptic curve field size)\n* mini private keys (short 30-char base-57 keys)\n* wallet import format (checksummed private keys)\n* public keys, prefixed, compressed (from private)\n* public keys, unprefixed and prefixed, uncompressed (from private)\n* conversion between the different public key formats\n\nthis library allows for address generation of:\n* bitcoin address, compressed and uncompressed (from private or public key)\n* any other bitcoin-based address by passing a `version` byte\n* ethereum address, checksummed and unchecksummed (from private or public key)\n* any other ethereum-based address\n\nfurthermore, this library allows for:\n* signing `(r, s)` and verification of arbitrary messages and message-hashes (with key pairs)\n\n# installation\n\nadd the `secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.2\"\n```\n\n# usage\n\n_tl;dr,_ check out [`crystal run ./try.cr`](./try.cr)!\n\n\n```crystal\n# import secp256k1\nrequire \"secp256k1\"\n```\n\nthis library exposes the following modules (in logical order):\n\n* `Secp256k1`: necessary constants and data structures\n* `Secp256k1::Core`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: all tools for the handling of private-public key-pairs\n* `Secp256k1::Hash`: implementation of various hashing algorithms for convenience\n* `Secp256k1::Signature`: allows for signing messages and verifying signatures\n* `Secp256k1::Bitcoin`: for the generation of bitcoin addresses\n* `Secp256k1::Ethereum`: for the generation of ethereum addresses\n\nbasic usage:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\n\n# display the compressed public key with prefix\nputs Secp256k1::Util.public_key_compressed_prefix public_key\n\n# > 02b3c141fba20c129806290f04cee097305fb7391abfde01b3bb3affcd935332a1\n```\n\ngenerate a compressed bitcoin mainnet address:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\ncompressed = Secp256k1::Util.public_key_compressed_prefix public_key\n\n# display the bitcoin address (version \"00\" for bitcoin mainnet)\nputs Secp256k1::Bitcoin.address_from_public_key compressed, \"00\"\n\n# > \"1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\"\n```\n\ngenerate a checksummed ethereum address:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\nuncompressed = Secp256k1::Util.public_key_uncompressed public_key\n\n# display the ethereum address\nputs Secp256k1::Ethereum.address_from_public_key uncompressed\n\n# > \"0x2Ef1f605AF5d03874eE88773f41c1382ac71C239\"\n```\n\n# documentation\n\ncan be found here: https://q9f.github.io/secp256k1.cr/\n\ngenerate a local copy with:\n\n```\ncrystal docs\n```\n\n# testing\n\nthe library is entirely specified through tests in `./spec`; run:\n\n```bash\ncrystal spec --verbose\n```\n\n# understand\n\nprivate keys are just scalars and public keys are points with `x` and `y` coordinates.\n\nbitcoin 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.\n\nethereum 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.\n\nneither bitcoin nor ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# known issues\n\n_note: this library should not be used in production without proper auditing._\n\n* this library is not constant time and might be subject to side-channel attacks. [#4](https://github.com/q9f/secp256k1.cr/issues/4)\n* 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)\n\nfound another issue? report it: https://github.com/q9f/secp256k1.cr/issues\n\n# contribute\n\ncreate a pull request, and make sure tests and linter passes.\n\nthis 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.\n\nhonerable 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.\n\nlicense: apache license v2.0\n","program":{"html_id":"github.com/q9f/secp256k1.cr/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"superclass":null,"ancestors":[],"locations":[],"repository_name":"github.com/q9f/secp256k1.cr","program":true,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr"},{"filename":"constants.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/constants.cr"},{"filename":"structs.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr"},{"filename":"version.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/version.cr"},{"filename":"secp256k1.cr","line_number":26,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/secp256k1.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"EC_BASE_G","name":"EC_BASE_G","value":"EC_Point.new(EC_BASE_G_X, EC_BASE_G_Y)","doc":null,"summary":null},{"id":"EC_BASE_G_COMPRESSED","name":"EC_BASE_G_COMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_compressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in compressed form is:","summary":"

The base point G in compressed form is:

"},{"id":"EC_BASE_G_UNCOMPRESSED","name":"EC_BASE_G_UNCOMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_uncompressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in uncompressed form is:","summary":"

The base point G in uncompressed form is:

"},{"id":"EC_BASE_G_X","name":"EC_BASE_G_X","value":"BigInt.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\", 16)","doc":"The commonly used base point G coordinates x, y;\nany other point that satisfies y^2 = x^3 + 7 would also do:","summary":"

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

"},{"id":"EC_BASE_G_Y","name":"EC_BASE_G_Y","value":"BigInt.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\", 16)","doc":null,"summary":null},{"id":"EC_COFACTOR_H","name":"EC_COFACTOR_H","value":"BigInt.new(\"01\", 16)","doc":null,"summary":null},{"id":"EC_FACTOR_A","name":"EC_FACTOR_A","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000000\", 16)","doc":"The curve E: y^2 = x^3 + ax + b over F_p is defined by a, b:\nAs the a constant is zero, the ax term in the curve equation is always zero,\nhence the curve equation becomes y^2 = x^3 + 7.","summary":"

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.

"},{"id":"EC_FACTOR_B","name":"EC_FACTOR_B","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000007\", 16)","doc":null,"summary":null},{"id":"EC_ORDER_N","name":"EC_ORDER_N","value":"BigInt.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", 16)","doc":"Finally, the order n of G and the cofactor h are:","summary":"

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

"},{"id":"EC_PARAM_PRIME","name":"EC_PARAM_PRIME","value":"BigInt.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\", 16)","doc":"The elliptic curve domain parameters over F_p associated with a Koblitz curve\nSecp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite\nfield F_p is defined by p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1:","summary":"

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:

"},{"id":"VERSION","name":"VERSION","value":"\"0.2.0\"","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":"expose the secp256k1 module","summary":"

expose the secp256k1 module

","class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Bitcoin","path":"Secp256k1/Bitcoin.html","kind":"module","full_name":"Secp256k1::Bitcoin","name":"Bitcoin","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the bitcoin address space","summary":"

implements the bitcoin address space

","class_methods":[{"id":"address_from_private(priv:String,version="00",compressed=true)-class-method","html_id":"address_from_private(priv:String,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_private","doc":"generates a bitcoin address from a private key","summary":"

generates a bitcoin address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(priv : String, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L231","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p, version, compressed)\n"}},{"id":"address_from_public_key(pub:String,version="00")-class-method","html_id":"address_from_public_key(pub:String,version=&quot;00&quot;)-class-method","name":"address_from_public_key","doc":"generates a bitcoin address for any public key; compressed and uncompressed\nversion 0x00 = btc mainnet; pass different versions for different networks","summary":"

generates a bitcoin address for any public key; compressed and uncompressed version 0x00 = btc mainnet; pass different versions for different networks

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"args_string":"(pub : String, version = "00")","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L163","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (pub.size === 130) || (pub.size === 66)\n sha2 = Hash.sha256(pub)\n ripe = Hash.ripemd160(sha2)\n ripe_versioned = \"#{version}#{ripe}\"\n hashed = Hash.sha256(ripe_versioned)\n hashed_twice = Hash.sha256(hashed)\n binary = \"#{ripe_versioned}#{hashed_twice[0, 8]}\"\n return Hash.base58_encode(binary)\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point,version="00",compressed=true)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_public_point","doc":"generates a bitcoin address from an public key ec point","summary":"

generates a bitcoin address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(p : Secp256k1::EC_Point, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L195","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed_prefix(p)\nif compressed\n pub = Secp256k1::Util.public_key_compressed_prefix(p)\nend\nreturn address_from_public_key(pub, version)\n"}},{"id":"address_from_wif(wif:String)-class-method","html_id":"address_from_wif(wif:String)-class-method","name":"address_from_wif","doc":"gets a bitcoin address from a wif key","summary":"

gets a bitcoin address from a wif key

","abstract":false,"args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"args_string":"(wif : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L205","def":{"name":"address_from_wif","args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if wif_is_valid?(wif)\n vers = version_byte_from_wif(wif)\n vers = vers.to_i(16)\n vers = vers - 128\n vers = Secp256k1::Util.to_padded_hex_01(vers)\n priv = private_key_from_wif(wif)\n comp = is_wif_compressed?(wif)\n return address_from_private(priv, vers, comp)\nelse\n raise(\"invalid wallet import format (invalid wif: #{wif})\")\n return \"-999\"\nend"}},{"id":"is_wif_compressed?(w:String)-class-method","html_id":"is_wif_compressed?(w:String)-class-method","name":"is_wif_compressed?","doc":"checks if it's compressed or uncompressed wallet import format","summary":"

checks if it's compressed or uncompressed wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L111","def":{"name":"is_wif_compressed?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned.size === 76\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"new_mini_private_key-class-method","html_id":"new_mini_private_key-class-method","name":"new_mini_private_key","doc":"generates a new mini private key (30 characters, base-57)","summary":"

generates a new mini private key (30 characters, base-57)

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L18","def":{"name":"new_mini_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"valid = false\nkey = String.new\nwhile !valid\n i = 1\n key = \"S\"\n while i < 30\n i = i + 1\n r = Random.rand(57)\n key = key + (Hash.base57_char(r))\n end\n checksum = Hash.sha256_string(\"#{key}?\")\n valid = checksum[0, 2] === \"00\"\n priv = private_key_from_mini(key)\n valid = valid && priv > 0\n valid = valid && (priv === (priv % Secp256k1::EC_ORDER_N))\nend\nreturn key\n"}},{"id":"private_key_from_mini(m:String)-class-method","html_id":"private_key_from_mini(m:String)-class-method","name":"private_key_from_mini","doc":"gets a private key from a mini key","summary":"

gets a private key from a mini key

","abstract":false,"args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"args_string":"(m : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L47","def":{"name":"private_key_from_mini","args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"private_key = Hash.sha256_string(m)\nreturn BigInt.new(private_key, 16)\n"}},{"id":"private_key_from_wif(w:String)-class-method","html_id":"private_key_from_wif(w:String)-class-method","name":"private_key_from_wif","doc":"gets a private key from a wallet import format","summary":"

gets a private key from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L80","def":{"name":"private_key_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nif (checksum_key.size == 74) || (checksum_key.size == 76)\n private_key = BigInt.new(checksum_key[2, 64], 16)\n return Secp256k1::Util.to_padded_hex_32(private_key)\nelse\n raise(\"invalid wallet import format (invalid wif size: #{checksum_key.size})\")\n return \"-999\"\nend\n"}},{"id":"version_byte_from_wif(w:String)-class-method","html_id":"version_byte_from_wif(w:String)-class-method","name":"version_byte_from_wif","doc":"gets the version byte from a wallet import format","summary":"

gets the version byte from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L96","def":{"name":"version_byte_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned[0, 2]\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"wif_compressed_from_private(k:BigInt,version="80")-class-method","html_id":"wif_compressed_from_private(k:BigInt,version=&quot;80&quot;)-class-method","name":"wif_compressed_from_private","doc":"to indicate a compressed key to be used, append a \"01\" byte","summary":"

to indicate a compressed key to be used, append a \"01\" byte

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"args_string":"(k : BigInt, version = "80")","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L75","def":{"name":"wif_compressed_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return wif_from_private(k, version, \"01\")"}},{"id":"wif_from_private(k:BigInt,version="80",compr="")-class-method","html_id":"wif_from_private(k:BigInt,version=&quot;80&quot;,compr=&quot;&quot;)-class-method","name":"wif_from_private","doc":"gets a base-58 wallet import format from private key","summary":"

gets a base-58 wallet import format from private key

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"args_string":"(k : BigInt, version = "80", compr = "")","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L53","def":{"name":"wif_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = Secp256k1::Util.to_padded_hex_32(k)\nversioned = \"#{version}#{priv}#{compr}\"\nhashed = Hash.sha256(versioned)\nhashed_twice = Hash.sha256(hashed)\nbinary = \"#{versioned}#{hashed_twice[0, 8]}\"\nreturn Hash.base58_encode(binary)\n"}},{"id":"wif_is_valid?(w:String)-class-method","html_id":"wif_is_valid?(w:String)-class-method","name":"wif_is_valid?","doc":"validates wether a wif has a correct checksum","summary":"

validates wether a wif has a correct checksum

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L126","def":{"name":"wif_is_valid?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nvalid = (checksum_key.size === 74) || (checksum_key.size === 76)\nif valid\n private_key = private_key_from_wif(w)\n valid = (valid && (private_key != \"-999\")) && (private_key.size === 64)\n versioned = checksum_key[0, 66]\n wif_checksum = checksum_key[66, 8]\n if checksum_key.size === 76\n versioned = checksum_key[0, 68]\n wif_checksum = checksum_key[68, 8]\n end\n hashed = Hash.sha256(versioned)\n hashed_twice = Hash.sha256(hashed)\n pk_checksum = hashed_twice[0, 8]\n valid = valid && (wif_checksum === pk_checksum)\nend\nreturn valid\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Core","path":"Secp256k1/Core.html","kind":"module","full_name":"Secp256k1::Core","name":"Core","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"core.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit Secp256k1 Koblitz elliptic curve\nreference https://www.secg.org/sec2-v2.pdf","summary":"

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

","class_methods":[{"id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_add","doc":"elliptic curve jive addition of point p(x, y) and q(x, y).\n'draw' a line between p and q which will intersect the\ncurve in the point r which will be mirrored over the x-axis.","summary":"

elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, q : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L43","def":{"name":"ec_add","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x_delta = q.x - p.x\nx_inv = ec_mod_inv(x_delta)\ny_delta = q.y - p.y\nm = (y_delta * x_inv) % prime\nx = (((m * m) - p.x) - q.x) % prime\ny = ((m * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_double","doc":"elliptic curve juke point doubling of p(x, y).\na special case of addition where both points are the same.\n'draw' a tangent line at p which will intersect the curve\nat point r which will be mirrored over the x-axis.","summary":"

elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L59","def":{"name":"ec_double","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"lam_numer = ((3 * p.x) * p.x) + EC_FACTOR_A\nlam_denom = 2 * p.y\nlam_inv = ec_mod_inv(lam_denom)\nlam = (lam_numer * lam_inv) % prime\nx = ((lam * lam) - (2 * p.x)) % prime\ny = ((lam * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","name":"ec_mod_inv","doc":"elliptic curve modular multiplicative inverse of a","summary":"

elliptic curve modular multiplicative inverse of a

","abstract":false,"args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(a : BigInt, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L19","def":{"name":"ec_mod_inv","args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"m_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nreturn m_low % prime\n"}},{"id":"ec_mul(p:EC_Point,s:BigInt)-class-method","html_id":"ec_mul(p:EC_Point,s:BigInt)-class-method","name":"ec_mul","doc":"elliptic curve sequence multiplication of point p(x, y) and\na skalar s, with s being a private key within the elliptic\ncurve field size of EC_ORDER_N","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(p : EC_Point, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L74","def":{"name":"ec_mul","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (s === 0) || s >= EC_ORDER_N\n raise(\"invalid private key: outside of ec field size.\")\n exit(1)\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = ec_double(q)\n if char === '1'\n q = ec_add(q, p)\n end\nend\nreturn q\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/EC_Point","path":"Secp256k1/EC_Point.html","kind":"class","full_name":"Secp256k1::EC_Point","name":"EC_Point","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":18,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"A point in the two-dimensional space of an elliptic curve","summary":"

A point in the two-dimensional space of an elliptic curve

","class_methods":[],"constructors":[{"id":"new(x:BigInt,y:BigInt)-class-method","html_id":"new(x:BigInt,y:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(x : BigInt, y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L25","def":{"name":"new","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"x:BigInt-instance-method","html_id":"x:BigInt-instance-method","name":"x","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L20","def":{"name":"x","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@x"}},{"id":"x=(x:BigInt)-instance-method","html_id":"x=(x:BigInt)-instance-method","name":"x=","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"args_string":"(x : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L20","def":{"name":"x=","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@x = x"}},{"id":"y:BigInt-instance-method","html_id":"y:BigInt-instance-method","name":"y","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L23","def":{"name":"y","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@y"}},{"id":"y=(y:BigInt)-instance-method","html_id":"y=(y:BigInt)-instance-method","name":"y=","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L23","def":{"name":"y=","args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@y = y"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/ECDSA_Signature","path":"Secp256k1/ECDSA_Signature.html","kind":"class","full_name":"Secp256k1::ECDSA_Signature","name":"ECDSA_Signature","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":30,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"an ecdsa signature","summary":"

an ecdsa signature

","class_methods":[],"constructors":[{"id":"new(r:BigInt,s:BigInt)-class-method","html_id":"new(r:BigInt,s:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(r : BigInt, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L37","def":{"name":"new","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(r, s)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"r:BigInt-instance-method","html_id":"r:BigInt-instance-method","name":"r","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L32","def":{"name":"r","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@r"}},{"id":"r=(r:BigInt)-instance-method","html_id":"r=(r:BigInt)-instance-method","name":"r=","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"args_string":"(r : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L32","def":{"name":"r=","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@r = r"}},{"id":"s:BigInt-instance-method","html_id":"s:BigInt-instance-method","name":"s","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L35","def":{"name":"s","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@s"}},{"id":"s=(s:BigInt)-instance-method","html_id":"s=(s:BigInt)-instance-method","name":"s=","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L35","def":{"name":"s=","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@s = s"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Ethereum","path":"Secp256k1/Ethereum.html","kind":"module","full_name":"Secp256k1::Ethereum","name":"Ethereum","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"ethereum.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the Ethereum address space","summary":"

implements the Ethereum address space

","class_methods":[{"id":"address_checksum(adr:String)-class-method","html_id":"address_checksum(adr:String)-class-method","name":"address_checksum","doc":"returns a checksummed ethereum address as per eip-55","summary":"

returns a checksummed ethereum address as per eip-55

","abstract":false,"args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"args_string":"(adr : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L18","def":{"name":"address_checksum","args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"adr = adr.downcase\nif adr.size === 42\n adr = adr[2, 40]\nend\nif adr.size === 40\n keccak = Hash.keccak256_string(adr)\n address = \"0x\"\n i = 0\n while i < adr.size\n k = keccak[i].to_i(16)\n if k >= 8\n address = address + \"#{adr[i]}\".upcase\n else\n address = address + \"#{adr[i]}\"\n end\n i = i + 1\n end\n return address\nelse\n raise(\"malformed ethereum address (invalid size: #{adr.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_private(priv:String)-class-method","html_id":"address_from_private(priv:String)-class-method","name":"address_from_private","doc":"generates an ethereum address from a private key","summary":"

generates an ethereum address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"args_string":"(priv : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L75","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p)\n"}},{"id":"address_from_public_key(pub:String)-class-method","html_id":"address_from_public_key(pub:String)-class-method","name":"address_from_public_key","doc":"generates an ethereum address for an uncompressed public key","summary":"

generates an ethereum address for an uncompressed public key

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L53","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 128\n keccak = Hash.keccak256(pub)\n return address_checksum(keccak[24, 40])\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","name":"address_from_public_point","doc":"generates an ethereum address from an public key ec point","summary":"

generates an ethereum address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"args_string":"(p : Secp256k1::EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L68","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed(p)\nreturn address_from_public_key(pub)\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Hash","path":"Secp256k1/Hash.html","kind":"module","full_name":"Secp256k1::Hash","name":"Hash","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"hash.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"BASE_57","name":"BASE_57","value":"\"23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-57 alphabet (for mini private keys)","summary":"

the base-57 alphabet (for mini private keys)

"},{"id":"BASE_58","name":"BASE_58","value":"\"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-58 alphabet (for bitcoin)","summary":"

the base-58 alphabet (for bitcoin)

"}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"wraps various hashing functions for convenience","summary":"

wraps various hashing functions for convenience

","class_methods":[{"id":"base57_char(i:Int32)-class-method","html_id":"base57_char(i:Int32)-class-method","name":"base57_char","doc":"get a character from the base-57 alphabet at position i","summary":"

get a character from the base-57 alphabet at position i

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L120","def":{"name":"base57_char","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"i = i % 57\nreturn BASE_57[i]\n"}},{"id":"base58_decode(s:String)-class-method","html_id":"base58_decode(s:String)-class-method","name":"base58_decode","doc":"decode a hex string from base-58","summary":"

decode a hex string from base-58

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L70","def":{"name":"base58_decode","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"index = 0\ndecimal = BigInt.new(0)\nwhile index < s.size\n b58_char = s[index]\n position = BASE_58.index(b58_char)\n if !position.nil?\n decimal = (decimal * 58) + position\n index = index + 1\n else\n raise(\"cannot decode, invalid base58 character: '#{s[index]}'\")\n return \"-999\"\n end\nend\nhex = decimal.to_s(16)\nleading = 0\nwhile s[leading] === '1'\n leading = leading + 1\n hex = \"00#{hex}\"\nend\nreturn hex\n"}},{"id":"base58_encode(h:String)-class-method","html_id":"base58_encode(h:String)-class-method","name":"base58_encode","doc":"encode a hex string as base-58","summary":"

encode a hex string as base-58

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L97","def":{"name":"base58_encode","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = BigInt.new(h, 16)\nadr = String.new\nwhile pub > 0\n pub, rem = pub.divmod(58)\n adr = adr + BASE_58[rem]\nend\ni, s = 0, 2\ncurrent_byte = h[i, s]\nwhile (current_byte.to_i(16)) === 0\n adr = \"#{adr}1\"\n i = i + s\n current_byte = h[i, s]\nend\nreturn adr.reverse\n"}},{"id":"bin_to_hex(b:Bytes)-class-method","html_id":"bin_to_hex(b:Bytes)-class-method","name":"bin_to_hex","doc":"helper function to convert byte arrays to hex strings","summary":"

helper function to convert byte arrays to hex strings

","abstract":false,"args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"args_string":"(b : Bytes)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L126","def":{"name":"bin_to_hex","args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return b.hexstring"}},{"id":"hex_to_bin(s:String)-class-method","html_id":"hex_to_bin(s:String)-class-method","name":"hex_to_bin","doc":"helper function to convert hex strings to byte arrays","summary":"

helper function to convert hex strings to byte arrays

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L131","def":{"name":"hex_to_bin","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return s.hexbytes"}},{"id":"keccak256(h:String)-class-method","html_id":"keccak256(h:String)-class-method","name":"keccak256","doc":"operating a keccak-256 hash on the byte array","summary":"

operating a keccak-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L40","def":{"name":"keccak256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nb = hex_to_bin(h)\nreturn (keccak.update(b)).hexdigest\n"}},{"id":"keccak256_string(h:String)-class-method","html_id":"keccak256_string(h:String)-class-method","name":"keccak256_string","doc":"operating a keccak-256 hash on the actual string literal","summary":"

operating a keccak-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L47","def":{"name":"keccak256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nreturn (keccak.update(h)).hexdigest\n"}},{"id":"ripemd160(h:String)-class-method","html_id":"ripemd160(h:String)-class-method","name":"ripemd160","doc":"operating a ripemd-160 hash on the byte array","summary":"

operating a ripemd-160 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L64","def":{"name":"ripemd160","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"RIPEMD160\")).update(b)).hexdigest\n"}},{"id":"sha256(h:String)-class-method","html_id":"sha256(h:String)-class-method","name":"sha256","doc":"operating a sha2-256 hash on the byte array","summary":"

operating a sha2-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L53","def":{"name":"sha256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"SHA256\")).update(b)).hexdigest\n"}},{"id":"sha256_string(h:String)-class-method","html_id":"sha256_string(h:String)-class-method","name":"sha256_string","doc":"operating a sha2-256 hash on the actual string literal","summary":"

operating a sha2-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L59","def":{"name":"sha256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return ((OpenSSL::Digest.new(\"SHA256\")).update(h)).hexdigest"}},{"id":"sha3(h:String)-class-method","html_id":"sha3(h:String)-class-method","name":"sha3","doc":"operating a sha3-256 hash on the byte array","summary":"

operating a sha3-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L27","def":{"name":"sha3","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nb = hex_to_bin(h)\nreturn (sha3.update(b)).hexdigest\n"}},{"id":"sha3_string(h:String)-class-method","html_id":"sha3_string(h:String)-class-method","name":"sha3_string","doc":"operating a sha3-256 hash on the actual string literal","summary":"

operating a sha3-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L34","def":{"name":"sha3_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nreturn (sha3.update(h)).hexdigest\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"module","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"signature.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements ecdsa signature generation and verification for secp256k1\nref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages","summary":"

implements ecdsa signature generation and verification for secp256k1 ref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages

","class_methods":[{"id":"sign(msg:String,priv:BigInt)-class-method","html_id":"sign(msg:String,priv:BigInt)-class-method","name":"sign","doc":"the ecdsa signing algorithm (rfc 6979) takes as input a message `msg`\nand a private key `priv`. It produces as output a signature, which\nconsists of pair of integers `(r, s)`.","summary":"

the ecdsa signing algorithm (rfc 6979) takes as input a message msg and a private key priv.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(msg : String, priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr#L21","def":{"name":"sign","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nk = Util.new_private_key\nr = (Core.ec_mul(EC_BASE_G, k)).x % EC_ORDER_N\nk_inv = Core.ec_mod_inv(k, EC_ORDER_N)\ns = ((hash + (r * priv)) * k_inv) % EC_ORDER_N\nsig = ECDSA_Signature.new(r, s)\nreturn sig\n"}},{"id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify","doc":"the algorithm to verify an ecdsa signature takes as input the signed message `msg`\nand the signature `(r, s)` produced from self.sign and the public key `pub`,\ncorresponding to the signer's private key. The result is boolean.","summary":"

the algorithm to verify an ecdsa signature takes as input the signed message msg and the signature (r, s) produced from self.sign and the public key pub, corresponding to the signer's private key.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(msg : String, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr#L42","def":{"name":"verify","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nreturn verify_hash(hash, sig, pub)\n"}},{"id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify_hash","doc":"same as self.verify, just using the hashed message directly","summary":"

same as self.verify, just using the hashed message directly

","abstract":false,"args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(hash : BigInt, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr#L49","def":{"name":"verify_hash","args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"s_inv = Core.ec_mod_inv(sig.s, EC_ORDER_N)\np0 = Core.ec_mul(EC_BASE_G, (hash * s_inv) % EC_ORDER_N)\np1 = Core.ec_mul(pub, (sig.r * s_inv) % EC_ORDER_N)\np = Core.ec_add(p0, p1)\nreturn sig.r === p.x\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"util.cr","line_number":22,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"a collection of utilities for secp256k1 key management","summary":"

a collection of utilities for secp256k1 key management

","class_methods":[{"id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","html_id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","name":"decode_compressed_public_key","doc":"decodes a public key as ec point from a compressed public key string","summary":"

decodes a public key as ec point from a compressed public key string

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(pub : String, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L76","def":{"name":"decode_compressed_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 66\n prefix = pub[0, 2]\n if (prefix === \"02\") || (prefix === \"03\")\n x = BigInt.new(pub[2, 64], 16)\n a = (x ** 3) % prime\n a = (a + 7) % prime\n e = ((prime + 1) // 4) % prime\n y = BigInt.new\n LibGMP.mpz_powm_sec(y, a, e, prime)\n parity = prefix.to_i - 2\n if (y % 2) != parity\n y = (-y) % prime\n end\n return EC_Point.new(x, y)\n else\n raise(\"invalid prefix for compressed public key: #{prefix}\")\n end\nelse\n raise(\"malformed compressed public key (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"new_private_key-class-method","html_id":"new_private_key-class-method","name":"new_private_key","doc":"a helper to generate 32 pseudo-random bytes","summary":"

a helper to generate 32 pseudo-random bytes

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L43","def":{"name":"new_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"key = -999\nwhile !key > 0\n key = Random::Secure.hex(32)\n key = BigInt.new(key, 16)\nend\nreturn key % EC_ORDER_N\n"}},{"id":"public_key_compressed_prefix(p:EC_Point)-class-method","html_id":"public_key_compressed_prefix(p:EC_Point)-class-method","name":"public_key_compressed_prefix","doc":"exports the compressed public key from an ec point with prefix 02 or 03","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L58","def":{"name":"public_key_compressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"prefix = (p.y % 2) === 1 ? \"03\" : \"02\"\nreturn \"#{prefix}#{public_key_compressed(p)}\"\n"}},{"id":"public_key_from_private(priv:BigInt)-class-method","html_id":"public_key_from_private(priv:BigInt)-class-method","name":"public_key_from_private","doc":"wrapper function to perform an ec multiplication with\nthe generator point and a provided private key","summary":"

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

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L141","def":{"name":"public_key_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return Core.ec_mul(EC_BASE_G, priv)"}},{"id":"public_key_uncompressed(p:EC_Point)-class-method","html_id":"public_key_uncompressed(p:EC_Point)-class-method","name":"public_key_uncompressed","doc":"exports the uncompressed public key from an ec point without prefix","summary":"

exports the uncompressed public key from an ec point without prefix

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L64","def":{"name":"public_key_uncompressed","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x = to_padded_hex_32(p.x)\ny = to_padded_hex_32(p.y)\nreturn \"#{x}#{y}\"\n"}},{"id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","html_id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","name":"public_key_uncompressed_prefix","doc":"exports the uncompressed public key from an ec point with prefix 04","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L71","def":{"name":"public_key_uncompressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return \"04#{public_key_uncompressed(p)}\""}},{"id":"restore_public_key(pub:String)-class-method","html_id":"restore_public_key(pub:String)-class-method","name":"restore_public_key","doc":"detects public key type and tries to restore the ec point from it","summary":"

detects public key type and tries to restore the ec point from it

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L126","def":{"name":"restore_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"case pub.size\nwhen 130, 128\n return decode_uncompressed_public_key(pub)\nwhen 66\n return decode_compressed_public_key(pub)\nelse\n raise(\"unknown public key format (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"to_padded_hex_01(i:Int32)-class-method","html_id":"to_padded_hex_01(i:Int32)-class-method","name":"to_padded_hex_01","doc":"generic tool to encode single hex bytes as strings, e.g., \"07\"","summary":"

generic tool to encode single hex bytes as strings, e.g., \"07\"

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L24","def":{"name":"to_padded_hex_01","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 2\n hex = '0' + hex\nend\nreturn hex\n"}},{"id":"to_padded_hex_32(i:BigInt)-class-method","html_id":"to_padded_hex_32(i:BigInt)-class-method","name":"to_padded_hex_32","doc":"utility tool to ensure hex keys are always 32 bytes\nit pads the number with leading zeros if not","summary":"

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

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"args_string":"(i : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L34","def":{"name":"to_padded_hex_32","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 64\n hex = '0' + hex\nend\nreturn hex\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]}]}} \ No newline at end of file diff --git a/docs/search-index.js b/docs/search-index.js index 4090751..c8103e9 100644 --- a/docs/search-index.js +++ b/docs/search-index.js @@ -1 +1 @@ -crystal_doc_search_index_callback({"repository_name":"github.com/q9f/secp256k1.cr","body":"# secp256k1.cr\n\n\n[![Badge](https://github.com/q9f/secp256k1.cr/workflows/Nightly/badge.svg)](https://github.com/q9f/secp256k1.cr/actions)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg)](LICENSE)\n\na 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.\n\nthis library allows for key generation of:\n* private keys (from secure random within the elliptic curve field size)\n* mini private keys (short 30-char base-57 keys)\n* wallet import format (checksummed private keys)\n* public keys, prefixed, compressed (from private)\n* public keys, unprefixed and prefixed, uncompressed (from private)\n* conversion between the different public key formats\n\nthis library allows for address generation of:\n* bitcoin address, compressed and uncompressed (from private or public key)\n* any other bitcoin-based address by passing a `version` byte\n* ethereum address, checksummed and unchecksummed (from private or public key)\n* any other ethereum-based address\n\nfurthermore, this library allows for:\n* signing `(r, s)` and verification of arbitrary messages and message-hashes (with key pairs)\n\n# installation\n\nadd the `secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.2\"\n```\n\n# usage\n\n_tl;dr,_ check out [`crystal run ./try.cr`](./try.cr)!\n\n\n```crystal\n# import secp256k1\nrequire \"secp256k1\"\n```\n\nthis library exposes the following modules (in logical order):\n\n* `Secp256k1`: necessary constants and data structures\n* `Secp256k1::Core`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: all tools for the handling of private-public key-pairs\n* `Secp256k1::Hash`: implementation of various hashing algorithms for convenience\n* `Secp256k1::Signature`: allows for signing messages and verifying signatures\n* `Secp256k1::Bitcoin`: for the generation of bitcoin addresses\n* `Secp256k1::Ethereum`: for the generation of ethereum addresses\n\nbasic usage:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\n\n# display the compressed public key with prefix\nputs Secp256k1::Util.public_key_compressed_prefix public_key\n\n# > 02b3c141fba20c129806290f04cee097305fb7391abfde01b3bb3affcd935332a1\n```\n\ngenerate a compressed bitcoin mainnet address:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\ncompressed = Secp256k1::Util.public_key_compressed_prefix public_key\n\n# display the bitcoin address (version \"00\" for bitcoin mainnet)\nputs Secp256k1::Bitcoin.address_from_public_key compressed, \"00\"\n\n# > \"1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\"\n```\n\ngenerate a checksummed ethereum address:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\nuncompressed = Secp256k1::Util.public_key_uncompressed public_key\n\n# display the ethereum address\nputs Secp256k1::Ethereum.address_from_public_key uncompressed\n\n# > \"0x2Ef1f605AF5d03874eE88773f41c1382ac71C239\"\n```\n\n# testing\n\nthe library is entirely specified through tests in `./spec`; run:\n\n```bash\ncrystal spec --verbose\n```\n\n# understand\n\nprivate keys are just scalars and public keys are points with `x` and `y` coordinates.\n\nbitcoin 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.\n\nethereum 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.\n\nneither bitcoin nor ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# known issues\n\n_note: this library should not be used in production without proper auditing._\n\n* this library is not constant time and might be subject to side-channel attacks. [#4](https://github.com/q9f/secp256k1.cr/issues/4)\n* 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)\n\nfound another issue? report it: https://github.com/q9f/secp256k1.cr/issues\n\n# contribute\n\ncreate a pull request, and make sure tests and linter passes.\n\nthis 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.\n\nhonerable 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.\n\nlicense: apache license v2.0\n","program":{"html_id":"github.com/q9f/secp256k1.cr/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"superclass":null,"ancestors":[],"locations":[],"repository_name":"github.com/q9f/secp256k1.cr","program":true,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr"},{"filename":"constants.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/constants.cr"},{"filename":"structs.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr"},{"filename":"version.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/version.cr"},{"filename":"secp256k1.cr","line_number":26,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/secp256k1.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"EC_BASE_G","name":"EC_BASE_G","value":"EC_Point.new(EC_BASE_G_X, EC_BASE_G_Y)","doc":null,"summary":null},{"id":"EC_BASE_G_COMPRESSED","name":"EC_BASE_G_COMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_compressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in compressed form is:","summary":"

The base point G in compressed form is:

"},{"id":"EC_BASE_G_UNCOMPRESSED","name":"EC_BASE_G_UNCOMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_uncompressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in uncompressed form is:","summary":"

The base point G in uncompressed form is:

"},{"id":"EC_BASE_G_X","name":"EC_BASE_G_X","value":"BigInt.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\", 16)","doc":"The commonly used base point G coordinates x, y;\nany other point that satisfies y^2 = x^3 + 7 would also do:","summary":"

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

"},{"id":"EC_BASE_G_Y","name":"EC_BASE_G_Y","value":"BigInt.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\", 16)","doc":null,"summary":null},{"id":"EC_COFACTOR_H","name":"EC_COFACTOR_H","value":"BigInt.new(\"01\", 16)","doc":null,"summary":null},{"id":"EC_FACTOR_A","name":"EC_FACTOR_A","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000000\", 16)","doc":"The curve E: y^2 = x^3 + ax + b over F_p is defined by a, b:\nAs the a constant is zero, the ax term in the curve equation is always zero,\nhence the curve equation becomes y^2 = x^3 + 7.","summary":"

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.

"},{"id":"EC_FACTOR_B","name":"EC_FACTOR_B","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000007\", 16)","doc":null,"summary":null},{"id":"EC_ORDER_N","name":"EC_ORDER_N","value":"BigInt.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", 16)","doc":"Finally, the order n of G and the cofactor h are:","summary":"

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

"},{"id":"EC_PARAM_PRIME","name":"EC_PARAM_PRIME","value":"BigInt.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\", 16)","doc":"The elliptic curve domain parameters over F_p associated with a Koblitz curve\nSecp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite\nfield F_p is defined by p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1:","summary":"

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:

"},{"id":"VERSION","name":"VERSION","value":"\"0.2.0\"","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":"expose the secp256k1 module","summary":"

expose the secp256k1 module

","class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Bitcoin","path":"Secp256k1/Bitcoin.html","kind":"module","full_name":"Secp256k1::Bitcoin","name":"Bitcoin","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the bitcoin address space","summary":"

implements the bitcoin address space

","class_methods":[{"id":"address_from_private(priv:String,version="00",compressed=true)-class-method","html_id":"address_from_private(priv:String,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_private","doc":"generates a bitcoin address from a private key","summary":"

generates a bitcoin address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(priv : String, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L231","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p, version, compressed)\n"}},{"id":"address_from_public_key(pub:String,version="00")-class-method","html_id":"address_from_public_key(pub:String,version=&quot;00&quot;)-class-method","name":"address_from_public_key","doc":"generates a bitcoin address for any public key; compressed and uncompressed\nversion 0x00 = btc mainnet; pass different versions for different networks","summary":"

generates a bitcoin address for any public key; compressed and uncompressed version 0x00 = btc mainnet; pass different versions for different networks

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"args_string":"(pub : String, version = "00")","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L163","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (pub.size === 130) || (pub.size === 66)\n sha2 = Hash.sha256(pub)\n ripe = Hash.ripemd160(sha2)\n ripe_versioned = \"#{version}#{ripe}\"\n hashed = Hash.sha256(ripe_versioned)\n hashed_twice = Hash.sha256(hashed)\n binary = \"#{ripe_versioned}#{hashed_twice[0, 8]}\"\n return Hash.base58_encode(binary)\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point,version="00",compressed=true)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_public_point","doc":"generates a bitcoin address from an public key ec point","summary":"

generates a bitcoin address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(p : Secp256k1::EC_Point, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L195","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed_prefix(p)\nif compressed\n pub = Secp256k1::Util.public_key_compressed_prefix(p)\nend\nreturn address_from_public_key(pub, version)\n"}},{"id":"address_from_wif(wif:String)-class-method","html_id":"address_from_wif(wif:String)-class-method","name":"address_from_wif","doc":"gets a bitcoin address from a wif key","summary":"

gets a bitcoin address from a wif key

","abstract":false,"args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"args_string":"(wif : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L205","def":{"name":"address_from_wif","args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if wif_is_valid?(wif)\n vers = version_byte_from_wif(wif)\n vers = vers.to_i(16)\n vers = vers - 128\n vers = Secp256k1::Util.to_padded_hex_01(vers)\n priv = private_key_from_wif(wif)\n comp = is_wif_compressed?(wif)\n return address_from_private(priv, vers, comp)\nelse\n raise(\"invalid wallet import format (invalid wif: #{wif})\")\n return \"-999\"\nend"}},{"id":"is_wif_compressed?(w:String)-class-method","html_id":"is_wif_compressed?(w:String)-class-method","name":"is_wif_compressed?","doc":"checks if it's compressed or uncompressed wallet import format","summary":"

checks if it's compressed or uncompressed wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L111","def":{"name":"is_wif_compressed?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned.size === 76\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"new_mini_private_key-class-method","html_id":"new_mini_private_key-class-method","name":"new_mini_private_key","doc":"generates a new mini private key (30 characters, base-57)","summary":"

generates a new mini private key (30 characters, base-57)

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L18","def":{"name":"new_mini_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"valid = false\nkey = String.new\nwhile !valid\n i = 1\n key = \"S\"\n while i < 30\n i = i + 1\n r = Random.rand(57)\n key = key + (Hash.base57_char(r))\n end\n checksum = Hash.sha256_string(\"#{key}?\")\n valid = checksum[0, 2] === \"00\"\n priv = private_key_from_mini(key)\n valid = valid && priv > 0\n valid = valid && (priv === (priv % Secp256k1::EC_ORDER_N))\nend\nreturn key\n"}},{"id":"private_key_from_mini(m:String)-class-method","html_id":"private_key_from_mini(m:String)-class-method","name":"private_key_from_mini","doc":"gets a private key from a mini key","summary":"

gets a private key from a mini key

","abstract":false,"args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"args_string":"(m : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L47","def":{"name":"private_key_from_mini","args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"private_key = Hash.sha256_string(m)\nreturn BigInt.new(private_key, 16)\n"}},{"id":"private_key_from_wif(w:String)-class-method","html_id":"private_key_from_wif(w:String)-class-method","name":"private_key_from_wif","doc":"gets a private key from a wallet import format","summary":"

gets a private key from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L80","def":{"name":"private_key_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nif (checksum_key.size == 74) || (checksum_key.size == 76)\n private_key = BigInt.new(checksum_key[2, 64], 16)\n return Secp256k1::Util.to_padded_hex_32(private_key)\nelse\n raise(\"invalid wallet import format (invalid wif size: #{checksum_key.size})\")\n return \"-999\"\nend\n"}},{"id":"version_byte_from_wif(w:String)-class-method","html_id":"version_byte_from_wif(w:String)-class-method","name":"version_byte_from_wif","doc":"gets the version byte from a wallet import format","summary":"

gets the version byte from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L96","def":{"name":"version_byte_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned[0, 2]\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"wif_compressed_from_private(k:BigInt,version="80")-class-method","html_id":"wif_compressed_from_private(k:BigInt,version=&quot;80&quot;)-class-method","name":"wif_compressed_from_private","doc":"to indicate a compressed key to be used, append a \"01\" byte","summary":"

to indicate a compressed key to be used, append a \"01\" byte

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"args_string":"(k : BigInt, version = "80")","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L75","def":{"name":"wif_compressed_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return wif_from_private(k, version, \"01\")"}},{"id":"wif_from_private(k:BigInt,version="80",compr="")-class-method","html_id":"wif_from_private(k:BigInt,version=&quot;80&quot;,compr=&quot;&quot;)-class-method","name":"wif_from_private","doc":"gets a base-58 wallet import format from private key","summary":"

gets a base-58 wallet import format from private key

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"args_string":"(k : BigInt, version = "80", compr = "")","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L53","def":{"name":"wif_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = Secp256k1::Util.to_padded_hex_32(k)\nversioned = \"#{version}#{priv}#{compr}\"\nhashed = Hash.sha256(versioned)\nhashed_twice = Hash.sha256(hashed)\nbinary = \"#{versioned}#{hashed_twice[0, 8]}\"\nreturn Hash.base58_encode(binary)\n"}},{"id":"wif_is_valid?(w:String)-class-method","html_id":"wif_is_valid?(w:String)-class-method","name":"wif_is_valid?","doc":"validates wether a wif has a correct checksum","summary":"

validates wether a wif has a correct checksum

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/bitcoin.cr#L126","def":{"name":"wif_is_valid?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nvalid = (checksum_key.size === 74) || (checksum_key.size === 76)\nif valid\n private_key = private_key_from_wif(w)\n valid = (valid && (private_key != \"-999\")) && (private_key.size === 64)\n versioned = checksum_key[0, 66]\n wif_checksum = checksum_key[66, 8]\n if checksum_key.size === 76\n versioned = checksum_key[0, 68]\n wif_checksum = checksum_key[68, 8]\n end\n hashed = Hash.sha256(versioned)\n hashed_twice = Hash.sha256(hashed)\n pk_checksum = hashed_twice[0, 8]\n valid = valid && (wif_checksum === pk_checksum)\nend\nreturn valid\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Core","path":"Secp256k1/Core.html","kind":"module","full_name":"Secp256k1::Core","name":"Core","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"core.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit Secp256k1 Koblitz elliptic curve\nreference https://www.secg.org/sec2-v2.pdf","summary":"

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

","class_methods":[{"id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_add","doc":"elliptic curve jive addition of point p(x, y) and q(x, y).\n'draw' a line between p and q which will intersect the\ncurve in the point r which will be mirrored over the x-axis.","summary":"

elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, q : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L43","def":{"name":"ec_add","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x_delta = q.x - p.x\nx_inv = ec_mod_inv(x_delta)\ny_delta = q.y - p.y\nm = (y_delta * x_inv) % prime\nx = (((m * m) - p.x) - q.x) % prime\ny = ((m * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_double","doc":"elliptic curve juke point doubling of p(x, y).\na special case of addition where both points are the same.\n'draw' a tangent line at p which will intersect the curve\nat point r which will be mirrored over the x-axis.","summary":"

elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L59","def":{"name":"ec_double","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"lam_numer = ((3 * p.x) * p.x) + EC_FACTOR_A\nlam_denom = 2 * p.y\nlam_inv = ec_mod_inv(lam_denom)\nlam = (lam_numer * lam_inv) % prime\nx = ((lam * lam) - (2 * p.x)) % prime\ny = ((lam * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","name":"ec_mod_inv","doc":"elliptic curve modular multiplicative inverse of a","summary":"

elliptic curve modular multiplicative inverse of a

","abstract":false,"args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(a : BigInt, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L19","def":{"name":"ec_mod_inv","args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"m_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nreturn m_low % prime\n"}},{"id":"ec_mul(p:EC_Point,s:BigInt)-class-method","html_id":"ec_mul(p:EC_Point,s:BigInt)-class-method","name":"ec_mul","doc":"elliptic curve sequence multiplication of point p(x, y) and\na skalar s, with s being a private key within the elliptic\ncurve field size of EC_ORDER_N","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(p : EC_Point, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/core.cr#L74","def":{"name":"ec_mul","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (s === 0) || s >= EC_ORDER_N\n raise(\"invalid private key: outside of ec field size.\")\n exit(1)\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = ec_double(q)\n if char === '1'\n q = ec_add(q, p)\n end\nend\nreturn q\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/EC_Point","path":"Secp256k1/EC_Point.html","kind":"class","full_name":"Secp256k1::EC_Point","name":"EC_Point","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":18,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"A point in the two-dimensional space of an elliptic curve","summary":"

A point in the two-dimensional space of an elliptic curve

","class_methods":[],"constructors":[{"id":"new(x:BigInt,y:BigInt)-class-method","html_id":"new(x:BigInt,y:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(x : BigInt, y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L25","def":{"name":"new","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"x:BigInt-instance-method","html_id":"x:BigInt-instance-method","name":"x","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L20","def":{"name":"x","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@x"}},{"id":"x=(x:BigInt)-instance-method","html_id":"x=(x:BigInt)-instance-method","name":"x=","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"args_string":"(x : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L20","def":{"name":"x=","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@x = x"}},{"id":"y:BigInt-instance-method","html_id":"y:BigInt-instance-method","name":"y","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L23","def":{"name":"y","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@y"}},{"id":"y=(y:BigInt)-instance-method","html_id":"y=(y:BigInt)-instance-method","name":"y=","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L23","def":{"name":"y=","args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@y = y"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/ECDSA_Signature","path":"Secp256k1/ECDSA_Signature.html","kind":"class","full_name":"Secp256k1::ECDSA_Signature","name":"ECDSA_Signature","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":30,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"an ecdsa signature","summary":"

an ecdsa signature

","class_methods":[],"constructors":[{"id":"new(r:BigInt,s:BigInt)-class-method","html_id":"new(r:BigInt,s:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(r : BigInt, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L37","def":{"name":"new","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(r, s)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"r:BigInt-instance-method","html_id":"r:BigInt-instance-method","name":"r","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L32","def":{"name":"r","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@r"}},{"id":"r=(r:BigInt)-instance-method","html_id":"r=(r:BigInt)-instance-method","name":"r=","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"args_string":"(r : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L32","def":{"name":"r=","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@r = r"}},{"id":"s:BigInt-instance-method","html_id":"s:BigInt-instance-method","name":"s","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L35","def":{"name":"s","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@s"}},{"id":"s=(s:BigInt)-instance-method","html_id":"s=(s:BigInt)-instance-method","name":"s=","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/structs.cr#L35","def":{"name":"s=","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@s = s"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Ethereum","path":"Secp256k1/Ethereum.html","kind":"module","full_name":"Secp256k1::Ethereum","name":"Ethereum","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"ethereum.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the Ethereum address space","summary":"

implements the Ethereum address space

","class_methods":[{"id":"address_checksum(adr:String)-class-method","html_id":"address_checksum(adr:String)-class-method","name":"address_checksum","doc":"returns a checksummed ethereum address as per eip-55","summary":"

returns a checksummed ethereum address as per eip-55

","abstract":false,"args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"args_string":"(adr : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L18","def":{"name":"address_checksum","args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"adr = adr.downcase\nif adr.size === 42\n adr = adr[2, 40]\nend\nif adr.size === 40\n keccak = Hash.keccak256_string(adr)\n address = \"0x\"\n i = 0\n while i < adr.size\n k = keccak[i].to_i(16)\n if k >= 8\n address = address + \"#{adr[i]}\".upcase\n else\n address = address + \"#{adr[i]}\"\n end\n i = i + 1\n end\n return address\nelse\n raise(\"malformed ethereum address (invalid size: #{adr.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_private(priv:String)-class-method","html_id":"address_from_private(priv:String)-class-method","name":"address_from_private","doc":"generates an ethereum address from a private key","summary":"

generates an ethereum address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"args_string":"(priv : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L75","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p)\n"}},{"id":"address_from_public_key(pub:String)-class-method","html_id":"address_from_public_key(pub:String)-class-method","name":"address_from_public_key","doc":"generates an ethereum address for an uncompressed public key","summary":"

generates an ethereum address for an uncompressed public key

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L53","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 128\n keccak = Hash.keccak256(pub)\n return address_checksum(keccak[24, 40])\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","name":"address_from_public_point","doc":"generates an ethereum address from an public key ec point","summary":"

generates an ethereum address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"args_string":"(p : Secp256k1::EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/ethereum.cr#L68","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed(p)\nreturn address_from_public_key(pub)\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Hash","path":"Secp256k1/Hash.html","kind":"module","full_name":"Secp256k1::Hash","name":"Hash","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"hash.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"BASE_57","name":"BASE_57","value":"\"23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-57 alphabet (for mini private keys)","summary":"

the base-57 alphabet (for mini private keys)

"},{"id":"BASE_58","name":"BASE_58","value":"\"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-58 alphabet (for bitcoin)","summary":"

the base-58 alphabet (for bitcoin)

"}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"wraps various hashing functions for convenience","summary":"

wraps various hashing functions for convenience

","class_methods":[{"id":"base57_char(i:Int32)-class-method","html_id":"base57_char(i:Int32)-class-method","name":"base57_char","doc":"get a character from the base-57 alphabet at position i","summary":"

get a character from the base-57 alphabet at position i

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L120","def":{"name":"base57_char","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"i = i % 57\nreturn BASE_57[i]\n"}},{"id":"base58_decode(s:String)-class-method","html_id":"base58_decode(s:String)-class-method","name":"base58_decode","doc":"decode a hex string from base-58","summary":"

decode a hex string from base-58

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L70","def":{"name":"base58_decode","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"index = 0\ndecimal = BigInt.new(0)\nwhile index < s.size\n b58_char = s[index]\n position = BASE_58.index(b58_char)\n if !position.nil?\n decimal = (decimal * 58) + position\n index = index + 1\n else\n raise(\"cannot decode, invalid base58 character: '#{s[index]}'\")\n return \"-999\"\n end\nend\nhex = decimal.to_s(16)\nleading = 0\nwhile s[leading] === '1'\n leading = leading + 1\n hex = \"00#{hex}\"\nend\nreturn hex\n"}},{"id":"base58_encode(h:String)-class-method","html_id":"base58_encode(h:String)-class-method","name":"base58_encode","doc":"encode a hex string as base-58","summary":"

encode a hex string as base-58

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L97","def":{"name":"base58_encode","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = BigInt.new(h, 16)\nadr = String.new\nwhile pub > 0\n pub, rem = pub.divmod(58)\n adr = adr + BASE_58[rem]\nend\ni, s = 0, 2\ncurrent_byte = h[i, s]\nwhile (current_byte.to_i(16)) === 0\n adr = \"#{adr}1\"\n i = i + s\n current_byte = h[i, s]\nend\nreturn adr.reverse\n"}},{"id":"bin_to_hex(b:Bytes)-class-method","html_id":"bin_to_hex(b:Bytes)-class-method","name":"bin_to_hex","doc":"helper function to convert byte arrays to hex strings","summary":"

helper function to convert byte arrays to hex strings

","abstract":false,"args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"args_string":"(b : Bytes)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L126","def":{"name":"bin_to_hex","args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return b.hexstring"}},{"id":"hex_to_bin(s:String)-class-method","html_id":"hex_to_bin(s:String)-class-method","name":"hex_to_bin","doc":"helper function to convert hex strings to byte arrays","summary":"

helper function to convert hex strings to byte arrays

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L131","def":{"name":"hex_to_bin","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return s.hexbytes"}},{"id":"keccak256(h:String)-class-method","html_id":"keccak256(h:String)-class-method","name":"keccak256","doc":"operating a keccak-256 hash on the byte array","summary":"

operating a keccak-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L40","def":{"name":"keccak256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nb = hex_to_bin(h)\nreturn (keccak.update(b)).hexdigest\n"}},{"id":"keccak256_string(h:String)-class-method","html_id":"keccak256_string(h:String)-class-method","name":"keccak256_string","doc":"operating a keccak-256 hash on the actual string literal","summary":"

operating a keccak-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L47","def":{"name":"keccak256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nreturn (keccak.update(h)).hexdigest\n"}},{"id":"ripemd160(h:String)-class-method","html_id":"ripemd160(h:String)-class-method","name":"ripemd160","doc":"operating a ripemd-160 hash on the byte array","summary":"

operating a ripemd-160 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L64","def":{"name":"ripemd160","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"RIPEMD160\")).update(b)).hexdigest\n"}},{"id":"sha256(h:String)-class-method","html_id":"sha256(h:String)-class-method","name":"sha256","doc":"operating a sha2-256 hash on the byte array","summary":"

operating a sha2-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L53","def":{"name":"sha256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"SHA256\")).update(b)).hexdigest\n"}},{"id":"sha256_string(h:String)-class-method","html_id":"sha256_string(h:String)-class-method","name":"sha256_string","doc":"operating a sha2-256 hash on the actual string literal","summary":"

operating a sha2-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L59","def":{"name":"sha256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return ((OpenSSL::Digest.new(\"SHA256\")).update(h)).hexdigest"}},{"id":"sha3(h:String)-class-method","html_id":"sha3(h:String)-class-method","name":"sha3","doc":"operating a sha3-256 hash on the byte array","summary":"

operating a sha3-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L27","def":{"name":"sha3","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nb = hex_to_bin(h)\nreturn (sha3.update(b)).hexdigest\n"}},{"id":"sha3_string(h:String)-class-method","html_id":"sha3_string(h:String)-class-method","name":"sha3_string","doc":"operating a sha3-256 hash on the actual string literal","summary":"

operating a sha3-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/hash.cr#L34","def":{"name":"sha3_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nreturn (sha3.update(h)).hexdigest\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"module","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"signature.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements ecdsa signature generation and verification for secp256k1\nref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages","summary":"

implements ecdsa signature generation and verification for secp256k1 ref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages

","class_methods":[{"id":"sign(msg:String,priv:BigInt)-class-method","html_id":"sign(msg:String,priv:BigInt)-class-method","name":"sign","doc":"the ecdsa signing algorithm (rfc 6979) takes as input a message `msg`\nand a private key `priv`. It produces as output a signature, which\nconsists of pair of integers `(r, s)`.","summary":"

the ecdsa signing algorithm (rfc 6979) takes as input a message msg and a private key priv.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(msg : String, priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr#L21","def":{"name":"sign","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nk = Util.new_private_key\nr = (Core.ec_mul(EC_BASE_G, k)).x % EC_ORDER_N\nk_inv = Core.ec_mod_inv(k, EC_ORDER_N)\ns = ((hash + (r * priv)) * k_inv) % EC_ORDER_N\nsig = ECDSA_Signature.new(r, s)\nreturn sig\n"}},{"id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify","doc":"the algorithm to verify an ecdsa signature takes as input the signed message `msg`\nand the signature `(r, s)` produced from self.sign and the public key `pub`,\ncorresponding to the signer's private key. The result is boolean.","summary":"

the algorithm to verify an ecdsa signature takes as input the signed message msg and the signature (r, s) produced from self.sign and the public key pub, corresponding to the signer's private key.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(msg : String, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr#L42","def":{"name":"verify","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nreturn verify_hash(hash, sig, pub)\n"}},{"id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify_hash","doc":"same as self.verify, just using the hashed message directly","summary":"

same as self.verify, just using the hashed message directly

","abstract":false,"args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(hash : BigInt, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/signature.cr#L49","def":{"name":"verify_hash","args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"s_inv = Core.ec_mod_inv(sig.s, EC_ORDER_N)\np0 = Core.ec_mul(EC_BASE_G, (hash * s_inv) % EC_ORDER_N)\np1 = Core.ec_mul(pub, (sig.r * s_inv) % EC_ORDER_N)\np = Core.ec_add(p0, p1)\nreturn sig.r === p.x\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"util.cr","line_number":22,"url":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"a collection of utilities for secp256k1 key management","summary":"

a collection of utilities for secp256k1 key management

","class_methods":[{"id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","html_id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","name":"decode_compressed_public_key","doc":"decodes a public key as ec point from a compressed public key string","summary":"

decodes a public key as ec point from a compressed public key string

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(pub : String, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L76","def":{"name":"decode_compressed_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 66\n prefix = pub[0, 2]\n if (prefix === \"02\") || (prefix === \"03\")\n x = BigInt.new(pub[2, 64], 16)\n a = (x ** 3) % prime\n a = (a + 7) % prime\n e = ((prime + 1) // 4) % prime\n y = BigInt.new\n LibGMP.mpz_powm_sec(y, a, e, prime)\n parity = prefix.to_i - 2\n if (y % 2) != parity\n y = (-y) % prime\n end\n return EC_Point.new(x, y)\n else\n raise(\"invalid prefix for compressed public key: #{prefix}\")\n end\nelse\n raise(\"malformed compressed public key (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"new_private_key-class-method","html_id":"new_private_key-class-method","name":"new_private_key","doc":"a helper to generate 32 pseudo-random bytes","summary":"

a helper to generate 32 pseudo-random bytes

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L43","def":{"name":"new_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"key = -999\nwhile !key > 0\n key = Random::Secure.hex(32)\n key = BigInt.new(key, 16)\nend\nreturn key % EC_ORDER_N\n"}},{"id":"public_key_compressed_prefix(p:EC_Point)-class-method","html_id":"public_key_compressed_prefix(p:EC_Point)-class-method","name":"public_key_compressed_prefix","doc":"exports the compressed public key from an ec point with prefix 02 or 03","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L58","def":{"name":"public_key_compressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"prefix = (p.y % 2) === 1 ? \"03\" : \"02\"\nreturn \"#{prefix}#{public_key_compressed(p)}\"\n"}},{"id":"public_key_from_private(priv:BigInt)-class-method","html_id":"public_key_from_private(priv:BigInt)-class-method","name":"public_key_from_private","doc":"wrapper function to perform an ec multiplication with\nthe generator point and a provided private key","summary":"

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

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L141","def":{"name":"public_key_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return Core.ec_mul(EC_BASE_G, priv)"}},{"id":"public_key_uncompressed(p:EC_Point)-class-method","html_id":"public_key_uncompressed(p:EC_Point)-class-method","name":"public_key_uncompressed","doc":"exports the uncompressed public key from an ec point without prefix","summary":"

exports the uncompressed public key from an ec point without prefix

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L64","def":{"name":"public_key_uncompressed","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x = to_padded_hex_32(p.x)\ny = to_padded_hex_32(p.y)\nreturn \"#{x}#{y}\"\n"}},{"id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","html_id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","name":"public_key_uncompressed_prefix","doc":"exports the uncompressed public key from an ec point with prefix 04","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L71","def":{"name":"public_key_uncompressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return \"04#{public_key_uncompressed(p)}\""}},{"id":"restore_public_key(pub:String)-class-method","html_id":"restore_public_key(pub:String)-class-method","name":"restore_public_key","doc":"detects public key type and tries to restore the ec point from it","summary":"

detects public key type and tries to restore the ec point from it

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L126","def":{"name":"restore_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"case pub.size\nwhen 130, 128\n return decode_uncompressed_public_key(pub)\nwhen 66\n return decode_compressed_public_key(pub)\nelse\n raise(\"unknown public key format (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"to_padded_hex_01(i:Int32)-class-method","html_id":"to_padded_hex_01(i:Int32)-class-method","name":"to_padded_hex_01","doc":"generic tool to encode single hex bytes as strings, e.g., \"07\"","summary":"

generic tool to encode single hex bytes as strings, e.g., \"07\"

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L24","def":{"name":"to_padded_hex_01","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 2\n hex = '0' + hex\nend\nreturn hex\n"}},{"id":"to_padded_hex_32(i:BigInt)-class-method","html_id":"to_padded_hex_32(i:BigInt)-class-method","name":"to_padded_hex_32","doc":"utility tool to ensure hex keys are always 32 bytes\nit pads the number with leading zeros if not","summary":"

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

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"args_string":"(i : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/f44b5dce027b43592aa6dd7ab8d3cea3319a517a/src/util.cr#L34","def":{"name":"to_padded_hex_32","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 64\n hex = '0' + hex\nend\nreturn hex\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]}]}}) \ No newline at end of file +crystal_doc_search_index_callback({"repository_name":"github.com/q9f/secp256k1.cr","body":"# secp256k1.cr\n\n\n[![Badge](https://github.com/q9f/secp256k1.cr/workflows/Nightly/badge.svg)](https://github.com/q9f/secp256k1.cr/actions)\n[![Language](https://img.shields.io/github/languages/top/q9f/secp256k1.cr?color=black)](https://github.com/q9f/secp256k1.cr/search?l=crystal)\n[![License](https://img.shields.io/github/license/q9f/secp256k1.cr.svg)](LICENSE)\n\na 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.\n\nthis library allows for key generation of:\n* private keys (from secure random within the elliptic curve field size)\n* mini private keys (short 30-char base-57 keys)\n* wallet import format (checksummed private keys)\n* public keys, prefixed, compressed (from private)\n* public keys, unprefixed and prefixed, uncompressed (from private)\n* conversion between the different public key formats\n\nthis library allows for address generation of:\n* bitcoin address, compressed and uncompressed (from private or public key)\n* any other bitcoin-based address by passing a `version` byte\n* ethereum address, checksummed and unchecksummed (from private or public key)\n* any other ethereum-based address\n\nfurthermore, this library allows for:\n* signing `(r, s)` and verification of arbitrary messages and message-hashes (with key pairs)\n\n# installation\n\nadd the `secp256k1` library to your `shard.yml`\n\n```yaml\ndependencies:\n secp256k1:\n github: q9f/secp256k1.cr\n version: \"~> 0.2\"\n```\n\n# usage\n\n_tl;dr,_ check out [`crystal run ./try.cr`](./try.cr)!\n\n\n```crystal\n# import secp256k1\nrequire \"secp256k1\"\n```\n\nthis library exposes the following modules (in logical order):\n\n* `Secp256k1`: necessary constants and data structures\n* `Secp256k1::Core`: the entire core mathematics behind the elliptic curve cryptography\n* `Secp256k1::Util`: all tools for the handling of private-public key-pairs\n* `Secp256k1::Hash`: implementation of various hashing algorithms for convenience\n* `Secp256k1::Signature`: allows for signing messages and verifying signatures\n* `Secp256k1::Bitcoin`: for the generation of bitcoin addresses\n* `Secp256k1::Ethereum`: for the generation of ethereum addresses\n\nbasic usage:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\n\n# display the compressed public key with prefix\nputs Secp256k1::Util.public_key_compressed_prefix public_key\n\n# > 02b3c141fba20c129806290f04cee097305fb7391abfde01b3bb3affcd935332a1\n```\n\ngenerate a compressed bitcoin mainnet address:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\ncompressed = Secp256k1::Util.public_key_compressed_prefix public_key\n\n# display the bitcoin address (version \"00\" for bitcoin mainnet)\nputs Secp256k1::Bitcoin.address_from_public_key compressed, \"00\"\n\n# > \"1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs\"\n```\n\ngenerate a checksummed ethereum address:\n\n```crystal\n# generate a keypair\nprivate_key = Secp256k1::Util.new_private_key\npublic_key = Secp256k1::Util.public_key_from_private private_key\nuncompressed = Secp256k1::Util.public_key_uncompressed public_key\n\n# display the ethereum address\nputs Secp256k1::Ethereum.address_from_public_key uncompressed\n\n# > \"0x2Ef1f605AF5d03874eE88773f41c1382ac71C239\"\n```\n\n# documentation\n\ncan be found here: https://q9f.github.io/secp256k1.cr/\n\ngenerate a local copy with:\n\n```\ncrystal docs\n```\n\n# testing\n\nthe library is entirely specified through tests in `./spec`; run:\n\n```bash\ncrystal spec --verbose\n```\n\n# understand\n\nprivate keys are just scalars and public keys are points with `x` and `y` coordinates.\n\nbitcoin 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.\n\nethereum 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.\n\nneither bitcoin nor ethereum allow for recovering public keys from an address unless there exists a transaction with a valid signature on the blockchain.\n\n# known issues\n\n_note: this library should not be used in production without proper auditing._\n\n* this library is not constant time and might be subject to side-channel attacks. [#4](https://github.com/q9f/secp256k1.cr/issues/4)\n* 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)\n\nfound another issue? report it: https://github.com/q9f/secp256k1.cr/issues\n\n# contribute\n\ncreate a pull request, and make sure tests and linter passes.\n\nthis 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.\n\nhonerable 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.\n\nlicense: apache license v2.0\n","program":{"html_id":"github.com/q9f/secp256k1.cr/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"superclass":null,"ancestors":[],"locations":[],"repository_name":"github.com/q9f/secp256k1.cr","program":true,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":null,"summary":null,"class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","path":"Secp256k1.html","kind":"module","full_name":"Secp256k1","name":"Secp256k1","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr"},{"filename":"constants.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/constants.cr"},{"filename":"structs.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr"},{"filename":"version.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/version.cr"},{"filename":"secp256k1.cr","line_number":26,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/secp256k1.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"EC_BASE_G","name":"EC_BASE_G","value":"EC_Point.new(EC_BASE_G_X, EC_BASE_G_Y)","doc":null,"summary":null},{"id":"EC_BASE_G_COMPRESSED","name":"EC_BASE_G_COMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_compressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in compressed form is:","summary":"

The base point G in compressed form is:

"},{"id":"EC_BASE_G_UNCOMPRESSED","name":"EC_BASE_G_UNCOMPRESSED","value":"BigInt.new((Secp256k1::Util.public_key_uncompressed_prefix(EC_BASE_G)), 16)","doc":"The base point G in uncompressed form is:","summary":"

The base point G in uncompressed form is:

"},{"id":"EC_BASE_G_X","name":"EC_BASE_G_X","value":"BigInt.new(\"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\", 16)","doc":"The commonly used base point G coordinates x, y;\nany other point that satisfies y^2 = x^3 + 7 would also do:","summary":"

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

"},{"id":"EC_BASE_G_Y","name":"EC_BASE_G_Y","value":"BigInt.new(\"483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8\", 16)","doc":null,"summary":null},{"id":"EC_COFACTOR_H","name":"EC_COFACTOR_H","value":"BigInt.new(\"01\", 16)","doc":null,"summary":null},{"id":"EC_FACTOR_A","name":"EC_FACTOR_A","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000000\", 16)","doc":"The curve E: y^2 = x^3 + ax + b over F_p is defined by a, b:\nAs the a constant is zero, the ax term in the curve equation is always zero,\nhence the curve equation becomes y^2 = x^3 + 7.","summary":"

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.

"},{"id":"EC_FACTOR_B","name":"EC_FACTOR_B","value":"BigInt.new(\"0000000000000000000000000000000000000000000000000000000000000007\", 16)","doc":null,"summary":null},{"id":"EC_ORDER_N","name":"EC_ORDER_N","value":"BigInt.new(\"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141\", 16)","doc":"Finally, the order n of G and the cofactor h are:","summary":"

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

"},{"id":"EC_PARAM_PRIME","name":"EC_PARAM_PRIME","value":"BigInt.new(\"fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f\", 16)","doc":"The elliptic curve domain parameters over F_p associated with a Koblitz curve\nSecp256k1 are specified by the sextuple T = (p, a, b, G, n, h) where the finite\nfield F_p is defined by p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1:","summary":"

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:

"},{"id":"VERSION","name":"VERSION","value":"\"0.2.0\"","doc":null,"summary":null}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":null,"doc":"expose the secp256k1 module","summary":"

expose the secp256k1 module

","class_methods":[],"constructors":[],"instance_methods":[],"macros":[],"types":[{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Bitcoin","path":"Secp256k1/Bitcoin.html","kind":"module","full_name":"Secp256k1::Bitcoin","name":"Bitcoin","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"bitcoin.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the bitcoin address space","summary":"

implements the bitcoin address space

","class_methods":[{"id":"address_from_private(priv:String,version="00",compressed=true)-class-method","html_id":"address_from_private(priv:String,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_private","doc":"generates a bitcoin address from a private key","summary":"

generates a bitcoin address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(priv : String, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L231","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p, version, compressed)\n"}},{"id":"address_from_public_key(pub:String,version="00")-class-method","html_id":"address_from_public_key(pub:String,version=&quot;00&quot;)-class-method","name":"address_from_public_key","doc":"generates a bitcoin address for any public key; compressed and uncompressed\nversion 0x00 = btc mainnet; pass different versions for different networks","summary":"

generates a bitcoin address for any public key; compressed and uncompressed version 0x00 = btc mainnet; pass different versions for different networks

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"args_string":"(pub : String, version = "00")","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L163","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (pub.size === 130) || (pub.size === 66)\n sha2 = Hash.sha256(pub)\n ripe = Hash.ripemd160(sha2)\n ripe_versioned = \"#{version}#{ripe}\"\n hashed = Hash.sha256(ripe_versioned)\n hashed_twice = Hash.sha256(hashed)\n binary = \"#{ripe_versioned}#{hashed_twice[0, 8]}\"\n return Hash.base58_encode(binary)\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point,version="00",compressed=true)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point,version=&quot;00&quot;,compressed=true)-class-method","name":"address_from_public_point","doc":"generates a bitcoin address from an public key ec point","summary":"

generates a bitcoin address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"args_string":"(p : Secp256k1::EC_Point, version = "00", compressed = true)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L195","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"},{"name":"version","doc":null,"default_value":"\"00\"","external_name":"version","restriction":""},{"name":"compressed","doc":null,"default_value":"true","external_name":"compressed","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed_prefix(p)\nif compressed\n pub = Secp256k1::Util.public_key_compressed_prefix(p)\nend\nreturn address_from_public_key(pub, version)\n"}},{"id":"address_from_wif(wif:String)-class-method","html_id":"address_from_wif(wif:String)-class-method","name":"address_from_wif","doc":"gets a bitcoin address from a wif key","summary":"

gets a bitcoin address from a wif key

","abstract":false,"args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"args_string":"(wif : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L205","def":{"name":"address_from_wif","args":[{"name":"wif","doc":null,"default_value":"","external_name":"wif","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if wif_is_valid?(wif)\n vers = version_byte_from_wif(wif)\n vers = vers.to_i(16)\n vers = vers - 128\n vers = Secp256k1::Util.to_padded_hex_01(vers)\n priv = private_key_from_wif(wif)\n comp = is_wif_compressed?(wif)\n return address_from_private(priv, vers, comp)\nelse\n raise(\"invalid wallet import format (invalid wif: #{wif})\")\n return \"-999\"\nend"}},{"id":"is_wif_compressed?(w:String)-class-method","html_id":"is_wif_compressed?(w:String)-class-method","name":"is_wif_compressed?","doc":"checks if it's compressed or uncompressed wallet import format","summary":"

checks if it's compressed or uncompressed wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L111","def":{"name":"is_wif_compressed?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned.size === 76\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"new_mini_private_key-class-method","html_id":"new_mini_private_key-class-method","name":"new_mini_private_key","doc":"generates a new mini private key (30 characters, base-57)","summary":"

generates a new mini private key (30 characters, base-57)

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L18","def":{"name":"new_mini_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"valid = false\nkey = String.new\nwhile !valid\n i = 1\n key = \"S\"\n while i < 30\n i = i + 1\n r = Random.rand(57)\n key = key + (Hash.base57_char(r))\n end\n checksum = Hash.sha256_string(\"#{key}?\")\n valid = checksum[0, 2] === \"00\"\n priv = private_key_from_mini(key)\n valid = valid && priv > 0\n valid = valid && (priv === (priv % Secp256k1::EC_ORDER_N))\nend\nreturn key\n"}},{"id":"private_key_from_mini(m:String)-class-method","html_id":"private_key_from_mini(m:String)-class-method","name":"private_key_from_mini","doc":"gets a private key from a mini key","summary":"

gets a private key from a mini key

","abstract":false,"args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"args_string":"(m : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L47","def":{"name":"private_key_from_mini","args":[{"name":"m","doc":null,"default_value":"","external_name":"m","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"private_key = Hash.sha256_string(m)\nreturn BigInt.new(private_key, 16)\n"}},{"id":"private_key_from_wif(w:String)-class-method","html_id":"private_key_from_wif(w:String)-class-method","name":"private_key_from_wif","doc":"gets a private key from a wallet import format","summary":"

gets a private key from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L80","def":{"name":"private_key_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nif (checksum_key.size == 74) || (checksum_key.size == 76)\n private_key = BigInt.new(checksum_key[2, 64], 16)\n return Secp256k1::Util.to_padded_hex_32(private_key)\nelse\n raise(\"invalid wallet import format (invalid wif size: #{checksum_key.size})\")\n return \"-999\"\nend\n"}},{"id":"version_byte_from_wif(w:String)-class-method","html_id":"version_byte_from_wif(w:String)-class-method","name":"version_byte_from_wif","doc":"gets the version byte from a wallet import format","summary":"

gets the version byte from a wallet import format

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L96","def":{"name":"version_byte_from_wif","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"versioned = Hash.base58_decode(w)\nif (versioned.size === 74) || (versioned.size === 76)\n return versioned[0, 2]\nelse\n raise(\"invalid wallet import format (invalid wif size: #{versioned.size})\")\n return \"-999\"\nend\n"}},{"id":"wif_compressed_from_private(k:BigInt,version="80")-class-method","html_id":"wif_compressed_from_private(k:BigInt,version=&quot;80&quot;)-class-method","name":"wif_compressed_from_private","doc":"to indicate a compressed key to be used, append a \"01\" byte","summary":"

to indicate a compressed key to be used, append a \"01\" byte

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"args_string":"(k : BigInt, version = "80")","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L75","def":{"name":"wif_compressed_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return wif_from_private(k, version, \"01\")"}},{"id":"wif_from_private(k:BigInt,version="80",compr="")-class-method","html_id":"wif_from_private(k:BigInt,version=&quot;80&quot;,compr=&quot;&quot;)-class-method","name":"wif_from_private","doc":"gets a base-58 wallet import format from private key","summary":"

gets a base-58 wallet import format from private key

","abstract":false,"args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"args_string":"(k : BigInt, version = "80", compr = "")","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L53","def":{"name":"wif_from_private","args":[{"name":"k","doc":null,"default_value":"","external_name":"k","restriction":"BigInt"},{"name":"version","doc":null,"default_value":"\"80\"","external_name":"version","restriction":""},{"name":"compr","doc":null,"default_value":"\"\"","external_name":"compr","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = Secp256k1::Util.to_padded_hex_32(k)\nversioned = \"#{version}#{priv}#{compr}\"\nhashed = Hash.sha256(versioned)\nhashed_twice = Hash.sha256(hashed)\nbinary = \"#{versioned}#{hashed_twice[0, 8]}\"\nreturn Hash.base58_encode(binary)\n"}},{"id":"wif_is_valid?(w:String)-class-method","html_id":"wif_is_valid?(w:String)-class-method","name":"wif_is_valid?","doc":"validates wether a wif has a correct checksum","summary":"

validates wether a wif has a correct checksum

","abstract":false,"args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"args_string":"(w : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/bitcoin.cr#L126","def":{"name":"wif_is_valid?","args":[{"name":"w","doc":null,"default_value":"","external_name":"w","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"checksum_key = Hash.base58_decode(w)\nvalid = (checksum_key.size === 74) || (checksum_key.size === 76)\nif valid\n private_key = private_key_from_wif(w)\n valid = (valid && (private_key != \"-999\")) && (private_key.size === 64)\n versioned = checksum_key[0, 66]\n wif_checksum = checksum_key[66, 8]\n if checksum_key.size === 76\n versioned = checksum_key[0, 68]\n wif_checksum = checksum_key[68, 8]\n end\n hashed = Hash.sha256(versioned)\n hashed_twice = Hash.sha256(hashed)\n pk_checksum = hashed_twice[0, 8]\n valid = valid && (wif_checksum === pk_checksum)\nend\nreturn valid\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Core","path":"Secp256k1/Core.html","kind":"module","full_name":"Secp256k1::Core","name":"Core","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"core.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"Implements 256-bit Secp256k1 Koblitz elliptic curve\nreference https://www.secg.org/sec2-v2.pdf","summary":"

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

","class_methods":[{"id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_add(p:EC_Point,q:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_add","doc":"elliptic curve jive addition of point p(x, y) and q(x, y).\n'draw' a line between p and q which will intersect the\ncurve in the point r which will be mirrored over the x-axis.","summary":"

elliptic curve jive addition of point p(x, y) and q(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, q : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L43","def":{"name":"ec_add","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"q","doc":null,"default_value":"","external_name":"q","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x_delta = q.x - p.x\nx_inv = ec_mod_inv(x_delta)\ny_delta = q.y - p.y\nm = (y_delta * x_inv) % prime\nx = (((m * m) - p.x) - q.x) % prime\ny = ((m * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_double(p:EC_Point,prime=EC_PARAM_PRIME)-class-method","name":"ec_double","doc":"elliptic curve juke point doubling of p(x, y).\na special case of addition where both points are the same.\n'draw' a tangent line at p which will intersect the curve\nat point r which will be mirrored over the x-axis.","summary":"

elliptic curve juke point doubling of p(x, y).

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(p : EC_Point, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L59","def":{"name":"ec_double","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"lam_numer = ((3 * p.x) * p.x) + EC_FACTOR_A\nlam_denom = 2 * p.y\nlam_inv = ec_mod_inv(lam_denom)\nlam = (lam_numer * lam_inv) % prime\nx = ((lam * lam) - (2 * p.x)) % prime\ny = ((lam * (p.x - x)) - p.y) % prime\nx = BigInt.new(x)\ny = BigInt.new(y)\nreturn EC_Point.new(x, y)\n"}},{"id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","html_id":"ec_mod_inv(a:BigInt,prime=EC_PARAM_PRIME)-class-method","name":"ec_mod_inv","doc":"elliptic curve modular multiplicative inverse of a","summary":"

elliptic curve modular multiplicative inverse of a

","abstract":false,"args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(a : BigInt, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L19","def":{"name":"ec_mod_inv","args":[{"name":"a","doc":null,"default_value":"","external_name":"a","restriction":"BigInt"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"m_low = 1\nm_high = 0\nv_low = a % prime\nv_high = prime\nwhile v_low > 1\n v_ratio = v_high // v_low\n m_low_r = m_low * v_ratio\n v_low_r = v_low * v_ratio\n m = m_high - m_low_r\n v = v_high - v_low_r\n m_high = m_low\n v_high = v_low\n m_low = m\n v_low = v\nend\nreturn m_low % prime\n"}},{"id":"ec_mul(p:EC_Point,s:BigInt)-class-method","html_id":"ec_mul(p:EC_Point,s:BigInt)-class-method","name":"ec_mul","doc":"elliptic curve sequence multiplication of point p(x, y) and\na skalar s, with s being a private key within the elliptic\ncurve field size of EC_ORDER_N","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(p : EC_Point, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/core.cr#L74","def":{"name":"ec_mul","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if (s === 0) || s >= EC_ORDER_N\n raise(\"invalid private key: outside of ec field size.\")\n exit(1)\nend\ns_bin = s.to_s(2)\nq = p\ns_bin.each_char_with_index do |char, index|\n if index === 0\n next\n end\n q = ec_double(q)\n if char === '1'\n q = ec_add(q, p)\n end\nend\nreturn q\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/EC_Point","path":"Secp256k1/EC_Point.html","kind":"class","full_name":"Secp256k1::EC_Point","name":"EC_Point","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":18,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"A point in the two-dimensional space of an elliptic curve","summary":"

A point in the two-dimensional space of an elliptic curve

","class_methods":[],"constructors":[{"id":"new(x:BigInt,y:BigInt)-class-method","html_id":"new(x:BigInt,y:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(x : BigInt, y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L25","def":{"name":"new","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"},{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(x, y)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"x:BigInt-instance-method","html_id":"x:BigInt-instance-method","name":"x","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L20","def":{"name":"x","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@x"}},{"id":"x=(x:BigInt)-instance-method","html_id":"x=(x:BigInt)-instance-method","name":"x=","doc":"the position on the x-axis","summary":"

the position on the x-axis

","abstract":false,"args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"args_string":"(x : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L20","def":{"name":"x=","args":[{"name":"x","doc":null,"default_value":"","external_name":"x","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@x = x"}},{"id":"y:BigInt-instance-method","html_id":"y:BigInt-instance-method","name":"y","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L23","def":{"name":"y","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@y"}},{"id":"y=(y:BigInt)-instance-method","html_id":"y=(y:BigInt)-instance-method","name":"y=","doc":"the position on the y-axis","summary":"

the position on the y-axis

","abstract":false,"args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"args_string":"(y : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L23","def":{"name":"y=","args":[{"name":"y","doc":null,"default_value":"","external_name":"y","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@y = y"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/ECDSA_Signature","path":"Secp256k1/ECDSA_Signature.html","kind":"class","full_name":"Secp256k1::ECDSA_Signature","name":"ECDSA_Signature","abstract":false,"superclass":{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"github.com/q9f/secp256k1.cr/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"github.com/q9f/secp256k1.cr/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"structs.cr","line_number":30,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"an ecdsa signature","summary":"

an ecdsa signature

","class_methods":[],"constructors":[{"id":"new(r:BigInt,s:BigInt)-class-method","html_id":"new(r:BigInt,s:BigInt)-class-method","name":"new","doc":null,"summary":null,"abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(r : BigInt, s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L37","def":{"name":"new","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"},{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"_ = allocate\n_.initialize(r, s)\nif _.responds_to?(:finalize)\n ::GC.add_finalizer(_)\nend\n_\n"}}],"instance_methods":[{"id":"r:BigInt-instance-method","html_id":"r:BigInt-instance-method","name":"r","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L32","def":{"name":"r","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@r"}},{"id":"r=(r:BigInt)-instance-method","html_id":"r=(r:BigInt)-instance-method","name":"r=","doc":"the x coordinate of a random point","summary":"

the x coordinate of a random point

","abstract":false,"args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"args_string":"(r : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L32","def":{"name":"r=","args":[{"name":"r","doc":null,"default_value":"","external_name":"r","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@r = r"}},{"id":"s:BigInt-instance-method","html_id":"s:BigInt-instance-method","name":"s","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[],"args_string":" : BigInt","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L35","def":{"name":"s","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"BigInt","visibility":"Public","body":"@s"}},{"id":"s=(s:BigInt)-instance-method","html_id":"s=(s:BigInt)-instance-method","name":"s=","doc":"the signature proof of a message","summary":"

the signature proof of a message

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"args_string":"(s : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/structs.cr#L35","def":{"name":"s=","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"@s = s"}}],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Ethereum","path":"Secp256k1/Ethereum.html","kind":"module","full_name":"Secp256k1::Ethereum","name":"Ethereum","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"ethereum.cr","line_number":16,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements the Ethereum address space","summary":"

implements the Ethereum address space

","class_methods":[{"id":"address_checksum(adr:String)-class-method","html_id":"address_checksum(adr:String)-class-method","name":"address_checksum","doc":"returns a checksummed ethereum address as per eip-55","summary":"

returns a checksummed ethereum address as per eip-55

","abstract":false,"args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"args_string":"(adr : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L18","def":{"name":"address_checksum","args":[{"name":"adr","doc":null,"default_value":"","external_name":"adr","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"adr = adr.downcase\nif adr.size === 42\n adr = adr[2, 40]\nend\nif adr.size === 40\n keccak = Hash.keccak256_string(adr)\n address = \"0x\"\n i = 0\n while i < adr.size\n k = keccak[i].to_i(16)\n if k >= 8\n address = address + \"#{adr[i]}\".upcase\n else\n address = address + \"#{adr[i]}\"\n end\n i = i + 1\n end\n return address\nelse\n raise(\"malformed ethereum address (invalid size: #{adr.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_private(priv:String)-class-method","html_id":"address_from_private(priv:String)-class-method","name":"address_from_private","doc":"generates an ethereum address from a private key","summary":"

generates an ethereum address from a private key

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"args_string":"(priv : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L75","def":{"name":"address_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"priv = BigInt.new(priv, 16)\np = Secp256k1::Util.public_key_from_private(priv)\nreturn address_from_public_point(p)\n"}},{"id":"address_from_public_key(pub:String)-class-method","html_id":"address_from_public_key(pub:String)-class-method","name":"address_from_public_key","doc":"generates an ethereum address for an uncompressed public key","summary":"

generates an ethereum address for an uncompressed public key

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L53","def":{"name":"address_from_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 128\n keccak = Hash.keccak256(pub)\n return address_checksum(keccak[24, 40])\nelse\n raise(\"malformed public key (invalid key size: #{pub.size})\")\nend\nreturn \"-999\"\n"}},{"id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","html_id":"address_from_public_point(p:Secp256k1::EC_Point)-class-method","name":"address_from_public_point","doc":"generates an ethereum address from an public key ec point","summary":"

generates an ethereum address from an public key ec point

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"args_string":"(p : Secp256k1::EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/ethereum.cr#L68","def":{"name":"address_from_public_point","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"Secp256k1::EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = Secp256k1::Util.public_key_uncompressed(p)\nreturn address_from_public_key(pub)\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Hash","path":"Secp256k1/Hash.html","kind":"module","full_name":"Secp256k1::Hash","name":"Hash","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"hash.cr","line_number":19,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[{"id":"BASE_57","name":"BASE_57","value":"\"23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-57 alphabet (for mini private keys)","summary":"

the base-57 alphabet (for mini private keys)

"},{"id":"BASE_58","name":"BASE_58","value":"\"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\"","doc":"the base-58 alphabet (for bitcoin)","summary":"

the base-58 alphabet (for bitcoin)

"}],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"wraps various hashing functions for convenience","summary":"

wraps various hashing functions for convenience

","class_methods":[{"id":"base57_char(i:Int32)-class-method","html_id":"base57_char(i:Int32)-class-method","name":"base57_char","doc":"get a character from the base-57 alphabet at position i","summary":"

get a character from the base-57 alphabet at position i

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L120","def":{"name":"base57_char","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"i = i % 57\nreturn BASE_57[i]\n"}},{"id":"base58_decode(s:String)-class-method","html_id":"base58_decode(s:String)-class-method","name":"base58_decode","doc":"decode a hex string from base-58","summary":"

decode a hex string from base-58

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L70","def":{"name":"base58_decode","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"index = 0\ndecimal = BigInt.new(0)\nwhile index < s.size\n b58_char = s[index]\n position = BASE_58.index(b58_char)\n if !position.nil?\n decimal = (decimal * 58) + position\n index = index + 1\n else\n raise(\"cannot decode, invalid base58 character: '#{s[index]}'\")\n return \"-999\"\n end\nend\nhex = decimal.to_s(16)\nleading = 0\nwhile s[leading] === '1'\n leading = leading + 1\n hex = \"00#{hex}\"\nend\nreturn hex\n"}},{"id":"base58_encode(h:String)-class-method","html_id":"base58_encode(h:String)-class-method","name":"base58_encode","doc":"encode a hex string as base-58","summary":"

encode a hex string as base-58

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L97","def":{"name":"base58_encode","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"pub = BigInt.new(h, 16)\nadr = String.new\nwhile pub > 0\n pub, rem = pub.divmod(58)\n adr = adr + BASE_58[rem]\nend\ni, s = 0, 2\ncurrent_byte = h[i, s]\nwhile (current_byte.to_i(16)) === 0\n adr = \"#{adr}1\"\n i = i + s\n current_byte = h[i, s]\nend\nreturn adr.reverse\n"}},{"id":"bin_to_hex(b:Bytes)-class-method","html_id":"bin_to_hex(b:Bytes)-class-method","name":"bin_to_hex","doc":"helper function to convert byte arrays to hex strings","summary":"

helper function to convert byte arrays to hex strings

","abstract":false,"args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"args_string":"(b : Bytes)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L126","def":{"name":"bin_to_hex","args":[{"name":"b","doc":null,"default_value":"","external_name":"b","restriction":"Bytes"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return b.hexstring"}},{"id":"hex_to_bin(s:String)-class-method","html_id":"hex_to_bin(s:String)-class-method","name":"hex_to_bin","doc":"helper function to convert hex strings to byte arrays","summary":"

helper function to convert hex strings to byte arrays

","abstract":false,"args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"args_string":"(s : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L131","def":{"name":"hex_to_bin","args":[{"name":"s","doc":null,"default_value":"","external_name":"s","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return s.hexbytes"}},{"id":"keccak256(h:String)-class-method","html_id":"keccak256(h:String)-class-method","name":"keccak256","doc":"operating a keccak-256 hash on the byte array","summary":"

operating a keccak-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L40","def":{"name":"keccak256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nb = hex_to_bin(h)\nreturn (keccak.update(b)).hexdigest\n"}},{"id":"keccak256_string(h:String)-class-method","html_id":"keccak256_string(h:String)-class-method","name":"keccak256_string","doc":"operating a keccak-256 hash on the actual string literal","summary":"

operating a keccak-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L47","def":{"name":"keccak256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"keccak = Digest::Keccak3.new(256)\nreturn (keccak.update(h)).hexdigest\n"}},{"id":"ripemd160(h:String)-class-method","html_id":"ripemd160(h:String)-class-method","name":"ripemd160","doc":"operating a ripemd-160 hash on the byte array","summary":"

operating a ripemd-160 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L64","def":{"name":"ripemd160","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"RIPEMD160\")).update(b)).hexdigest\n"}},{"id":"sha256(h:String)-class-method","html_id":"sha256(h:String)-class-method","name":"sha256","doc":"operating a sha2-256 hash on the byte array","summary":"

operating a sha2-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L53","def":{"name":"sha256","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"b = hex_to_bin(h)\nreturn ((OpenSSL::Digest.new(\"SHA256\")).update(b)).hexdigest\n"}},{"id":"sha256_string(h:String)-class-method","html_id":"sha256_string(h:String)-class-method","name":"sha256_string","doc":"operating a sha2-256 hash on the actual string literal","summary":"

operating a sha2-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L59","def":{"name":"sha256_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return ((OpenSSL::Digest.new(\"SHA256\")).update(h)).hexdigest"}},{"id":"sha3(h:String)-class-method","html_id":"sha3(h:String)-class-method","name":"sha3","doc":"operating a sha3-256 hash on the byte array","summary":"

operating a sha3-256 hash on the byte array

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L27","def":{"name":"sha3","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nb = hex_to_bin(h)\nreturn (sha3.update(b)).hexdigest\n"}},{"id":"sha3_string(h:String)-class-method","html_id":"sha3_string(h:String)-class-method","name":"sha3_string","doc":"operating a sha3-256 hash on the actual string literal","summary":"

operating a sha3-256 hash on the actual string literal

","abstract":false,"args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"args_string":"(h : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/hash.cr#L34","def":{"name":"sha3_string","args":[{"name":"h","doc":null,"default_value":"","external_name":"h","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"sha3 = Digest::SHA3.new(256)\nreturn (sha3.update(h)).hexdigest\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Signature","path":"Secp256k1/Signature.html","kind":"module","full_name":"Secp256k1::Signature","name":"Signature","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"signature.cr","line_number":17,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"implements ecdsa signature generation and verification for secp256k1\nref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages","summary":"

implements ecdsa signature generation and verification for secp256k1 ref: https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages

","class_methods":[{"id":"sign(msg:String,priv:BigInt)-class-method","html_id":"sign(msg:String,priv:BigInt)-class-method","name":"sign","doc":"the ecdsa signing algorithm (rfc 6979) takes as input a message `msg`\nand a private key `priv`. It produces as output a signature, which\nconsists of pair of integers `(r, s)`.","summary":"

the ecdsa signing algorithm (rfc 6979) takes as input a message msg and a private key priv.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(msg : String, priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr#L21","def":{"name":"sign","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nk = Util.new_private_key\nr = (Core.ec_mul(EC_BASE_G, k)).x % EC_ORDER_N\nk_inv = Core.ec_mod_inv(k, EC_ORDER_N)\ns = ((hash + (r * priv)) * k_inv) % EC_ORDER_N\nsig = ECDSA_Signature.new(r, s)\nreturn sig\n"}},{"id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify(msg:String,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify","doc":"the algorithm to verify an ecdsa signature takes as input the signed message `msg`\nand the signature `(r, s)` produced from self.sign and the public key `pub`,\ncorresponding to the signer's private key. The result is boolean.","summary":"

the algorithm to verify an ecdsa signature takes as input the signed message msg and the signature (r, s) produced from self.sign and the public key pub, corresponding to the signer's private key.

","abstract":false,"args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(msg : String, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr#L42","def":{"name":"verify","args":[{"name":"msg","doc":null,"default_value":"","external_name":"msg","restriction":"String"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hash = BigInt.new(Hash.sha256_string(msg), 16)\nreturn verify_hash(hash, sig, pub)\n"}},{"id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","html_id":"verify_hash(hash:BigInt,sig:ECDSA_Signature,pub:EC_Point)-class-method","name":"verify_hash","doc":"same as self.verify, just using the hashed message directly","summary":"

same as self.verify, just using the hashed message directly

","abstract":false,"args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"args_string":"(hash : BigInt, sig : ECDSA_Signature, pub : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/signature.cr#L49","def":{"name":"verify_hash","args":[{"name":"hash","doc":null,"default_value":"","external_name":"hash","restriction":"BigInt"},{"name":"sig","doc":null,"default_value":"","external_name":"sig","restriction":"ECDSA_Signature"},{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"s_inv = Core.ec_mod_inv(sig.s, EC_ORDER_N)\np0 = Core.ec_mul(EC_BASE_G, (hash * s_inv) % EC_ORDER_N)\np1 = Core.ec_mul(pub, (sig.r * s_inv) % EC_ORDER_N)\np = Core.ec_add(p0, p1)\nreturn sig.r === p.x\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]},{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1/Util","path":"Secp256k1/Util.html","kind":"module","full_name":"Secp256k1::Util","name":"Util","abstract":false,"superclass":null,"ancestors":[],"locations":[{"filename":"util.cr","line_number":22,"url":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr"}],"repository_name":"github.com/q9f/secp256k1.cr","program":false,"enum":false,"alias":false,"aliased":"","const":false,"constants":[],"included_modules":[],"extended_modules":[],"subclasses":[],"including_types":[],"namespace":{"html_id":"github.com/q9f/secp256k1.cr/Secp256k1","kind":"module","full_name":"Secp256k1","name":"Secp256k1"},"doc":"a collection of utilities for secp256k1 key management","summary":"

a collection of utilities for secp256k1 key management

","class_methods":[{"id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","html_id":"decode_compressed_public_key(pub:String,prime=EC_PARAM_PRIME)-class-method","name":"decode_compressed_public_key","doc":"decodes a public key as ec point from a compressed public key string","summary":"

decodes a public key as ec point from a compressed public key string

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"args_string":"(pub : String, prime = EC_PARAM_PRIME)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L76","def":{"name":"decode_compressed_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"},{"name":"prime","doc":null,"default_value":"EC_PARAM_PRIME","external_name":"prime","restriction":""}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"if pub.size === 66\n prefix = pub[0, 2]\n if (prefix === \"02\") || (prefix === \"03\")\n x = BigInt.new(pub[2, 64], 16)\n a = (x ** 3) % prime\n a = (a + 7) % prime\n e = ((prime + 1) // 4) % prime\n y = BigInt.new\n LibGMP.mpz_powm_sec(y, a, e, prime)\n parity = prefix.to_i - 2\n if (y % 2) != parity\n y = (-y) % prime\n end\n return EC_Point.new(x, y)\n else\n raise(\"invalid prefix for compressed public key: #{prefix}\")\n end\nelse\n raise(\"malformed compressed public key (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"new_private_key-class-method","html_id":"new_private_key-class-method","name":"new_private_key","doc":"a helper to generate 32 pseudo-random bytes","summary":"

a helper to generate 32 pseudo-random bytes

","abstract":false,"args":[],"args_string":"","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L43","def":{"name":"new_private_key","args":[],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"key = -999\nwhile !key > 0\n key = Random::Secure.hex(32)\n key = BigInt.new(key, 16)\nend\nreturn key % EC_ORDER_N\n"}},{"id":"public_key_compressed_prefix(p:EC_Point)-class-method","html_id":"public_key_compressed_prefix(p:EC_Point)-class-method","name":"public_key_compressed_prefix","doc":"exports the compressed public key from an ec point with prefix 02 or 03","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L58","def":{"name":"public_key_compressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"prefix = (p.y % 2) === 1 ? \"03\" : \"02\"\nreturn \"#{prefix}#{public_key_compressed(p)}\"\n"}},{"id":"public_key_from_private(priv:BigInt)-class-method","html_id":"public_key_from_private(priv:BigInt)-class-method","name":"public_key_from_private","doc":"wrapper function to perform an ec multiplication with\nthe generator point and a provided private key","summary":"

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

","abstract":false,"args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"args_string":"(priv : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L141","def":{"name":"public_key_from_private","args":[{"name":"priv","doc":null,"default_value":"","external_name":"priv","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return Core.ec_mul(EC_BASE_G, priv)"}},{"id":"public_key_uncompressed(p:EC_Point)-class-method","html_id":"public_key_uncompressed(p:EC_Point)-class-method","name":"public_key_uncompressed","doc":"exports the uncompressed public key from an ec point without prefix","summary":"

exports the uncompressed public key from an ec point without prefix

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L64","def":{"name":"public_key_uncompressed","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"x = to_padded_hex_32(p.x)\ny = to_padded_hex_32(p.y)\nreturn \"#{x}#{y}\"\n"}},{"id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","html_id":"public_key_uncompressed_prefix(p:EC_Point)-class-method","name":"public_key_uncompressed_prefix","doc":"exports the uncompressed public key from an ec point with prefix 04","summary":"

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

","abstract":false,"args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"args_string":"(p : EC_Point)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L71","def":{"name":"public_key_uncompressed_prefix","args":[{"name":"p","doc":null,"default_value":"","external_name":"p","restriction":"EC_Point"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"return \"04#{public_key_uncompressed(p)}\""}},{"id":"restore_public_key(pub:String)-class-method","html_id":"restore_public_key(pub:String)-class-method","name":"restore_public_key","doc":"detects public key type and tries to restore the ec point from it","summary":"

detects public key type and tries to restore the ec point from it

","abstract":false,"args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"args_string":"(pub : String)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L126","def":{"name":"restore_public_key","args":[{"name":"pub","doc":null,"default_value":"","external_name":"pub","restriction":"String"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"case pub.size\nwhen 130, 128\n return decode_uncompressed_public_key(pub)\nwhen 66\n return decode_compressed_public_key(pub)\nelse\n raise(\"unknown public key format (invalid key size: #{pub.size})\")\nend\ni = BigInt.new(-999)\nreturn EC_Point.new(i, i)\n"}},{"id":"to_padded_hex_01(i:Int32)-class-method","html_id":"to_padded_hex_01(i:Int32)-class-method","name":"to_padded_hex_01","doc":"generic tool to encode single hex bytes as strings, e.g., \"07\"","summary":"

generic tool to encode single hex bytes as strings, e.g., \"07\"

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"args_string":"(i : Int32)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L24","def":{"name":"to_padded_hex_01","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"Int32"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 2\n hex = '0' + hex\nend\nreturn hex\n"}},{"id":"to_padded_hex_32(i:BigInt)-class-method","html_id":"to_padded_hex_32(i:BigInt)-class-method","name":"to_padded_hex_32","doc":"utility tool to ensure hex keys are always 32 bytes\nit pads the number with leading zeros if not","summary":"

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

","abstract":false,"args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"args_string":"(i : BigInt)","source_link":"https://github.com/q9f/secp256k1.cr/blob/90277a931d1866de696bde9fe0ca31871b26b7c4/src/util.cr#L34","def":{"name":"to_padded_hex_32","args":[{"name":"i","doc":null,"default_value":"","external_name":"i","restriction":"BigInt"}],"double_splat":null,"splat_index":null,"yields":null,"block_arg":null,"return_type":"","visibility":"Public","body":"hex = i.to_s(16)\nwhile hex.size < 64\n hex = '0' + hex\nend\nreturn hex\n"}}],"constructors":[],"instance_methods":[],"macros":[],"types":[]}]}]}}) \ No newline at end of file From 1cf95760b25107469737e747c0c4d3abd52b0e03 Mon Sep 17 00:00:00 2001 From: /raw PONG _GHMoaCXLT <58883403+q9f@users.noreply.github.com> Date: Mon, 6 Jan 2020 15:13:47 +0100 Subject: [PATCH 2/3] update readme --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 4e16185..c01cb26 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,16 @@ puts Secp256k1::Ethereum.address_from_public_key uncompressed # > "0x2Ef1f605AF5d03874eE88773f41c1382ac71C239" ``` +# documentation + +can be found here: https://q9f.github.io/secp256k1.cr/ + +generate a local copy with: + +``` +crystal docs +``` + # testing the library is entirely specified through tests in `./spec`; run: From eb71bb767e435879911717049476606cf535c2f8 Mon Sep 17 00:00:00 2001 From: /raw PONG _GHMoaCXLT <58883403+q9f@users.noreply.github.com> Date: Mon, 6 Jan 2020 15:14:50 +0100 Subject: [PATCH 3/3] add a proper link to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c01cb26..cd00fda 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ puts Secp256k1::Ethereum.address_from_public_key uncompressed # documentation -can be found here: https://q9f.github.io/secp256k1.cr/ +the full library documentation can be found here: [q9f.github.io/secp256k1.cr](https://q9f.github.io/secp256k1.cr/) generate a local copy with: