secp256k1zkp 0.9.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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