bech32 1.0.1 → 1.1.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
- SHA1:
3
- metadata.gz: 1dbf369ac8990456626ab97fbc98580c01a47110
4
- data.tar.gz: 6c12e12379890d8a47aec779e19f68c04d0ce919
2
+ SHA256:
3
+ metadata.gz: 975a0d606b86cdb7487afad52363ef284de471f1530cf7614b0a7db0728dc937
4
+ data.tar.gz: 1e3d9f3f389cbfd94a8af919a0ec842395605649138bdf3860ac9db2617e3939
5
5
  SHA512:
6
- metadata.gz: 29940231175f3150e370c4fbe5b9d2955e61673af9bdc953304a61761048047fde43827037b25fa66dea0f4ba28e9a0be080a3aebfa76a7acc9c809f88f1fc50
7
- data.tar.gz: 659fd697fc7edcad0645c26768ef6f320dd5db4fdd8e986d2cc19fb3b5df88791d0dc2a7309792576457800a8107034875aca91e445671148b8155f9364472c1
6
+ metadata.gz: ab8fdc36df45376ea1ec0e7d7553fb6309900d8db824998f327dbfe670451a00ec240bbd75fe59e1bdda2590981d174e0be086756e919582dad55ce5441fe5fb
7
+ data.tar.gz: 07bf7ac092a89c997932d380a57f30916baa809fd3adf2c86b7418e599949be6fc593b226bcdb7240247fde19d7f092ebdcdd82bfce154adde9d16b5de2df68e
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3.0
1
+ ruby-3.0.0
data/.travis.yml CHANGED
@@ -1,6 +1,9 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1
4
- - 2.2.2
5
- - 2.3.0
6
- - 2.4.0
3
+ - 2.2.10
4
+ - 2.3.8
5
+ - 2.4.10
6
+ - 2.5.8
7
+ - 2.6.6
8
+ - 2.7.2
9
+ - 3.0.0
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.
@@ -55,6 +61,20 @@ segwit_addr.to_script_pubkey
55
61
  => 0014751e76e8199196d454941c45d1b3a323f1433bd6
56
62
  ```
57
63
 
64
+ #### Advanced
65
+
66
+ The maximum number of characters of Bech32 defined in [BIP-173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki) is limited to 90 characters.
67
+ However, LN specification [BOLT#11](https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md) has no limitation.
68
+
69
+ To decode data of more than 90 characters, specify `max_length` at decode as below. (The default value of `max_length` is 90.)
70
+
71
+ ```ruby
72
+ MAX_INTEGER = 2**31 - 1
73
+ Bech32.decode(bechString, MAX_INTEGER)
74
+ ```
75
+
76
+ Note that between length of the addresses and the error-detection capabilities are [trade-off](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#checksum-design).
77
+
58
78
  ### Encode
59
79
 
60
80
  Encode Bech32 human-readable part and data part into Bech32 string.
@@ -63,7 +83,7 @@ Encode Bech32 human-readable part and data part into Bech32 string.
63
83
  hrp = 'bc'
64
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]
65
85
 
66
- bech = Bech32.encode(hrp, data)
86
+ bech = Bech32.encode(hrp, data, Bech32::Encoding::BECH32)
67
87
  => bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
68
88
  ```
69
89
 
data/bech32.gemspec CHANGED
@@ -1,10 +1,11 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bech32/version'
4
5
 
5
6
  Gem::Specification.new do |spec|
6
7
  spec.name = "bech32"
7
- spec.version = "1.0.1"
8
+ spec.version = Bech32::VERSION
8
9
  spec.authors = ["Shigeyuki Azuchi"]
9
10
  spec.email = ["azuchi@haw.co.jp"]
10
11
 
@@ -18,6 +19,6 @@ Gem::Specification.new do |spec|
18
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
20
  spec.require_paths = ["lib"]
20
21
 
21
- spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rake", ">= 12.3.3"
22
23
  spec.add_development_dependency "rspec", "~> 3.0"
23
24
  end
data/lib/bech32.rb CHANGED
@@ -1,66 +1,84 @@
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 Bach32 decoded hrp and data.
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
- def decode(bech)
44
+ def decode(bech, max_length = 90)
37
45
  # check uppercase/lowercase
46
+ return nil if bech.bytes.index{|x| x < 33 || x > 126}
38
47
  return nil if (bech.downcase != bech && bech.upcase != bech)
39
- bech.each_char{|c|return nil if c.ord < 33 || c.ord > 126}
40
48
  bech = bech.downcase
41
49
  # check data length
42
50
  pos = bech.rindex(SEPARATOR)
43
- return nil if pos.nil? || pos + 7 > bech.length || bech.length > 90
51
+ return nil if pos.nil? || pos + 7 > bech.length || bech.length > max_length
44
52
  # check valid charset
45
53
  bech[pos+1..-1].each_char{|c|return nil unless CHARSET.include?(c)}
46
54
  # split hrp and data
47
55
  hrp = bech[0..pos-1]
