costan-tem_ruby 0.10.2 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.10.3. Fixed benchmarking via the tem_bench binary.
2
+
1
3
  v0.10.2. More internal refactorings.
2
4
 
3
5
  v0.10.1. Internal refactorings.
data/Manifest CHANGED
@@ -14,6 +14,14 @@ lib/tem/apdus/keys.rb
14
14
  lib/tem/apdus/lifecycle.rb
15
15
  lib/tem/apdus/tag.rb
16
16
  lib/tem/auto_conf.rb
17
+ lib/tem/benchmarks/benchmarks.rb
18
+ lib/tem/benchmarks/blank_bound_secpack.rb
19
+ lib/tem/benchmarks/blank_sec.rb
20
+ lib/tem/benchmarks/devchip_decrypt.rb
21
+ lib/tem/benchmarks/post_buffer.rb
22
+ lib/tem/benchmarks/simple_apdu.rb
23
+ lib/tem/benchmarks/vm_perf.rb
24
+ lib/tem/benchmarks/vm_perf_bound.rb
17
25
  lib/tem/builders/abi.rb
18
26
  lib/tem/builders/assembler.rb
19
27
  lib/tem/builders/crypto.rb
@@ -44,7 +52,6 @@ LICENSE
44
52
  Manifest
45
53
  Rakefile
46
54
  README
47
- tem_ruby.gemspec
48
55
  test/_test_cert.rb
49
56
  test/builders/test_abi_builder.rb
50
57
  test/tem_test_case.rb
@@ -65,11 +72,3 @@ test/test_exceptions.rb
65
72
  test/transport/test_auto_configurator.rb
66
73
  test/transport/test_java_card_mixin.rb
67
74
  test/transport/test_jcop_remote.rb
68
- timings/blank_bound_secpack.rb
69
- timings/blank_sec.rb
70
- timings/devchip_decrypt.rb
71
- timings/post_buffer.rb
72
- timings/simple_apdu.rb
73
- timings/timings.rb
74
- timings/vm_perf.rb
75
- timings/vm_perf_bound.rb
@@ -4,6 +4,6 @@
4
4
  require 'rubygems'
5
5
  require 'tem_ruby'
6
6
 
7
- require 'timings/timings.rb'
7
+ require 'tem/benchmarks/benchmarks.rb'
8
8
 
