secp256k1zkp 0.9.0 → 0.9.6

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: 951b1330ba2ce304878210145ac200583994dad6
4
- data.tar.gz: ac91e14b4c07918be085d3d32f0df83cafae6f7e
3
+ metadata.gz: 303aa7af695c95b2547b94d982a7cf0c03475a2f
4
+ data.tar.gz: 7d23be044ed0ace606f30d8381884b40b004b299
5
5
  SHA512:
6
- metadata.gz: b150ff39fd63b32f55f324fc99abf20d336e961a7a2348dc5cf26527726a52a18dc7cb006eead9fae9533eb94c9d2f302532e2bc6e474a64424814e04010cff5
7
- data.tar.gz: 5b58160792d93e8b46b998e25e0de1773e73ee90c137f742c4ef76cf88ba7bc629e38e1aa0d6fbb6926b900477d02c439fb2dd279be96f8923768ae3afd51857
6
+ metadata.gz: e8a9763f9cfd0b3fa9fc878a7ba5420f8d78661f0affe1c084641e8fa2db01fd9469d5c03204473a3efd6c73b8b06e3537f63e51aba530e8b2c4e4ddefe8644c
7
+ data.tar.gz: 4a3e66737896497638c2fb98398171092bb12cf772d0287aaaab295a4b04fe7cf0bddfa4a724970cac1d4cc768c6de650b1908a4d79c4dbceb3fe177ddd06c31
@@ -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
  {
@@ -379,6 +385,7 @@ static VALUE dm_context_pedersen_blind_sum(VALUE self, VALUE blinds_in, VALUE no
379
385
  {
380
386
  rb_struct_context *context;
381
387
  long blinds_in_size;
388
+ long i;
382
389
  rb_struct_blind_factor_type result = {
383
390
  0,
384
391
  };
@@ -393,7 +400,7 @@ static VALUE dm_context_pedersen_blind_sum(VALUE self, VALUE blinds_in, VALUE no
393
400
  return Qnil;
394
401
  }
395
402
  const unsigned char *blinds[blinds_in_size];
396
- for (long i = 0; i < blinds_in_size; ++i)
403
+ for (i = 0; i < blinds_in_size; ++i)
397
404
  {
398
405
  VALUE blind_factor = rb_ary_entry(blinds_in, i);
399
406
  SafeStringValue(blind_factor);
@@ -707,7 +714,7 @@ void Init_secp256k1zkp()
707
714
  rb_define_method(rb_cSecp256k1Context, "is_valid_private_keydata?", dm_context_verify_private_keydata, 1);
708
715
  rb_define_method(rb_cSecp256k1Context, "clone", dm_context_clone, 0);
709
716
  rb_define_method(rb_cSecp256k1Context, "dup", dm_context_clone, 0);
710
- 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);
711
718
  rb_define_method(rb_cSecp256k1Context, "pedersen_commit", dm_context_pedersen_commit, 2);
712
719
  rb_define_method(rb_cSecp256k1Context, "pedersen_blind_sum", dm_context_pedersen_blind_sum, 2);
713
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,57 @@
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))
9
+ class << self
10
+
11
+ include Secp256k1Zkp::Utility
12
+
13
+ SECP256K1_CURVE_ORDER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
14
+
15
+ def nonce
16
+ # => 私钥有效范围。[1, SECP256K1_CURVE_ORDER)。 REMARK:大部分 lib 范围是 [1, SECP256K1_CURVE_ORDER] 的闭区间,该C库范围为开区间。
17
+ SecureRandom.random_number(SECP256K1_CURVE_ORDER - 1) + 1
18
+ end
19
+
20
+ def random
21
+ new(hex_decode("%064x" % self.nonce))
14
22
  end
15
23
 
16
- def shared_secret(public_key)
17
- return public_key * self.bytes
24
+ # => role - owner / active
25
+ def from_account_and_password(account, password, role = 'active')
26
+ return from_seed(format("%s%s%s", account, role, password))
18
27
  end
19
28
 
20
- def hex_encode(data)
21
- return data.unpack("H*").first.downcase
29
+ def from_seed(seed)
30
+ return new(sha256(seed))
22
31
  end
23
32
 
24
- def hex_decode(data)
25
- return [data].pack("H*")
33
+ def from_wif(wif_private_key_string)
34
+ raw = base58_decode(wif_private_key_string)
35
+ version = raw[0].unpack("C").first
36
+ raise 'invalid private key.' if version != 0x80
37
+ # => raw = [1B]0x80 + [32B]privatekey + [4B]checksum
38
+ checksum_size = 4
39
+ checksum4 = raw[-checksum_size..-1]
40
+ private_key_with_prefix = raw[0...-checksum_size]
41
+ digest = sha256(sha256(private_key_with_prefix))
42
+ raise 'invalid private key.' if checksum4 != digest[0, checksum_size]
43
+ return new(raw[1, 32])
26
44
  end
27
45
 
28
46
  end
47
+
48
+ def to_wif
49
+ private_key_with_prefix = 0x80.chr + self.bytes
50
+ checksum = sha256(sha256(private_key_with_prefix))[0, 4]
51
+ return base58_encode(private_key_with_prefix + checksum)
52
+ end
53
+
54
+ def shared_secret(public_key)
55
+ return public_key * self.bytes
56
+ end
29
57
 
30
58
  end
@@ -1,13 +1,41 @@
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
7
+ class << self
8
+
9
+ include Secp256k1Zkp::Utility
10
+
11
+ def from_wif(wif_public_key, public_key_prefix = 'BTS')
12
+ prefix_size = public_key_prefix.bytesize
13
+ prefix = wif_public_key[0, prefix_size]
14
+ raise 'invalid public key prefix.' if prefix != public_key_prefix
15
+
16
+ raw = base58_decode(wif_public_key[prefix_size..-1])
17
+ checksum_size = 4
18
+ compression_public_key = raw[0, raw.bytesize - checksum_size]
19
+ checksum4 = raw[-checksum_size..-1]
20
+ raise 'invalid public key.' if checksum4 != rmd160(compression_public_key)[0, checksum_size]
21
+ return new(compression_public_key)
9
22
  end
10
23
 
11
24
  end
12
25
 
26
+ def to_wif(public_key_prefix = 'BTS')
27
+ checksum = rmd160(self.bytes)
28
+ addr = self.bytes + checksum[0, 4]
29
+ return public_key_prefix + base58_encode(addr)
30
+ end
31
+
32
+ # => (public) 生成bts地址(序列化时公钥排序会用到。)
33
+ def to_blockchain_address
34
+ return rmd160(sha512(self.bytes))
35
+ end
36
+
37
+ def shared_secret(private_key)
38
+ return self * private_key.bytes
39
+ end
40
+
13
41
  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.0'.freeze
5
+ VERSION = '0.9.6'.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.0
4
+ version: 0.9.6
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-22 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:
@@ -68,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
82
  requirements:
69
83
  - - ">="
70
84
  - !ruby/object:Gem::Version
71
- version: '0'
85
+ version: 2.3.0
72
86
  required_rubygems_version: !ruby/object:Gem::Requirement
73
87
  requirements:
74
88
  - - ">="
@@ -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