rbsecp256k1 6.0.1 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +24 -24
- data/README.md +134 -129
- data/Rakefile +23 -18
- data/documentation/context.md +125 -98
- data/documentation/index.md +391 -378
- data/documentation/key_pair.md +25 -25
- data/documentation/private_key.md +25 -25
- data/documentation/public_key.md +36 -36
- data/documentation/recoverable_signature.md +30 -30
- data/documentation/schnorr_signature.md +34 -30
- data/documentation/secp256k1.md +24 -24
- data/documentation/shared_secret.md +14 -14
- data/documentation/signature.md +42 -42
- data/documentation/util.md +17 -17
- data/documentation/xonly_public_key.md +29 -29
- data/ext/rbsecp256k1/extconf.rb +62 -121
- data/ext/rbsecp256k1/rbsecp256k1.c +2429 -2244
- data/ext/rbsecp256k1/secp256k1_recipe.rb +76 -0
- data/lib/rbsecp256k1/context.rb +40 -36
- data/lib/rbsecp256k1/util.rb +28 -28
- data/lib/rbsecp256k1/version.rb +5 -5
- data/lib/rbsecp256k1.rb +14 -14
- metadata +16 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mini_portile2'
|
|
4
|
+
require 'zip'
|
|
5
|
+
|
|
6
|
+
# Enable the recovery module by default
|
|
7
|
+
WITH_RECOVERY = ENV.fetch('WITH_RECOVERY', '1') == '1'
|
|
8
|
+
|
|
9
|
+
# Recipe for downloading and building libsecp256k1 as part of installation
|
|
10
|
+
class Secp256k1Recipe < MiniPortile
|
|
11
|
+
# Hard-coded URL for libsecp256k1 zipfile (Official release v0.8.0)
|
|
12
|
+
LIBSECP256K1_ZIP_URL = 'https://github.com/bitcoin-core/secp256k1/archive/refs/tags/v0.8.0.zip'
|
|
13
|
+
|
|
14
|
+
# Expected SHA-256 of the zipfile above (computed using sha256sum)
|
|
15
|
+
LIBSECP256K1_SHA256 = 'ecece6a1cec8bdecdccbf22e1ee65455feae1a5312913bd62c45bbdc912b442c'
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
super('libsecp256k1', '0.8.0')
|
|
19
|
+
@tarball = File.join(Dir.pwd, "/ports/archives/libsecp256k1.zip")
|
|
20
|
+
@files = ["file://#{@tarball}"]
|
|
21
|
+
self.configure_options += [
|
|
22
|
+
"--with-pic=yes"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
# MiniPortile builds a static library. Its benchmark consumers also need
|
|
26
|
+
# this definition on Windows to avoid references to DLL import symbols.
|
|
27
|
+
if RUBY_PLATFORM =~ /mingw|mswin/
|
|
28
|
+
configure_options << "CPPFLAGS=#{ENV.fetch('CPPFLAGS', '')} -DSECP256K1_STATIC"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# ECDH, extrakeys and schnorrsig are enabled by default in release v0.8.0,
|
|
32
|
+
# but recovery still needs to be enabled manually.
|
|
33
|
+
configure_options << "--enable-module-recovery" if WITH_RECOVERY
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def configure
|
|
37
|
+
# Need to run autogen.sh before configure since it creates it
|
|
38
|
+
if RUBY_PLATFORM =~ /mingw|mswin/
|
|
39
|
+
# Windows doesn't recognize the shebang.
|
|
40
|
+
execute('autogen', %w[sh ./autogen.sh])
|
|
41
|
+
else
|
|
42
|
+
execute('chmod', %w[chmod +x ./autogen.sh])
|
|
43
|
+
execute('autogen', %w[./autogen.sh])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def download
|
|
50
|
+
download_file_http(LIBSECP256K1_ZIP_URL, @tarball)
|
|
51
|
+
verify_file(local_path: @tarball, sha256: LIBSECP256K1_SHA256)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def downloaded?
|
|
55
|
+
File.exist?(@tarball)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def extract_zip_file(file, destination)
|
|
59
|
+
FileUtils.mkdir_p(destination)
|
|
60
|
+
|
|
61
|
+
Zip::File.open(file) do |zip_file|
|
|
62
|
+
zip_file.each do |f|
|
|
63
|
+
fpath = File.join(destination, f.name)
|
|
64
|
+
zip_file.extract(f, fpath) unless File.exist?(fpath)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def extract
|
|
70
|
+
files_hashs.each do |file|
|
|
71
|
+
# Cached and interrupted downloads also reach extraction without download.
|
|
72
|
+
verify_file(local_path: file[:local_path], sha256: LIBSECP256K1_SHA256)
|
|
73
|
+
extract_zip_file(file[:local_path], tmp_path)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/lib/rbsecp256k1/context.rb
CHANGED
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'securerandom'
|
|
4
|
-
|
|
5
|
-
module Secp256k1
|
|
6
|
-
# Wrapper around a secp256k1_context object.
|
|
7
|
-
class Context
|
|
8
|
-
# Create a new randomized context.
|
|
9
|
-
#
|
|
10
|
-
# @return [Secp256k1::Context] randomized context
|
|
11
|
-
def self.create
|
|
12
|
-
new(context_randomization_bytes: SecureRandom.random_bytes(32))
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# Create a new non-randomized context.
|
|
16
|
-
#
|
|
17
|
-
# @return [Secp256k1::Context] non-randomized context
|
|
18
|
-
def self.create_unrandomized
|
|
19
|
-
new
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Generates a new random key pair.
|
|
23
|
-
#
|
|
24
|
-
# @return [Secp256k1::KeyPair] public-private key pair.
|
|
25
|
-
def generate_key_pair
|
|
26
|
-
key_pair_from_private_key(SecureRandom.random_bytes(32))
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Secp256k1
|
|
6
|
+
# Wrapper around a secp256k1_context object.
|
|
7
|
+
class Context
|
|
8
|
+
# Create a new randomized context.
|
|
9
|
+
#
|
|
10
|
+
# @return [Secp256k1::Context] randomized context
|
|
11
|
+
def self.create
|
|
12
|
+
new(context_randomization_bytes: SecureRandom.random_bytes(32))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Create a new non-randomized context.
|
|
16
|
+
#
|
|
17
|
+
# @return [Secp256k1::Context] non-randomized context
|
|
18
|
+
def self.create_unrandomized
|
|
19
|
+
new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Generates a new random key pair.
|
|
23
|
+
#
|
|
24
|
+
# @return [Secp256k1::KeyPair] public-private key pair.
|
|
25
|
+
def generate_key_pair
|
|
26
|
+
key_pair_from_private_key(SecureRandom.random_bytes(32))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Sign message bytes directly with fresh 32-byte auxiliary randomness.
|
|
30
|
+
# No implicit hashing, padding, or truncation is performed.
|
|
31
|
+
#
|
|
32
|
+
# @param keypair [Secp256k1::KeyPair] key pair used for signing
|
|
33
|
+
# @param message [String] message of any byte length, including zero
|
|
34
|
+
#
|
|
35
|
+
# @return [Secp256k1::SchnorrSignature] schnorr signature
|
|
36
|
+
def sign_schnorr(keypair, message)
|
|
37
|
+
sign_schnorr_custom(keypair, message, SecureRandom.random_bytes(32))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/rbsecp256k1/util.rb
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Secp256k1
|
|
4
|
-
# Contains utility methods that complement the functionality of the library.
|
|
5
|
-
module Util
|
|
6
|
-
# Regexp to validate a hexadecimal string
|
|
7
|
-
HEX_REGEXP = /^[A-Fa-f\d]+$/.freeze
|
|
8
|
-
|
|
9
|
-
# Converts a binary string to a hex string.
|
|
10
|
-
#
|
|
11
|
-
# @param binary_string [String] binary string to be converted.
|
|
12
|
-
# @return [String] hex string equivalent of the given binary string.
|
|
13
|
-
def self.bin_to_hex(binary_string)
|
|
14
|
-
binary_string.unpack('H*').first
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Converts a hex string to a binary string.
|
|
18
|
-
#
|
|
19
|
-
# @param hex_string [String] string with hexadeimcal value.
|
|
20
|
-
# @return [String] binary string equivalent of the given hex string.
|
|
21
|
-
# @raise [ArgumentError] if hex string is an invalid hexadecimal string.
|
|
22
|
-
def self.hex_to_bin(hex_string)
|
|
23
|
-
raise ArgumentError, "Invalid hexadecimal string" unless hex_string =~ HEX_REGEXP
|
|
24
|
-
|
|
25
|
-
[hex_string].pack('H*')
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Secp256k1
|
|
4
|
+
# Contains utility methods that complement the functionality of the library.
|
|
5
|
+
module Util
|
|
6
|
+
# Regexp to validate a hexadecimal string
|
|
7
|
+
HEX_REGEXP = /^[A-Fa-f\d]+$/.freeze
|
|
8
|
+
|
|
9
|
+
# Converts a binary string to a hex string.
|
|
10
|
+
#
|
|
11
|
+
# @param binary_string [String] binary string to be converted.
|
|
12
|
+
# @return [String] hex string equivalent of the given binary string.
|
|
13
|
+
def self.bin_to_hex(binary_string)
|
|
14
|
+
binary_string.unpack('H*').first
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Converts a hex string to a binary string.
|
|
18
|
+
#
|
|
19
|
+
# @param hex_string [String] string with hexadeimcal value.
|
|
20
|
+
# @return [String] binary string equivalent of the given hex string.
|
|
21
|
+
# @raise [ArgumentError] if hex string is an invalid hexadecimal string.
|
|
22
|
+
def self.hex_to_bin(hex_string)
|
|
23
|
+
raise ArgumentError, "Invalid hexadecimal string" unless hex_string =~ HEX_REGEXP
|
|
24
|
+
|
|
25
|
+
[hex_string].pack('H*')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/rbsecp256k1/version.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Secp256k1
|
|
4
|
-
VERSION = '6.0.
|
|
5
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Secp256k1
|
|
4
|
+
VERSION = '6.0.2'
|
|
5
|
+
end
|
data/lib/rbsecp256k1.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Wraps libsecp256k1 in a ruby module and provides object interfaces.
|
|
4
|
-
module Secp256k1
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
require 'rbsecp256k1/context'
|
|
8
|
-
require 'rbsecp256k1/util'
|
|
9
|
-
require 'rbsecp256k1/version'
|
|
10
|
-
|
|
11
|
-
# The ext directory is where the compiled shared object files go for native
|
|
12
|
-
# extension gems. Rubygems adds this to the LOAD_PATH so we should just need to
|
|
13
|
-
# explicitly require the shared object
|
|
14
|
-
require 'rbsecp256k1/rbsecp256k1'
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Wraps libsecp256k1 in a ruby module and provides object interfaces.
|
|
4
|
+
module Secp256k1
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rbsecp256k1/context'
|
|
8
|
+
require 'rbsecp256k1/util'
|
|
9
|
+
require 'rbsecp256k1/version'
|
|
10
|
+
|
|
11
|
+
# The ext directory is where the compiled shared object files go for native
|
|
12
|
+
# extension gems. Rubygems adds this to the LOAD_PATH so we should just need to
|
|
13
|
+
# explicitly require the shared object
|
|
14
|
+
require 'rbsecp256k1/rbsecp256k1'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbsecp256k1
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.0.
|
|
4
|
+
version: 6.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Scrivner
|
|
@@ -81,6 +81,20 @@ dependencies:
|
|
|
81
81
|
- - "~>"
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
83
|
version: '0.5'
|
|
84
|
+
- !ruby/object:Gem::Dependency
|
|
85
|
+
name: csv
|
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
|
87
|
+
requirements:
|
|
88
|
+
- - "~>"
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
version: '3.0'
|
|
91
|
+
type: :development
|
|
92
|
+
prerelease: false
|
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
94
|
+
requirements:
|
|
95
|
+
- - "~>"
|
|
96
|
+
- !ruby/object:Gem::Version
|
|
97
|
+
version: '3.0'
|
|
84
98
|
- !ruby/object:Gem::Dependency
|
|
85
99
|
name: keccak
|
|
86
100
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -217,6 +231,7 @@ files:
|
|
|
217
231
|
- documentation/xonly_public_key.md
|
|
218
232
|
- ext/rbsecp256k1/extconf.rb
|
|
219
233
|
- ext/rbsecp256k1/rbsecp256k1.c
|
|
234
|
+
- ext/rbsecp256k1/secp256k1_recipe.rb
|
|
220
235
|
- lib/rbsecp256k1.rb
|
|
221
236
|
- lib/rbsecp256k1/context.rb
|
|
222
237
|
- lib/rbsecp256k1/util.rb
|