saltpack 0.1.0.pre.20200506181314

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'msgpack'
5
+ require 'rbnacl'
6
+
7
+ require 'saltpack' unless defined?( Saltpack )
8
+
9
+ # A recipient in a Saltpack header.
10
+ class Saltpack::Recipient
11
+
12
+
13
+ ### Create a new Saltbox::Recipient using their +public_key+.
14
+ def initialize( public_key )
15
+ @public_key = public_key
16
+ end
17
+
18
+
19
+ ######
20
+ public
21
+ ######
22
+
23
+ ##
24
+ # The recipient's public key
25
+ attr_reader :public_key
26
+
27
+
28
+ ###
29
+ def payload_key_box
30
+
31
+ end
32
+
33
+ end # class Saltpack::Recipient
@@ -0,0 +1,38 @@
1
+ # -*- ruby -*-
2
+ # frozen_string_literal: true
3
+
4
+ require 'rbnacl'
5
+
6
+ require 'saltpack' unless defined?( Saltpack )
7
+
8
+
9
+ module Saltpack::Refinements
10
+
11
+ refine RbNaCl::Box do
12
+
13
+ ### Get the shared key for the box derived from the specified +public_key+ and
14
+ ### +private_key+.
15
+ def self::beforenm( public_key, private_key )
16
+ key = RbNaCl::Utils.zeros( RbNaCl::Box::BEFORENMBYTES )
17
+ self.box_curve25519xsalsa20poly1305_beforenm( key, public_key, private_key ) or
18
+ return nil
19
+
20
+ return key
21
+ end
22
+
23
+
24
+ ### Decrypt the specified +num_bytes+ of +ciphertext+ using the given +nonce+
25
+ ### and +beforenm+.
26
+ def self::open_afternm( ciphertext, beforenm, nonce, num_bytes )
27
+ message = RbNaCl::Utils.zeros( num_bytes )
28
+ # m,c,clen,n,k
29
+ self.box_curve25519xsalsa20poly1305_open_afternm( message,
30
+ ciphertext, ciphertext.bytesize, nonce, beforenm ) or return nil
31
+
32
+ return message
33
+ end
34
+
35
+ end # refine RbNaCl::Box
36
+
37
+ end # module Saltpack::Refinements
38
+
@@ -0,0 +1 @@
1
+ BEGIN SALTPACK ENCRYPTED MESSAGE. kfIwgFPlzTTT0Og Kbn6DhSfhdijxPo i3hNtd1WJb8mlkO sAJbPf3zfiM1Lv1 bZ3xL1vcHmPuO9N lo05gdRKD5FwWoB ym9HRewWXSMvxjM PRSHSqTeQlx9hDy cdx3ejyR0TAGovj twNYhdiku6YyycY ld0o4jz8Vua8aY4 yAV9Ha3REXQRzrw iNkycKpi5Mf1d7m qrp9XM1DbUa8qAI 5Bx4DE1n1tmSPBN M8rj6oQa5ygJs2Y zFgRVk1N0f9HvcD yUk28P7XIZxIXTc Jb9kneJIRaciqhA CEfbkXY9iGPQAFU LSRzUbjEhJotszN 8xRKodgMeA0dQSS DjEJQYNF2Ffcvx5 TIMtNlwgorUwpHo G0e04o3zLtdFrYM r4jL61tMTi0Os38 mKMuCaf2hSxLZKE YimkLXEUGsjlKNF EN4kpIhyWLGUMmY 0SYrQn2fcpsDVGn iPoUj1tFHUaw3vQ CG0iwreDyR9Cxad 1th1KHqlwk1TUiS UuP9HiXsAoyhIpT BNzL0pDlUm0VeGb jrVIZYpHJMX3nWd M0TTihQPZlIAJRP JseJRjQPTmmgQay wUgMLCw5HgG9wEh l37X5CrPVZlldJB yRCemVHtkbAgOwL xvJ2jWnnF8K3OCg DiDbVVyPaLXJacC DcyUM4kg1EFYULK zGZ1xgsst8QFlIa vFJwcLawn3PVk58 Jvzq4NyZebf1LgR j5L2ITHsZI3TABO IqHdfKKsjmmx87G Rgooq5oaPu7Aj6l qw80hk1teljUSXO 3yllISVthrdth1X 8SXaI9G2cGQcWW0 BcqwXyEnxKlE3Xd ENkjHW3xDIk40T1 JH1cvrdfCRfoiQX K0enlacL8X81qkn CgaMw24CQIJPpzd vuLsEsl4t6Cv477 y7Yw82pF6Q2UeWj JxAYfdP81wv7u28 tZJChPyUbEO3klA ckj4UYb3SJ06kCP npsgZe4qjvxUhKl fLMAjFnOaNxNxJL BgDIHA5w0TYeQ3V Y4GdymuVwfjZrM1 GPl0hio8At8NtjI UzE28ScUpjM2kVS kvcGor0byThrel2 DNb0zUOl8TdP6pB AQCYtYqNUFdzFAS O7MtSGQc6uF1kmn Rl5Pin2oTncSjVS VUh3XLTk45edMfx tC0yZi38qssEbMe Lusihf6H. END SALTPACK ENCRYPTED MESSAGE.
@@ -0,0 +1,16 @@
1
+ Once there came a man
2
+ Who said:
3
+ “Range me all men of the world in rows.”
4
+ And instantly
5
+ There was a terrific clamor among the people
6
+ Against being ranged in rows.
7
+ There was a loud quarrel, world-wide.
8
+ It endured for ages;
9
+ And blood was shed
10
+ By those who would not stand in rows,
11
+ And by those who pined to stand in rows.
12
+ Eventually, the man went to death, weeping.
13
+ And those who stayed in the bloody scuffle
14
+ Knew not the great simplicity.
15
+
16
+ - Stephen Crane
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ require 'saltpack/armor'
6
+
7
+
8
+ describe Saltpack::Armor do
9
+
10
+ INPUT_STRING = <<~END_PLAINTEXT
11
+ Two roads diverged in a yellow wood, and sorry I could not travel both
12
+ and be one traveller, long I stood, and looked down one as far as I
13
+ could, to where it bent in the undergrowth.
14
+ END_PLAINTEXT
15
+
16
+
17
+ it "can be round-tripped" do
18
+ encoded = described_class.armor( INPUT_STRING )
19
+ Saltpack.log.debug "encoded: %p" % [ encoded ]
20
+ decoded = described_class.dearmor( encoded )
21
+ Saltpack.log.debug "decoded: %p" % [ decoded ]
22
+
23
+ expect( decoded ).to eq( INPUT_STRING )
24
+ end
25
+
26
+
27
+ it "can be round-tripped in raw format" do
28
+ encoded = described_class.armor( INPUT_STRING, raw: true )
29
+ decoded = described_class.dearmor( encoded, raw: true )
30
+
31
+ expect( decoded ).to eq( INPUT_STRING )
32
+ end
33
+
34
+
35
+ describe "blocks" do
36
+
37
+ it "can be round-tripped" do
38
+ blocked = described_class.encode_block( INPUT_STRING )
39
+ unblocked = described_class.decode_block( blocked )
40
+
41
+ expect( unblocked ).to eq( INPUT_STRING )
42
+ end
43
+
44
+ end
45
+
46
+
47
+ describe "efficient block sizes" do
48
+
49
+ it "can be calculated for a given alphabet size" do
50
+ results = described_class.efficient_chars_sizes( 64 )
51
+ expect( results ).to include( [4, 3, 0.75] )
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ require 'rbnacl'
6
+ require 'msgpack'
7
+
8
+ require 'saltpack'
9
+
10
+
11
+ describe Saltpack::Header do
12
+
13
+ let( :sender_key ) { RbNaCl::PrivateKey.generate }
14
+ let( :sender_public_key ) { sender_key.public_key }
15
+
16
+ let( :recipient_keys ) do
17
+ 4.times.map { RbNaCl::PrivateKey.generate }
18
+ end
19
+ let( :recipient_public_keys ) do
20
+ recipient_keys.map( &:public_key )
21
+ end
22
+
23
+
24
+ it "can generate a valid Saltpack header" do
25
+ header = described_class.new( sender_key: sender_key )
26
+ header.recipients.append( *recipient_public_keys )
27
+
28
+ data = header.data
29
+ once_unpacked = MessagePack.unpack( data )
30
+ twice_unpacked = MessagePack.unpack( once_unpacked )
31
+
32
+ expect( header.hash ).to eq( RbNaCl::Hash.sha512(once_unpacked) )
33
+ expect( twice_unpacked ).to be_an( Array )
34
+ expect( twice_unpacked.length ).to eq( 6 )
35
+ end
36
+
37
+
38
+ it "can set the mode as a Symbol" do
39
+ header = described_class.new
40
+ header.mode = :detached_signing
41
+
42
+ expect( header.mode ).to eq( :detached_signing )
43
+ expect( header.numeric_mode ).to eq( 2 )
44
+ end
45
+
46
+
47
+ it "can set the mode as an Integer" do
48
+ header = described_class.new
49
+ header.mode = 4
50
+
51
+ expect( header.mode ).to eq( :signcryption )
52
+ expect( header.numeric_mode ).to eq( 4 )
53
+ end
54
+
55
+
56
+ it "raises if the mode is set to an invalid value" do
57
+ header = described_class.new
58
+
59
+ expect {
60
+ header.mode = 18
61
+ }.to raise_error( ArgumentError, /invalid/i )
62
+ end
63
+
64
+
65
+ it "can be parsed from a string" do
66
+ hdr = described_class.parse( "", recipient_keys )
67
+
68
+ expect( hdr ).to be_a( described_class )
69
+ expect( hdr.format_name ).to eq( "saltpack" )
70
+ expect( hdr.version ).to eq([ 2, 0 ])
71
+ expect( hdr.numeric_mode ).to eq( 0 )
72
+ expect( hdr.mode ).to eq( :encryption )
73
+ expect( hdr.numeric_mode ).to eq( 0 )
74
+ expect( hdr.ephemeral_public_key ).to match( /\A.{32}\z/n )
75
+ expect( hdr.sender_secretbox ).to be_a( RbNaCl::SecretBox )
76
+ expect( hdr.recipients ).to be_an( Array ).and( all be_a Saltpack::Recipient )
77
+ end
78
+
79
+
80
+ it "raises an appropriate exception if asked to parse anything other than msgpack format" do
81
+ expect {
82
+ described_class.parse( "\xc1", recipient_keys )
83
+ }.to raise_error( Saltpack::MalformedMessage )
84
+ end
85
+
86
+ end
87
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env rspec -cfd
2
+
3
+ require_relative '../spec_helper'
4
+
5
+ require 'saltpack'
6
+
7
+
8
+ describe Saltpack::Recipient do
9
+
10
+ let( :ephemeral_private_key ) { RbNaCl::PrivateKey.generate }
11
+ let( :ephemeral_public_key ) { ephemeral_private_key.public_key }
12
+
13
+ let( :recipient_private_key ) { RbNaCl::PrivateKey.generate }
14
+ let( :recipient_public_key ) { recipient_private_key.public_key }
15
+
16
+
17
+ it "can be created with a NaCl public key" do
18
+ recipient = described_class.new( recipient_public_key )
19
+
20
+ expect( recipient ).to be_a( described_class )
21
+ expect( recipient.payload_key_box ).to be_a( RbNaCl::Box )
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env rspec -cfd
2
+ #encoding: utf-8
3
+
4
+ require_relative 'spec_helper'
5
+
6
+ require 'rspec'
7
+ require 'saltpack'
8
+
9
+ describe Saltpack do
10
+
11
+ KEY1_PRIVATE = '82d2cd66f092bd818e083e6739b8d15c58d04b73dff5d1bc95c26b0ace849bb3'
12
+ KEY1_PUBLIC = '864a7cc8e98e956afa59ad3a7c9bd6ee578a2c1ce5ea6c450120ac6cdd727ee2'
13
+
14
+ KEY2_PRIVATE = 'c4ac045f627ed4203a62fad6ee1aeb1ad59c1ed389143e14857a79d011daa7e5'
15
+ KEY2_PUBLIC = 'a123fb8b2de9eb142d5c8283b0bfc6076bc94d5a24039e8d485cae2d81e18293'
16
+
17
+ KEYBASE_TEST_MESSAGE = read_test_data( 'msg1.txt' )
18
+ KEYBASE_TEST_CIPHERTEXT = read_test_data( 'msg1-ciphertext.txt' )
19
+
20
+ KEYBASE_TEST_CIPHERTEXT_CORRUPT = KEYBASE_TEST_CIPHERTEXT.sub( /7/, 'h' )
21
+
22
+ MALFORMED_MESSAGE = \
23
+ # badness here ↓
24
+ "\xc4\x97\x96\xa8XXXXpack\x92\x01\x00\x00\xc4 \xf6\xa9\x9e\xe2\xac7\x8c.B" \
25
+ "o\x02-\x8b}^\xf0\x90\xee4_C\xeb\xc9\x842\x1fe\xbf\xd8\x18\x0bb\xc402\xe9" \
26
+ "\xc6c\xcf;=;\xfd\x17\xc5\xc1\x04\"\xa7\xc9\xe9\xb0*\xc2\xbfa\xa0<\xc4 T" \
27
+ "\x7f\xc4-z\x8d\xa4\x07\xd6\xa1\xa1\xecP\xf5\x1b\n\xc2\xdc\x952\xf09\x91" \
28
+ "\x92\xc0\xc40\xd0\xf3\xdcM[\x94\xb0F\xa0l\x109\xd64\xd6\x89\x7f\x12.\x13" \
29
+ "/C\x83\xd6\xba\xbaQ\xf1W\x990\x94\x83\x10fh\x9c\xa8$]\x7fn\x93*\x99\x83" \
30
+ "\xe4\x0e\x92\x91\xc4 y\xe1*\xbda\x9bE\x85+7\xfd\xfasE\xf6\xaa\x9f\x97o" \
31
+ "\xa4\xfeB\xf5r\xcb\x01\x8a\xd9\xa5d\xbc\xa6\xc4\x10:\x0b\x8f\xbf\xfa>#" \
32
+ "\xaa\xe3ax\xfb\xd2?M\x9c".b
33
+
34
+ BAD_VERSION_MESSAGE = \
35
+ # badness here ↓
36
+ "\xc4\x97\x96\xa8saltpack\x92\xff\x00\x00\xc4 \xf6\xa9\x9e\xe2\xac7\x8c.B" \
37
+ "o\x02-\x8b}^\xf0\x90\xee4_C\xeb\xc9\x842\x1fe\xbf\xd8\x18\x0bb\xc402\xe9" \
38
+ "\xc6c\xcf;=;\xfd\x17\xc5\xc1\x04\"\xa7\xc9\xe9\xb0*\xc2\xbfa\xa0<\xc4 T" \
39
+ "\x7f\xc4-z\x8d\xa4\x07\xd6\xa1\xa1\xecP\xf5\x1b\n\xc2\xdc\x952\xf09\x91" \
40
+ "\x92\xc0\xc40\xd0\xf3\xdcM[\x94\xb0F\xa0l\x109\xd64\xd6\x89\x7f\x12.\x13" \
41
+ "/C\x83\xd6\xba\xbaQ\xf1W\x990\x94\x83\x10fh\x9c\xa8$]\x7fn\x93*\x99\x83" \
42
+ "\xe4\x0e\x92\x91\xc4 y\xe1*\xbda\x9bE\x85+7\xfd\xfasE\xf6\xaa\x9f\x97o" \
43
+ "\xa4\xfeB\xf5r\xcb\x01\x8a\xd9\xa5d\xbc\xa6\xc4\x10:\x0b\x8f\xbf\xfa>#" \
44
+ "\xaa\xe3ax\xfb\xd2?M\x9c".b
45
+
46
+
47
+ describe "encryption" do
48
+
49
+ xit "can encrypt and decrypt with defaults" do
50
+ result = described_class.encrypt( KEYBASE_TEST_MESSAGE )
51
+ expect( described_class.decrypt(result) ).to eq( KEYBASE_TEST_MESSAGE )
52
+ end
53
+
54
+
55
+ xit "can decrypt with a secret key" do
56
+ ciphertext_binary = described_class.dearmor( KEYBASE_TEST_CIPHERTEXT )
57
+ result = described_class.decrypt( ciphertext_binary, KEY2_PRIVATE )
58
+ expect( result ).to eq( KEYBASE_TEST_MESSAGE )
59
+ end
60
+
61
+
62
+ xit "errors when the message armor has been tampered with" do
63
+ ciphertext_binary = described_class.dearmor( KEYBASE_TEST_CIPHERTEXT_CORRUPT )
64
+ expect {
65
+ described_class.decrypt( ciphertext_binary, KEY2_PRIVATE )
66
+ }.to raise_error( Saltpack::HMACError )
67
+ end
68
+
69
+
70
+ xit "errors when the message is malformed" do
71
+ expect {
72
+ described_class.decrypt( MALFORMED_MESSAGE )
73
+ }.to raise_error( Saltpack::MalformedMessage )
74
+ end
75
+
76
+
77
+ xit "errors when the message is the wrong version" do
78
+ expect {
79
+ described_class.decrypt( BAD_VERSION_MESSAGE )
80
+ }.to raise_error( Saltpack::UnsupportedVersion )
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,43 @@
1
+ # -*- ruby -*-
2
+ #encoding: utf-8
3
+
4
+ require 'simplecov' if ENV['COVERAGE']
5
+
6
+ require 'pathname'
7
+ require 'rspec'
8
+ require 'loggability/spechelpers'
9
+
10
+ require 'saltpack'
11
+
12
+
13
+ module Saltpack::SpecHelpers
14
+
15
+ SPEC_DIR = Pathname( __FILE__ ).parent
16
+ DATA_DIR = SPEC_DIR + 'data'
17
+
18
+
19
+ ### Load a file named +name+ from the test data directory and return it as a
20
+ ### frozen String.
21
+ def read_test_data( name, **options )
22
+ path = DATA_DIR + name
23
+ return path.read( **options )
24
+ end
25
+
26
+
27
+ end # module Saltpack::SpecHelpers
28
+
29
+
30
+ ### Mock with RSpec
31
+ RSpec.configure do |config|
32
+ config.run_all_when_everything_filtered = true
33
+ config.filter_run :focus
34
+ config.order = 'random'
35
+ config.mock_with( :rspec ) do |mock|
36
+ mock.syntax = :expect
37
+ end
38
+
39
+ config.include( Loggability::SpecHelpers )
40
+ config.extend( Saltpack::SpecHelpers )
41
+ end
42
+
43
+
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: saltpack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre.20200506181314
5
+ platform: ruby
6
+ authors:
7
+ - Michael Granger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIID+DCCAmCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQDDBdnZWQv
14
+ REM9RmFlcmllTVVEL0RDPW9yZzAeFw0xOTEyMjQyMDE5NTFaFw0yMDEyMjMyMDE5
15
+ NTFaMCIxIDAeBgNVBAMMF2dlZC9EQz1GYWVyaWVNVUQvREM9b3JnMIIBojANBgkq
16
+ hkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyVhkRzvlEs0fe7145BYLfN6njX9ih5H
17
+ L60U0p0euIurpv84op9CNKF9tx+1WKwyQvQP7qFGuZxkSUuWcP/sFhDXL1lWUuIl
18
+ M4uHbGCRmOshDrF4dgnBeOvkHr1fIhPlJm5FO+Vew8tSQmlDsosxLUx+VB7DrVFO
19
+ 5PU2AEbf04GGSrmqADGWXeaslaoRdb1fu/0M5qfPTRn5V39sWD9umuDAF9qqil/x
20
+ Sl6phTvgBrG8GExHbNZpLARd3xrBYLEFsX7RvBn2UPfgsrtvpdXjsHGfpT3IPN+B
21
+ vQ66lts4alKC69TE5cuKasWBm+16A4aEe3XdZBRNmtOu/g81gvwA7fkJHKllJuaI
22
+ dXzdHqq+zbGZVSQ7pRYHYomD0IiDe1DbIouFnPWmagaBnGHwXkDT2bKKP+s2v21m
23
+ ozilJg4aar2okb/RA6VS87o+d7g6LpDDMMQjH4G9OPnJENLdhu8KnPw/ivSVvQw7
24
+ N2I4L/ZOIe2DIVuYH7aLHfjZDQv/mNgpAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYD
25
+ VR0PBAQDAgSwMB0GA1UdDgQWBBRyjf55EbrHagiRLqt5YAd3yb8k4DANBgkqhkiG
26
+ 9w0BAQsFAAOCAYEAifxlz7x0EfT3fjhM520ZEIrWa+tLMuLKNefkY18u8tZnx4EX
27
+ Xxwh3tna3fvNfrOrdY5leIj1dbv4FTRg+gIBnIxAySqvpGvI/Axg5EdYbwninCLL
28
+ LAKCmRo+5QwaPMYN2zdHIjGrp8jg1neCo5zy6tVvyTv0DMI6FLrydVJYduMMDFSy
29
+ gQKR1rVOcCJtnBnLCF9+kKEUKohAHOmGsE7OBZFnjMIpH5yUDUVJKByv0gIipFt0
30
+ 1T6zff6oVU0w8WBiNKR381+6sF3wIZVnVY0XeJg6hNL+YecE8ILxLhHTmtT/BO0S
31
+ 3xPze9uXDR+iD6HYl8KU5QEg/dXFPhfQb512vVkTJDZvMcwu6PxDUjHFChLjAji/
32
+ AZXjg1C5E9znTkeUR8ieU9F1MOKoiH57a5lYSTI8Ga8PpsNXTxNeXc16Ob26CqrJ
33
+ 83uuAYSy65yXDGXXPVBeKPVnYrqp91pqpS5Nh7wfuiCrE8lgU8PATh7K4BV1UhAT
34
+ 0MHbAT42wTYkfUj3
35
+ -----END CERTIFICATE-----
36
+ date: 2020-05-06 00:00:00.000000000 Z
37
+ dependencies:
38
+ - !ruby/object:Gem::Dependency
39
+ name: loggability
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - "~>"
43
+ - !ruby/object:Gem::Version
44
+ version: '0.14'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - "~>"
50
+ - !ruby/object:Gem::Version
51
+ version: '0.14'
52
+ - !ruby/object:Gem::Dependency
53
+ name: rbnacl
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '5.0'
59
+ type: :runtime
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '5.0'
66
+ - !ruby/object:Gem::Dependency
67
+ name: msgpack
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '1.2'
73
+ type: :runtime
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '1.2'
80
+ - !ruby/object:Gem::Dependency
81
+ name: hoe-deveiate
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '0.10'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '0.10'
94
+ - !ruby/object:Gem::Dependency
95
+ name: simplecov
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '0.7'
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '0.7'
108
+ - !ruby/object:Gem::Dependency
109
+ name: rdoc-generator-fivefish
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '0.3'
115
+ type: :development
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '0.3'
122
+ - !ruby/object:Gem::Dependency
123
+ name: rdoc
124
+ requirement: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '6.2'
129
+ type: :development
130
+ prerelease: false
131
+ version_requirements: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '6.2'
136
+ description: A Ruby implementation of Saltpack, a modern crypto messaging format based
137
+ on Dan Bernstein's {NaCl}[https://nacl.cr.yp.to/].
138
+ email:
139
+ - ged@faeriemud.org
140
+ executables: []
141
+ extensions: []
142
+ extra_rdoc_files: []
143
+ files:
144
+ - ".document"
145
+ - ".rdoc_options"
146
+ - ".simplecov"
147
+ - ChangeLog
148
+ - History.md
149
+ - LICENSE.txt
150
+ - Manifest.txt
151
+ - README.md
152
+ - Rakefile
153
+ - examples/post_signed_message.rb
154
+ - lib/saltpack.rb
155
+ - lib/saltpack/armor.rb
156
+ - lib/saltpack/errors.rb
157
+ - lib/saltpack/header.rb
158
+ - lib/saltpack/message.rb
159
+ - lib/saltpack/payload.rb
160
+ - lib/saltpack/recipient.rb
161
+ - lib/saltpack/refinements.rb
162
+ - spec/data/msg1-ciphertext.txt
163
+ - spec/data/msg1.txt
164
+ - spec/saltpack/armor_spec.rb
165
+ - spec/saltpack/header_spec.rb
166
+ - spec/saltpack/recipient_spec.rb
167
+ - spec/saltpack_spec.rb
168
+ - spec/spec_helper.rb
169
+ homepage: https://hg.sr.ht/~ged/Saltpack
170
+ licenses:
171
+ - MIT
172
+ metadata: {}
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">"
185
+ - !ruby/object:Gem::Version
186
+ version: 1.3.1
187
+ requirements: []
188
+ rubygems_version: 3.0.6
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: A Ruby implementation of Saltpack, a modern crypto messaging format based
192
+ on Dan Bernstein's {NaCl}[https://nacl.cr.yp.to/].
193
+ test_files: []