diff --git a/Gemfile b/Gemfile index f5c5361..33ccb72 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gemspec gem 'base32', '~> 0.3.4' gem 'bitcoin-ruby', '~> 0.0.20' -gem 'bls12-381', '~> 0.2.2' +gem 'bls12-381', '~> 0.3.0' gem 'byebug', '~> 11.1', '>= 11.1.3' gem 'cbor', '~> 0.5.9.6' gem 'ctf-party', '~> 2.3' diff --git a/Gemfile.lock b/Gemfile.lock index d897080..d394436 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,10 @@ PATH remote: . specs: - ic_agent (0.1.4) + ic_agent (0.2.0) base32 (~> 0.3.4) bitcoin-ruby (~> 0.0.20) - bls12-381 (~> 0.2.2) + bls12-381 (~> 0.3.0) cbor (~> 0.5.9.6) ctf-party (~> 2.3) ecdsa (~> 1.2) @@ -24,7 +24,8 @@ GEM eventmachine ffi scrypt - bls12-381 (0.2.2) + bls12-381 (0.3.0) + h2c (~> 0.2.0) byebug (11.1.3) cbor (0.5.9.6) coderay (1.1.3) @@ -36,7 +37,7 @@ GEM ecdsa (1.2.0) ed25519 (1.3.0) eventmachine (1.2.7) - faraday (2.7.4) + faraday (2.7.10) faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) faraday-net_http (3.0.2) @@ -44,13 +45,15 @@ GEM ffi-compiler (1.0.1) ffi (>= 1.0.0) rake - i18n (1.12.0) + h2c (0.2.0) + ecdsa (~> 1.2.0) + i18n (1.14.1) concurrent-ruby (~> 1.0) json (2.6.3) leb128 (1.0.0) method_source (1.0.0) - mini_portile2 (2.8.2) - pkg-config (1.5.1) + mini_portile2 (2.8.4) + pkg-config (1.5.2) polyglot (0.3.5) pry (0.14.2) coderay (~> 1.1) @@ -64,19 +67,19 @@ GEM rspec-core (~> 3.12.0) rspec-expectations (~> 3.12.0) rspec-mocks (~> 3.12.0) - rspec-core (3.12.1) + rspec-core (3.12.2) rspec-support (~> 3.12.0) - rspec-expectations (3.12.2) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-mocks (3.12.5) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-support (3.12.0) + rspec-support (3.12.1) ruby-enum (0.9.0) i18n ruby2_keywords (0.0.5) - rubytree (2.0.0) + rubytree (2.0.2) json (~> 2.0, > 2.3.1) rubyzip (2.3.2) scrypt (3.0.7) @@ -90,7 +93,7 @@ PLATFORMS DEPENDENCIES base32 (~> 0.3.4) bitcoin-ruby (~> 0.0.20) - bls12-381 (~> 0.2.2) + bls12-381 (~> 0.3.0) byebug (~> 11.1, >= 11.1.3) cbor (~> 0.5.9.6) ctf-party (~> 2.3) diff --git a/ic_agent.gemspec b/ic_agent.gemspec index f3f6807..f4edab1 100644 --- a/ic_agent.gemspec +++ b/ic_agent.gemspec @@ -34,7 +34,7 @@ Gem::Specification.new do |spec| # spec.add_dependency "example-gem", "~> 1.0" spec.add_dependency 'base32', '~> 0.3.4' spec.add_dependency 'bitcoin-ruby', '~> 0.0.20' - spec.add_dependency 'bls12-381', '~> 0.2.2' + spec.add_dependency 'bls12-381', '~> 0.3.0' spec.add_dependency 'cbor', '~> 0.5.9.6' spec.add_dependency 'ctf-party', '~> 2.3' spec.add_dependency 'ecdsa', '~> 1.2' diff --git a/lib/ic_agent/agent.rb b/lib/ic_agent/agent.rb index 71884f0..2c7559e 100644 --- a/lib/ic_agent/agent.rb +++ b/lib/ic_agent/agent.rb @@ -176,36 +176,9 @@ def update_raw(canister_id, method_name, arg, return_type = nil, effective_canis # # @param canister_id [String] The ID of the target canister. # @param paths [Array] The paths to read from the canister's state. + # @param [TrueClass] bls_verify # @return [Object] The decoded response from the canister. - def read_state_raw(canister_id, paths) - req = { - 'request_type' => 'read_state', - 'sender' => @identity.sender.bytes, - 'paths' => paths, - 'ingress_expiry' => get_expiry_date - } - _, data = Request.sign_request(req, @identity) - ret = read_state_endpoint(canister_id, data) - if ret == 'Invalid path requested.' - raise ValueError, 'Invalid path requested!' - elsif ret == 'Could not parse body as read request: invalid type: byte array, expected a sequence' - raise ValueError, 'Could not parse body as read request: invalid type: byte array, expected a sequence' - end - - begin - d = CBOR.decode(ret) - rescue StandardError - raise ValueError, "Unable to decode cbor value: #{ret}" - end - CBOR.decode(d.value['certificate']) - end - - # Sends a raw read state request to a canister, verifies the response, and handles it. - # - # @param canister_id [String] The ID of the target canister. - # @param paths [Array] The paths to read from the canister's state. - # @return [Object] The decoded response from the canister. - def read_state_raw_and_verify(canister_id, paths) + def read_state_raw(canister_id, paths, bls_verify = true) req = { 'request_type' => 'read_state', 'sender' => @identity.sender.bytes, @@ -227,10 +200,10 @@ def read_state_raw_and_verify(canister_id, paths) end cert = CBOR.decode(d.value['certificate']) - if verify(cert, canister_id) - cert + if bls_verify + verify(cert, canister_id) ? cert : false else - false + cert end end @@ -276,17 +249,17 @@ def poll(canister_id, req_id, delay = 1, timeout = IcAgent::DEFAULT_POLL_TIMEOUT end def verify(cert, canister_id) - sig = IcAgent::Certificate.signature(cert).str2hex + signature_hex = IcAgent::Certificate.signature(cert).str2hex tree = IcAgent::Certificate.tree(cert) delegation = IcAgent::Certificate.delegation(cert) root_hash = IcAgent::Certificate.reconstruct(tree).str2hex msg = IcAgent::IC_STATE_ROOT_DOMAIN_SEPARATOR + root_hash der_key = check_delegation(delegation, canister_id, true) public_key_hash = extract_der(der_key).str2hex - byebug - public_key = BLS::PointG1.from_hex(public_key_hash) - BLS.verify(sig, msg, public_key) + public_key = BLS::PointG2.from_hex(public_key_hash) + signature = BLS::PointG1.from_hex(signature_hex) + BLS.verify(signature, msg, public_key) end def check_delegation(delegation, effective_canister_id, disable_range_check) diff --git a/lib/ic_agent/version.rb b/lib/ic_agent/version.rb index 6ca96d6..abe34a1 100644 --- a/lib/ic_agent/version.rb +++ b/lib/ic_agent/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module IcAgent - VERSION = '0.1.4' + VERSION = '0.2.0' end diff --git a/spec/ic_agent/agent_spec.rb b/spec/ic_agent/agent_spec.rb index c78a071..90e1fc9 100644 --- a/spec/ic_agent/agent_spec.rb +++ b/spec/ic_agent/agent_spec.rb @@ -26,14 +26,15 @@ expect(result[0]).to include('type' => 'rec_0') end - it 'IcAgent::Agent read_state_raw' do + it 'IcAgent::Agent read_state_raw and bls verify certificate' do iden = IcAgent::Identity.new client = IcAgent::Client.new agent = IcAgent::Agent.new(iden, client) canister_id = 'gvbup-jyaaa-aaaah-qcdwa-cai' - cert = agent.read_state_raw_and_verify(canister_id, [['time']]) - + cert = agent.read_state_raw(canister_id, [['time']]) + verify = agent.verify(cert, canister_id) + expect(verify).to eql(true) end end diff --git a/spec/version_spec.rb b/spec/version_spec.rb index 1cd0d53..a049154 100644 --- a/spec/version_spec.rb +++ b/spec/version_spec.rb @@ -1,5 +1,5 @@ describe IcAgent::VERSION do it 'IcAgent::VERSION' do - expect(IcAgent::VERSION).to eql('0.1.4') + expect(IcAgent::VERSION).to eql('0.2.0') end end \ No newline at end of file