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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 07e0b24c6a5eff2bebfa1287f30299e3e20516a9
4
- data.tar.gz: 64b92f4a1274272b62a2b4f8447f7f97b3726e05
3
+ metadata.gz: 35c4817fc53d1512f07b574c444ac2ff39d723b7
4
+ data.tar.gz: 2c0acf62b066d43caf45ba96530b330ef8db2927
5
5
  SHA512:
6
- metadata.gz: f4123386a3b2add1c25e711eae40013a418fad7d614f0283caa0f5f8e961889de623be103b023035d441d42d4823b964ea129218d857ad66c722560b29f910f1
7
- data.tar.gz: 45abd20b35e91cbf4ac5b33fa3b472a32383f140426edce77eabab58180f39ea9afc4e63b85f4cfc6a59f257e6e1dfe6ed8bca1ac3199e8239dedae860ada7bb
6
+ metadata.gz: 4f831335807714f0cbd888e0adf8846293a3187ab7bde70306d61dce530947ab192b01770f6cfd43a1185c35417493c951af5dd08eb69ab8d63efc769f73d44f
7
+ data.tar.gz: 9e9b0e898a4db87c076921fbc50a4614ed411e2505a218d28380d8afc2ba18a261faa20ec84186c010376d4c2c28e87eb833b9fdab0c33f4ff5a82e0f82472eb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bitcoin-secp256k1 (0.1.1)
4
+ bitcoin-secp256k1 (0.2.0)
5
5
  ffi (>= 1.9.10)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -17,7 +17,7 @@ git submodule update --init --recursive
17
17
  gem i bitcoin-secp256k1
18
18
  ```
19
19
 
20
- Then require 'secp256k1' (without `bitcoin-` prefix) in your source code.
20
+ Then `require 'secp256k1'` (without `bitcoin-` prefix) in your source code.
21
21
 
22
22
  ## Usage
23
23
 
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
@@ -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 = FFI::MemoryPointer.new :byte, C::ECDSARecoverableSignature, false
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
@@ -1,3 +1,3 @@
1
1
  module Secp256k1
2
- VERSION = '0.1.1'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -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.1.1
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-24 00:00:00.000000000 Z
11
+ date: 2016-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi