poly_pseudo 0.1.0

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.
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: []