48
56
  data = bech[pos+1..-1].each_char.map{|c|CHARSET.index(c)}
49
57
  # check checksum
50
- return nil unless verify_checksum(hrp, data)
51
- [hrp, data[0..-7]]
58
+ spec = verify_checksum(hrp, data)
59
+ spec ? [hrp, data[0..-7], spec] : nil
52
60
  end
53
61
 
54
62
  # Returns computed checksum values of +hrp+ and +data+
55
- def create_checksum(hrp, data)
63
+ def create_checksum(hrp, data, spec)
56
64
  values = expand_hrp(hrp) + data
57
- polymod = polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1
65
+ const = (spec == Bech32::Encoding::BECH32M ? Bech32::BECH32M_CONST : 1)
66
+ polymod = polymod(values + [0, 0, 0, 0, 0, 0]) ^ const
58
67
  (0..5).map{|i|(polymod >> 5 * (5 - i)) & 31}
59
68
  end
60
69
 
61
70
  # Verify a checksum given Bech32 string
71
+ # @param [String] hrp hrp part.
72
+ # @param [Array[Integer]] data data array.
73
+ # @return [Integer] spec
62
74
  def verify_checksum(hrp, data)
63
- polymod(expand_hrp(hrp) + data) == 1
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
64
82
  end
65
83
 
66
84
  # Expand the hrp into values for checksum computation.
@@ -82,4 +100,4 @@ module Bech32
82
100
 
83
101
  private_class_method :polymod, :expand_hrp
84
102
 
85
- end
103
+ end
@@ -4,6 +4,7 @@ module Bech32
4
4
 
5
5
  HRP_MAINNET = 'bc'
6
6
  HRP_TESTNET = 'tb'
7
+ HRP_REGTEST = 'bcrt'
7
8
 
8
9
  attr_accessor :hrp # human-readable part
9
10
  attr_accessor :ver # witness version
@@ -16,32 +17,34 @@ module Bech32
16
17
 
17
18
  # Returns segwit script pubkey which generated from witness version and witness program.
18
19
  def to_script_pubkey
19
- v = ver == 0 ? ver : ver + 0x80
20
+ v = ver == 0 ? ver : ver + 0x50
20
21
  ([v, prog.length].pack("CC") + prog.map{|p|[p].pack("C")}.join).unpack('H*').first
21
22
  end
22
23
 
23
24
  # parse script pubkey into witness version and witness program
24
25
  def script_pubkey=(script_pubkey)
25
26
  values = [script_pubkey].pack('H*').unpack("C*")
26
- @ver = values[0]
27
+ @ver = values[0] == 0 ? values[0] : values[0] - 0x50
27
28
  @prog = values[2..-1]
28
29
  end
29
30
 
30
31
  # Returns segwit address string which generated from hrp, witness version and witness program.
31
32
  def addr
32
- Bech32.encode(hrp, [ver] + convert_bits(prog, 8, 5))
33
+ spec = (ver == 0 ? Bech32::Encoding::BECH32 : Bech32::Encoding::BECH32M)
34
+ Bech32.encode(hrp, [ver] + convert_bits(prog, 8, 5), spec)
33
35
  end
34
36
 
35
37
  private
36
38
 
37
39
  def parse_addr(addr)
38
- @hrp, data = Bech32.decode(addr)
39
- raise 'Invalid address.' if @hrp.nil? || ![HRP_MAINNET, HRP_TESTNET].include?(@hrp)
40
+ @hrp, data, spec = Bech32.decode(addr)
41
+ raise 'Invalid address.' if hrp.nil? || data[0].nil? || ![HRP_MAINNET, HRP_TESTNET, HRP_REGTEST].include?(hrp)
40
42
  @ver = data[0]
41
43
  raise 'Invalid witness version' if @ver > 16
42
44
  @prog = convert_bits(data[1..-1], 5, 8, false)
43
45
  raise 'Invalid witness program' if @prog.nil? || @prog.length < 2 || @prog.length > 40
44
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)
45
48
  end
46
49
 
47
50
  def convert_bits(data, from, to, padding=true)
@@ -0,0 +1,3 @@
1
+ module Bech32
2
+ VERSION = "1.1.0"
3
+ end
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.1
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: 2017-07-04 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
26
+ version: 12.3.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +60,7 @@ files:
60
60
  - bin/setup
61
61
  - lib/bech32.rb
62
62
  - lib/bech32/segwit_addr.rb
63
+ - lib/bech32/version.rb
63
64
  homepage: https://github.com/azuchi/bech32rb
64
65
  licenses:
65
66
  - MIT
@@ -79,8 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
80
  - !ruby/object:Gem::Version
80
81
  version: '0'
81
82
  requirements: []
82
- rubyforge_project:
83
- rubygems_version: 2.5.1
83
+ rubygems_version: 3.2.3
84
84
  signing_key:
85
85
  specification_version: 4
86
86
  summary: The implementation of Bech32 encoder and decoder.