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 +4 -4
- data/ext/secp256k1zkp/secp256k1zkp.c +11 -5
- data/lib/secp256k1zkp.rb +1 -1
- data/lib/secp256k1zkp/private_key.rb +39 -17
- data/lib/secp256k1zkp/public_key.rb +27 -5
- data/lib/secp256k1zkp/utility.rb +60 -0
- data/lib/secp256k1zkp/version.rb +1 -1
- metadata +17 -3
- 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: 6f9f439836bf01ac6f1b0ac87ffe86d574fb0940
|
4
|
+
data.tar.gz: e4aa8985dd05aa5be9cb5defa141876ad21aaf10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
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
|
{
|
@@ -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,
|
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);
|
data/lib/secp256k1zkp.rb
CHANGED
@@ -2,29 +2,51 @@
|
|
2
2
|
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
|
-
|
5
|
+
class Secp256k1Zkp::PrivateKey
|
6
6
|
|
7
|
-
|
7
|
+
include Secp256k1Zkp::Utility
|
8
8
|
|
9
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
16
|
+
def self.random
|
17
|
+
new(hex_decode("%064x" % self.nonce))
|
18
|
+
end
|
23
19
|
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
3
|
+
class Secp256k1Zkp::PublicKey
|
4
4
|
|
5
|
-
|
5
|
+
include Secp256k1Zkp::Utility
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
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.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-
|
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/
|
70
|
+
- lib/secp256k1zkp/utility.rb
|
57
71
|
- lib/secp256k1zkp/version.rb
|
58
72
|
homepage: https://github.com/jokenshi/ruby-secp256zkp.git
|
59
73
|
licenses:
|
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
|