bech32 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/.travis.yml +7 -5
- data/README.md +9 -3
- data/bech32.gemspec +1 -1
- data/lib/bech32.rb +30 -14
- data/lib/bech32/segwit_addr.rb +4 -2
- data/lib/bech32/version.rb +1 -1
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 975a0d606b86cdb7487afad52363ef284de471f1530cf7614b0a7db0728dc937
|
4
|
+
data.tar.gz: 1e3d9f3f389cbfd94a8af919a0ec842395605649138bdf3860ac9db2617e3939
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab8fdc36df45376ea1ec0e7d7553fb6309900d8db824998f327dbfe670451a00ec240bbd75fe59e1bdda2590981d174e0be086756e919582dad55ce5441fe5fb
|
7
|
+
data.tar.gz: 07bf7ac092a89c997932d380a57f30916baa809fd3adf2c86b7418e599949be6fc593b226bcdb7240247fde19d7f092ebdcdd82bfce154adde9d16b5de2df68e
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
ruby-3.0.0
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
# Bech32 [![Build Status](https://travis-ci.org/azuchi/bech32rb.svg?branch=master)](https://travis-ci.org/azuchi/bech32rb) [![Gem Version](https://badge.fury.io/rb/bech32.svg)](https://badge.fury.io/rb/bech32) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) <img src="http://segwit.co/static/public/images/logo.png" width="100">
|
2
2
|
|
3
|
-
The implementation of the Bech32 encoder and decoder for Ruby.
|
3
|
+
The implementation of the Bech32/Bech32m encoder and decoder for Ruby.
|
4
4
|
|
5
5
|
Bech32 is checksummed base32 format that is used in following Bitcoin address format.
|
6
6
|
|
7
7
|
https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
|
8
8
|
|
9
|
+
Bech32m is checksummed base32m format that is used in following Bitcoin address format.
|
10
|
+
|
11
|
+
https://github.com/bitcoin/bips/blob/master/bip-0350.mediawiki
|
12
|
+
|
9
13
|
## Installation
|
10
14
|
|
11
15
|
Add this line to your application's Gemfile:
|
@@ -35,13 +39,15 @@ require 'bech32'
|
|
35
39
|
Decode Bech32-encoded data into hrp part and data part.
|
36
40
|
|
37
41
|
```ruby
|
38
|
-
hrp, data = Bech32.decode('BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4')
|
42
|
+
hrp, data, spec = Bech32.decode('BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4')
|
39
43
|
|
40
44
|
# hrp is human-readable part of Bech32 format
|
41
45
|
'bc'
|
42
46
|
|
43
47
|
# data is data part of Bech32 format
|
44
48
|
[0, 14, 20, 15, 7, 13, 26, 0, 25, 18, 6, 11, 13, 8, 21, 4, 20, 3, 17, 2, 29, 3, 12, 29, 3, 4, 15, 24, 20, 6, 14, 30, 22]
|
49
|
+
|
50
|
+
# spec is whether Bech32::Encoding::BECH32 or Bech32::Encoding::BECH32M
|
45
51
|
```
|
46
52
|
|
47
53
|
Decode Bech32-encoded Segwit address into `Bech32::SegwitAddr` instance.
|
@@ -77,7 +83,7 @@ Encode Bech32 human-readable part and data part into Bech32 string.
|
|
77
83
|
hrp = 'bc'
|
78
84
|
data = [0, 14, 20, 15, 7, 13, 26, 0, 25, 18, 6, 11, 13, 8, 21, 4, 20, 3, 17, 2, 29, 3, 12, 29, 3, 4, 15, 24, 20, 6, 14, 30, 22]
|
79
85
|
|
80
|
-
bech = Bech32.encode(hrp, data)
|
86
|
+
bech = Bech32.encode(hrp, data, Bech32::Encoding::BECH32)
|
81
87
|
=> bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
|
82
88
|
```
|
83
89
|
|
data/bech32.gemspec
CHANGED
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_development_dependency "rake", "
|
22
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.0"
|
24
24
|
end
|
data/lib/bech32.rb
CHANGED
@@ -1,44 +1,50 @@
|
|
1
1
|
module Bech32
|
2
2
|
|
3
|
+
module Encoding
|
4
|
+
BECH32 = 1
|
5
|
+
BECH32M = 2
|
6
|
+
end
|
7
|
+
|
3
8
|
autoload :SegwitAddr, 'bech32/segwit_addr'
|
4
9
|
|
5
10
|
SEPARATOR = '1'
|
6
11
|
|
7
12
|
CHARSET = %w(q p z r y 9 x 8 g f 2 t v d w 0 s 3 j n 5 4 k h c e 6 m u a 7 l)
|
8
13
|
|
14
|
+
BECH32M_CONST = 0x2bc830a3
|
15
|
+
|
9
16
|
module_function
|
10
17
|
|
11
18
|
# Returns the encoded Bech32 string.
|
12
19
|
#
|
13
20
|
# require 'bech32'
|
14
21
|
#
|
15
|
-
# bech = Bech32.encode('bc', [])
|
22
|
+
# bech = Bech32.encode('bc', [], Bech32::Encoding::BECH32)
|
16
23
|
#
|
17
24
|
# <i>Generates:</i>
|
18
25
|
# 'BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4' # bech
|
19
26
|
#
|
20
|
-
def encode(hrp, data)
|
21
|
-
checksummed = data + create_checksum(hrp, data)
|
27
|
+
def encode(hrp, data, spec)
|
28
|
+
checksummed = data + create_checksum(hrp, data, spec)
|
22
29
|
hrp + SEPARATOR + checksummed.map{|i|CHARSET[i]}.join
|
23
30
|
end
|
24
31
|
|
25
|
-
# Returns the
|
32
|
+
# Returns the Bech32 decoded hrp and data.
|
26
33
|
#
|
27
34
|
# require 'bech32'
|
28
35
|
#
|
29
36
|
# addr = 'BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4'
|
30
|
-
# hrp, data = Bech32.decode(addr)
|
37
|
+
# hrp, data, spec = Bech32.decode(addr)
|
31
38
|
#
|
32
39
|
# <i>Generates:</i>
|
33
40
|
# 'bc' # hrp
|
34
41
|
# [0, 14, 20, 15, 7, 13, 26, 0, 25, 18, 6, 11, 13, 8, 21, 4, 20, 3, 17, 2, 29, 3, 12, 29, 3, 4, 15, 24, 20, 6, 14, 30, 22] # data
|
42
|
+
# 1 # spec see Bech32::Encoding
|
35
43
|
#
|
36
44
|
def decode(bech, max_length = 90)
|
37
|
-
# check invalid bytes
|
38
|
-
return nil if bech.scrub('?').include?('?')
|
39
45
|
# check uppercase/lowercase
|
46
|
+
return nil if bech.bytes.index{|x| x < 33 || x > 126}
|
40
47
|
return nil if (bech.downcase != bech && bech.upcase != bech)
|
41
|
-
bech.each_char{|c|return nil if c.ord < 33 || c.ord > 126}
|
42
48
|
bech = bech.downcase
|
43
49
|
# check data length
|
44
50
|
pos = bech.rindex(SEPARATOR)
|
@@ -49,20 +55,30 @@ module Bech32
|
|
49
55
|
hrp = bech[0..pos-1]
|
50
56
|
data = bech[pos+1..-1].each_char.map{|c|CHARSET.index(c)}
|
51
57
|
# check checksum
|
52
|
-
|
53
|
-
[hrp, data[0..-7]]
|
58
|
+
spec = verify_checksum(hrp, data)
|
59
|
+
spec ? [hrp, data[0..-7], spec] : nil
|
54
60
|
end
|
55
61
|
|
56
62
|
# Returns computed checksum values of +hrp+ and +data+
|
57
|
-
def create_checksum(hrp, data)
|
63
|
+
def create_checksum(hrp, data, spec)
|
58
64
|
values = expand_hrp(hrp) + data
|
59
|
-
|
65
|
+
const = (spec == Bech32::Encoding::BECH32M ? Bech32::BECH32M_CONST : 1)
|
66
|
+
polymod = polymod(values + [0, 0, 0, 0, 0, 0]) ^ const
|
60
67
|
(0..5).map{|i|(polymod >> 5 * (5 - i)) & 31}
|
61
68
|
end
|
62
69
|
|
63
70
|
# Verify a checksum given Bech32 string
|
71
|
+
# @param [String] hrp hrp part.
|
72
|
+
# @param [Array[Integer]] data data array.
|
73
|
+
# @return [Integer] spec
|
64
74
|
def verify_checksum(hrp, data)
|
65
|
-
polymod(expand_hrp(hrp) + data)
|
75
|
+
const = polymod(expand_hrp(hrp) + data)
|
76
|
+
case const
|
77
|
+
when 1
|
78
|
+
Encoding::BECH32
|
79
|
+
when BECH32M_CONST
|
80
|
+
Encoding::BECH32M
|
81
|
+
end
|
66
82
|
end
|
67
83
|
|
68
84
|
# Expand the hrp into values for checksum computation.
|
@@ -84,4 +100,4 @@ module Bech32
|
|
84
100
|
|
85
101
|
private_class_method :polymod, :expand_hrp
|
86
102
|
|
87
|
-
end
|
103
|
+
end
|
data/lib/bech32/segwit_addr.rb
CHANGED
@@ -30,19 +30,21 @@ module Bech32
|
|
30
30
|
|
31
31
|
# Returns segwit address string which generated from hrp, witness version and witness program.
|
32
32
|
def addr
|
33
|
-
|
33
|
+
spec = (ver == 0 ? Bech32::Encoding::BECH32 : Bech32::Encoding::BECH32M)
|
34
|
+
Bech32.encode(hrp, [ver] + convert_bits(prog, 8, 5), spec)
|
34
35
|
end
|
35
36
|
|
36
37
|
private
|
37
38
|
|
38
39
|
def parse_addr(addr)
|
39
|
-
@hrp, data = Bech32.decode(addr)
|
40
|
+
@hrp, data, spec = Bech32.decode(addr)
|
40
41
|
raise 'Invalid address.' if hrp.nil? || data[0].nil? || ![HRP_MAINNET, HRP_TESTNET, HRP_REGTEST].include?(hrp)
|
41
42
|
@ver = data[0]
|
42
43
|
raise 'Invalid witness version' if @ver > 16
|
43
44
|
@prog = convert_bits(data[1..-1], 5, 8, false)
|
44
45
|
raise 'Invalid witness program' if @prog.nil? || @prog.length < 2 || @prog.length > 40
|
45
46
|
raise 'Invalid witness program with version 0' if @ver == 0 && (@prog.length != 20 && @prog.length != 32)
|
47
|
+
raise 'Witness version and encoding spec do not match' if (@ver == 0 && spec != Bech32::Encoding::BECH32) || (@ver != 0 && spec != Bech32::Encoding::BECH32M)
|
46
48
|
end
|
47
49
|
|
48
50
|
def convert_bits(data, from, to, padding=true)
|
data/lib/bech32/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bech32
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shigeyuki Azuchi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 12.3.3
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 12.3.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,8 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
version: '0'
|
82
82
|
requirements: []
|
83
|
-
|
84
|
-
rubygems_version: 2.7.3
|
83
|
+
rubygems_version: 3.2.3
|
85
84
|
signing_key:
|
86
85
|
specification_version: 4
|
87
86
|
summary: The implementation of Bech32 encoder and decoder.
|