rbsecp256k1 3.0.1 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 529c72afdaa5cd79bc685fd28661d367be89a019366e9b9d46bb9db7dd99e499
4
- data.tar.gz: 21d2af92f7c0c696f2a36b6a6de4c330f0dac30078a1d61327e3e22bb80bd4ef
3
+ metadata.gz: 911e42c1184881dc8aa0fd52c833b5c5cc092d5ef04c1d264755acfa9668545b
4
+ data.tar.gz: 808c994ea9dd8965deb16feb82393a044a69fdeeada0654f64031fa74e4b4761
5
5
  SHA512:
6
- metadata.gz: 2d32348b294c9e75ac950f1be1ae2dc0de0c1a31a3038da397426dc56f5cde637a453037f0e5dab0c6bb7bc1761f9afc6934c2f804d328bb4f31279754ec1584
7
- data.tar.gz: '03028eee4ffcf8d8df75488444a8fc963ffa2e10fceb0ac4ac9fb8762f5c403594d74eafedf110ff2c955091fb2d9f76257a5517c7f80fdd2bccc6e2274d6882'
6
+ metadata.gz: 8038fffce14eb3e4b5fdb41f7001349823f4cf0a2b291fca66e6d024e75e4f5e58c1286d7d8473f5daf05016740c61e7d056b6c2c6b118e367bf3a532451e78c
7
+ data.tar.gz: 5430aaefc5a6c8e8ea348d39a425ce48943f3a467744182f68a170bc8784877b95d07c4d66c0351cb7860de4f01b71661d87e70e422a1f382fe0a48dae89e663
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # rbsecp256k1
2
2
 