9
- TemTimings.all_timings
9
+ Tem::Benchmarks.display_all_benchmarks
@@ -0,0 +1,66 @@
1
+ require 'tem_ruby'
2
+
3
+ require 'tem/benchmarks/blank_bound_secpack.rb'
4
+ require 'tem/benchmarks/blank_sec.rb'
5
+ require 'tem/benchmarks/devchip_decrypt.rb'
6
+ require 'tem/benchmarks/post_buffer.rb'
7
+ require 'tem/benchmarks/simple_apdu.rb'
8
+ require 'tem/benchmarks/vm_perf.rb'
9
+ require 'tem/benchmarks/vm_perf_bound.rb'
10
+
11
+ class Tem::Benchmarks
12
+ def setup
13
+ @tem = Tem.auto_tem
14
+
15
+ @tem.kill
16
+ @tem.activate
17
+ @tem.emit
18
+ end
19
+
20
+ def teardown
21
+ @tem.kill
22
+ @tem.disconnect if @tem
23
+ end
24
+
25
+ def do_timing
26
+ @tem.flush_buffers
27
+
28
+ n = 10
29
+ loop do
30
+ timings = (0...3).map do |i|
31
+ t_start = Time.now
32
+ n.times do
33
+ yield
34
+ end
35
+ t_delta = Time.now - t_start
36
+ end
37
+ avg_time = timings.inject { |a,v| a + v } / timings.length
38
+ max_diff = timings.map { |t| (t - avg_time).abs }.max
39
+ uncertainty = 100 * max_diff / avg_time
40
+ print "%8d: %3.8fs per run, %3.8fs uncertainty (%2.5f%%)\n" %
41
+ [n, avg_time / n, max_diff / n, 100 * uncertainty]
42
+
43
+ return avg_time / n unless max_diff / avg_time >= 0.01
44
+ n *= 2
45
+ end
46
+ end
47
+
48
+ def self.all_benchmarks
49
+ benchmarks = {}
50
+ t = Tem::Benchmarks.new
51
+ t.setup
52
+ t.methods.select { |m| m =~ /time_/ }.each do |m|
53
+ print "Timing: #{m[5..-1]}...\n"
54
+ benchmarks[m] = t.send m.to_sym
55
+ end
56
+ t.teardown
57
+ benchmarks
58
+ end
59
+
60
+ def self.display_all_benchmarks
61
+ benchmarks = Tem::Benchmarks.all_benchmarks
62
+ benchmarks.map { |k, v| [k.to_s, v] }.sort.each do |benchmark|
63
+ print "#{benchmark.first}: #{'%.5f' % benchmark.last}s\n"
64
+ end
65
+ end
66
+ end
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_blank_bound_secpack
3
3
  secpack = @tem.assemble { |s|
4
4
  s.ldbc 0
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_blank_sec
3
3
  secpack = @tem.assemble { |s|
4
4
  s.ldbc 0
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_devchip_decrypt
3
3
  pubek = @tem.pubek
4
4
  data = (1...120).map { |i| (i * i * 217 + i * 661 + 393) % 256 }
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_post_buffer
3
3
  data = (0...490).map { |i| (39 * i * i + 91 * i + 17) % 256 }
4
4
  p @tem.stat_buffers
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_simple_apdu
3
3
  do_timing { @tem.get_tag_length }
4
4
  end
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_vm_perf
3
3
  secpack = @tem.assemble { |s|
4
4
  s.ldwc 48 * 10
@@ -1,4 +1,4 @@
1
- class TemTimings
1
+ class Tem::Benchmarks
2
2
  def time_vm_perf_bound
3
3
  secpack = @tem.assemble { |s|
4
4
  s.ldwc 48 * 10
@@ -3,7 +3,7 @@ require 'yaml'
3
3
 
4
4
  # Certificate Authority (CA) functionality for TEM manufacturers
5
5
  module Tem::CA
6
- # creates an Endorsement Certificate for a TEM's Public Endorsement Key
6
+ # Creates an Endorsement Certificate for a TEM's Public Endorsement Key.
7
7
  def new_ecert(pubek)
8
8
  ca_cert = Tem::CA.ca_cert
9
9
  ca_key = Tem::CA.ca_key
@@ -22,10 +22,16 @@ module Tem::CA
22
22
  cf.subject_certificate = ecert
23
23
  cf.issuer_certificate = ca_cert
24
24
  ecert.add_extension cf.create_extension("basicConstraints", "CA:true", true)
25
- ecert.add_extension cf.create_extension("authorityKeyIdentifier", "keyid,issuer")
26
- ecert.add_extension cf.create_extension("keyUsage", "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign")
27
- ecert.add_extension cf.create_extension("extendedKeyUsage", "serverAuth,clientAuth,codeSigning,emailProtection,timeStamping,msCodeInd,msCodeCom,msCTLSign,msSGC,msEFS,nsSGC")
28
- ecert.add_extension cf.create_extension("nsCertType", "client,server,email,objsign,sslCA,emailCA,objCA")
25
+ ecert.add_extension cf.create_extension("authorityKeyIdentifier",
26
+ "keyid,issuer")
27
+ ecert.add_extension cf.create_extension("keyUsage",
28
+ "digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment," +
29
+ "keyAgreement,keyCertSign,cRLSign")
30
+ ecert.add_extension cf.create_extension("extendedKeyUsage",
31
+ "serverAuth,clientAuth,codeSigning,emailProtection,timeStamping," +
32
+ "msCodeInd,msCodeCom,msCTLSign,msSGC,msEFS,nsSGC")
33
+ ecert.add_extension cf.create_extension("nsCertType",
34
+ "client,server,email,objsign,sslCA,emailCA,objCA")
29
35
  ecert.add_extension cf.create_extension("subjectKeyIdentifier", "hash")
30
36
  ecert.sign ca_key, OpenSSL::Digest::SHA1.new
31
37
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{tem_ruby}
5
- s.version = "0.10.2"
5
+ s.version = "0.10.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Victor Costan"]
@@ -10,8 +10,8 @@ Gem::Specification.new do |s|
10
10
  s.description = %q{TEM (Trusted Execution Module) driver, written in and for ruby.}
11
11
  s.email = %q{victor@costan.us}
12
12
  s.executables = ["tem_bench", "tem_ca", "tem_irb", "tem_proxy", "tem_stat"]
13
- s.extra_rdoc_files = ["bin/tem_bench", "bin/tem_ca", "bin/tem_irb", "bin/tem_proxy", "bin/tem_stat", "CHANGELOG", "lib/tem/_cert.rb", "lib/tem/apdus/buffers.rb", "lib/tem/apdus/keys.rb", "lib/tem/apdus/lifecycle.rb", "lib/tem/apdus/tag.rb", "lib/tem/auto_conf.rb", "lib/tem/builders/abi.rb", "lib/tem/builders/assembler.rb", "lib/tem/builders/crypto.rb", "lib/tem/builders/isa.rb", "lib/tem/ca.rb", "lib/tem/definitions/abi.rb", "lib/tem/definitions/assembler.rb", "lib/tem/definitions/isa.rb", "lib/tem/ecert.rb", "lib/tem/hive.rb", "lib/tem/keys/asymmetric.rb", "lib/tem/keys/key.rb", "lib/tem/keys/symmetric.rb", "lib/tem/sec_exec_error.rb", "lib/tem/seclosures.rb", "lib/tem/secpack.rb", "lib/tem/tem.rb", "lib/tem/toolkit.rb", "lib/tem/transport/auto_configurator.rb", "lib/tem/transport/java_card_mixin.rb", "lib/tem/transport/jcop_remote_protocol.rb", "lib/tem/transport/jcop_remote_server.rb", "lib/tem/transport/jcop_remote_transport.rb", "lib/tem/transport/pcsc_transport.rb", "lib/tem/transport/transport.rb", "lib/tem_ruby.rb", "LICENSE", "README"]
14
- s.files = ["bin/tem_bench", "bin/tem_ca", "bin/tem_irb", "bin/tem_proxy", "bin/tem_stat", "CHANGELOG", "dev_ca/ca_cert.cer", "dev_ca/ca_cert.pem", "dev_ca/ca_key.pem", "dev_ca/config.yml", "lib/tem/_cert.rb", "lib/tem/apdus/buffers.rb", "lib/tem/apdus/keys.rb", "lib/tem/apdus/lifecycle.rb", "lib/tem/apdus/tag.rb", "lib/tem/auto_conf.rb", "lib/tem/builders/abi.rb", "lib/tem/builders/assembler.rb", "lib/tem/builders/crypto.rb", "lib/tem/builders/isa.rb", "lib/tem/ca.rb", "lib/tem/definitions/abi.rb", "lib/tem/definitions/assembler.rb", "lib/tem/definitions/isa.rb", "lib/tem/ecert.rb", "lib/tem/hive.rb", "lib/tem/keys/asymmetric.rb", "lib/tem/keys/key.rb", "lib/tem/keys/symmetric.rb", "lib/tem/sec_exec_error.rb", "lib/tem/seclosures.rb", "lib/tem/secpack.rb", "lib/tem/tem.rb", "lib/tem/toolkit.rb", "lib/tem/transport/auto_configurator.rb", "lib/tem/transport/java_card_mixin.rb", "lib/tem/transport/jcop_remote_protocol.rb", "lib/tem/transport/jcop_remote_server.rb", "lib/tem/transport/jcop_remote_transport.rb", "lib/tem/transport/pcsc_transport.rb", "lib/tem/transport/transport.rb", "lib/tem_ruby.rb", "LICENSE", "Manifest", "Rakefile", "README", "tem_ruby.gemspec", "test/_test_cert.rb", "test/builders/test_abi_builder.rb", "test/tem_test_case.rb", "test/tem_unit/test_tem_alu.rb", "test/tem_unit/test_tem_bound_secpack.rb", "test/tem_unit/test_tem_branching.rb", "test/tem_unit/test_tem_crypto_asymmetric.rb", "test/tem_unit/test_tem_crypto_hash.rb", "test/tem_unit/test_tem_crypto_pstore.rb", "test/tem_unit/test_tem_crypto_random.rb", "test/tem_unit/test_tem_emit.rb", "test/tem_unit/test_tem_memory.rb", "test/tem_unit/test_tem_memory_compare.rb", "test/tem_unit/test_tem_output.rb", "test/tem_unit/test_tem_yaml_secpack.rb", "test/test_driver.rb", "test/test_exceptions.rb", "test/transport/test_auto_configurator.rb", "test/transport/test_java_card_mixin.rb", "test/transport/test_jcop_remote.rb", "timings/blank_bound_secpack.rb", "timings/blank_sec.rb", "timings/devchip_decrypt.rb", "timings/post_buffer.rb", "timings/simple_apdu.rb", "timings/timings.rb", "timings/vm_perf.rb", "timings/vm_perf_bound.rb"]
13
+ s.extra_rdoc_files = ["bin/tem_bench", "bin/tem_ca", "bin/tem_irb", "bin/tem_proxy", "bin/tem_stat", "CHANGELOG", "lib/tem/_cert.rb", "lib/tem/apdus/buffers.rb", "lib/tem/apdus/keys.rb", "lib/tem/apdus/lifecycle.rb", "lib/tem/apdus/tag.rb", "lib/tem/auto_conf.rb", "lib/tem/benchmarks/benchmarks.rb", "lib/tem/benchmarks/blank_bound_secpack.rb", "lib/tem/benchmarks/blank_sec.rb", "lib/tem/benchmarks/devchip_decrypt.rb", "lib/tem/benchmarks/post_buffer.rb", "lib/tem/benchmarks/simple_apdu.rb", "lib/tem/benchmarks/vm_perf.rb", "lib/tem/benchmarks/vm_perf_bound.rb", "lib/tem/builders/abi.rb", "lib/tem/builders/assembler.rb", "lib/tem/builders/crypto.rb", "lib/tem/builders/isa.rb", "lib/tem/ca.rb", "lib/tem/definitions/abi.rb", "lib/tem/definitions/assembler.rb", "lib/tem/definitions/isa.rb", "lib/tem/ecert.rb", "lib/tem/hive.rb", "lib/tem/keys/asymmetric.rb", "lib/tem/keys/key.rb", "lib/tem/keys/symmetric.rb", "lib/tem/sec_exec_error.rb", "lib/tem/seclosures.rb", "lib/tem/secpack.rb", "lib/tem/tem.rb", "lib/tem/toolkit.rb", "lib/tem/transport/auto_configurator.rb", "lib/tem/transport/java_card_mixin.rb", "lib/tem/transport/jcop_remote_protocol.rb", "lib/tem/transport/jcop_remote_server.rb", "lib/tem/transport/jcop_remote_transport.rb", "lib/tem/transport/pcsc_transport.rb", "lib/tem/transport/transport.rb", "lib/tem_ruby.rb", "LICENSE", "README"]
14
+ s.files = ["bin/tem_bench", "bin/tem_ca", "bin/tem_irb", "bin/tem_proxy", "bin/tem_stat", "CHANGELOG", "dev_ca/ca_cert.cer", "dev_ca/ca_cert.pem", "dev_ca/ca_key.pem", "dev_ca/config.yml", "lib/tem/_cert.rb", "lib/tem/apdus/buffers.rb", "lib/tem/apdus/keys.rb", "lib/tem/apdus/lifecycle.rb", "lib/tem/apdus/tag.rb", "lib/tem/auto_conf.rb", "lib/tem/benchmarks/benchmarks.rb", "lib/tem/benchmarks/blank_bound_secpack.rb", "lib/tem/benchmarks/blank_sec.rb", "lib/tem/benchmarks/devchip_decrypt.rb", "lib/tem/benchmarks/post_buffer.rb", "lib/tem/benchmarks/simple_apdu.rb", "lib/tem/benchmarks/vm_perf.rb", "lib/tem/benchmarks/vm_perf_bound.rb", "lib/tem/builders/abi.rb", "lib/tem/builders/assembler.rb", "lib/tem/builders/crypto.rb", "lib/tem/builders/isa.rb", "lib/tem/ca.rb", "lib/tem/definitions/abi.rb", "lib/tem/definitions/assembler.rb", "lib/tem/definitions/isa.rb", "lib/tem/ecert.rb", "lib/tem/hive.rb", "lib/tem/keys/asymmetric.rb", "lib/tem/keys/key.rb", "lib/tem/keys/symmetric.rb", "lib/tem/sec_exec_error.rb", "lib/tem/seclosures.rb", "lib/tem/secpack.rb", "lib/tem/tem.rb", "lib/tem/toolkit.rb", "lib/tem/transport/auto_configurator.rb", "lib/tem/transport/java_card_mixin.rb", "lib/tem/transport/jcop_remote_protocol.rb", "lib/tem/transport/jcop_remote_server.rb", "lib/tem/transport/jcop_remote_transport.rb", "lib/tem/transport/pcsc_transport.rb", "lib/tem/transport/transport.rb", "lib/tem_ruby.rb", "LICENSE", "Manifest", "Rakefile", "README", "test/_test_cert.rb", "test/builders/test_abi_builder.rb", "test/tem_test_case.rb", "test/tem_unit/test_tem_alu.rb", "test/tem_unit/test_tem_bound_secpack.rb", "test/tem_unit/test_tem_branching.rb", "test/tem_unit/test_tem_crypto_asymmetric.rb", "test/tem_unit/test_tem_crypto_hash.rb", "test/tem_unit/test_tem_crypto_pstore.rb", "test/tem_unit/test_tem_crypto_random.rb", "test/tem_unit/test_tem_emit.rb", "test/tem_unit/test_tem_memory.rb", "test/tem_unit/test_tem_memory_compare.rb", "test/tem_unit/test_tem_output.rb", "test/tem_unit/test_tem_yaml_secpack.rb", "test/test_driver.rb", "test/test_exceptions.rb", "test/transport/test_auto_configurator.rb", "test/transport/test_java_card_mixin.rb", "test/transport/test_jcop_remote.rb", "tem_ruby.gemspec"]
15
15
  s.homepage = %q{http://tem.rubyforge.org}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Tem_ruby", "--main", "README"]
17
17
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: costan-tem_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.10.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan
@@ -45,6 +45,14 @@ extra_rdoc_files:
45
45
  - lib/tem/apdus/lifecycle.rb
46
46
  - lib/tem/apdus/tag.rb
47
47
  - lib/tem/auto_conf.rb
48
+ - lib/tem/benchmarks/benchmarks.rb
49
+ - lib/tem/benchmarks/blank_bound_secpack.rb
50
+ - lib/tem/benchmarks/blank_sec.rb
51
+ - lib/tem/benchmarks/devchip_decrypt.rb
52
+ - lib/tem/benchmarks/post_buffer.rb
53
+ - lib/tem/benchmarks/simple_apdu.rb
54
+ - lib/tem/benchmarks/vm_perf.rb
55
+ - lib/tem/benchmarks/vm_perf_bound.rb
48
56
  - lib/tem/builders/abi.rb
49
57
  - lib/tem/builders/assembler.rb
50
58
  - lib/tem/builders/crypto.rb
@@ -90,6 +98,14 @@ files:
90
98
  - lib/tem/apdus/lifecycle.rb
91
99
  - lib/tem/apdus/tag.rb
92
100
  - lib/tem/auto_conf.rb
101
+ - lib/tem/benchmarks/benchmarks.rb
102
+ - lib/tem/benchmarks/blank_bound_secpack.rb
103
+ - lib/tem/benchmarks/blank_sec.rb
104
+ - lib/tem/benchmarks/devchip_decrypt.rb
105
+ - lib/tem/benchmarks/post_buffer.rb
106
+ - lib/tem/benchmarks/simple_apdu.rb
107
+ - lib/tem/benchmarks/vm_perf.rb
108
+ - lib/tem/benchmarks/vm_perf_bound.rb
93
109
  - lib/tem/builders/abi.rb
94
110
  - lib/tem/builders/assembler.rb
95
111
  - lib/tem/builders/crypto.rb
@@ -120,7 +136,6 @@ files:
120
136
  - Manifest
121
137
  - Rakefile
122
138
  - README
123
- - tem_ruby.gemspec
124
139
  - test/_test_cert.rb
125
140
  - test/builders/test_abi_builder.rb
126
141
  - test/tem_test_case.rb
@@ -141,14 +156,7 @@ files:
141
156
  - test/transport/test_auto_configurator.rb
142
157
  - test/transport/test_java_card_mixin.rb
143
158
  - test/transport/test_jcop_remote.rb
144
- - timings/blank_bound_secpack.rb
145
- - timings/blank_sec.rb
146
- - timings/devchip_decrypt.rb
147
- - timings/post_buffer.rb
148
- - timings/simple_apdu.rb
149
- - timings/timings.rb
150
- - timings/vm_perf.rb
151
- - timings/vm_perf_bound.rb
159
+ - tem_ruby.gemspec
152
160
  has_rdoc: false
153
161
  homepage: http://tem.rubyforge.org
154
162
  post_install_message:
@@ -1,64 +0,0 @@
1
- require 'tem_ruby'
2
-
3
- require 'timings/blank_bound_secpack.rb'
4
- require 'timings/blank_sec.rb'
5
- require 'timings/devchip_decrypt.rb'
6
- require 'timings/post_buffer.rb'
7
- require 'timings/simple_apdu.rb'
8
- require 'timings/vm_perf.rb'
9
- require 'timings/vm_perf_bound.rb'
10
-
11
- class TemTimings
12
- def setup
13
- @tem = Tem.auto_tem
14
-
15
- @tem.kill
16
- @tem.activate
17
- @tem.emit
18
- end
19
-
20
- def teardown
21
- @tem.kill
22
- @tem.disconnect if @tem
23
- end
24
-
25
- def do_timing
26
- @tem.flush_buffers
27
-
28
- n = 10
29
- loop do
30
- timings = (0...3).map do |i|
31
- t_start = Time.now
32
- n.times do
33
- yield
34
- end
35
- t_delta = Time.now - t_start
36
- end
37
- avg_time = timings.inject { |a,v| a + v } / timings.length
38
- max_diff = timings.map { |t| (t - avg_time).abs }.max
39
- print "%8d: %3.8fs per run, %3.8fs uncertainty (%2.5f%%)\n" % [n, avg_time / n, max_diff / n, 100 * max_diff / avg_time]
40
-
41
- return avg_time unless max_diff / avg_time >= 0.01
42
- n *= 2
43
- end
44
- end
45
-
46
- def self.all_timings
47
- timings = {}
48
- t = TemTimings.new
49
- t.setup
50
- t.methods.select { |m| m =~ /time_/ }.each do |m|
51
- print "Timing: #{m[5..-1]}...\n"
52
- timings[m] = t.send m.to_sym
53
- end
54
- t.teardown
55
- timings
56
- end
57
- end
58
-
59
- if __FILE__ == $0
60
- timings = TemTimings.all_timings
61
- timings.map { |k, v| [k.to_s, v] }.sort.each do |timing|
62
- print "#{timing.first}: #{'%.5f' % timing.last}s\n"
63
- end
64
- end