secp256k1zkp 0.9.2 → 0.9.4

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: 90d4e882b70ea376377b9388e8c1020e06fbb696
4
- data.tar.gz: 36d462d75514cf76ac8a366d4bbdcc7838e706f0
3
+ metadata.gz: 6f9f439836bf01ac6f1b0ac87ffe86d574fb0940
4
+ data.tar.gz: e4aa8985dd05aa5be9cb5defa141876ad21aaf10
5
5
  SHA512:
6
- metadata.gz: fe741e6e78fd7fcb300e37725bc8b9ac3320b44e85af75ee8438cec203947bae476d8e5ba145c2dba4608684baceb8e8d043efd48f22892e86dca2fb503c269f
7
- data.tar.gz: 4b6990004b8888bf9ae57accded553c75338c9d7096f4d63210fad622f9eb03e75de4c78cca3a1dab2e0ca232bfe6565f7c1b9c8aa19b359c4b57046abac5c19
6
+ metadata.gz: becdcd95251016ab442147136c8ceb95d98a66395a96357e4311acb28428f8e85df084b28c18ea4bb8c88bc234b1adead3963b3ac7fba964744a8876b183f58f
7
+ data.tar.gz: f1cf4ed558e7017f36427b1571918ae788c94a7885d2526c2f46b1ccc0bb7237f688449b318e53761f541347eb7649246134232869b3564a13ba547fb04bd5ff
@@ -265,7 +265,7 @@ static int is_canonical(const rb_struct_compact_signature *sign)
265
265
  }
266
266
 
267
267
  /**
268
- * Secp256k1Zkp::Context#sign_compact(message_digest, private_key)
268
+ * Secp256k1Zkp::Context#sign_compact(message_digest, private_key[, require_canonical = true])
269
269
  *
270
270
  * 生成紧凑格式的 ECDSA 签名(recId + 64字节)。
271
271
  *
@@ -273,8 +273,9 @@ static int is_canonical(const rb_struct_compact_signature *sign)
273
273
  * @param private_key [Secp256k1Zkp::PrivateKey] 私钥。
274
274
  * @return [String]
275
275
  */
