poly_pseudo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fdab923c65e6f7879610f7942818cca80a8454eb
4
+ data.tar.gz: ef974d8386486a49767e202a1ded93a98fb67bbf
5
+ SHA512:
6
+ metadata.gz: ca52fb9aeb48edcf19768067ad46d5b25f0e3091a3db70e3c62d67d6c89fb22b602b64a92f2be7599402b2bfca34089b65eb0a227cd0a0466b73708dd76368b2
7
+ data.tar.gz: 4512bb3314f9b1493ca06be4b2e18418c34042f8eb4f184ba1762808f56e8fbd8621248727c39b19eb950002aa9b009b5208f018439f2aabf978231adcf3b6bc
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.13.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in poly_pseudo.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # PolyPseudo
2
+
3
+ ## Installation
4
+
5
+ Make sure you have installed OpenSSL 1.0.2+.
6
+
7
+ $ brew install openssl
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'poly_pseudo'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install poly_pseudo
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ require 'poly_pseudo'
27
+
28
+ encoded_asn1 = <<-BASE64
29
+ MIIBVAYMYIQQAYdrg+MFAQIBAgEBAgEBFhQwMDAwMDAwNDAwMzIxNDM0NTAwMRYU
30
+ MDAwMDAwMDMyNzMyMjYzMTAwMDACBAEzok4wgfkEUQQdTrTmvUoznOB+4bGfted+
31
+ sc7mnN2M2k9T/c2ZXvOYf8CwniAsnxVgzTzsoEpg8NRJq6aBjFCyBz3NwOulwrNE
32
+ 4/Q+2v0eE6R9Cvd8ngeL7QRRBEybIwRxjf6/9xWlMSg3aINSJf2GQaJjkp+uQudg
33
+ slmExVSUUidHeS4rRqh7MEiOulqAYF6UkvXFYCUGU7DRScIxGf8xPYmULaYnMSle
34
+ cpeMBFEElI6gAq+crdUFVzkF7bNFX+tEUIiGvc7daUbYpoatwogyGveoPvgOt3MC
35
+ t38iHgW3leqaRomZgNHbjQEgCCy/2VJgdwQYDSs/j++K1KtUMOgEEAAAAAAAAAAA
36
+ AAAAAAAAAAA=
37
+ BASE64
38
+
39
+ identity_or_pseudonym = PolyPseudo::PseudoId.from_asn1(encoded_asn1)
40
+
41
+ identity_key = PolyPseudo::Util.read_key(File.read('EI_Decryption.pem'))
42
+ decryption_key = PolyPseudo::Util.read_key(File.read('EP_Decryption.pem'))
43
+ closing_key = PolyPseudo::Util.read_key(File.read('EP_Closing.pem'))
44
+
45
+ case identity_or_pseudonym
46
+ when PolyPseudo::Identity
47
+ identity_or_pseudonym.decrypt(identity_key)
48
+ when PolyPseudo::Pseudonym
49
+ identity_or_pseudonym.decrypt(decryption_key, closing_key)
50
+ end
51
+
52
+ puts identity_or_pseudonym.pseudo_id
53
+ ```
54
+
55
+ ## Caveats
56
+
57
+ OpenSSL 1.0.2 is required.
58
+ On OSX the default openssl is not capable of handling the Brainpool curves.
59
+ If you installed openssl via homebrew, chances are it's not correctly configured for FFI.
60
+ You will probably get a segmentation fault if you don't have the correct version.
61
+
62
+ You can configure the openssl library location using the config
63
+
64
+ ```ruby
65
+ PolyPseudo.configure do |config|
66
+ config.ffi_lib = '/usr/local/opt/openssl/lib/libssl.dylib'
67
+ end
68
+ ```
69
+
70
+ ## Development
71
+
72
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
73
+
74
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
75
+
76
+ ## Contributing
77
+
78
+ Bug reports and pull requests are welcome on GitHub at https://github.com/digidentity/poly_pseudo.
79
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "poly_pseudo"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,78 @@
1
+ module PolyPseudo
2
+ module OpenSSLPointExtension
3
+ extend FFI::Library
4
+ ffi_lib PolyPseudo.config.ffi_lib
5
+
6
+ NID_brainpoolP320r1 = 929
7
+
8
+ POINT_CONVERSION_COMPRESSED = 2
9
+ POINT_CONVERSION_UNCOMPRESSED = 4
10
+
11
+ attach_function :EC_GROUP_new_by_curve_name, [:int], :pointer
12
+ attach_function :EC_POINT_free, [:pointer], :int
13
+ attach_function :EC_POINT_add, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
14
+ attach_function :EC_POINT_point2hex, [:pointer, :pointer, :int, :pointer], :string
15
+ attach_function :EC_POINT_hex2point, [:pointer, :string, :pointer, :pointer], :pointer
16
+ attach_function :EC_POINT_new, [:pointer], :pointer
17
+ attach_function :BN_new, [], :pointer
18
+ attach_function :BN_free, [:pointer], :int
19
+ attach_function :BN_bn2hex, [:pointer], :string
20
+ attach_function :EC_POINT_get_affine_coordinates_GFp, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
21
+
22
+ def self.add(point_0, point_1)
23
+ group = EC_GROUP_new_by_curve_name(NID_brainpoolP320r1)
24
+ point_0_hex = point_0.to_bn.to_s(16)
25
+ point_0_pt = EC_POINT_hex2point(group, point_0_hex, nil, nil)
26
+ point_1_hex = point_1.to_bn.to_s(16)
27
+ point_1_pt = EC_POINT_hex2point(group, point_1_hex, nil, nil)
28
+ sum_point = EC_POINT_new(group)
29
+ success = EC_POINT_add(group, sum_point, point_0_pt, point_1_pt, nil)
30
+ if success
31
+ hex = EC_POINT_point2hex(group, sum_point, POINT_CONVERSION_COMPRESSED, nil)
32
+ OpenSSL::PKey::EC::Point.new(PolyPseudo.config.group, OpenSSL::BN.new(hex, 16))
33
+ end
34
+ ensure
35
+ EC_POINT_free(sum_point)
36
+ end
37
+
38
+ def self.x_y(point)
39
+ group = EC_GROUP_new_by_curve_name(NID_brainpoolP320r1)
40
+ point_hex = point.to_bn.to_s(16)
41
+ point_pt = EC_POINT_hex2point(group, point_hex, nil, nil)
42
+ x_coord = BN_new()
43
+ y_coord = BN_new()
44
+
45
+ EC_POINT_get_affine_coordinates_GFp(group, point_pt, x_coord, y_coord, nil)
46
+
47
+ [OpenSSL::BN.new(BN_bn2hex(x_coord), 16), OpenSSL::BN.new(BN_bn2hex(y_coord), 16)]
48
+ ensure
49
+ BN_free(x_coord)
50
+ BN_free(y_coord)
51
+ end
52
+
53
+ def self.point2hex(point, compressed)
54
+ group = EC_GROUP_new_by_curve_name(NID_brainpoolP320r1)
55
+ point_hex = point.to_bn.to_s(16)
56
+ point_pt = EC_POINT_hex2point(group, point_hex, nil, nil)
57
+ EC_POINT_point2hex(group, point_pt, compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED, nil)
58
+ end
59
+ end
60
+ end
61
+
62
+ class OpenSSL::PKey::EC::Point
63
+ def add(point)
64
+ PolyPseudo::OpenSSLPointExtension.add(self, point)
65
+ end
66
+
67
+ def x
68
+ PolyPseudo::OpenSSLPointExtension.x_y(self)[0]
69
+ end
70
+
71
+ def y
72
+ PolyPseudo::OpenSSLPointExtension.x_y(self)[1]
73
+ end
74
+
75
+ def to_hex(compressed = true)
76
+ PolyPseudo::OpenSSLPointExtension.point2hex(self, compressed)
77
+ end
78
+ end
@@ -0,0 +1,31 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+ require 'digest'
4
+ require 'ffi'
5
+
6
+ require 'poly_pseudo/version'
7
+ require 'poly_pseudo/util'
8
+ require 'poly_pseudo/config'
9
+ require 'poly_pseudo/key'
10
+ require 'poly_pseudo/pseudo_id'
11
+ require 'poly_pseudo/identity'
12
+ require 'poly_pseudo/pseudonym'
13
+
14
+ module PolyPseudo
15
+ @@loaded = false
16
+ def self.init!
17
+ unless @@loaded
18
+ require 'ext/openssl_ec'
19
+ @@loaded = true
20
+ end
21
+ end
22
+
23
+ def self.configure
24
+ yield config
25
+ PolyPseudo.init!
26
+ end
27
+
28
+ def self.config
29
+ @@config ||= Config.new
30
+ end
31
+ end
@@ -0,0 +1,14 @@
1
+ module PolyPseudo
2
+ class Config
3
+ attr_accessor :group_name, :ffi_lib
4
+
5
+ def initialize
6
+ @group_name = 'brainpoolP320r1'
7
+ @ffi_lib = 'ssl'
8
+ end
9
+
10
+ def group
11
+ OpenSSL::PKey::EC::Group.new(group_name)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ module PolyPseudo
2
+ class Identity
3
+ include PolyPseudo::PseudoId
4
+
5
+ # @param [PolyPseudo::Key] key
6
+ def decrypt(key)
7
+ PolyPseudo.init!
8
+
9
+ public_key = key.ec.public_key
10
+
11
+ raise "Invalid key for decryption" if point_3 != public_key
12
+
13
+ private_key = key.ec.private_key
14
+
15
+ identity_point = point_1.mul(private_key)
16
+ .invert!
17
+ .add(point_2)
18
+ .make_affine!
19
+
20
+ identity_point.x.to_s(16)
21
+ @identity = Util.oaep_decode(identity_point.x.to_s(2)).slice(3, 10)
22
+ end
23
+
24
+ def identity
25
+ @identity || raise('Identity not decrypted yet. call .decrypt first')
26
+ end
27
+
28
+ alias_method :pseudo_id, :identity
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ module PolyPseudo
2
+ class Key
3
+ attr_reader :scheme_version, :scheme_key_version, :type, :recipient, :recipient_key_set_version, :ec
4
+
5
+ def initialize(attributes)
6
+ @scheme_version = attributes["SchemeVersion"]
7
+ @scheme_key_version = attributes["SchemeKeyVersion"]
8
+ @type = attributes["Type"]
9
+ @recipient = attributes["Recipient"]
10
+ @recipient_key_set_version = attributes["RecipientKeySetVersion"]
11
+ @ec = attributes["PrivateKey"]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,43 @@
1
+ module PolyPseudo
2
+ module PseudoId
3
+ def self.from_asn1(encoded)
4
+ attributes = {}
5
+ asn1 = OpenSSL::ASN1.decode(Base64.decode64(encoded))
6
+ attributes["Type"] = asn1.value[0].value.to_s
7
+ attributes["SchemaVersion"] = asn1.value[1].value.to_i
8
+ attributes["SchemaKeyVersion"] = asn1.value[2].value.to_i
9
+ attributes["Creator"] = asn1.value[3].value.to_s
10
+ attributes["Recipient"] = asn1.value[4].value.to_s
11
+ attributes["RecipientKeySetVersion"] = asn1.value[5].value.to_i
12
+ attributes["Point1"] = OpenSSL::PKey::EC::Point.new(PolyPseudo.config.group,
13
+ OpenSSL::BN.new(asn1.value[6].value[0].value, 2))
14
+ attributes["Point2"] = OpenSSL::PKey::EC::Point.new(PolyPseudo.config.group,
15
+ OpenSSL::BN.new(asn1.value[6].value[1].value, 2))
16
+ attributes["Point3"] = OpenSSL::PKey::EC::Point.new(PolyPseudo.config.group,
17
+ OpenSSL::BN.new(asn1.value[6].value[2].value, 2))
18
+
19
+ case attributes["Type"]
20
+ when /\A.*1\.2\.1\Z/
21
+ Identity.new(attributes)
22
+ when /\A.*1\.2\.1\Z/
23
+ Pseudonym.new(attributes)
24
+ else
25
+ raise "Invalid type"
26
+ end
27
+ end
28
+
29
+ attr_reader :type, :schema_version, :schema_key_version, :creator, :recipient, :recipient_key_set_version, :point_1, :point_2, :point_3
30
+
31
+ def initialize(attributes)
32
+ @type = attributes["Type"]
33
+ @schema_version = attributes["SchemaVersion"]
34
+ @schema_key_version = attributes["SchemaKeyVersion"]
35
+ @recipient = attributes["Creator"]
36
+ @recipient = attributes["Recipient"]
37
+ @recipient_key_set_version = attributes["RecipientKeySetVersion"]
38
+ @point_1 = attributes["Point1"]
39
+ @point_2 = attributes["Point2"]
40
+ @point_3 = attributes["Point3"]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ module PolyPseudo
2
+ class Pseudonym
3
+ include PolyPseudo::PseudoId
4
+
5
+ # @param [PolyPseudo::Key] closing_key
6
+ def decrypt(decryption_key, closing_key)
7
+ PolyPseudo.init!
8
+ decryption_private_key = decryption_key.ec.private_key
9
+ closing_private_key = closing_key.ec.private_key
10
+
11
+ product = decryption_private_key.mod_mul(closing_private_key, PolyPseudo.config.group.order)
12
+ point_2_multiplied = point_2.mul(closing_private_key)
13
+
14
+ pseudo_point = point_1.mul(product)
15
+ .invert!
16
+ .add(point_2_multiplied)
17
+ .make_affine!
18
+
19
+ @pseudonym = closing_key.recipient_key_set_version.to_s + pseudo_point.to_hex
20
+ end
21
+
22
+ def pseudonym
23
+ @pseudonym || raise("Pseudonym not decrypted yet. call .decrypt first")
24
+ end
25
+
26
+ alias_method :pseudo_id, :pseudonym
27
+ end
28
+ end
@@ -0,0 +1,83 @@
1
+ module PolyPseudo
2
+ module Util
3
+ extend self
4
+
5
+ # @param [String] raw in pem format with metadata
6
+ def read_key(raw)
7
+ attributes = {}
8
+ lines = raw.lines
9
+ meta_lines = lines.slice!(1, 6)
10
+ attributes["PrivateKey"] = OpenSSL::PKey::EC.new(lines.join)
11
+
12
+ meta_lines.each do |line|
13
+ key, value = line.split(":").map(&:strip)
14
+ attributes[key] = value
15
+ end
16
+
17
+ Key.new(attributes)
18
+ end
19
+
20
+ # @param [OpenSSL::BN] bn
21
+ def oaep_decode(em, p = '', hlen = 10)
22
+ raise 'message is too short!' if em.length < hlen * 2 + 1
23
+
24
+ maskedSeed = em[0...hlen]
25
+ maskedDB = em[hlen..-1]
26
+
27
+ seedMask = mgf1 maskedDB, hlen
28
+ seed = xor maskedSeed, seedMask
29
+ dbMask = mgf1 seed, em.size - hlen
30
+ db = xor maskedDB, dbMask
31
+ pHash = Digest::SHA384.digest(p)[0...hlen]
32
+
33
+ ind = db.index("\x01", hlen)
34
+ raise 'message is invalid!' if ind.nil?
35
+
36
+ pHash2 = db[0...hlen]
37
+ ps = db[hlen...ind]
38
+ m = db[(ind + 1)..-1]
39
+
40
+ raise 'message is invalid!' unless ps.bytes.all?(&:zero?)
41
+ raise "specified p = #{p.inspect} is wrong!" unless pHash2 == pHash
42
+
43
+ m
44
+ end
45
+
46
+ def self.i2osp(x, len = nil)
47
+ raise ArgumentError, "integer too large" if len && x >= 256**len
48
+
49
+ StringIO.open do |buffer|
50
+ while x > 0
51
+ b = (x & 0xFF).chr
52
+ x >>= 8
53
+ buffer << b
54
+ end
55
+ s = buffer.string
56
+ s.force_encoding(Encoding::BINARY) if s.respond_to?(:force_encoding)
57
+ s.reverse!
58
+ s = len ? s.rjust(len, "\0") : s
59
+ end
60
+ end
61
+
62
+ def self.mgf1(z, l)
63
+ t = ''
64
+
65
+ (0..(l / 10)).each { |i|
66
+ t += Digest::SHA384.digest(z + i2osp(i, 4))
67
+ }
68
+
69
+ t[0...l]
70
+ end
71
+
72
+ def self.xor s1, s2
73
+ b1 = s1.unpack('c*')
74
+ b2 = s2.unpack('c*')
75
+
76
+ if b1.length != b2.length
77
+ raise DecodeError, 'cannot xor strings of different lengths!'
78
+ end
79
+
80
+ b1.zip(b2).map { |a, b| a ^ b }.pack('c*')
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ module PolyPseudo
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'poly_pseudo/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "poly_pseudo"
8
+ spec.version = PolyPseudo::VERSION
9
+ spec.authors = ["Benoist Claassen"]
10
+ spec.email = ["bclaassen@digidentity.eu"]
11
+
12
+ spec.summary = %q{Gem to decrypt polymorphic pseudonyms and identities}
13
+ spec.description = %q{Gem to decrypt polymorphic pseudonyms and identities}
14
+ spec.homepage = "https://www.digidentity.eu"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.13"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "minitest", "~> 5.0"
26
+ spec.add_development_dependency "minitest-reporters", "~> 1.1"
27
+
28
+ spec.add_dependency "ffi", "~> 1.9"
29
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: poly_pseudo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Benoist Claassen
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: ffi
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.9'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.9'
83
+ description: Gem to decrypt polymorphic pseudonyms and identities
84
+ email:
85
+ - bclaassen@digidentity.eu
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - README.md
94
+ - Rakefile
95
+ - bin/console
96
+ - bin/setup
97
+ - lib/ext/openssl_ec.rb
98
+ - lib/poly_pseudo.rb
99
+ - lib/poly_pseudo/config.rb
100
+ - lib/poly_pseudo/identity.rb
101
+ - lib/poly_pseudo/key.rb
102
+ - lib/poly_pseudo/pseudo_id.rb
103
+ - lib/poly_pseudo/pseudonym.rb
104
+ - lib/poly_pseudo/util.rb
105
+ - lib/poly_pseudo/version.rb
106
+ - poly_pseudo.gemspec
107
+ homepage: https://www.digidentity.eu
108
+ licenses: []
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.5.1
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Gem to decrypt polymorphic pseudonyms and identities
130
+ test_files: []