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 +4 -4
- data/ext/secp256k1zkp/secp256k1zkp.c +13 -6
- data/lib/secp256k1zkp.rb +1 -1
- data/lib/secp256k1zkp/private_key.rb +41 -13
- data/lib/secp256k1zkp/public_key.rb +32 -4
- data/lib/secp256k1zkp/utility.rb +60 -0
- data/lib/secp256k1zkp/version.rb +1 -1
- metadata +18 -4
- data/lib/secp256k1zkp/utils.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 303aa7af695c95b2547b94d982a7cf0c03475a2f
|
4
|
+
data.tar.gz: 7d23be044ed0ace606f30d8381884b40b004b299
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
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 =
|
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 (
|
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,
|
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);
|
data/lib/secp256k1zkp.rb
CHANGED
@@ -2,29 +2,57 @@
|
|
2
2
|
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
|
-
|
5
|
+
class Secp256k1Zkp::PrivateKey
|
6
6
|
|
7
|
-
|
7
|
+
include Secp256k1Zkp::Utility
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
17
|
-
|
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
|
21
|
-
return
|
29
|
+
def from_seed(seed)
|
30
|
+
return new(sha256(seed))
|
22
31
|
end
|
23
32
|
|
24
|
-
def
|
25
|
-
|
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
|
-
|
3
|
+
class Secp256k1Zkp::PublicKey
|
4
4
|
|
5
|
-
|
5
|
+
include Secp256k1Zkp::Utility
|
6
6
|
|
7
|
-
|
8
|
-
|
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
|
data/lib/secp256k1zkp/version.rb
CHANGED
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.
|
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-
|
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/
|
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:
|
85
|
+
version: 2.3.0
|
72
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
87
|
requirements:
|
74
88
|
- - ">="
|
data/lib/secp256k1zkp/utils.rb
DELETED
@@ -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
|