bitcoin-secp256k1 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/secp256k1/c.rb +20 -0
- data/lib/secp256k1/ecdsa.rb +54 -0
- data/lib/secp256k1/key.rb +1 -1
- data/lib/secp256k1/version.rb +1 -1
- data/test/secp256k1_test.rb +52 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35c4817fc53d1512f07b574c444ac2ff39d723b7
|
4
|
+
data.tar.gz: 2c0acf62b066d43caf45ba96530b330ef8db2927
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4f831335807714f0cbd888e0adf8846293a3187ab7bde70306d61dce530947ab192b01770f6cfd43a1185c35417493c951af5dd08eb69ab8d63efc769f73d44f
|
7
|
+
data.tar.gz: 9e9b0e898a4db87c076921fbc50a4614ed411e2505a218d28380d8afc2ba18a261faa20ec84186c010376d4c2c28e87eb833b9fdab0c33f4ff5a82e0f82472eb
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
data/lib/secp256k1/c.rb
CHANGED
@@ -36,6 +36,9 @@ module Secp256k1
|
|
36
36
|
# int secp256k1_ec_pubkey_create(const secp256k1_context* ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey)
|
37
37
|
attach_function :secp256k1_ec_pubkey_create, [:pointer, :pointer, :pointer], :int
|
38
38
|
|
39
|
+
# int secp256k1_ec_pubkey_serialize(const secp256k1_context* ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags)
|
40
|
+
attach_function :secp256k1_ec_pubkey_serialize, [:pointer, :pointer, :pointer, :pointer, :uint], :int
|
41
|
+
|
39
42
|
# int secp256k1_ec_seckey_verify(const secp256k1_context* ctx, const unsigned char *seckey)
|
40
43
|
attach_function :secp256k1_ec_seckey_verify, [:pointer, :pointer], :int
|
41
44
|
|
@@ -54,8 +57,25 @@ module Secp256k1
|
|
54
57
|
# int secp256k1_ecdsa_sign(const secp256k1_context* ctx, secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata)
|
55
58
|
attach_function :secp256k1_ecdsa_sign, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int
|
56
59
|
|
60
|
+
# int secp256k1_ecdsa_sign_recoverable(const secp256k1_context* ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata)
|
61
|
+
attach_function :secp256k1_ecdsa_sign_recoverable, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int
|
62
|
+
|
63
|
+
# int secp256k1_ecdsa_recover(const secp256k1_context* ctx, secp256k1_pubkey* pubkey, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32)
|
64
|
+
attach_function :secp256k1_ecdsa_recover, [:pointer, :pointer, :pointer, :pointer], :int
|
65
|
+
|
57
66
|
# int secp256k1_ecdsa_verify(const secp256k1_context *ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey)
|
58
67
|
attach_function :secp256k1_ecdsa_verify, [:pointer, :pointer, :pointer, :pointer], :int
|
59
68
|
|
69
|
+
# int secp256k1_ecdsa_signature_normalize(const secp256k1_context *ctx, const secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin)
|
70
|
+
attach_function :secp256k1_ecdsa_signature_normalize, [:pointer, :pointer, :pointer], :int
|
71
|
+
|
72
|
+
# int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context *ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature *sig)
|
73
|
+
attach_function :secp256k1_ecdsa_recoverable_signature_serialize_compact, [:pointer, :pointer, :pointer, :pointer], :int
|
74
|
+
|
75
|
+
# int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *input64, int recid)
|
76
|
+
attach_function :secp256k1_ecdsa_recoverable_signature_parse_compact, [:pointer, :pointer, :pointer, :int], :int
|
77
|
+
|
78
|
+
# int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const secp256k1_ecdsa_recoverable_signature *sigin)
|
79
|
+
attach_function :secp256k1_ecdsa_recoverable_signature_convert, [:pointer, :pointer, :pointer], :int
|
60
80
|
end
|
61
81
|
end
|
data/lib/secp256k1/ecdsa.rb
CHANGED
@@ -43,5 +43,59 @@ module Secp256k1
|
|
43
43
|
raw_sig
|
44
44
|
end
|
45
45
|
|
46
|
+
##
|
47
|
+
# Check and optionally convert a signature to a normalized lower-S form. If
|
48
|
+
# check_only is `true` then the normalized signature is not returned.
|
49
|
+
#
|
50
|
+
# This function always return a tuple containing a boolean (`true` if not
|
51
|
+
# previously normalized or `false` if signature was already normalized),
|
52
|
+
# and the normalized signature. When check_only is `true`, the normalized
|
53
|
+
# signature returned is always `nil`.
|
54
|
+
#
|
55
|
+
def ecdsa_signature_normalize(raw_sig, check_only: false)
|
56
|
+
sigout = check_only ? nil : C::ECDSASignature.new.pointer
|
57
|
+
res = C.secp256k1_ecdsa_signature_normalize(@ctx, sigout, raw_sig)
|
58
|
+
[res == 1, sigout]
|
59
|
+
end
|
60
|
+
|
61
|
+
def ecdsa_recover(msg, recover_sig, raw: false, digest: Digest::SHA256)
|
62
|
+
raise AssertError, 'instance not configured for ecdsa recover' if (@flags & ALL_FLAGS) != ALL_FLAGS
|
63
|
+
|
64
|
+
msg32 = hash32 msg, raw, digest
|
65
|
+
pubkey = C::Pubkey.new.pointer
|
66
|
+
|
67
|
+
res = C.secp256k1_ecdsa_recover(@ctx, pubkey, recover_sig, msg32)
|
68
|
+
raise AssertError, 'failed to recover ECDSA public key' unless res == 1
|
69
|
+
|
70
|
+
pubkey
|
71
|
+
end
|
72
|
+
|
73
|
+
def ecdsa_recoverable_serialize(recover_sig)
|
74
|
+
output = FFI::MemoryPointer.new :uchar, SIZE_COMPACT
|
75
|
+
recid = FFI::MemoryPointer.new :int
|
76
|
+
|
77
|
+
C.secp256k1_ecdsa_recoverable_signature_serialize_compact(@ctx, output, recid, recover_sig)
|
78
|
+
|
79
|
+
[output.read_bytes(SIZE_COMPACT), recid.read_int]
|
80
|
+
end
|
81
|
+
|
82
|
+
def ecdsa_recoverable_deserialize(ser_sig, rec_id)
|
83
|
+
raise ArgumentError, 'invalid rec_id' if rec_id < 0 || rec_id > 3
|
84
|
+
raise ArgumentError, 'invalid signature length' if ser_sig.size != 64
|
85
|
+
|
86
|
+
recover_sig = C::ECDSARecoverableSignature.new.pointer
|
87
|
+
|
88
|
+
res = C.secp256k1_ecdsa_recoverable_signature_parse_compact(@ctx, recover_sig, ser_sig, rec_id)
|
89
|
+
raise AssertError, 'failed to parse ECDSA compact sig' unless res == 1
|
90
|
+
|
91
|
+
recover_sig
|
92
|
+
end
|
93
|
+
|
94
|
+
def ecdsa_recoverable_convert(recover_sig)
|
95
|
+
normal_sig = C::ECDSASignature.new.pointer
|
96
|
+
C.secp256k1_ecdsa_recoverable_signature_convert(@ctx, normal_sig, recover_sig)
|
97
|
+
normal_sig
|
98
|
+
end
|
99
|
+
|
46
100
|
end
|
47
101
|
end
|
data/lib/secp256k1/key.rb
CHANGED
@@ -175,7 +175,7 @@ module Secp256k1
|
|
175
175
|
|
176
176
|
def ecdsa_sign_recoverable(msg, raw: false, digest: Digest::SHA256)
|
177
177
|
msg32 = hash32 msg, raw, digest
|
178
|
-
raw_sig =
|
178
|
+
raw_sig = C::ECDSARecoverableSignature.new.pointer
|
179
179
|
|
180
180
|
res = C.secp256k1_ecdsa_sign_recoverable @ctx, raw_sig, msg32, @private_key, nil, nil
|
181
181
|
raise AssertError, "failed to sign" unless res == 1
|
data/lib/secp256k1/version.rb
CHANGED
data/test/secp256k1_test.rb
CHANGED
@@ -7,6 +7,14 @@ require 'secp256k1'
|
|
7
7
|
|
8
8
|
require 'json'
|
9
9
|
|
10
|
+
class MyECDSA < Secp256k1::BaseKey
|
11
|
+
include Secp256k1::Utils, Secp256k1::ECDSA
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super(nil, Secp256k1::ALL_FLAGS)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
10
18
|
class Secp256k1Test < Minitest::Test
|
11
19
|
include Secp256k1
|
12
20
|
|
@@ -42,6 +50,50 @@ class Secp256k1Test < Minitest::Test
|
|
42
50
|
assert_equal true, pk.pubkey.ecdsa_verify('test', sig_raw)
|
43
51
|
end
|
44
52
|
|
53
|
+
def test_ecdsa_normalize
|
54
|
+
pk = PrivateKey.new
|
55
|
+
raw_sig = pk.ecdsa_sign 'hi'
|
56
|
+
|
57
|
+
had_to_normalize, normsig = pk.ecdsa_signature_normalize raw_sig
|
58
|
+
assert_equal false, had_to_normalize
|
59
|
+
assert_equal pk.ecdsa_serialize(raw_sig), pk.ecdsa_serialize(normsig)
|
60
|
+
assert_equal pk.ecdsa_serialize_compact(raw_sig), pk.ecdsa_serialize_compact(normsig)
|
61
|
+
|
62
|
+
had_to_normalize, normsig = pk.ecdsa_signature_normalize(raw_sig, check_only: true)
|
63
|
+
assert_equal false, had_to_normalize
|
64
|
+
assert_equal nil, normsig
|
65
|
+
|
66
|
+
sig = "\xAA" + "\xFF"*31 + "\xAA" + "\xFF"*31
|
67
|
+
raw_sig = pk.ecdsa_deserialize_compact sig
|
68
|
+
|
69
|
+
normalized, normsig = pk.ecdsa_signature_normalize raw_sig
|
70
|
+
assert_equal true, normalized
|
71
|
+
assert pk.ecdsa_serialize(raw_sig) != pk.ecdsa_serialize(normsig)
|
72
|
+
|
73
|
+
normalized, normsig = pk.ecdsa_signature_normalize raw_sig, check_only: true
|
74
|
+
assert_equal true, normalized
|
75
|
+
assert_equal nil, normsig
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_ecdsa_recover
|
79
|
+
pk = PrivateKey.new
|
80
|
+
unrelated = MyECDSA.new
|
81
|
+
|
82
|
+
recsig = pk.ecdsa_sign_recoverable 'hello'
|
83
|
+
pubkey = unrelated.ecdsa_recover 'hello', recsig
|
84
|
+
pubser = PublicKey.new(pubkey: pubkey).serialize
|
85
|
+
assert_equal pubser, pk.pubkey.serialize
|
86
|
+
|
87
|
+
recsig_ser = unrelated.ecdsa_recoverable_serialize recsig
|
88
|
+
recsig2 = unrelated.ecdsa_recoverable_deserialize *recsig_ser
|
89
|
+
pubkey2 = unrelated.ecdsa_recover 'hello', recsig2
|
90
|
+
pubser2 = PublicKey.new(pubkey: pubkey2).serialize
|
91
|
+
assert_equal pubser, pubser2
|
92
|
+
|
93
|
+
raw_sig = unrelated.ecdsa_recoverable_convert recsig2
|
94
|
+
unrelated.ecdsa_deserialize(unrelated.ecdsa_serialize(raw_sig))
|
95
|
+
end
|
96
|
+
|
45
97
|
private
|
46
98
|
|
47
99
|
def ecdsa_sig
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitcoin-secp256k1
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Xie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|