sr25519 0.4.0 → 0.8.0

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
  SHA256:
3
- metadata.gz: 4410fbe296d51933ad70ac7d650dc3f284415679a202bbd31a8b241ecc197aa5
4
- data.tar.gz: 240b6a8ded57e70fb19ff1a9cb827feea667db6b8f94043a1df3e36f3c475f3f
3
+ metadata.gz: f850eb36c7764e13d17631a64774c526e4358d6943d22148e8fe73ef3dc4fba1
4
+ data.tar.gz: 23599472953b497a43cd86b4f3352315bb5b5fca9b8ee26fead4c8f3ee50a672
5
5
  SHA512:
6
- metadata.gz: dfb7ca72c9d855583601be1a6dd6aafa49b1ff79bf372dcf52a65d848b4ee708263dd2644570d6fbc14f20dbea98c75721c03c42c40330f51c67972039ce0367
7
- data.tar.gz: ab2ecfcc66ea295b22fd933edaadeae188801ca0d18b856351eead3ae30fa0c511f5cd29184926e79d7ce440e189693fc9928ad049899d1386f040a899d8c6e2
6
+ metadata.gz: 868da7d03a1d747a65d093704c160f37e61714aa273f186da73ed38587ccd08bbfbc20df40e2d6344ee2d305a2f83f7d6e1876fe4ed5433dd60faf8ec53a5962
7
+ data.tar.gz: 97679a83b7680568aaf8a709ce165fd24af6e048e114b4a43b75c06971abf5eedbfb2ac0aa717e3ac50f4df9c3cdc8440149ac08b75f9f7f835eaed6262ca4bd
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sr25519 (0.4.0)
4
+ sr25519 (0.8.0)
5
5
  base58
6
6
  blake2b
7
+ ed25519 (~> 1.2, >= 1.2.4)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -11,6 +12,7 @@ GEM
11
12
  base58 (0.2.3)
12
13
  blake2b (0.10.0)
13
14
  diff-lcs (1.4.4)
15
+ ed25519 (1.2.4)
14
16
  ffi (1.15.4)
15
17
  rake (13.0.6)
16
18
  rspec (3.10.0)
data/README.md CHANGED
@@ -22,21 +22,21 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- 1. Require ed25519.rb in your Ruby program:
25
+ #### 1. Require ed25519.rb in your Ruby program:
26
26
  ```ruby
27
27
  require "sr25519"
28
28
  ```
29
29
 
30
- 2. Generate keypair
30
+ #### 2. SR25519 Generate keypair
31
31
 
32
32
  ```ruby
33
33
  # seed is priviate key, is a hex string.
34
- # example: SR25519.sr25519_keypair_from_seed("0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e")
35
- keypaire = SR25519.sr25519_keypair_from_seed(seed)
34
+ # example: SR25519.keypair_from_seed("0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e")
35
+ keypair = SR25519.keypair_from_seed(seed)
36
36
 
37
37
  ```
38
38
 
39
- 3. Generate public_key
39
+ #### 3. SR25519 Generate public_key
40
40
 
41
41
  ```ruby
42
42
  public_key = SR25519.get_public_key_from_seed(seed)
@@ -46,30 +46,58 @@ public_key_str = public_key.to_s
46
46
 
47
47
  ```
48
48
 
49
- 4. Encode address
49
+ #### 4. Encode address
50
50
  ```ruby
51
51
  address = Address.encode(public_key.to_s)
52
52
  ```
53
53
 
54
- 5. Decode address
54
+ #### 5. Decode address
55
55
 
56
56
  ```ruby
57
- address = Address.decode(address)
57
+ public_key_str = Address.decode(address)
58
58
  ```
59
59
 
60
- 6. Sign message
60
+ #### 6. SR25519 Sign message
61
61
 
62
62
  ```ruby
63
+ # message = "Hello World"
63
64
  signature_result = SR25519.sign(message, keypair)
64
65
 
65
66
  ```
66
67
 
67
- 7. Verify message
68
+ #### 7. SR25519 Verify message
68
69
 
