miscreant 0.2.0 → 0.3.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 +4 -4
- data/README.md +15 -11
- data/ci.bat +1 -0
- data/ci.sh +6 -0
- data/lib/miscreant.rb +5 -0
- data/lib/miscreant/stream.rb +132 -0
- data/lib/miscreant/version.rb +1 -1
- data/miscreant.gemspec +2 -2
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28739a2b5b206f73877d8c3ecf7d1b90591dbbcb
|
4
|
+
data.tar.gz: d044df29dbe78614ef99cded5a1a0a3ccacbfed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 536b1a5d7b38885783b24d99e19716ab72ea5167684f190ddccb2f5740329c55af95be9782c4f2246eb4b9684e03f0f1329b92abf22d7aee698cb117619eedcc
|
7
|
+
data.tar.gz: 4aa49283f01fc63f3b15b77b92b92ce2b98c4888342943355043bb731c915934742319e9e54862f82b25fc163a4b88e82c6304706e9fd6e88a9f256a463c6cb3
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
# miscreant.rb [![Latest Version][gem-shield]][gem-link] [![Build Status][build-image]][build-link] [![
|
1
|
+
# miscreant.rb [![Latest Version][gem-shield]][gem-link] [![Build Status][build-image]][build-link] [![Yard Docs][docs-image]][docs-link] [![MIT licensed][license-image]][license-link] [![Gitter Chat][gitter-image]][gitter-link]
|
2
2
|
|
3
3
|
[gem-shield]: https://badge.fury.io/rb/miscreant.svg
|
4
4
|
[gem-link]: https://rubygems.org/gems/miscreant
|
5
5
|
[build-image]: https://secure.travis-ci.org/miscreant/miscreant.svg?branch=master
|
6
6
|
[build-link]: http://travis-ci.org/miscreant/miscreant
|
7
|
-
[
|
8
|
-
[
|
7
|
+
[docs-image]: https://img.shields.io/badge/yard-docs-blue.svg
|
8
|
+
[docs-link]: http://www.rubydoc.info/gems/miscreant/0.3.0
|
9
9
|
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
|
10
10
|
[license-link]: https://github.com/miscreant/miscreant/blob/master/LICENSE.txt
|
11
11
|
[gitter-image]: https://badges.gitter.im/badge.svg
|
@@ -13,9 +13,17 @@
|
|
13
13
|
|
14
14
|
> The best crypto you've never heard of, brought to you by [Phil Rogaway]
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
[Phil Rogaway]: https://en.wikipedia.org/wiki/Phillip_Rogaway
|
17
|
+
|
18
|
+
Ruby implementation of **Miscreant**: Advanced symmetric encryption library
|
19
|
+
which provides the [AES-SIV] ([RFC 5297]), [AES-PMAC-SIV], and [STREAM]
|
20
|
+
constructions. These algorithms are easy-to-use (or rather, hard-to-misuse)
|
21
|
+
and support encryption of individual messages or message streams.
|
22
|
+
|
23
|
+
[AES-SIV]: https://github.com/miscreant/miscreant/wiki/AES-SIV
|
24
|
+
[RFC 5297]: https://tools.ietf.org/html/rfc5297
|
25
|
+
[AES-PMAC-SIV]: https://github.com/miscreant/miscreant/wiki/AES-PMAC-SIV
|
26
|
+
[STREAM]: https://github.com/miscreant/miscreant/wiki/STREAM
|
19
27
|
|
20
28
|
**AES-SIV** provides [nonce-reuse misuse-resistance] (NRMR): accidentally
|
21
29
|
reusing a nonce with this construction is not a security catastrophe,
|
@@ -27,11 +35,7 @@ full plaintext recovery.
|
|
27
35
|
|
28
36
|
For more information, see the [toplevel README.md].
|
29
37
|
|
30
|
-
[
|
31
|
-
[AES-SIV]: https://www.iacr.org/archive/eurocrypt2006/40040377/40040377.pdf
|
32
|
-
[RFC 5297]: https://tools.ietf.org/html/rfc5297
|
33
|
-
[CHAIN/STREAM]: http://web.cs.ucdavis.edu/~rogaway/papers/oae.pdf
|
34
|
-
[nonce-reuse misuse-resistance]: https://www.lvh.io/posts/nonce-misuse-resistance-101.html
|
38
|
+
[nonce-reuse misuse-resistance]: https://github.com/miscreant/miscreant/wiki/Nonce-Reuse-Misuse-Resistance
|
35
39
|
[AES-GCM]: https://en.wikipedia.org/wiki/Galois/Counter_Mode
|
36
40
|
[chosen ciphertext attacks]: https://en.wikipedia.org/wiki/Chosen-ciphertext_attack
|
37
41
|
[toplevel README.md]: https://github.com/miscreant/miscreant/blob/master/README.md
|
data/ci.bat
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bundle && bundle exec rake spec
|
data/lib/miscreant.rb
CHANGED
@@ -5,11 +5,13 @@ require "openssl"
|
|
5
5
|
require "securerandom"
|
6
6
|
|
7
7
|
require "miscreant/version"
|
8
|
+
|
8
9
|
require "miscreant/aead"
|
9
10
|
require "miscreant/aes/cmac"
|
10
11
|
require "miscreant/aes/pmac"
|
11
12
|
require "miscreant/aes/siv"
|
12
13
|
require "miscreant/internals"
|
14
|
+
require "miscreant/stream"
|
13
15
|
|
14
16
|
# Miscreant: A misuse-resistant symmetric encryption library
|
15
17
|
module Miscreant
|
@@ -19,6 +21,9 @@ module Miscreant
|
|
19
21
|
# Ciphertext failed to verify as authentic
|
20
22
|
IntegrityError = Class.new(CryptoError)
|
21
23
|
|
24
|
+
# Integer value overflowed
|
25
|
+
OverflowError = Class.new(StandardError)
|
26
|
+
|
22
27
|
# Hide internals from the outside world
|
23
28
|
private_constant :Internals
|
24
29
|
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# encoding: binary
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Miscreant
|
5
|
+
# The STREAM online authenticated encryption construction.
|
6
|
+
# See <https://eprint.iacr.org/2015/189.pdf> for definition.
|
7
|
+
#
|
8
|
+
# Miscreant's implementation of STREAM uses an 8-byte (64-bit) nonce
|
9
|
+
# prefix along with a 32-bit counter and 1-byte "last block" flag
|
10
|
+
module STREAM
|
11
|
+
# Size of a nonce required by STREAM in bytes
|
12
|
+
NONCE_SIZE = 8
|
13
|
+
|
14
|
+
# Byte flag indicating this is the last block in the STREAM (otherwise 0)
|
15
|
+
LAST_BLOCK_FLAG = 1
|
16
|
+
|
17
|
+
# Maximum value of the STREAM counter
|
18
|
+
COUNTER_MAX = 2**32
|
19
|
+
|
20
|
+
# Raised if we attempt to continue an already-finished STREAM
|
21
|
+
FinishedError = Class.new(StandardError)
|
22
|
+
|
23
|
+
# A STREAM encryptor
|
24
|
+
#
|
25
|
+
# This corresponds to the ℰ stream encryptor object as defined in the paper
|
26
|
+
# Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance
|
27
|
+
class Encryptor
|
28
|
+
# Create a new STREAM encryptor.
|
29
|
+
#
|
30
|
+
# @param alg ["AES-SIV", "AES-PMAC-SIV"] cryptographic algorithm to use
|
31
|
+
# @param key [String] 32-byte or 64-byte random Encoding::BINARY secret key
|
32
|
+
# @param nonce [String] 8-byte nonce
|
33
|
+
#
|
34
|
+
# @raise [TypeError] nonce is not a String
|
35
|
+
# @raise [ArgumentError] nonce is wrong length or not Encoding::BINARY
|
36
|
+
def initialize(alg, key, nonce)
|
37
|
+
@aead = AEAD.new(alg, key)
|
38
|
+
@nonce_encoder = NonceEncoder.new(nonce)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Encrypt the next message in the stream
|
42
|
+
#
|
43
|
+
# @param plaintext [String] plaintext message to encrypt
|
44
|
+
# @param ad [String] (optional) associated data to authenticate
|
45
|
+
# @param last_block [true, false] is this the last block in the STREAM?
|
46
|
+
#
|
47
|
+
# @return [String] ciphertext message
|
48
|
+
def seal(plaintext, ad: "", last_block: false)
|
49
|
+
@aead.seal(plaintext, nonce: @nonce_encoder.next(last_block), ad: ad)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Inspect this STREAM encryptor instance
|
53
|
+
#
|
54
|
+
# @return [String] description of this instance
|
55
|
+
def inspect
|
56
|
+
to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# A STREAM decryptor
|
61
|
+
#
|
62
|
+
# This corresponds to the 𝒟 stream decryptor object as defined in the paper
|
63
|
+
# Online Authenticated-Encryption and its Nonce-Reuse Misuse-Resistance
|
64
|
+
class Decryptor
|
65
|
+
# Create a new STREAM decryptor.
|
66
|
+
#
|
67
|
+
# @param alg ["AES-SIV", "AES-PMAC-SIV"] cryptographic algorithm to use
|
68
|
+
# @param key [String] 32-byte or 64-byte random Encoding::BINARY secret key
|
69
|
+
# @param nonce [String] 8-byte nonce
|
70
|
+
#
|
71
|
+
# @raise [TypeError] nonce is not a String
|
72
|
+
# @raise [ArgumentError] nonce is wrong length or not Encoding::BINARY
|
73
|
+
def initialize(alg, key, nonce)
|
74
|
+
@aead = AEAD.new(alg, key)
|
75
|
+
@nonce_encoder = NonceEncoder.new(nonce)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Decrypt the next message in the stream
|
79
|
+
#
|
80
|
+
# @param ciphertext [String] cipher message to encrypt
|
81
|
+
# @param ad [String] (optional) associated data to authenticate
|
82
|
+
# @param last_block [true, false] is this the last block in the STREAM?
|
83
|
+
#
|
84
|
+
# @raise [Miscreant::IntegrityError] ciphertext and/or associated data are corrupt or tampered with
|
85
|
+
# @return [String] plaintext message
|
86
|
+
def open(ciphertext, ad: "", last_block: false)
|
87
|
+
@aead.open(ciphertext, nonce: @nonce_encoder.next(last_block), ad: ad)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Inspect this STREAM encryptor instance
|
91
|
+
#
|
92
|
+
# @return [String] description of this instance
|
93
|
+
def inspect
|
94
|
+
to_s
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
# Computes STREAM nonces based on the current position in the STREAM.
|
99
|
+
class NonceEncoder
|
100
|
+
# Create a new nonce encoder with the given prefix
|
101
|
+
#
|
102
|
+
# @param [nonce_prefix] 64-bit string used as the STREAM nonce prefix
|
103
|
+
#
|
104
|
+
# @raise [TypeError] nonce prefix is not a String
|
105
|
+
# @raise [ArgumentError] nonce prefix is wrong length or not Encoding::BINARY
|
106
|
+
def initialize(nonce_prefix)
|
107
|
+
Internals::Util.validate_bytestring("nonce", nonce_prefix, length: NONCE_SIZE)
|
108
|
+
@nonce_prefix = nonce_prefix
|
109
|
+
@counter = 0
|
110
|
+
@finished = false
|
111
|
+
end
|
112
|
+
|
113
|
+
# Obtain the next nonce in the stream
|
114
|
+
#
|
115
|
+
# @param last_block [true, false] is this the last block?
|
116
|
+
#
|
117
|
+
# @return [String] encoded STREAM nonce
|
118
|
+
def next(last_block)
|
119
|
+
raise FinishedError, "STREAM is already finished" if @finished
|
120
|
+
@finished = last_block
|
121
|
+
|
122
|
+
encoded_nonce = [@nonce_prefix, @counter, last_block ? LAST_BLOCK_FLAG : 0].pack("a8NC")
|
123
|
+
@counter += 1
|
124
|
+
raise OverflowError, "STREAM counter overflowed" if @counter >= COUNTER_MAX
|
125
|
+
|
126
|
+
encoded_nonce
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
private_constant :NonceEncoder
|
131
|
+
end
|
132
|
+
end
|
data/lib/miscreant/version.rb
CHANGED
data/miscreant.gemspec
CHANGED
@@ -11,8 +11,8 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.email = ["bascule@gmail.com"]
|
12
12
|
spec.summary = "Misuse-resistant authenticated symmetric encryption"
|
13
13
|
spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
14
|
-
Misuse
|
15
|
-
and
|
14
|
+
Misuse resistant symmetric encryption library providing AES-SIV (RFC 5297),
|
15
|
+
AES-PMAC-SIV, and STREAM constructions
|
16
16
|
DESCRIPTION
|
17
17
|
|
18
18
|
spec.version = Miscreant::VERSION
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miscreant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,8 @@ files:
|
|
38
38
|
- Gemfile
|
39
39
|
- README.md
|
40
40
|
- Rakefile
|
41
|
+
- ci.bat
|
42
|
+
- ci.sh
|
41
43
|
- lib/miscreant.rb
|
42
44
|
- lib/miscreant/aead.rb
|
43
45
|
- lib/miscreant/aes/cmac.rb
|
@@ -48,6 +50,7 @@ files:
|
|
48
50
|
- lib/miscreant/internals/aes/ctr.rb
|
49
51
|
- lib/miscreant/internals/block.rb
|
50
52
|
- lib/miscreant/internals/util.rb
|
53
|
+
- lib/miscreant/stream.rb
|
51
54
|
- lib/miscreant/version.rb
|
52
55
|
- miscreant.gemspec
|
53
56
|
homepage: https://github.com/miscreant/miscreant/tree/master/ruby/
|
@@ -70,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
73
|
version: '0'
|
71
74
|
requirements: []
|
72
75
|
rubyforge_project:
|
73
|
-
rubygems_version: 2.6.
|
76
|
+
rubygems_version: 2.6.13
|
74
77
|
signing_key:
|
75
78
|
specification_version: 4
|
76
79
|
summary: Misuse-resistant authenticated symmetric encryption
|