rbsecp256k1 3.0.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/documentation/context.md +66 -0
- data/documentation/index.md +319 -0
- data/documentation/key_pair.md +28 -0
- data/documentation/private_key.md +25 -0
- data/documentation/public_key.md +32 -0
- data/documentation/recoverable_signature.md +30 -0
- data/documentation/secp256k1.md +19 -0
- data/documentation/shared_secret.md +16 -0
- data/documentation/signature.md +42 -0
- data/documentation/util.md +17 -0
- data/ext/rbsecp256k1/rbsecp256k1.c +160 -178
- data/lib/rbsecp256k1/version.rb +1 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0bda0a3b5513e2716322c5bd47668b1fe17493ee6a542848d4d3add50cabd67
|
4
|
+
data.tar.gz: 45d1d8dccfa8303b5d750f270dd65331ae6c72948982863e430628cfe9ce2b9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 980d07a3fb920d7c873aca6969dc7102896379005e5a30741f637387fd43c06efdfddb09905e5c24a1dd1bb780211ebe9d46e3a8d16f02f95bf0a180cc6a7652
|
7
|
+
data.tar.gz: acb8d3284c484d946a5e22ebb4f4f2fb2c72f4e0e1e3b9bdb5b8beed2890283c361a14eda2453817401c0a8d98ace34219208f10d8997d98d21ef49766843d0c
|
@@ -0,0 +1,66 @@
|
|
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
|
14
|
+
|
15
|
+
Returns a newly initialized libsecp256k1 context. The context is randomized at
|
16
|
+
initialization.
|
17
|
+
|
18
|
+
Instance Methods
|
19
|
+
----------------
|
20
|
+
|
21
|
+
#### ecdh(point, scalar)
|
22
|
+
|
23
|
+
**Requires:** libsecp256k1 was built with the experimental ECDH module.
|
24
|
+
|
25
|
+
Takes a `point` ([PublicKey](public_key.md)) and a `scalar` ([PrivateKey](private_key.md)) and returns a new
|
26
|
+
[SharedSecret](shared_secret.md) containing the 32-byte shared secret. Raises a `RuntimeError` if
|
27
|
+
the `scalar` is invalid (zero or causes an overflow).
|
28
|
+
|
29
|
+
#### generate_key_pair
|
30
|
+
|
31
|
+
Generates and returns a new [KeyPair](key_pair.md) using a cryptographically
|
32
|
+
secure random number generator (CSRNG) provided by OpenSSL.
|
33
|
+
|
34
|
+
#### key_pair_from_private_key(private_key_data)
|
35
|
+
|
36
|
+
Returns a new [KeyPair](key_pair.md) from the given `private_key_data`. The
|
37
|
+
`private_key_data` is expected to be a binary string. Raises a `RuntimeError`
|
38
|
+
if the private key is invalid or key derivation fails.
|
39
|
+
|
40
|
+
#### recoverable_signature_from_compact(compact_signature, recovery_id)
|
41
|
+
|
42
|
+
**Requires:** libsecp256k1 was build with recovery module.
|
43
|
+
|
44
|
+
Attempts to load a [RecoverableSignature](recoverable_signature.md) from the given `compact_signature`
|
45
|
+
and `recovery_id`. Raises a RuntimeError if the signature data or recovery ID are invalid.
|
46
|
+
|
47
|
+
#### sign(private_key, hash32)
|
48
|
+
|
49
|
+
Signs the SHA-256 hash given by `hash32` using `private_key` and returns a new
|
50
|
+
[Signature](signature.md). The `private_key` is expected to be a [PrivateKey](private_key.md)
|
51
|
+
object and `data` can be either a binary string or text.
|
52
|
+
|
53
|
+
#### sign_recoverable(private_key, hash32)
|
54
|
+
|
55
|
+
**Requires:** libsecp256k1 was build with recovery module.
|
56
|
+
|
57
|
+
Signs the data represented by the SHA-256 hash `hash32` using `private_key` and returns a
|
58
|
+
new [RecoverableSignature](recoverable_signature.md). The `private_key` is expected to be a [PrivateKey](private_key.md) and
|
59
|
+
`data` can be either a binary string or text.
|
60
|
+
|
61
|
+
#### verify(signature, public_key, hash32)
|
62
|
+
|
63
|
+
Verifies the given `signature` ([Signature](signature.md)) was signed by
|
64
|
+
the private key corresponding to `public_key` ([PublicKey](public_key.md)) and signed `hash32`. Returns `true`
|
65
|
+
if `signature` is valid or `false` otherwise. Note that `data` can be either a
|
66
|
+
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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.new
|
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
|
+
`ArgumentError` 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 `RuntimeError` if the
|
17
|
+
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
|
+
`RuntimeError` ig 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
|
+
`RuntimeError` ig 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`
|
@@ -87,17 +87,14 @@ typedef struct KeyPair_dummy {
|
|
87
87
|
|
88
88
|
typedef struct PublicKey_dummy {
|
89
89
|
secp256k1_pubkey pubkey; // Opaque object containing public key data
|
90
|
-
secp256k1_context *ctx;
|
91
90
|
} PublicKey;
|
92
91
|
|
93
92
|
typedef struct PrivateKey_dummy {
|
94
93
|
unsigned char data[32]; // Bytes comprising the private key data
|
95
|
-
secp256k1_context *ctx;
|
96
94
|
} PrivateKey;
|
97
95
|
|
98
96
|
typedef struct Signature_dummy {
|
99
97
|
secp256k1_ecdsa_signature sig; // Signature object, contains 64-byte signature
|
100
|
-
secp256k1_context *ctx;
|
101
98
|
} Signature;
|
102
99
|
|
103
100
|
#ifdef HAVE_SECP256K1_RECOVERY_H
|
@@ -140,7 +137,6 @@ PublicKey_free(void *in_public_key)
|
|
140
137
|
{
|
141
138
|
PublicKey *public_key;
|
142
139
|
public_key = (PublicKey*)in_public_key;
|
143
|
-
secp256k1_context_destroy(public_key->ctx);
|
144
140
|
xfree(public_key);
|
145
141
|
}
|
146
142
|
|
@@ -157,7 +153,6 @@ PrivateKey_free(void *in_private_key)
|
|
157
153
|
{
|
158
154
|
PrivateKey *private_key;
|
159
155
|
private_key = (PrivateKey*)in_private_key;
|
160
|
-
secp256k1_context_destroy(private_key->ctx);
|
161
156
|
xfree(private_key);
|
162
157
|
}
|
163
158
|
|
@@ -197,7 +192,6 @@ static void
|
|
197
192
|
Signature_free(void *in_signature)
|
198
193
|
{
|
199
194
|
Signature *signature = (Signature*)in_signature;
|
200
|
-
secp256k1_context_destroy(signature->ctx);
|
201
195
|
xfree(signature);
|
202
196
|
}
|
203
197
|
|
@@ -471,13 +465,11 @@ PublicKey_create_from_private_key(Context *in_context,
|
|
471
465
|
rb_raise(rb_eTypeError, "invalid private key data");
|
472
466
|
}
|
473
467
|
|
474
|
-
public_key->ctx = secp256k1_context_clone(in_context->ctx);
|
475
468
|
return result;
|
476
469
|
}
|
477
470
|
|
478
471
|
static VALUE
|
479
|
-
PublicKey_create_from_data(
|
480
|
-
unsigned char *in_public_key_data,
|
472
|
+
PublicKey_create_from_data(unsigned char *in_public_key_data,
|
481
473
|
unsigned int in_public_key_data_len)
|
482
474
|
{
|
483
475
|
PublicKey *public_key;
|
@@ -486,7 +478,7 @@ PublicKey_create_from_data(Context *in_context,
|
|
486
478
|
result = PublicKey_alloc(Secp256k1_PublicKey_class);
|
487
479
|
TypedData_Get_Struct(result, PublicKey, &PublicKey_DataType, public_key);
|
488
480
|
|
489
|
-
if (secp256k1_ec_pubkey_parse(
|
481
|
+
if (secp256k1_ec_pubkey_parse(secp256k1_context_no_precomp,
|
490
482
|
&(public_key->pubkey),
|
491
483
|
in_public_key_data,
|
492
484
|
in_public_key_data_len) != 1)
|
@@ -494,10 +486,31 @@ PublicKey_create_from_data(Context *in_context,
|
|
494
486
|
rb_raise(rb_eRuntimeError, "invalid public key data");
|
495
487
|
}
|
496
488
|
|
497
|
-
public_key->ctx = secp256k1_context_clone(in_context->ctx);
|
498
489
|
return result;
|
499
490
|
}
|
500
491
|
|
492
|
+
/**
|
493
|
+
* Loads a public key from compressed or uncompressed binary data.
|
494
|
+
*
|
495
|
+
* @param in_public_key_data [String] binary string with compressed or
|
496
|
+
* uncompressed public key data.
|
497
|
+
* @return [Secp256k1::PublicKey] public key derived from data.
|
498
|
+
* @raise [RuntimeError] if public key data is invalid.
|
499
|
+
*/
|
500
|
+
static VALUE
|
501
|
+
PublicKey_from_data(VALUE klass, VALUE in_public_key_data)
|
502
|
+
{
|
503
|
+
unsigned char *public_key_data;
|
504
|
+
|
505
|
+
Check_Type(in_public_key_data, T_STRING);
|
506
|
+
|
507
|
+
public_key_data = (unsigned char*)StringValuePtr(in_public_key_data);
|
508
|
+
return PublicKey_create_from_data(
|
509
|
+
public_key_data,
|
510
|
+
(int)RSTRING_LEN(in_public_key_data)
|
511
|
+
);
|
512
|
+
}
|
513
|
+
|
501
514
|
/**
|
502
515
|
* @return [String] binary string containing the uncompressed representation
|
503
516
|
* of this public key.
|
@@ -512,7 +525,7 @@ PublicKey_uncompressed(VALUE self)
|
|
512
525
|
|
513
526
|
TypedData_Get_Struct(self, PublicKey, &PublicKey_DataType, public_key);
|
514
527
|
|
515
|
-
secp256k1_ec_pubkey_serialize(
|
528
|
+
secp256k1_ec_pubkey_serialize(secp256k1_context_no_precomp,
|
516
529
|
serialized_pubkey,
|
517
530
|
&serialized_pubkey_len,
|
518
531
|
&(public_key->pubkey),
|
@@ -535,7 +548,7 @@ PublicKey_compressed(VALUE self)
|
|
535
548
|
|
536
549
|
TypedData_Get_Struct(self, PublicKey, &PublicKey_DataType, public_key);
|
537
550
|
|
538
|
-
secp256k1_ec_pubkey_serialize(
|
551
|
+
secp256k1_ec_pubkey_serialize(secp256k1_context_no_precomp,
|
539
552
|
serialized_pubkey,
|
540
553
|
&serialized_pubkey_len,
|
541
554
|
&(public_key->pubkey),
|
@@ -569,14 +582,14 @@ PublicKey_equals(VALUE self, VALUE other)
|
|
569
582
|
TypedData_Get_Struct(other, PublicKey, &PublicKey_DataType, rhs);
|
570
583
|
|
571
584
|
secp256k1_ec_pubkey_serialize(
|
572
|
-
|
585
|
+
secp256k1_context_no_precomp,
|
573
586
|
lhs_compressed,
|
574
587
|
&lhs_len,
|
575
588
|
&(lhs->pubkey),
|
576
589
|
SECP256K1_EC_COMPRESSED
|
577
590
|
);
|
578
591
|
secp256k1_ec_pubkey_serialize(
|
579
|
-
|
592
|
+
secp256k1_context_no_precomp,
|
580
593
|
rhs_compressed,
|
581
594
|
&rhs_len,
|
582
595
|
&(rhs->pubkey),
|
@@ -610,12 +623,13 @@ PrivateKey_alloc(VALUE klass)
|
|
610
623
|
}
|
611
624
|
|
612
625
|
static VALUE
|
613
|
-
PrivateKey_create(
|
626
|
+
PrivateKey_create(unsigned char *in_private_key_data)
|
614
627
|
{
|
615
628
|
PrivateKey *private_key;
|
616
629
|
VALUE result;
|
617
630
|
|
618
|
-
if (secp256k1_ec_seckey_verify(
|
631
|
+
if (secp256k1_ec_seckey_verify(secp256k1_context_no_precomp,
|
632
|
+
in_private_key_data) != 1)
|
619
633
|
{
|
620
634
|
rb_raise(rb_eArgError, "invalid private key data");
|
621
635
|
}
|
@@ -623,13 +637,35 @@ PrivateKey_create(Context *in_context, unsigned char *in_private_key_data)
|
|
623
637
|
result = PrivateKey_alloc(Secp256k1_PrivateKey_class);
|
624
638
|
TypedData_Get_Struct(result, PrivateKey, &PrivateKey_DataType, private_key);
|
625
639
|
MEMCPY(private_key->data, in_private_key_data, char, 32);
|
626
|
-
private_key->ctx = secp256k1_context_clone(in_context->ctx);
|
627
640
|
|
628
641
|
rb_iv_set(result, "@data", rb_str_new((char*)in_private_key_data, 32));
|
629
642
|
|
630
643
|
return result;
|
631
644
|
}
|
632
645
|
|
646
|
+
/**
|
647
|
+
* Load a private key from binary data.
|
648
|
+
*
|
649
|
+
* @param in_private_key_data [String] 32 byte binary string of private key
|
650
|
+
* data.
|
651
|
+
* @return [Secp256k1::PrivateKey] private key loaded from the given data.
|
652
|
+
* @raise [ArgumentError] if private key data is not 32 bytes or is invalid.
|
653
|
+
*/
|
654
|
+
static VALUE
|
655
|
+
PrivateKey_from_data(VALUE klass, VALUE in_private_key_data)
|
656
|
+
{
|
657
|
+
unsigned char *private_key_data;
|
658
|
+
|
659
|
+
Check_Type(in_private_key_data, T_STRING);
|
660
|
+
if (RSTRING_LEN(in_private_key_data) != 32)
|
661
|
+
{
|
662
|
+
rb_raise(rb_eArgError, "private key data must be 32 bytes in length");
|
663
|
+
}
|
664
|
+
|
665
|
+
private_key_data = (unsigned char*)StringValuePtr(in_private_key_data);
|
666
|
+
return PrivateKey_create(private_key_data);
|
667
|
+
}
|
668
|
+
|
633
669
|
/**
|
634
670
|
* Compare two private keys.
|
635
671
|
*
|
@@ -672,6 +708,77 @@ Signature_alloc(VALUE klass)
|
|
672
708
|
return new_instance;
|
673
709
|
}
|
674
710
|
|
711
|
+
/**
|
712
|
+
* Deserializes a Signature from 64-byte compact signature data.
|
713
|
+
*
|
714
|
+
* @param in_compact_signature [String] compact signature as 64-byte binary
|
715
|
+
* string.
|
716
|
+
* @return [Secp256k1::Signature] object deserialized from compact signature.
|
717
|
+
* @raise [ArgumentError] if signature data is invalid.
|
718
|
+
*/
|
719
|
+
static VALUE
|
720
|
+
Signature_from_compact(VALUE klass, VALUE in_compact_signature)
|
721
|
+
{
|
722
|
+
Signature *signature;
|
723
|
+
VALUE signature_result;
|
724
|
+
unsigned char *signature_data;
|
725
|
+
|
726
|
+
Check_Type(in_compact_signature, T_STRING);
|
727
|
+
|
728
|
+
if (RSTRING_LEN(in_compact_signature) != 64)
|
729
|
+
{
|
730
|
+
rb_raise(rb_eArgError, "compact signature must be 64 bytes");
|
731
|
+
}
|
732
|
+
|
733
|
+
signature_data = (unsigned char*)StringValuePtr(in_compact_signature);
|
734
|
+
|
735
|
+
signature_result = Signature_alloc(Secp256k1_Signature_class);
|
736
|
+
TypedData_Get_Struct(signature_result, Signature, &Signature_DataType, signature);
|
737
|
+
|
738
|
+
if (secp256k1_ecdsa_signature_parse_compact(secp256k1_context_no_precomp,
|
739
|
+
&(signature->sig),
|
740
|
+
signature_data) != 1)
|
741
|
+
{
|
742
|
+
rb_raise(rb_eArgError, "invalid compact signature");
|
743
|
+
}
|
744
|
+
|
745
|
+
return signature_result;
|
746
|
+
}
|
747
|
+
|
748
|
+
/**
|
749
|
+
* Converts a DER encoded binary signature into a signature object.
|
750
|
+
*
|
751
|
+
* @param in_der_encoded_signature [String] DER encoded signature as binary
|
752
|
+
* string.
|
753
|
+
* @return [Secp256k1::Signature] signature object initialized using signature
|
754
|
+
* data.
|
755
|
+
* @raise [ArgumentError] if signature data is invalid.
|
756
|
+
*/
|
757
|
+
static VALUE
|
758
|
+
Signature_from_der_encoded(VALUE klass, VALUE in_der_encoded_signature)
|
759
|
+
{
|
760
|
+
Signature *signature;
|
761
|
+
VALUE signature_result;
|
762
|
+
unsigned char *signature_data;
|
763
|
+
|
764
|
+
Check_Type(in_der_encoded_signature, T_STRING);
|
765
|
+
|
766
|
+
signature_data = (unsigned char*)StringValuePtr(in_der_encoded_signature);
|
767
|
+
|
768
|
+
signature_result = Signature_alloc(Secp256k1_Signature_class);
|
769
|
+
TypedData_Get_Struct(signature_result, Signature, &Signature_DataType, signature);
|
770
|
+
|
771
|
+
if (secp256k1_ecdsa_signature_parse_der(secp256k1_context_no_precomp,
|
772
|
+
&(signature->sig),
|
773
|
+
signature_data,
|
774
|
+
RSTRING_LEN(in_der_encoded_signature)) != 1)
|
775
|
+
{
|
776
|
+
rb_raise(rb_eArgError, "invalid DER encoded signature");
|
777
|
+
}
|
778
|
+
|
779
|
+
return signature_result;
|
780
|
+
}
|
781
|
+
|
675
782
|
/**
|
676
783
|
* Return Distinguished Encoding Rules (DER) encoded signature data.
|
677
784
|
*
|
@@ -688,7 +795,7 @@ Signature_der_encoded(VALUE self)
|
|
688
795
|
TypedData_Get_Struct(self, Signature, &Signature_DataType, signature);
|
689
796
|
|
690
797
|
der_signature_len = 72;
|
691
|
-
if (secp256k1_ecdsa_signature_serialize_der(
|
798
|
+
if (secp256k1_ecdsa_signature_serialize_der(secp256k1_context_no_precomp,
|
692
799
|
der_signature,
|
693
800
|
&der_signature_len,
|
694
801
|
&(signature->sig)) != 1)
|
@@ -713,7 +820,7 @@ Signature_compact(VALUE self)
|
|
713
820
|
|
714
821
|
TypedData_Get_Struct(self, Signature, &Signature_DataType, signature);
|
715
822
|
|
716
|
-
if (secp256k1_ecdsa_signature_serialize_compact(
|
823
|
+
if (secp256k1_ecdsa_signature_serialize_compact(secp256k1_context_no_precomp,
|
717
824
|
compact_signature,
|
718
825
|
&(signature->sig)) != 1)
|
719
826
|
{
|
@@ -751,15 +858,13 @@ Signature_normalized(VALUE self)
|
|
751
858
|
|
752
859
|
was_normalized = Qfalse;
|
753
860
|
if (secp256k1_ecdsa_signature_normalize(
|
754
|
-
|
861
|
+
secp256k1_context_no_precomp,
|
755
862
|
&(normalized_signature->sig),
|
756
863
|
&(signature->sig)) == 1)
|
757
864
|
{
|
758
865
|
was_normalized = Qtrue;
|
759
866
|
}
|
760
867
|
|
761
|
-
normalized_signature->ctx = secp256k1_context_clone(signature->ctx);
|
762
|
-
|
763
868
|
result = rb_ary_new2(2);
|
764
869
|
rb_ary_push(result, was_normalized);
|
765
870
|
rb_ary_push(result, result_sig);
|
@@ -787,10 +892,10 @@ Signature_equals(VALUE self, VALUE other)
|
|
787
892
|
TypedData_Get_Struct(other, Signature, &Signature_DataType, rhs);
|
788
893
|
|
789
894
|
secp256k1_ecdsa_signature_serialize_compact(
|
790
|
-
|
895
|
+
secp256k1_context_no_precomp, lhs_compact, &(lhs->sig)
|
791
896
|
);
|
792
897
|
secp256k1_ecdsa_signature_serialize_compact(
|
793
|
-
|
898
|
+
secp256k1_context_no_precomp, rhs_compact, &(rhs->sig)
|
794
899
|
);
|
795
900
|
|
796
901
|
if (memcmp(lhs_compact, rhs_compact, 64) == 0)
|
@@ -845,7 +950,7 @@ RecoverableSignature_compact(VALUE self)
|
|
845
950
|
);
|
846
951
|
|
847
952
|
if (secp256k1_ecdsa_recoverable_signature_serialize_compact(
|
848
|
-
|
953
|
+
secp256k1_context_no_precomp,
|
849
954
|
compact_sig,
|
850
955
|
&recovery_id,
|
851
956
|
&(recoverable_signature->sig)) != 1)
|
@@ -891,11 +996,10 @@ RecoverableSignature_to_signature(VALUE self)
|
|
891
996
|
|
892
997
|
// NOTE: This method cannot fail
|
893
998
|
secp256k1_ecdsa_recoverable_signature_convert(
|
894
|
-
|
999
|
+
secp256k1_context_no_precomp,
|
895
1000
|
&(signature->sig),
|
896
1001
|
&(recoverable_signature->sig));
|
897
1002
|
|
898
|
-
signature->ctx = secp256k1_context_clone(recoverable_signature->ctx);
|
899
1003
|
return result;
|
900
1004
|
}
|
901
1005
|
|
@@ -936,7 +1040,6 @@ RecoverableSignature_recover_public_key(VALUE self, VALUE in_hash32)
|
|
936
1040
|
&(recoverable_signature->sig),
|
937
1041
|
hash32) == 1)
|
938
1042
|
{
|
939
|
-
public_key->ctx = secp256k1_context_clone(recoverable_signature->ctx);
|
940
1043
|
return result;
|
941
1044
|
}
|
942
1045
|
|
@@ -1076,7 +1179,7 @@ Context_generate_key_pair(VALUE self)
|
|
1076
1179
|
|
1077
1180
|
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1078
1181
|
|
1079
|
-
private_key = PrivateKey_create(
|
1182
|
+
private_key = PrivateKey_create(private_key_bytes);
|
1080
1183
|
public_key = PublicKey_create_from_private_key(context, private_key_bytes);
|
1081
1184
|
result = rb_funcall(
|
1082
1185
|
Secp256k1_KeyPair_class,
|
@@ -1089,57 +1192,6 @@ Context_generate_key_pair(VALUE self)
|
|
1089
1192
|
return result;
|
1090
1193
|
}
|
1091
1194
|
|
1092
|
-
/**
|
1093
|
-
* Loads a public key from compressed or uncompressed binary data.
|
1094
|
-
*
|
1095
|
-
* @param in_public_key_data [String] binary string with compressed or
|
1096
|
-
* uncompressed public key data.
|
1097
|
-
* @return [Secp256k1::PublicKey] public key derived from data.
|
1098
|
-
* @raise [RuntimeError] if public key data is invalid.
|
1099
|
-
*/
|
1100
|
-
static VALUE
|
1101
|
-
Context_public_key_from_data(VALUE self, VALUE in_public_key_data)
|
1102
|
-
{
|
1103
|
-
Context *context;
|
1104
|
-
unsigned char *public_key_data;
|
1105
|
-
|
1106
|
-
Check_Type(in_public_key_data, T_STRING);
|
1107
|
-
|
1108
|
-
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1109
|
-
public_key_data = (unsigned char*)StringValuePtr(in_public_key_data);
|
1110
|
-
return PublicKey_create_from_data(
|
1111
|
-
context,
|
1112
|
-
public_key_data,
|
1113
|
-
(int)RSTRING_LEN(in_public_key_data)
|
1114
|
-
);
|
1115
|
-
}
|
1116
|
-
|
1117
|
-
/**
|
1118
|
-
* Load a private key from binary data.
|
1119
|
-
*
|
1120
|
-
* @param in_private_key_data [String] 32 byte binary string of private key
|
1121
|
-
* data.
|
1122
|
-
* @return [Secp256k1::PrivateKey] private key loaded from the given data.
|
1123
|
-
* @raise [ArgumentError] if private key data is not 32 bytes or is invalid.
|
1124
|
-
*/
|
1125
|
-
static VALUE
|
1126
|
-
Context_private_key_from_data(VALUE self, VALUE in_private_key_data)
|
1127
|
-
{
|
1128
|
-
Context *context;
|
1129
|
-
unsigned char *private_key_data;
|
1130
|
-
|
1131
|
-
Check_Type(in_private_key_data, T_STRING);
|
1132
|
-
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1133
|
-
private_key_data = (unsigned char*)StringValuePtr(in_private_key_data);
|
1134
|
-
|
1135
|
-
if (RSTRING_LEN(in_private_key_data) != 32)
|
1136
|
-
{
|
1137
|
-
rb_raise(rb_eArgError, "private key data must be 32 bytes in length");
|
1138
|
-
}
|
1139
|
-
|
1140
|
-
return PrivateKey_create(context, private_key_data);
|
1141
|
-
}
|
1142
|
-
|
1143
1195
|
/**
|
1144
1196
|
* Converts binary private key data into a new key pair.
|
1145
1197
|
*
|
@@ -1157,16 +1209,16 @@ Context_key_pair_from_private_key(VALUE self, VALUE in_private_key_data)
|
|
1157
1209
|
unsigned char *private_key_data;
|
1158
1210
|
|
1159
1211
|
Check_Type(in_private_key_data, T_STRING);
|
1212
|
+
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1160
1213
|
|
1161
1214
|
if (RSTRING_LEN(in_private_key_data) != 32)
|
1162
1215
|
{
|
1163
1216
|
rb_raise(rb_eArgError, "private key data must be 32 bytes in length");
|
1164
1217
|
}
|
1165
1218
|
|
1166
|
-
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1167
1219
|
private_key_data = (unsigned char*)StringValuePtr(in_private_key_data);
|
1168
1220
|
|
1169
|
-
private_key = PrivateKey_create(
|
1221
|
+
private_key = PrivateKey_create(private_key_data);
|
1170
1222
|
public_key = PublicKey_create_from_private_key(context, private_key_data);
|
1171
1223
|
|
1172
1224
|
return rb_funcall(
|
@@ -1178,83 +1230,6 @@ Context_key_pair_from_private_key(VALUE self, VALUE in_private_key_data)
|
|
1178
1230
|
);
|
1179
1231
|
}
|
1180
1232
|
|
1181
|
-
/**
|
1182
|
-
* Converts a DER encoded binary signature into a signature object.
|
1183
|
-
*
|
1184
|
-
* @param in_der_encoded_signature [String] DER encoded signature as binary
|
1185
|
-
* string.
|
1186
|
-
* @return [Secp256k1::Signature] signature object initialized using signature
|
1187
|
-
* data.
|
1188
|
-
* @raise [ArgumentError] if signature data is invalid.
|
1189
|
-
*/
|
1190
|
-
static VALUE
|
1191
|
-
Context_signature_from_der_encoded(VALUE self, VALUE in_der_encoded_signature)
|
1192
|
-
{
|
1193
|
-
Context *context;
|
1194
|
-
Signature *signature;
|
1195
|
-
VALUE signature_result;
|
1196
|
-
unsigned char *signature_data;
|
1197
|
-
|
1198
|
-
Check_Type(in_der_encoded_signature, T_STRING);
|
1199
|
-
|
1200
|
-
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1201
|
-
signature_data = (unsigned char*)StringValuePtr(in_der_encoded_signature);
|
1202
|
-
|
1203
|
-
signature_result = Signature_alloc(Secp256k1_Signature_class);
|
1204
|
-
TypedData_Get_Struct(signature_result, Signature, &Signature_DataType, signature);
|
1205
|
-
|
1206
|
-
if (secp256k1_ecdsa_signature_parse_der(context->ctx,
|
1207
|
-
&(signature->sig),
|
1208
|
-
signature_data,
|
1209
|
-
RSTRING_LEN(in_der_encoded_signature)) != 1)
|
1210
|
-
{
|
1211
|
-
rb_raise(rb_eArgError, "invalid DER encoded signature");
|
1212
|
-
}
|
1213
|
-
|
1214
|
-
signature->ctx = secp256k1_context_clone(context->ctx);
|
1215
|
-
return signature_result;
|
1216
|
-
}
|
1217
|
-
|
1218
|
-
/**
|
1219
|
-
* Deserializes a Signature from 64-byte compact signature data.
|
1220
|
-
*
|
1221
|
-
* @param in_compact_signature [String] compact signature as 64-byte binary
|
1222
|
-
* string.
|
1223
|
-
* @return [Secp256k1::Signature] object deserialized from compact signature.
|
1224
|
-
* @raise [ArgumentError] if signature data is invalid.
|
1225
|
-
*/
|
1226
|
-
static VALUE
|
1227
|
-
Context_signature_from_compact(VALUE self, VALUE in_compact_signature)
|
1228
|
-
{
|
1229
|
-
Context *context;
|
1230
|
-
Signature *signature;
|
1231
|
-
VALUE signature_result;
|
1232
|
-
unsigned char *signature_data;
|
1233
|
-
|
1234
|
-
Check_Type(in_compact_signature, T_STRING);
|
1235
|
-
|
1236
|
-
if (RSTRING_LEN(in_compact_signature) != 64)
|
1237
|
-
{
|
1238
|
-
rb_raise(rb_eArgError, "compact signature must be 64 bytes");
|
1239
|
-
}
|
1240
|
-
|
1241
|
-
TypedData_Get_Struct(self, Context, &Context_DataType, context);
|
1242
|
-
signature_data = (unsigned char*)StringValuePtr(in_compact_signature);
|
1243
|
-
|
1244
|
-
signature_result = Signature_alloc(Secp256k1_Signature_class);
|
1245
|
-
TypedData_Get_Struct(signature_result, Signature, &Signature_DataType, signature);
|
1246
|
-
|
1247
|
-
if (secp256k1_ecdsa_signature_parse_compact(context->ctx,
|
1248
|
-
&(signature->sig),
|
1249
|
-
signature_data) != 1)
|
1250
|
-
{
|
1251
|
-
rb_raise(rb_eArgError, "invalid compact signature");
|
1252
|
-
}
|
1253
|
-
|
1254
|
-
signature->ctx = secp256k1_context_clone(context->ctx);
|
1255
|
-
return signature_result;
|
1256
|
-
}
|
1257
|
-
|
1258
1233
|
/**
|
1259
1234
|
* Computes the ECDSA signature of the data using the secp256k1 elliptic curve.
|
1260
1235
|
*
|
@@ -1294,7 +1269,6 @@ Context_sign(VALUE self, VALUE in_private_key, VALUE in_hash32)
|
|
1294
1269
|
private_key->data,
|
1295
1270
|
&(signature->sig))))
|
1296
1271
|
{
|
1297
|
-
signature->ctx = secp256k1_context_clone(context->ctx);
|
1298
1272
|
return signature_result;
|
1299
1273
|
}
|
1300
1274
|
|
@@ -1444,7 +1418,7 @@ Context_recoverable_signature_from_compact(
|
|
1444
1418
|
);
|
1445
1419
|
|
1446
1420
|
if (secp256k1_ecdsa_recoverable_signature_parse_compact(
|
1447
|
-
|
1421
|
+
secp256k1_context_no_precomp,
|
1448
1422
|
&(recoverable_signature->sig),
|
1449
1423
|
compact_sig,
|
1450
1424
|
recovery_id) == 1)
|
@@ -1587,14 +1561,6 @@ void Init_rbsecp256k1()
|
|
1587
1561
|
"key_pair_from_private_key",
|
1588
1562
|
Context_key_pair_from_private_key,
|
1589
1563
|
1);
|
1590
|
-
rb_define_method(Secp256k1_Context_class,
|
1591
|
-
"public_key_from_data",
|
1592
|
-
Context_public_key_from_data,
|
1593
|
-
1);
|
1594
|
-
rb_define_method(Secp256k1_Context_class,
|
1595
|
-
"private_key_from_data",
|
1596
|
-
Context_private_key_from_data,
|
1597
|
-
1);
|
1598
1564
|
rb_define_method(Secp256k1_Context_class,
|
1599
1565
|
"sign",
|
1600
1566
|
Context_sign,
|
@@ -1603,14 +1569,6 @@ void Init_rbsecp256k1()
|
|
1603
1569
|
"verify",
|
1604
1570
|
Context_verify,
|
1605
1571
|
3);
|
1606
|
-
rb_define_method(Secp256k1_Context_class,
|
1607
|
-
"signature_from_der_encoded",
|
1608
|
-
Context_signature_from_der_encoded,
|
1609
|
-
1);
|
1610
|
-
rb_define_method(Secp256k1_Context_class,
|
1611
|
-
"signature_from_compact",
|
1612
|
-
Context_signature_from_compact,
|
1613
|
-
1);
|
1614
1572
|
|
1615
1573
|
// Secp256k1::KeyPair
|
1616
1574
|
Secp256k1_KeyPair_class = rb_define_class_under(Secp256k1_module,
|
@@ -1638,6 +1596,12 @@ void Init_rbsecp256k1()
|
|
1638
1596
|
"uncompressed",
|
1639
1597
|
PublicKey_uncompressed,
|
1640
1598
|
0);
|
1599
|
+
rb_define_singleton_method(
|
1600
|
+
Secp256k1_PublicKey_class,
|
1601
|
+
"from_data",
|
1602
|
+
PublicKey_from_data,
|
1603
|
+
1
|
1604
|
+
);
|
1641
1605
|
rb_define_method(Secp256k1_PublicKey_class, "==", PublicKey_equals, 1);
|
1642
1606
|
|
1643
1607
|
// Secp256k1::PrivateKey
|
@@ -1647,6 +1611,12 @@ void Init_rbsecp256k1()
|
|
1647
1611
|
rb_define_alloc_func(Secp256k1_PrivateKey_class, PrivateKey_alloc);
|
1648
1612
|
rb_define_attr(Secp256k1_PrivateKey_class, "data", 1, 0);
|
1649
1613
|
rb_define_method(Secp256k1_PrivateKey_class, "==", PrivateKey_equals, 1);
|
1614
|
+
rb_define_singleton_method(
|
1615
|
+
Secp256k1_PrivateKey_class,
|
1616
|
+
"from_data",
|
1617
|
+
PrivateKey_from_data,
|
1618
|
+
1
|
1619
|
+
);
|
1650
1620
|
|
1651
1621
|
// Secp256k1::Signature
|
1652
1622
|
Secp256k1_Signature_class = rb_define_class_under(Secp256k1_module,
|
@@ -1669,6 +1639,18 @@ void Init_rbsecp256k1()
|
|
1669
1639
|
"==",
|
1670
1640
|
Signature_equals,
|
1671
1641
|
1);
|
1642
|
+
rb_define_singleton_method(
|
1643
|
+
Secp256k1_Signature_class,
|
1644
|
+
"from_compact",
|
1645
|
+
Signature_from_compact,
|
1646
|
+
1
|
1647
|
+
);
|
1648
|
+
rb_define_singleton_method(
|
1649
|
+
Secp256k1_Signature_class,
|
1650
|
+
"from_der_encoded",
|
1651
|
+
Signature_from_der_encoded,
|
1652
|
+
1
|
1653
|
+
);
|
1672
1654
|
|
1673
1655
|
#ifdef HAVE_SECP256K1_RECOVERY_H
|
1674
1656
|
// Secp256k1::RecoverableSignature
|
data/lib/rbsecp256k1/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbsecp256k1
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Scrivner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mini_portile2
|
@@ -131,6 +131,16 @@ extra_rdoc_files: []
|
|
131
131
|
files:
|
132
132
|
- README.md
|
133
133
|
- Rakefile
|
134
|
+
- documentation/context.md
|
135
|
+
- documentation/index.md
|
136
|
+
- documentation/key_pair.md
|
137
|
+
- documentation/private_key.md
|
138
|
+
- documentation/public_key.md
|
139
|
+
- documentation/recoverable_signature.md
|
140
|
+
- documentation/secp256k1.md
|
141
|
+
- documentation/shared_secret.md
|
142
|
+
- documentation/signature.md
|
143
|
+
- documentation/util.md
|
134
144
|
- ext/rbsecp256k1/extconf.rb
|
135
145
|
- ext/rbsecp256k1/rbsecp256k1.c
|
136
146
|
- lib/rbsecp256k1.rb
|