69
70
  ```ruby
70
- SR25519.verify(address, message, signature_result)
71
+ verify_result = SR25519.verify(address, message, signature_result)
71
72
  ```
72
73
 
74
+ #### 8. ED25519 Generate keypair
75
+
76
+ ```ruby
77
+ keypair = ED25519.keypair_from_seed(seed)
78
+ ```
79
+
80
+ #### 9. ED25519 Sign message
81
+
82
+ ```ruby
83
+ signature_result = ED25519.sign(message, keypair)
84
+ ```
85
+
86
+ #### 10. ED25519 Get public key
87
+
88
+ ```ruby
89
+ pulick_key_str = ED25519.get_public_key_from_seed(seed)
90
+ ```
91
+
92
+ #### 11. ED25519 Verify message
93
+
94
+ ```ruby
95
+ # public_key_str = ED25519.get_public_key_from_seed(seed)
96
+ # address = Address.encode(public_key_str)
97
+ verify_result = ED25519.verify(address, message, signature_result)
98
+ ```
99
+
100
+
73
101
  ## Running tests
74
102
  1. Run all tests
75
103
 
data/lib/address.rb CHANGED
@@ -1,7 +1,30 @@
1
+
2
+ # The MIT License (MIT)
3
+
4
+ # Copyright (c) 2019 Wu Minzhe
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
1
24
  require 'base58'
2
25
  require 'blake2b'
3
26
 
4
- # The code is copy from https://github.com/itering/scale.rb/blob/develop/lib/common.rb
27
+ # The code is copy from https://github.com/itering/scale.rb/blob/develop/lib/common.rb
5
28
  class Address
6
29
  SS58_PREFIX = 'SS58PRE'
7
30
 
@@ -0,0 +1,77 @@
1
+ require "ed25519"
2
+ class ED25519
3
+
4
+ # Sign the given message
5
+ # @param message [String] the message
6
+ # @param key_pair [Class] ED25519 keypair
7
+ # @return [String] sign result as a hex string
8
+ # @example
9
+ # message = "Hello world"
10
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
11
+ # keypair = ED25519.keypair_from_seed(seed)
12
+ # signature_result = ED25519.sign(message, keypair)
13
+
14
+ def self.sign(message, key_pair)
15
+ "0x" + key_pair.sign(message).unpack1("H*")
16
+ end
17
+
18
+ ##
19
+ # Verify the sign result
20
+ # @param message [String] the message
21
+ # @param key_pair [Class] ED25519 keypair
22
+ # @return [String] sign result as a hex string
23
+ # @example
24
+ # message = "Hello world"
25
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
26
+ # public_key = ED25519.get_public_key_from_seed(seed)
27
+ # address = Address.encode(public_key)
28
+ # keypair = ED25519.keypair_from_seed(seed)
29
+ # signature_result = ED25519.sign(message, keypair)
30
+ # verify_result = ED25519.verify(address, message, signature_result)
31
+
32
+ def self.verify(address, message, signature_result)
33
+ if signature_result.start_with?("0x")
34
+ signature_result = signature_result.sub(/0x/, "")
35
+ end
36
+ signature = [signature_result].pack("H*")
37
+ public_key = Address.decode(address)
38
+ verify_key_bytes = [public_key].pack("H*")
39
+ verify_key = Ed25519::VerifyKey.new(verify_key_bytes)
40
+ begin
41
+ verify_key.verify(signature, message)
42
+ rescue
43
+ return false
44
+ end
45
+ end
46
+
47
+ ##
48
+ # Generate ED25519 keypair
49
+ # @param seed [String] private key
50
+ # @return [Class] ED25519 keypair
51
+ # @example
52
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
53
+ # keypair = ED25519.keypair_from_seed(seed)
54
+
55
+ def self.keypair_from_seed(seed)
56
+ if seed.start_with?("0x")
57
+ seed = seed.sub(/0x/, "")
58
+ end
59
+ seed = "".tap { |binary| seed.scan(/../) { |hn| binary << hn.to_i(16).chr } }
60
+ signing_key = Ed25519::SigningKey.new(seed)
61
+ return signing_key
62
+ end
63
+
64
+ ##
65
+ # Get ED25519 public key
66
+ # @param seed [String] private key
67
+ # @return [String] public key
68
+ # @example
69
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
70
+ # public_key = ED25519.get_public_key_from_seed(seed)
71
+
72
+ def self.get_public_key_from_seed(seed)
73
+ signing_key = self.keypair_from_seed(seed)
74
+ return signing_key.verify_key.to_bytes.unpack1('H*')
75
+ end
76
+
77
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sr25519
4
- VERSION = "0.4.0"
4
+ VERSION = "0.8.0"
5
5
  end