276
- static VALUE dm_context_sign_compact(VALUE self, VALUE message_digest, VALUE private_key)
276
+ static VALUE dm_context_sign_compact(int argc, VALUE *argv, VALUE self)
277
277
  {
278
+ VALUE message_digest, private_key, v_require_canonical;
278
279
  rb_struct_context *context;
279
280
  rb_struct_private_key *sp_private_key;
280
281
  const unsigned char *digest32;
@@ -285,6 +286,11 @@ static VALUE dm_context_sign_compact(VALUE self, VALUE message_digest, VALUE pri
285
286
  0,
286
287
  };
287
288
 
289
+ if (2 == rb_scan_args(argc, argv, "21", &message_digest, &private_key, &v_require_canonical))
290
+ {
291
+ v_require_canonical = Qtrue;
292
+ }
293
+
288
294
  SafeStringValue(message_digest);
289
295
  if (RSTRING_LEN(message_digest) != kByteSizeSha256)
290
296
  {
@@ -304,9 +310,9 @@ static VALUE dm_context_sign_compact(VALUE self, VALUE message_digest, VALUE pri
304
310
 
305
311
  // 初始化部分参数
306
312
  digest32 = (const unsigned char *)RSTRING_PTR(message_digest);
307
- require_canonical = 0; // 0 or 1
313
+ require_canonical = RTEST(v_require_canonical) ? 1 : 0;
308
314
  counter = 0;
309
-
315
+
310
316
  // 循环计算签名,直到找到合适的 canonical 签名。
311
317
  do
312
318
  {
@@ -708,7 +714,7 @@ void Init_secp256k1zkp()
708
714
  rb_define_method(rb_cSecp256k1Context, "is_valid_private_keydata?", dm_context_verify_private_keydata, 1);
709
715
  rb_define_method(rb_cSecp256k1Context, "clone", dm_context_clone, 0);
710
716
  rb_define_method(rb_cSecp256k1Context, "dup", dm_context_clone, 0);
711
- rb_define_method(rb_cSecp256k1Context, "sign_compact", dm_context_sign_compact, 2);
717
+ rb_define_method(rb_cSecp256k1Context, "sign_compact", dm_context_sign_compact, -1);
712
718
  rb_define_method(rb_cSecp256k1Context, "pedersen_commit", dm_context_pedersen_commit, 2);
713
719
  rb_define_method(rb_cSecp256k1Context, "pedersen_blind_sum", dm_context_pedersen_blind_sum, 2);
714
720
  rb_define_method(rb_cSecp256k1Context, "range_proof_sign", dm_context_range_proof_sign, 7);
@@ -5,7 +5,7 @@ end
5
5
 
6
6
  require 'secp256k1zkp/secp256k1zkp'
7
7
  require 'secp256k1zkp/version'
8
- require 'secp256k1zkp/utils'
8
+ require 'secp256k1zkp/utility'
9
9
  require 'secp256k1zkp/context'
10
10
  require 'secp256k1zkp/public_key'
11
11
  require 'secp256k1zkp/private_key'
@@ -2,29 +2,51 @@
2
2
 
3
3
  require 'securerandom'
4
4
 
5
- module Secp256k1Zkp
5
+ class Secp256k1Zkp::PrivateKey
6
6
 
7
- class PrivateKey
7
+ include Secp256k1Zkp::Utility
8
8
 
9
- def self.random
10
- # # => REMARK:私钥有效范围。[1, secp256k1 curve order)。REMARK:大部分 lib 范围是 [1, secp256k1 curve order] 的闭区间,c库范围为开区间。
11
- # sec = SecureRandom.random_number(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - 1) + 1
12
- # new(hex_decode("%064x" % sec))
13
- new(SecureRandom.random_bytes(32))
14
- end
9
+ SECP256K1_CURVE_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
15
10
 
16
- def shared_secret(public_key)
17
- return public_key * self.bytes
18
- end
11
+ def self.nonce
12
+ # => 私钥有效范围。[1, SECP256K1_CURVE_ORDER)。 REMARK:大部分 lib 范围是 [1, SECP256K1_CURVE_ORDER] 的闭区间,该C库范围为开区间。
13
+ SecureRandom.random_number(SECP256K1_CURVE_ORDER - 1) + 1
14
+ end
19
15
 
20
- def hex_encode(data)
21
- return data.unpack("H*").first.downcase
22
- end
16
+ def self.random
17
+ new(hex_decode("%064x" % self.nonce))
18
+ end
23
19
 
24
- def hex_decode(data)
25
- return [data].pack("H*")
26
- end
20
+ # => role - owner / active
21
+ def self.from_account_and_password(account, password, role = 'active')
22
+ return from_seed(format("%s%s%s", account, role, password))
23
+ end
24
+
25
+ def self.from_seed(seed)
26
+ return new(sha256(seed))
27
+ end
28
+
29
+ def self.from_wif(wif_private_key_string)
30
+ raw = base58_decode(wif_private_key_string)
31
+ version = raw[0].unpack("C").first
32
+ raise 'invalid private key.' if version != 0x80
33
+ # => raw = [1B]0x80 + [32B]privatekey + [4B]checksum
34
+ checksum_size = 4
35
+ checksum4 = raw[-checksum_size..-1]
36
+ private_key_with_prefix = raw[0...-checksum_size]
37
+ digest = sha256(sha256(private_key_with_prefix))
38
+ raise 'invalid private key.' if checksum4 != digest[0, checksum_size]
39
+ return new(raw[1, 32])
40
+ end
41
+
42
+ def to_wif
43
+ private_key_with_prefix = 0x80.chr + self.bytes
44
+ checksum = sha256(sha256(private_key_with_prefix))[0, 4]
45
+ return base58_encode(private_key_with_prefix + checksum)
46
+ end
27
47
 
48
+ def shared_secret(public_key)
49
+ return public_key * self.bytes
28
50
  end
29
51
 
30
52
  end
@@ -1,13 +1,35 @@
1
1
  #encoding:utf-8
2
2
 
3
- module Secp256k1Zkp
3
+ class Secp256k1Zkp::PublicKey
4
4
 
5
- class PublicKey
5
+ include Secp256k1Zkp::Utility
6
6
 
7
- def shared_secret(private_key)
8
- return self * private_key.bytes
9
- end
7
+ def self.from_wif(wif_public_key, public_key_prefix = 'BTS')
8
+ prefix_size = public_key_prefix.bytesize
9
+ prefix = wif_public_key[0, prefix_size]
10
+ raise 'invalid public key prefix.' if prefix != public_key_prefix
10
11
 
12
+ raw = base58_decode(wif_public_key[prefix_size..-1])
13
+ checksum_size = 4
14
+ compression_public_key = raw[0, raw.bytesize - checksum_size]
15
+ checksum4 = raw[-checksum_size..-1]
16
+ raise 'invalid public key.' if checksum4 != rmd160(compression_public_key)[0, checksum_size]
17
+ return new(compression_public_key)
18
+ end
19
+
20
+ def to_wif(public_key_prefix = 'BTS')
21
+ checksum = rmd160(self.bytes)
22
+ addr = self.bytes + checksum[0, 4]
23
+ return public_key_prefix + base58_encode(addr)
24
+ end
25
+
26
+ # => (public) 生成bts地址(序列化时公钥排序会用到。)
27
+ def to_blockchain_address
28
+ return rmd160(sha512(self.bytes))
29
+ end
30
+
31
+ def shared_secret(private_key)
32
+ return self * private_key.bytes
11
33
  end
12
34
 
13
35
  end
@@ -0,0 +1,60 @@
1
+ #encoding:utf-8
2
+
3
+ require 'digest'
4
+ require 'base58'
5
+
6
+ module Secp256k1Zkp
7
+
8
+ module Utility
9
+
10
+ def md5(data, raw = true)
11
+ if raw
12
+ return Digest::MD5.digest(data)
13
+ else
14
+ return Digest::MD5.hexdigest(data)
15
+ end
16
+ end
17
+
18
+ def sha256(data, raw = true)
19
+ if raw
20
+ return Digest::SHA256.digest(data)
21
+ else
22
+ return Digest::SHA256.hexdigest(data)
23
+ end
24
+ end
25
+
26
+ def sha512(data, raw = true)
27
+ if raw
28
+ return Digest::SHA512.digest(data)
29
+ else
30
+ return Digest::SHA512.hexdigest(data)
31
+ end
32
+ end
33
+
34
+ def rmd160(data, raw = true)
35
+ if raw
36
+ return Digest::RMD160.digest(data)
37
+ else
38
+ return Digest::RMD160.hexdigest(data)
39
+ end
40
+ end
41
+
42
+ def hex_encode(data)
43
+ return data.unpack("H*").first.downcase
44
+ end
45
+
46
+ def hex_decode(data)
47
+ return [data].pack("H*")
48
+ end
49
+
50
+ def base58_encode(str, alphabet = :bitcoin)
51
+ Base58.binary_to_base58(str.force_encoding('BINARY'), alphabet)
52
+ end
53
+
54
+ def base58_decode(base58_str, alphabet = :bitcoin)
55
+ Base58.base58_to_binary(base58_str, alphabet)
56
+ end
57
+
58
+ end
59
+
60
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Secp256k1Zkp
4
4
 
5
- VERSION = '0.9.2'.freeze
5
+ VERSION = '0.9.4'.freeze
6
6
 
7
7
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secp256k1zkp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - jokenshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-17 00:00:00.000000000 Z
11
+ date: 2020-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base58
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.3
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: mini_portile2
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,7 +67,7 @@ files:
53
67
  - lib/secp256k1zkp/context.rb
54
68
  - lib/secp256k1zkp/private_key.rb
55
69
  - lib/secp256k1zkp/public_key.rb
56
- - lib/secp256k1zkp/utils.rb
70
+ - lib/secp256k1zkp/utility.rb
57
71
  - lib/secp256k1zkp/version.rb
58
72
  homepage: https://github.com/jokenshi/ruby-secp256zkp.git
59
73
  licenses:
@@ -1,20 +0,0 @@
1
- #encoding:utf-8
2
-
3
- require 'digest'
4
-
5
- module Secp256k1Zkp
6
-
7
- module Utils
8
-
9
- module_function
10
-
11
- #------------------------------------------------------------------------
12
- # ● 计算sha1
13
- #------------------------------------------------------------------------
14
- def sha1(str)
15
- return Digest::SHA1.hexdigest(str)
16
- end
17
-
18
- end
19
-
20
- end