3
- [![Build Status](https://travis-ci.com/etscrivner/rbsecp256k1.svg?branch=master)](https://travis-ci.com/etscrivner/rbsecp256k1) [![Gem Version](https://badge.fury.io/rb/rbsecp256k1.svg)](https://badge.fury.io/rb/rbsecp256k1)
3
+ [![Spec](https://github.com/etscrivner/rbsecp256k1/actions/workflows/spec.yml/badge.svg?branch=master)](https://github.com/etscrivner/rbsecp256k1/actions/workflows/spec.yml) [![Gem Version](https://badge.fury.io/rb/rbsecp256k1.svg)](https://badge.fury.io/rb/rbsecp256k1) [![Maintainability](https://api.codeclimate.com/v1/badges/d4b6e27bfa00030ca412/maintainability)](https://codeclimate.com/github/etscrivner/rbsecp256k1/maintainability)
4
4
 
5
- Compiled Ruby extension gem for [libsecp256k1](https://github.com/bitcoin-core/secp256k1). In rbsecp256k1 3.0.0
6
- and later libsecp256k1 is bundled with the gem.
5
+ Native extension gem for secp256k1 ECDSA. Wraps [libsecp256k1](https://github.com/bitcoin-core/secp256k1). In
6
+ rbsecp256k1 3.0.0 and later libsecp256k1 is bundled with the gem.
7
7
 
8
- [Documentation](documentation/index.md)
8
+ * [Documentation](https://github.com/etscrivner/rbsecp256k1/blob/master/documentation/index.md)
9
+ * [Examples](https://github.com/etscrivner/rbsecp256k1/blob/master/examples/README.md)
9
10
 
10
11
  ### Why wrap libsecp256k1?
11
12
 
@@ -16,6 +17,9 @@ faster than the OpenSSL implementation of the same curve. It is the only library
16
17
  that provides constant time signing of this curve and has been deployed as part
17
18
  of Bitcoin since [v0.10.0](https://bitcoin.org/en/release/v0.10.0#improved-signing-security)
18
19
 
20
+ Natively wrapping the library in an extension gem means users don't have to
21
+ worry about compiling or locating the library, unlike many [FFI](https://github.com/ffi/ffi) based gems.
22
+
19
23
  ## Installation
20
24
 
21
25
  The simplest installation:
@@ -55,7 +59,7 @@ brew install openssl libtool pkg-config gmp libffi
55
59
 
56
60
  ## Features
57
61
 
58
- See [rbsecp256k1 documentation](documentation/index.md) for examples and complete list of supported functionality.
62
+ See [rbsecp256k1 documentation](https://github.com/etscrivner/rbsecp256k1/blob/master/documentation/index.md) for examples and complete list of supported functionality.
59
63
 
60
64
  ## Development
61
65
 
@@ -108,6 +112,12 @@ To test with both disabled run:
108
112
  make test WITH_RECOVERY=0 WITH_ECDH=0
109
113
  ```
110
114
 
115
+ Testing for memory leaks with valgrind:
116
+
117
+ ```
118
+ make memcheck
119
+ ```
120
+
111
121
  ### Building Gem
112
122
 
113
123
  ```
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rake/extensiontask"
2
4
 
3
5
  Rake::ExtensionTask.new "rbsecp256k1" do |ext|
@@ -0,0 +1,81 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::Context
4
+ ==================
5
+
6
+ Secp256k1::Context represents a libsecp256k1 context object. Contexts are
7
+ thread-safe and initialization is expensive, so a single context should be used
8
+ for multiple operations as much as possible.
9
+
10
+ Initializers
11
+ ------------
12
+
13
+ #### new(context_randomization_bytes: nil)
14
+
15
+ Returns a newly initialized libsecp256k1 context. The context is randomized at
16
+ initialization if given `context_randomization_bytes`. The
17
+ `context_randomization_bytes` argument can optionally take a string containing
18
+ 32 bytes of random data, if not provided then the Context is not randomized and
19
+ may be vulnerable to side-channel attacks.
20
+
21
+ Class Methods
22
+ -------------
23
+
24
+ #### create
25
+
26
+ Creates and returns a new randomized `Context` using `SecureRandom` for the
27
+ random initialization bytes. This is the recommended method for initialization.
28
+
29
+ #### create_unrandomized
30
+
31
+ Creates a new unrandomized `Context`.
32
+
33
+ Instance Methods
34
+ ----------------
35
+
36
+ #### ecdh(point, scalar)
37
+
38
+ **Requires:** libsecp256k1 was built with the experimental ECDH module.
39
+
40
+ Takes a `point` ([PublicKey](public_key.md)) and a `scalar` ([PrivateKey](private_key.md)) and returns a new
41
+ [SharedSecret](shared_secret.md) containing the 32-byte shared secret. Raises a `Secp256k1::Error` if
42
+ the `scalar` is invalid (zero or causes an overflow).
43
+
44
+ #### generate_key_pair
45
+
46
+ Generates and returns a new [KeyPair](key_pair.md) using a cryptographically
47
+ secure random number generator (CSRNG) provided by OpenSSL.
48
+
49
+ #### key_pair_from_private_key(private_key_data)
50
+
51
+ Returns a new [KeyPair](key_pair.md) from the given `private_key_data`. The
52
+ `private_key_data` is expected to be a binary string. Raises a `Secp256k1::Error`
53
+ if the private key is invalid or key derivation fails.
54
+
55
+ #### recoverable_signature_from_compact(compact_signature, recovery_id)
56
+
57
+ **Requires:** libsecp256k1 was build with recovery module.
58
+
59
+ Attempts to load a [RecoverableSignature](recoverable_signature.md) from the given `compact_signature`
60
+ and `recovery_id`. Raises a `Secp256k1::DeserializationError` if the signature data or recovery ID are invalid.
61
+
62
+ #### sign(private_key, hash32)
63
+
64
+ Signs the SHA-256 hash given by `hash32` using `private_key` and returns a new
65
+ [Signature](signature.md). The `private_key` is expected to be a [PrivateKey](private_key.md)
66
+ object and `data` can be either a binary string or text.
67
+
68
+ #### sign_recoverable(private_key, hash32)
69
+
70
+ **Requires:** libsecp256k1 was build with recovery module.
71
+
72
+ Signs the data represented by the SHA-256 hash `hash32` using `private_key` and returns a
73
+ new [RecoverableSignature](recoverable_signature.md). The `private_key` is expected to be a [PrivateKey](private_key.md) and
74
+ `data` can be either a binary string or text.
75
+
76
+ #### verify(signature, public_key, hash32)
77
+
78
+ Verifies the given `signature` ([Signature](signature.md)) was signed by
79
+ the private key corresponding to `public_key` ([PublicKey](public_key.md)) and signed `hash32`. Returns `true`
80
+ if `signature` is valid or `false` otherwise. Note that `data` can be either a
81
+ text or binary string.
@@ -0,0 +1,319 @@
1
+ rbsecp256k1 Reference
2
+ =====================
3
+
4
+ Find your topic in the index, or refer to one of the examples below.
5
+
6
+ Classes and Modules
7
+ -------------------
8
+
9
+ | Module | Classes | Utilities
10
+ |----------------------------|:-------------------------------------------------|:--------------------------------
11
+ | [Secp256k1](secp256k1.md) | [Context](context.md) | [Util](util.md)
12
+ | | [KeyPair](key_pair.md) |
13
+ | | [PublicKey](public_key.md) |
14
+ | | [PrivateKey](private_key.md) |
15
+ | | [SharedSecret](shared_secret.md) |
16
+ | | [Signature](signature.md) |
17
+ | | [RecoverableSignature](recoverable_signature.md) |
18
+
19
+ Glossary
20
+ --------
21
+
22
+ **[Context](context.md)** is a libsecp256k1 library context. It contains
23
+ pre-computed tables and values to make ECDSA signing and verification more
24
+ efficient.
25
+
26
+ **[KeyPair](key_pair.md)** is a Secp256k1 elliptic-curve key pair.
27
+
28
+ **[PublicKey](public_key.md)** is a Secp256k1 public key. It can come in either
29
+ compressed or uncompressed format.
30
+
31
+ **[PrivateKey](private_key.md)** is a 64-byte Secp256k1 private key.
32
+
33
+ **[SharedSecret](shared_secret.md)** A 32-byte shared secret computed from a
34
+ public key (point) and private key (scalar).
35
+
36
+ **[Signature](signature.md)** is an ECDSA signature of the SHA-256 message hash
37
+ of a piece of data.
38
+
39
+ **[RecoverableSignature](recoverable_signature.md)** is a recoverable ECDSA signature of the SHA-256 message
40
+ hash of a piece of data.
41
+
42
+ Examples
43
+ --------
44
+
45
+ ### 1. Creating a libsecp256k1 context
46
+
47
+ This example demonstrates how to create a new libsecp256k1 context. This is the
48
+ first step of using this library:
49
+
50
+ ```ruby
51
+ context = Secp256k1::Context.create
52
+ # => #<Secp256k1::Context:0x0000559b0bd8f5d0>
53
+ ```
54
+
55
+ ### 2. Generating a key pair
56
+
57
+ This example shows how to generate a new public-private key pair:
58
+
59
+ ```ruby
60
+ context = Secp256k1::Context.create
61
+ key_pair = context.generate_key_pair
62
+ # => #<Secp256k1::KeyPair:0x0000559b0bc876b0 @public_key=#<Secp256k1::PublicKey:0x0000559b0bc876d8>, @private_key=#<Secp256k1::PrivateKey:0x0000559b0bc87700 @data="\r\xA7\xB3<\x92\xCDw\xC1\xDB\xEB[BB;=\x80\xB83\xA8]\x06\xD9\x90\xF8v\xFFi\xF0/\x1E\x96\xF9">>
63
+ ```
64
+
65
+ ### 3. Getting compressed and uncompressed public key representations
66
+
67
+ This example shows how to generate compressed and uncompressed public keys:
68
+
69
+ ```ruby
70
+ context = Secp256k1::Context.create
71
+ key_pair = context.generate_key_pair
72
+
73
+ # 1. Get the binary representation of compressed public key
74
+ key_pair.public_key.compressed
75
+ # => "\x03D\x88\xD6 3|3\x836\xCB(\x9CW%\xF4T\xB7\xCD\x8AF T\xE7\xE8\xCE\xB0\xC7c{\xE2:\xFE"
76
+
77
+ # 2. Show hex representation of compressed public key
78
+ Secp256k1::Util.bin_to_hex(key_pair.public_key.compressed)
79
+ # => "034488d620337c338336cb289c5725f454b7cd8a462054e7e8ceb0c7637be23afe"
80
+
81
+ # 3. Get the binary representation of uncompressed public key
82
+ key_pair.public_key.uncompressed
83
+ # => "\x04D\x88\xD6 3|3\x836\xCB(\x9CW%\xF4T\xB7\xCD\x8AF T\xE7\xE8\xCE\xB0\xC7c{\xE2:\xFE XRew\x1F\e\x05\xC8\xDC\xA7\xE3\x8C\xBD\x91s?\xFCW\xD5\xB3\xA8aaCCG\xD4\x94m\xA5c"
84
+
85
+ # 4. Show hex representation of uncompressed public key
86
+ Secp256k1::Util.bin_to_hex(key_pair.public_key.uncompressed)
87
+ # => "044488d620337c338336cb289c5725f454b7cd8a462054e7e8ceb0c7637be23afe20585265771f1b05c8dca7e38cbd91733ffc57d5b3a86161434347d4946da563"
88
+ ```
89
+
90
+ ### 3. Signing a message
91
+
92
+ This example shows how to sign a message using your private key:
93
+
94
+ ```ruby
95
+ require 'digest'
96
+
97
+ context = Secp256k1::Context.create
98
+ key_pair = context.generate_key_pair
99
+
100
+ signature = context.sign(key_pair.private_key, Digest::SHA256.digest("test message"))
101
+ # => #<Secp256k1::Signature:0x0000559b0bc79358>
102
+ ```
103
+
104
+ ### 4. Getting DER and Compact signature encodings
105
+
106
+ This example shows you how to get the DER encoded and compact encoded
107
+ representations of a signature:
108
+
109
+ ```ruby
110
+ require 'digest'
111
+
112
+ context = Secp256k1::Context.create
113
+ key_pair = context.generate_key_pair
114
+
115
+ signature = context.sign(key_pair.private_key, Digest::SHA256.digest("test message"))
116
+
117
+ # 1. Get the compact binary representation
118
+ signature.compact
119
+ # => "\xAB#e6_\x866\e\xAC\e\x92W\xC8a\x84N\xD4\xB6\x88\xF8\xEE\xDF\xFBC\xE8j\xB2\xF0\x10\xB8\xA0\x89\x13L\e\x9E\x91cB\xD7\xAC\x11\xF7\x02,Y&TM\xA5zp\xFD\xB3\xB1\xDCIV\xBB\\\xAF\x16@\xFC\x00"
120
+
121
+ # 2. Get the compact hex representation
122
+ Secp256k1::Util.bin_to_hex(signature.compact)
123
+ # => "ab2365365f86361bac1b9257c861844ed4b688f8eedffb43e86ab2f010b8a089134c1b9e916342d7ac11f7022c5926544da57a70fdb3b1dc4956bb5caf1640fc00"
124
+
125
+ # 3. Get the DER binary representation
126
+ signature.der_encoded
127
+ # => "0E\x02!\x00\xAB#e6_\x866\e\xAC\e\x92W\xC8a\x84N\xD4\xB6\x88\xF8\xEE\xDF\xFBC\xE8j\xB2\xF0\x10\xB8\xA0\x89\x02 \x13L\e\x9E\x91cB\xD7\xAC\x11\xF7\x02,Y&TM\xA5zp\xFD\xB3\xB1\xDCIV\xBB\\\xAF\x16@\xFC"
128
+
129
+ # 4. Get the DER hex representation
130
+ Secp256k1::Util.bin_to_hex(signature.der_encoded)
131
+ # => "3045022100ab2365365f86361bac1b9257c861844ed4b688f8eedffb43e86ab2f010b8a0890220134c1b9e916342d7ac11f7022c5926544da57a70fdb3b1dc4956bb5caf1640fc"
132
+ ```
133
+
134
+ ### 5. Verifying a signature
135
+
136
+ This example shows how to verify a signature using a public key:
137
+
138
+ ```ruby
139
+ require 'digest'
140
+
141
+ context = Secp256k1::Context.create
142
+ key_pair = context.generate_key_pair
143
+ hash = Digest::SHA256.digest("test message")
144
+
145
+ signature = context.sign(key_pair.private_key, hash)
146
+
147
+ # 1. Verify signature against matching message
148
+ context.verify(signature, key_pair.public_key, hash)
149
+ # => true
150
+
151
+ # 2. Verify signature against different message
152
+ context.verify(signature, key_pair.public_key, hash)
153
+ # => false
154
+ ```
155
+
156
+ ### 6. Loading a private key or key pair from private key data
157
+
158
+ This example shows how to load a key pair from raw binary private key data:
159
+
160
+ ```ruby
161
+ context = Secp256k1::Context.create
162
+
163
+ #1. Load private key alone
164
+ private_key = Secp256k1::PrivateKey.from_data("I\nX\x85\xAEz}\n\x9B\xA4\\\x81)\xD4\x9Aq\xFDH\t\xBE\x8EP\xC5.\xC6\x1F7-\x86\xA0\xCB\xF9")
165
+ # => #<Secp256k1::PrivateKey:0x00005647df1bcd30 @data="I\nX\x85\xAEz}\n\x9B\xA4\\\x81)\xD4\x9Aq\xFDH\t\xBE\x8EP\xC5.\xC6\x1F7-\x86\xA0\xCB\xF9">
166
+
167
+ # 2. Load key pair from private key data
168
+ key_pair = context.key_pair_from_private_key("I\nX\x85\xAEz}\n\x9B\xA4\\\x81)\xD4\x9Aq\xFDH\t\xBE\x8EP\xC5.\xC6\x1F7-\x86\xA0\xCB\xF9")
169
+ # => #<Secp256k1::KeyPair:0x0000559b0bbf9a90 @public_key=#<Secp256k1::PublicKey:0x0000559b0bbf9ab8>, @private_key=#<Secp256k1::PrivateKey:0x0000559b0bbf9ae0 @data="I\nX\x85\xAEz}\n\x9B\xA4\\\x81)Ԛq\xFDH\t\xBE\x8EP\xC5.\xC6\u001F7-\x86\xA0\xCB\xF9">>
170
+ ```
171
+
172
+ ### 7. Loading a public key from binary data
173
+
174
+ This example shows how to load a public key from binary data:
175
+
176
+ ```ruby
177
+ # 1. Load public key from uncompressed pubkey
178
+ public_key = Secp256k1::PublicKey.from_data("\x04$\xA2\xE7\xBB1\xC4|tN\xE6\xE4J-\xED\x9A[\xAFf-<\x14\x84^QQ\"\x14\xC3\x91\xE4\xF2\xB5\xEEEj\xAB\xD9\xFE\b\e7Zk\xC5{k\x12\xE3\xEA\xA2\xA5\xD7\xC1\xA5&\xE5|:K\xA9 X\xA3\x90")
179
+ # => #<Secp256k1::PublicKey:0x0000559b0bdc72f0>
180
+
181
+ # 2. Load public key from compressed pubkey
182
+ public_key = Secp256k1::PublicKey.from_data("\x02$\xA2\xE7\xBB1\xC4|tN\xE6\xE4J-\xED\x9A[\xAFf-<\x14\x84^QQ\"\x14\xC3\x91\xE4\xF2\xB5")
183
+ # => #<Secp256k1::PublicKey:0x0000559b0bdd3668>
184
+ ```
185
+
186
+ ### 8. Loading a DER or compact encoded signature
187
+
188
+ This example shows how to load signatures from binary data:
189
+
190
+ ```ruby
191
+ # 1. From DER encoded signature
192
+ signature = Secp256k1::Signature.from_der_encoded("0D\x02 <\xC6\x7F/\x921l\x89Z\xFBs\x89p\xEE\x18u\x8B\x92\x9D\xA6\x84\xC5Y<t\xB7\xF1\f\xEE\f\x81J\x02 \t\"\xDF]\x1D\xA7W@^\xAAokH\b\x00\xE2L\xCF\x82\xA3\x05\x1E\x00\xF9\xFC\xB19\x0F\x93|\xB1f")
193
+ # => #<Secp256k1::Signature:0x0000559b0b823d58>
194
+
195
+ # 2. From compact signature
196
+ signature = Secp256k1::Signature.from_compact("<\xC6\x7F/\x921l\x89Z\xFBs\x89p\xEE\x18u\x8B\x92\x9D\xA6\x84\xC5Y<t\xB7\xF1\f\xEE\f\x81J\t\"\xDF]\x1D\xA7W@^\xAAokH\b\x00\xE2L\xCF\x82\xA3\x05\x1E\x00\xF9\xFC\xB19\x0F\x93|\xB1f\x00")
197
+ # => #<Secp256k1::Signature:0x0000559b0bdcaa68>
198
+ ```
199
+
200
+ Recoverable Signature Examples
201
+ ------------------------------
202
+
203
+ ### 1. Checking for recovery module
204
+
205
+ To check if you have compiled the recovery module into your local libsecp256k1
206
+ run the following:
207
+
208
+ ```ruby
209
+ Secp256k1.have_recovery?
210
+ # => true
211
+ ```
212
+
213
+ ### 2. Sign data producing recoverable signature
214
+
215
+ You can sign data producing a recoverable signature as follows:
216
+
217
+ ```ruby
218
+ require 'digest'
219
+
220
+ hash = Digest::SHA256.digest('test message')
221
+ context = Secp256k1::Context.create
222
+ key_pair = context.generate_key_pair
223
+
224
+ signature = context.sign_recoverable(key_pair.private_key, hash)
225
+ # => #<Secp256k1::RecoverableSignature:0x000055f2ea76e548>
226
+ ```
227
+
228
+ ### 3. Serialize recoverable signature as compact representation
229
+
230
+ You can produce the compact binary serialization of a recoverable signature:
231
+
232
+ ```ruby
233
+ require 'digest'
234
+
235
+ hash = Digest::SHA256.digest('test message')
236
+ context = Secp256k1::Context.create
237
+ key_pair = context.generate_key_pair
238
+
239
+ signature = context.sign_recoverable(key_pair.private_key, hash)
240
+ compact_data, recovery_id = signature.compact
241
+ # => ["D,\x9C\xA6%I\x14-\xCA\xC0\x11\x0F\xEB\x1E\xB0\xB6\\-\xE2\b\x98\xFB\xEA\xD5\x9BZ\xE6\xDF#\xC1\x1A\xEEL\xF02\xB1\xE9{\r\xEBhh<\\\xCF\xB6\x98\xEA\x8F\xF65\xF2\xBF\x84\xD8\xE5x\xF0\xA5)\xA2Wb\x9D", 1]
242
+ ```
243
+
244
+ ### 4. Recoverable signature from compact representation
245
+
246
+ You can load a recoverable signature give its compact representation and
247
+ recovery ID:
248
+
249
+ ```ruby
250
+ context = Secp256k1::Context.create
251
+
252
+ compact_data = "D,\x9C\xA6%I\x14-\xCA\xC0\x11\x0F\xEB\x1E\xB0\xB6\\-\xE2\b\x98\xFB\xEA\xD5\x9BZ\xE6\xDF#\xC1\x1A\xEEL\xF02\xB1\xE9{\r\xEBhh<\\\xCF\xB6\x98\xEA\x8F\xF65\xF2\xBF\x84\xD8\xE5x\xF0\xA5)\xA2Wb\x9D"
253
+ recovery_id = 1
254
+
255
+ signature = context.recoverable_signature_from_compact(compact_data, recovery_id)
256
+ # => #<Secp256k1::RecoverableSignature:0x000055f2ea7615c8>
257
+ ```
258
+
259
+ ### 5. Convert recoverable signature to non-recoverable signature
260
+
261
+ You can convert a recoverable signature to a non-recoverable signature suitable
262
+ for use by all methods that take a [Signature](signature.md) object:
263
+
264
+ ```ruby
265
+ require 'digest'
266
+
267
+ hash = Digest::SHA256.digest('test message')
268
+ context = Secp256k1::Context.create
269
+ key_pair = context.generate_key_pair
270
+
271
+ recoverable_signature = context.sign_recoverable(key_pair.private_key, hash)
272
+ signature = recoverable_signature.to_signature
273
+ # => #<Secp256k1::Signature:0x000055f2ea8ca4f0>
274
+ ```
275
+
276
+ ### 6. Recover public key from recoverable signature
277
+
278
+ You can recover the [PublicKey](public_key.md) associated with a recoverable signature:
279
+
280
+ ```ruby
281
+ require 'digest'
282
+
283
+ hash = Digest::SHA256.digest('test message')
284
+ context = Secp256k1::Context.create
285
+ key_pair = context.generate_key_pair
286
+
287
+ recoverable_signature = context.sign_recoverable(key_pair.private_key, hash)
288
+ public_key = recoverable_signature.recover_public_key(hash)
289
+ # => #<Secp256k1::PublicKey:0x000055f2ea756678>
290
+
291
+ public_key == key_pair.public_key
292
+ # => true
293
+ ```
294
+
295
+ EC Diffie-Hellman
296
+ -----------------
297
+
298
+ ### 1. Checking for ECDH module
299
+
300
+ To check if you have compiled the ECDH module into your local libsecp256k1 run
301
+ the following:
302
+
303
+ ```ruby
304
+ Secp256k1.have_ecdh?
305
+ # => true
306
+ ```
307
+
308
+ ### 2. Generating a shared secret
309
+
310
+ To generate a shared secret run the following:
311
+
312
+ ```ruby
313
+ context = Secp256k1::Context.create
314
+ key_pair = context.generate_key_pair
315
+
316
+ shared_secret = context.ecdh(key_pair.public_key, key_pair.private_key)
317
+ shared_secret.data
318
+ # => "\x1FQ\x90X\xA5\xF2\xAEx;\xD7i\xB6\\T,2[\x90\xD1)a$\x1CA\x17\x8F\e\x91\xE3\x06C\x93"
319
+ ```
@@ -0,0 +1,28 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::KeyPair
4
+ ==================
5
+
6
+ Secp256k1::KeyPair represents a public-private Secp256k1 key pair.
7
+
8
+ Initializers
9
+ ------------
10
+
11
+ #### new(public_key, private_key)
12
+
13
+ Initializes a new key pair with `public_key` (type: [PublicKey](public_key.md)) and `private_key` (type: [PrivateKey](private_key.md)).
14
+
15
+ Instance Methods
16
+ ----------------
17
+
18
+ #### public_key
19
+
20
+ Returns the [PublicKey](public_key.md) part of this key pair.
21
+
22
+ #### private_key
23
+
24
+ Returns the [PrivateKey](private_key.md) part of this key pair.
25
+
26
+ #### ==(other)
27
+
28
+ Returns `true` if the `other` has the same public and private key.
@@ -0,0 +1,25 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::PrivateKey
4
+ =====================
5
+
6
+ Secp256k1::PrivateKey represents the private key part of a public-private key pair.
7
+
8
+ Class Methods
9
+ -------------
10
+
11
+ #### from_data(private_key_data)
12
+
13
+ Loads new private key from the given binary `private_key_data` string. Raises
14
+ `Secp256k1::Error` if the given data is invalid.
15
+
16
+ Instance Methods
17
+ ----------------
18
+
19
+ #### data
20
+
21
+ Returns the binary private key data as a `String`.
22
+
23
+ #### ==(other)
24
+
25
+ Returns `true` if this private key matches `other`.
@@ -0,0 +1,32 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::PublicKey
4
+ ====================
5
+
6
+ Secp256k1::PublicKey represents the public key part of a public-private key pair.
7
+
8
+ See: [KeyPair](key_pair.md)
9
+
10
+ Class Methods
11
+ -------------
12
+
13
+ #### from_data(public_key_data)
14
+
15
+ Parses compressed or uncompressed from binary string `public_key_data` and
16
+ creates and returns a new public key from it. Raises a `Secp256k1::DeserializationError`
17
+ if the given public key data is invalid.
18
+
19
+ Instance Methods
20
+ ----------------
21
+
22
+ #### compressed
23
+
24
+ Returns the binary compressed representation of this public key.
25
+
26
+ #### uncompressed
27
+
28
+ Returns the binary uncompressed representation of this public key.
29
+
30
+ #### ==(other)
31
+
32
+ Return `true` if this public key matches `other`.
@@ -0,0 +1,30 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::RecoverableSignature
4
+ ===============================
5
+
6
+ **Requires:** libsecp256k1 was build with recovery module.
7
+
8
+ Secp256k1::RecoverableSignature represents a recoverable ECDSA signature
9
+ signing the 32-byte SHA-256 hash of some data.
10
+
11
+ Instance Methods
12
+ ----------------
13
+
14
+ #### compact
15
+
16
+ Returns an array whose first element is the 64-byte compact signature as a
17
+ binary string and whose second element is the integer recovery ID.
18
+
19
+ #### recover_public_key
20
+
21
+ Recovers the public key corresponding to the recoverable signature. Returns a
22
+ [PublicKey](public_key.md).
23
+
24
+ #### to_signature
25
+
26
+ Converts a recoverable signature to a non-recoverable [Signature](signature.md) object.
27
+
28
+ #### ==(other)
29
+
30
+ Returns `true` if this recoverable signature matches `other`.
@@ -0,0 +1,19 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1
4
+ =========
5
+
6
+ Secp256k1 is the top-level module for this library.
7
+
8
+ Class Methods
9
+ -------------
10
+
11
+ #### have_recovery?
12
+
13
+ Returns `true` if the recovery module was built with libsecp256k1, `false`
14
+ otherwise.
15
+
16
+ #### have_ecdh?
17
+
18
+ Returns `true` if the EC Diffie-Hellman module was built with libsecp256k1,
19
+ `false` otherwise.
@@ -0,0 +1,16 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::SharedSecret
4
+ =======================
5
+
6
+ **Requires:** libsecp256k1 was build with ECDH module.
7
+
8
+ Secp256k1::SharedSecret represents a 32-byte shared secret computed from a
9
+ public key (point) and private key (scalar).
10
+
11
+ Instance Methods
12
+ ----------------
13
+
14
+ #### data
15
+
16
+ Binary string containing the 32-byte shared secret.
@@ -0,0 +1,42 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::Signature
4
+ ====================
5
+
6
+ Secp256k1::Signature represents an ECDSA signature signing the 32-byte SHA-256
7
+ hash of some data.
8
+
9
+ Class Methods
10
+ -------------
11
+
12
+ #### from_compact(compact_signature)
13
+
14
+ Parses a signature from binary string `compact_signature`. Raises a
15
+ `Secp256k1::DeserializationError` if the signature data is invalid.
16
+
17
+ #### from_der_encoded(der_encoded_signature)
18
+
19
+ Parses a signature from binary string `der_encoded_signature`. Raises a
20
+ `Secp256k1::DeserializationError` if the signature data is invalid.
21
+
22
+ Instance Methods
23
+ ----------------
24
+
25
+ #### der_encoded
26
+
27
+ Returns the DER encoded representation of this signature.
28
+
29
+ #### compact
30
+
31
+ Returns the compact 64-byte representation of this signature.
32
+
33
+ #### normalized
34
+
35
+ Returns an array containing two elements. The first is a Boolean indicating
36
+ whether or not the signature was normalized, false if it was already in lower-S
37
+ normal form. The second element is a `Signature` containing the normalized
38
+ signature object.
39
+
40
+ #### ==(other)
41
+
42
+ Returns `true` if this signature matches `other`.
@@ -0,0 +1,17 @@
1
+ [Index](index.md)
2
+
3
+ Secp256k1::Util
4
+ ===============
5
+
6
+ Secp256k1::Util in a module containing generally useful methods for using the library.
7
+
8
+ Class Methods
9
+ -------------
10
+
11
+ #### bin_to_hex(binary_data)
12
+
13
+ Returns the hexadecimal string representation of `binary_data`
14
+
15
+ #### hex_to_bin(hex_string)
16
+
17
+ Returns the binary string representation of `hex_string`