data/lib/sr25519.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require_relative "sr25519/version"
4
4
  require "address"
5
5
  require "sr25519_lib"
6
+ require "ed25519_lib"
6
7
 
7
8
  module Sr25519
8
9
  class Error < StandardError; end
data/lib/sr25519_lib.rb CHANGED
@@ -5,7 +5,6 @@ module SR25519Lib
5
5
 
6
6
  ffi_lib FFI::Library::LIBC
7
7
 
8
- # The library is compile from https://github.com/Warchant/sr25519-crust
9
8
  ffi_lib File.dirname(__FILE__) + '/libsr25519crust.so' if RUBY_PLATFORM =~ /linux/
10
9
  ffi_lib File.dirname(__FILE__) + '/libsr25519crust.dylib' if RUBY_PLATFORM =~ /darwin/
11
10
 
@@ -19,6 +18,8 @@ class KeyPair < FFI::Struct
19
18
  # [32b key | 32b nonce | 32b public]
20
19
  layout :String, [:uint8, 96]
21
20
 
21
+ ##
22
+ # Return the keypair public key
22
23
  def public_key
23
24
  pub_key = self[:String].to_a[64..96]
24
25
  public_key = PublicKey.new
@@ -55,6 +56,8 @@ end
55
56
  class SigMessage < FFI::Struct
56
57
  layout :String, [:uint8, 64]
57
58
 
59
+ ##
60
+ # Return the sign message as hex string
58
61
  def to_s
59
62
  self[:String].to_a.pack("c*").unpack1("H*")
60
63
  end
@@ -62,17 +65,32 @@ end
62
65
 
63
66
  class SR25519
64
67
 
68
+ # Sign message result
69
+ # @param message [String] message
70
+ # @param private_key [String] private_key
71
+ # @return [String] sign result
72
+ # @example
73
+ # message = "Hello World"
74
+ # private_key = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
75
+ # signature_result = SR25519.sr25519_sign(message, private_key)
65
76
  def self.sr25519_sign(message, private_key)
66
77
  sig = SigMessage.new
67
78
  msg = FFI::MemoryPointer.from_string(message)
68
- key_pair = self.sr25519_keypair_from_seed(private_key)
79
+ key_pair = self.keypair_from_seed(private_key)
69
80
  public_key = key_pair.public_key
70
81
  SR25519Lib.sr25519_sign(sig, public_key, key_pair, msg, message.length)
71
82
  sig.to_s
72
83
  end
73
84
 
74
-
75
- # Creates a signature for given data
85
+ # Sign message result
86
+ # @param message [String] message
87
+ # @param key_pair [KeyPair] Sr25519 keypair
88
+ # @return [String] sign result
89
+ # @example
90
+ # message = "Hello World"
91
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
92
+ # keypair = SR25519.keypair_from_seed(seed)
93
+ # signature_result = SR25519.sign(message, keypair)
76
94
  def self.sign(message, key_pair)
77
95
  sig = SigMessage.new
78
96
  msg = FFI::MemoryPointer.from_string(message)
@@ -81,6 +99,19 @@ class SR25519
81
99
  sig.to_s
82
100
  end
83
101
 
102
+ # Verify the sign result
103
+ # @param address [String] account address
104
+ # @param message [String] message
105
+ # @param signature_result [String] Sr25519 sign result
106
+ # @return [boolean] sign result
107
+ # @example
108
+ # message = "Hello World"
109
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
110
+ # keypair = SR25519.keypair_from_seed(seed)
111
+ # public_key = SR25519.get_public_key_from_seed(seed)
112
+ # address = Address.encode(public_key.to_s)
113
+ # signature_result = SR25519.sign(message, keypair)
114
+ # verify_result = SR25519.verify(address, message, signature_result)
84
115
  def self.verify(address, message, signature_result)
85
116
  pk = PublicKey.new
86
117
  public_key = self.decode_address(address)
@@ -97,7 +128,13 @@ class SR25519
97
128
  verify = SR25519Lib.sr25519_verify(sig, msg, message.size, pk)
98
129
  end
99
130
 
100
- def self.sr25519_keypair_from_seed(seed)
131
+ # Generate SR25519 keypair
132
+ # @param seed [String] private key
133
+ # @return [KeyPair] SR25519 keypair
134
+ # @example
135
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
136
+ # keypair = SR25519.keypair_from_seed(seed)
137
+ def self.keypair_from_seed(seed)
101
138
  if seed.start_with?("0x")
102
139
  seed = seed.sub(/0x/, "")
103
140
  end
@@ -109,11 +146,26 @@ class SR25519
109
146
  return key_pair
110
147
  end
111
148
 
149
+ # Get SR25519 public key
150
+ # @param seed [String] private key
151
+ # @return [String] public key
152
+ # @example
153
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
154
+ # public_key = SR25519.get_public_key_from_seed(seed)
112
155
  def self.get_public_key_from_seed(seed)
113
- key_pair = self.sr25519_keypair_from_seed(seed)
156
+ key_pair = self.keypair_from_seed(seed)
114
157
  key_pair.public_key
115
158
  end
116
159
 
160
+ # Get SR25519 public key
161
+ # @param address [String] account address
162
+ # @param addr_type [Interger] address type
163
+ # @return [String] public key
164
+ # @example
165
+ # seed = "0xfac7959dbfe72f052e5a0c3c8d6530f202b02fd8f9f5ca3580ec8deb7797479e"
166
+ # public_key = SR25519.get_public_key_from_seed(seed)
167
+ # address = Address.encode(public_key.to_s)
168
+ # public_key = SR25519.decode_address(address)
117
169
  def self.decode_address(address,addr_type=42)
118
170
  public_address = Address.decode(address,addr_type)
119
171
  end
data/sr25519.gemspec CHANGED
@@ -28,11 +28,14 @@ Gem::Specification.new do |spec|
28
28
  spec.bindir = "exe"
29
29
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
+ spec.extra_rdoc_files = [
32
+ "README.md"
33
+ ]
31
34
 
32
35
  spec.add_development_dependency "rake", "~> 13.0"
33
36
  spec.add_development_dependency "rspec", "~> 3.2"
34
37
  spec.add_dependency "blake2b"
35
38
  spec.add_dependency "base58"
36
39
  spec.add_development_dependency "ffi", "~> 1.15.0"
37
-
40
+ spec.add_dependency "ed25519", '~> 1.2', '>= 1.2.4'
38
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sr25519
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - xuxh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-12 00:00:00.000000000 Z
11
+ date: 2021-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -80,12 +80,33 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.15.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: ed25519
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.2'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.2.4
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.2'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.2.4
83
103
  description: Sign and verify message with sr25519
84
104
  email:
85
105
  - xxh2611@gmail.com
86
106
  executables: []
87
107
  extensions: []
88
- extra_rdoc_files: []
108
+ extra_rdoc_files:
109
+ - README.md
89
110
  files:
90
111
  - ".github/workflows/ruby.yml"
91
112
  - ".gitignore"
@@ -100,6 +121,7 @@ files:
100
121
  - bin/console
101
122
  - bin/setup
102
123
  - lib/address.rb
124
+ - lib/ed25519_lib.rb
103
125
  - lib/libsr25519crust.dylib
104
126
  - lib/libsr25519crust.so
105
127
  - lib/sr25519.rb