rbnacl 1.0.0.pre

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.
Files changed (68) hide show
  1. data/.coveralls.yml +1 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +21 -0
  5. data/.yardopts +1 -0
  6. data/CHANGES.md +4 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE.txt +23 -0
  9. data/README.md +179 -0
  10. data/Rakefile +5 -0
  11. data/images/dragons.png +0 -0
  12. data/images/ed25519.png +0 -0
  13. data/images/logo.png +0 -0
  14. data/lib/rbnacl.rb +46 -0
  15. data/lib/rbnacl/auth.rb +78 -0
  16. data/lib/rbnacl/auth/one_time.rb +38 -0
  17. data/lib/rbnacl/box.rb +141 -0
  18. data/lib/rbnacl/encoder.rb +44 -0
  19. data/lib/rbnacl/encoders/base32.rb +33 -0
  20. data/lib/rbnacl/encoders/base64.rb +30 -0
  21. data/lib/rbnacl/encoders/hex.rb +30 -0
  22. data/lib/rbnacl/encoders/raw.rb +12 -0
  23. data/lib/rbnacl/hash.rb +48 -0
  24. data/lib/rbnacl/hmac/sha256.rb +32 -0
  25. data/lib/rbnacl/hmac/sha512256.rb +35 -0
  26. data/lib/rbnacl/keys/key_comparator.rb +59 -0
  27. data/lib/rbnacl/keys/private_key.rb +62 -0
  28. data/lib/rbnacl/keys/public_key.rb +38 -0
  29. data/lib/rbnacl/keys/signing_key.rb +74 -0
  30. data/lib/rbnacl/keys/verify_key.rb +76 -0
  31. data/lib/rbnacl/nacl.rb +132 -0
  32. data/lib/rbnacl/point.rb +67 -0
  33. data/lib/rbnacl/rake_tasks.rb +56 -0
  34. data/lib/rbnacl/random.rb +19 -0
  35. data/lib/rbnacl/random_nonce_box.rb +109 -0
  36. data/lib/rbnacl/secret_box.rb +86 -0
  37. data/lib/rbnacl/self_test.rb +118 -0
  38. data/lib/rbnacl/serializable.rb +23 -0
  39. data/lib/rbnacl/test_vectors.rb +69 -0
  40. data/lib/rbnacl/util.rb +137 -0
  41. data/lib/rbnacl/version.rb +5 -0
  42. data/rbnacl.gemspec +28 -0
  43. data/rbnacl.gpg +30 -0
  44. data/spec/rbnacl/auth/one_time_spec.rb +8 -0
  45. data/spec/rbnacl/box_spec.rb +42 -0
  46. data/spec/rbnacl/encoder_spec.rb +14 -0
  47. data/spec/rbnacl/encoders/base32_spec.rb +16 -0
  48. data/spec/rbnacl/encoders/base64_spec.rb +15 -0
  49. data/spec/rbnacl/encoders/hex_spec.rb +15 -0
  50. data/spec/rbnacl/hash_spec.rb +52 -0
  51. data/spec/rbnacl/hmac/sha256_spec.rb +8 -0
  52. data/spec/rbnacl/hmac/sha512256_spec.rb +8 -0
  53. data/spec/rbnacl/keys/private_key_spec.rb +68 -0
  54. data/spec/rbnacl/keys/public_key_spec.rb +45 -0
  55. data/spec/rbnacl/keys/signing_key_spec.rb +40 -0
  56. data/spec/rbnacl/keys/verify_key_spec.rb +51 -0
  57. data/spec/rbnacl/point_spec.rb +29 -0
  58. data/spec/rbnacl/random_nonce_box_spec.rb +78 -0
  59. data/spec/rbnacl/random_spec.rb +9 -0
  60. data/spec/rbnacl/secret_box_spec.rb +24 -0
  61. data/spec/rbnacl/util_spec.rb +119 -0
  62. data/spec/shared/authenticator.rb +114 -0
  63. data/spec/shared/box.rb +51 -0
  64. data/spec/shared/key_equality.rb +26 -0
  65. data/spec/spec_helper.rb +14 -0
  66. data/tasks/ci.rake +11 -0
  67. data/tasks/rspec.rake +7 -0
  68. metadata +187 -0
@@ -0,0 +1 @@
1
+ service-name: travis-pro
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ libsodium
19
+ libsodium-*.tar.gz
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format documentation
3
+ --backtrace
4
+ --default_path spec
@@ -0,0 +1,21 @@
1
+ script: "LD_LIBRARY_PATH=lib bundle exec rake ci"
2
+
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - ree
8
+ - ruby-head
9
+ - jruby-18mode
10
+ - jruby-19mode
11
+ - jruby-head
12
+ - rbx-18mode
13
+ - rbx-19mode
14
+
15
+ matrix:
16
+ allow_failures:
17
+ - rvm: ruby-head
18
+ - rvm: jruby-head
19
+
20
+ notifications:
21
+ irc: "irc.freenode.org#cryptosphere"
@@ -0,0 +1 @@
1
+ --markup markdown --no-private lib/**/*.rb - README.md LICENSE.txt
@@ -0,0 +1,4 @@
1
+ HEAD
2
+ ----
3
+
4
+ Unreleased!
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rbnacl.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'base32'
8
+ gem 'coveralls', :require => false
9
+ end
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2012 Tony Arcieri
2
+ Copyright (c) 2013 Jonathan Stott
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,179 @@
1
+ ![RbNaCl](https://raw.github.com/cryptosphere/rbnacl/master/images/logo.png)
2
+ ======
3
+ [![Build Status](https://travis-ci.org/cryptosphere/rbnacl.png?branch=master)](https://travis-ci.org/cryptosphere/rbnacl)
4
+ [![Code Climate](https://codeclimate.com/github/cryptosphere/rbnacl.png)](https://codeclimate.com/github/cryptosphere/rbnacl)
5
+ [![Coverage Status](https://coveralls.io/repos/cryptosphere/rbnacl/badge.png?branch=master)](https://coveralls.io/r/cryptosphere/rbnacl)
6
+
7
+ A Ruby binding to the state-of-the-art [Networking and Cryptography][nacl]
8
+ library by Daniel J. Bernstein. This is **NOT** Google Native Client. This
9
+ is a crypto library.
10
+
11
+ On a completely unrelated topic, RbNaCl is also the empirical formula for
12
+ Rubidium Sodium Chloride.
13
+
14
+ Need help with RbNaCl? Join the [RbNaCl Google Group][group]
15
+
16
+ [nacl]: http://nacl.cr.yp.to/
17
+ [group]: http://groups.google.com/group/rbnacl
18
+
19
+ ## Why NaCl?
20
+
21
+ NaCl is a different kind of cryptographic library. In the past crypto
22
+ libraries were kitchen sinks of little bits and pieces, like ciphers,
23
+ MACs, signature algorithms, and hash functions. To accomplish anything
24
+ you had to make a lot of decisions about which specific pieces to use,
25
+ and if any of your decisions were wrong, the result was an insecure
26
+ system. The choices are also not easy: EAX? GCM? CCM? AES-CTR? CMAC?
27
+ OMAC1? AEAD? NIST? CBC? CFB? CTR? ECB? OMGWTFBBQ!
28
+
29
+ NaCl puts cryptography on Rails! Instead of making you choose which
30
+ cryptographic primitives to use, NaCl provides convention over configuration
31
+ in the form of expertly-assembled high-level cryptographic APIs that ensure
32
+ not only the confidentiality of your data, but also detect tampering.
33
+ These high-level, easy-to-use APIs are designed to be hard to attack by
34
+ default in ways primitives exposed by libraries like OpenSSL are not.
35
+
36
+ This approach makes NaCl a lot closer to a system like GPG than it is
37
+ to the cryptographic primitive APIs in a library like OpenSSL. In addition,
38
+ NaCl also uses state-of-the-art encryption, including Curve25519 elliptic
39
+ curves and the XSalsa20 stream cipher. This means with NaCl you not only get
40
+ a system which is designed to be secure-by-default, you also get one which
41
+ is extremely fast with comparatively small cryptographic keys.
42
+
43
+ For more information on NaCl's goals, see Dan Bernstein's presentation
44
+ [Blaming the Cryptographic User](http://cr.yp.to/talks/2012.08.08/slides.pdf)
45
+
46
+ ## Supported platforms
47
+
48
+ You can use RbNaCl anywhere you can get libsodium installed (see below).
49
+ RbNaCl is continuously integration tested on the following Ruby VMs:
50
+
51
+ * MRI 1.8 / REE
52
+ * MRI 1.9 (YARV)
53
+ * JRuby 1.7 (in both 1.8/1.9 mode)
54
+ * Rubinius HEAD (in both 1.8/1.9 mode)
55
+
56
+ In theory Windows should be supported, although there are not yet any
57
+ reports of successful Windows users.
58
+
59
+ ## Installation
60
+
61
+ ### libsodium
62
+
63
+ RbNaCl is implemented as a Ruby FFI binding, which is designed to bind to
64
+ shared libraries. Unfortunately NaCl does not presently ship a shared library,
65
+ so RbNaCl cannot take advantage of it via FFI. RbNaCl will support usage with
66
+ the upstream NaCl once it is able to compile a shared library.
67
+
68
+ For now, to use RbNaCl, you will need to install libsodium, a portable version
69
+ of NaCl based upon the reference C code. Please see the libsodium project
70
+ for information regarding installation:
71
+
72
+ https://github.com/jedisct1/libsodium
73
+
74
+ #### OS X
75
+
76
+ Unfortunately libsodium is not in homebrew proper yet (I would strongly
77
+ encourage you to [ask for libsodium's inclusion in homebrew][homebrew]),
78
+ however you can use homebrew's "tap" feature for the time being to
79
+ install libsodium:
80
+
81
+ ```
82
+ brew tap qmx/homebrew-libsodium
83
+ brew install libsodium
84
+ ```
85
+
86
+ [homebrew]: https://github.com/mxcl/homebrew/pull/17275
87
+
88
+ ### RbNaCl gem
89
+
90
+ Once you have libsodium installed, add this line to your application's Gemfile:
91
+
92
+ gem 'rbnacl'
93
+
94
+ And then execute:
95
+
96
+ $ bundle
97
+
98
+ Or install it yourself as:
99
+
100
+ $ gem install rbnacl
101
+
102
+ ## Documentation
103
+
104
+ RbNaCl's documentation can be found [in the Wiki][wiki]. The following features
105
+ are supported:
106
+
107
+ * [Secret-key Encryption][secretkey]: authenticated symmetric encryption using a
108
+ single key shared among parties
109
+ * [Public-key Encryption][publickey]: securely send messages to a given public
110
+ key which can only be decrypted by a secret key
111
+ * [Digital Signatures][signatures]: sign messages with a private key which can
112
+ be verified by a public one
113
+ * [Authenticators][macs]: create codes which can be used to check the
114
+ authenticity of messages
115
+ * [Hash Functions][hashes]: compute a secure, fixed-length code from a message
116
+ which does not reveal the contents of the message
117
+
118
+ Additional power-user features are available. Please see the Wiki for further
119
+ information.
120
+
121
+ [wiki]: https://github.com/cryptosphere/rbnacl/wiki
122
+ [secretkey]: https://github.com/cryptosphere/rbnacl/wiki/Secret-Key-Encryption
123
+ [publickey]: https://github.com/cryptosphere/rbnacl/wiki/Public-Key-Encryption
124
+ [signatures]: https://github.com/cryptosphere/rbnacl/wiki/Digital-Signatures
125
+ [macs]: https://github.com/cryptosphere/rbnacl/wiki/Authenticators
126
+ [hashes]: https://github.com/cryptosphere/rbnacl/wiki/Hash-Functions
127
+
128
+ ## Security Notes
129
+
130
+ NaCl itself has been expertly crafted to avoid a whole range of
131
+ side-channel attacks, however the RbNaCl code itself has not been
132
+ written with the same degree of expertise. While the code is
133
+ straightforward it should be considered experimental until audited
134
+ by professional cryptographers.
135
+
136
+ That said, it's probably still a million times better than OpenSSL...
137
+
138
+ ## Reporting Security Problems
139
+
140
+ If you have discovered a bug in RbNaCl of a sensitive nature, i.e.
141
+ one which can compromise the security of RbNaCl users, you can
142
+ report it securely by sending a GPG encrypted message. Please use
143
+ the following key:
144
+
145
+ https://raw.github.com/cryptosphere/rbnacl/master/rbnacl.gpg
146
+
147
+ The key fingerprint is (or should be):
148
+
149
+ `190E 42D6 8327 A515 BFDF AAE0 B210 269D BB2D 8787`
150
+
151
+ ## Learn More
152
+
153
+ While NaCl has designed to be easier-than-usual to use for a crypto
154
+ library, cryptography is an incredibly difficult subject and it's
155
+ always helpful to know as much as you can about it before applying
156
+ it to a particular use case. That said, the creator of NaCl, Dan
157
+ Bernstein, has published a number of papers about NaCl. If you are
158
+ interested in learning more about how NaCl works, it's recommended
159
+ that you read them:
160
+
161
+ * [Cryptography in NaCl](http://cr.yp.to/highspeed/naclcrypto-20090310.pdf)
162
+ * [Curve25519: new Diffie-Hellman speed records](http://cr.yp.to/ecdh/curve25519-20060209.pdf)
163
+ * [Ed25519: High-speed high-security signatures](http://ed25519.cr.yp.to/ed25519-20110926.pdf)
164
+
165
+ Have a general interest in cryptography? Check out the free course
166
+ Coursera offers from Stanford University Professor Dan Boneh:
167
+
168
+ [http://crypto-class.org](http://crypto-class.org)
169
+
170
+ ## Contributing
171
+
172
+ * Fork this repository on Github
173
+ * Make your changes and send a pull request
174
+ * If your changes look good, we'll merge 'em
175
+
176
+ ## License
177
+
178
+ Copyright (c) 2013 Tony Arcieri, Jonathan Stott.
179
+ Distributed under the MIT License. See LICENSE.txt for further details.
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ Dir[File.expand_path("../tasks/**/*.rake", __FILE__)].each { |task| load task }
3
+ require File.expand_path("../lib/rbnacl/rake_tasks", __FILE__)
4
+
5
+ task :default => :spec
Binary file
Binary file
Binary file
@@ -0,0 +1,46 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Oh no, something went wrong!
4
+ #
5
+ # This indicates a failure in the operation of a cryptographic primitive such
6
+ # as authentication failing on an attempt to decrypt a ciphertext. Classes
7
+ # in the library may define more specific subclasses.
8
+ class CryptoError < StandardError; end
9
+
10
+ # Something, probably a key, is the wrong length
11
+ #
12
+ # This indicates some argument with an expected length was not that length.
13
+ # Since this is probably a cryptographic key, you should check that!
14
+ class LengthError < ArgumentError; end
15
+ end
16
+
17
+ # TIMTOWTDI!
18
+ RbNaCl = Crypto
19
+
20
+ require "rbnacl/nacl"
21
+ require "rbnacl/version"
22
+ require "rbnacl/serializable"
23
+ require "rbnacl/keys/key_comparator"
24
+ require "rbnacl/keys/private_key"
25
+ require "rbnacl/keys/public_key"
26
+ require "rbnacl/keys/signing_key"
27
+ require "rbnacl/keys/verify_key"
28
+ require "rbnacl/box"
29
+ require "rbnacl/secret_box"
30
+ require "rbnacl/hash"
31
+ require "rbnacl/util"
32
+ require "rbnacl/auth"
33
+ require "rbnacl/hmac/sha512256"
34
+ require "rbnacl/hmac/sha256"
35
+ require "rbnacl/auth/one_time"
36
+ require "rbnacl/random"
37
+ require "rbnacl/encoder"
38
+ require "rbnacl/encoders/base64"
39
+ require "rbnacl/encoders/hex"
40
+ require "rbnacl/encoders/raw"
41
+ require "rbnacl/point"
42
+ require "rbnacl/random_nonce_box"
43
+ require "rbnacl/test_vectors"
44
+
45
+ # Perform self test on load
46
+ require "rbnacl/self_test"
@@ -0,0 +1,78 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Secret Key Authenticators
4
+ #
5
+ # These provide a means of verifying the integrity of a message, but only
6
+ # with the knowledge of a shared key. This can be a preshared key, or one
7
+ # that is derived through some cryptographic protocol.
8
+ class Auth
9
+ # Number of bytes in a valid key
10
+ KEYBYTES = 0
11
+
12
+ # Number of bytes in a valid authenticator
13
+ BYTES = 0
14
+
15
+ attr_reader :key
16
+ private :key
17
+
18
+ # A new authenticator, ready for auth and verification
19
+ #
20
+ # @param [#to_str] key the key used for authenticators, 32 bytes.
21
+ # @param [#to_sym] encoding decode key from this format (default raw)
22
+ def initialize(key, encoding = :raw)
23
+ @key = Encoder[encoding].decode(key)
24
+ Util.check_length(@key, self.class::KEYBYTES, "#{self.class} key")
25
+ end
26
+
27
+ # Compute authenticator for message
28
+ #
29
+ # @param [#to_str] key the key used for the authenticator
30
+ # @param [#to_str] message message to construct an authenticator for
31
+ #
32
+ # @return [String] The authenticator, as raw bytes
33
+ def self.auth(key, message)
34
+ new(key).auth(message)
35
+ end
36
+
37
+ # Verifies the given authenticator with the message.
38
+ #
39
+ # @param [#to_str] key the key used for the authenticator
40
+ # @param [#to_str] message the message to be authenticated
41
+ # @param [#to_str] authenticator to be checked
42
+ #
43
+ # @return [Boolean] Was it valid?
44
+ def self.verify(key, message, authenticator)
45
+ new(key).verify(message, authenticator)
46
+ end
47
+
48
+ # Compute authenticator for message
49
+ #
50
+ # @param [#to_str] message the message to authenticate
51
+ # @param [#to_sym] authenticator_encoding format of the authenticator (default raw)
52
+ #
53
+ # @return [String] The authenticator in the requested encoding (default raw)
54
+ def auth(message, authenticator_encoding = :raw)
55
+ authenticator = Util.zeros(self.class::BYTES)
56
+ message = message.to_str
57
+ compute_authenticator(message, authenticator)
58
+ Encoder[authenticator_encoding].encode(authenticator)
59
+ end
60
+
61
+ # Verifies the given authenticator with the message.
62
+ #
63
+ # @param [#to_str] authenticator to be checked
64
+ # @param [#to_str] message the message to be authenticated
65
+ # @param [#to_sym] authenticator_encoding format of the authenticator (default raw)
66
+ #
67
+ # @return [Boolean] Was it valid?
68
+ def verify(message, authenticator, authenticator_encoding = :raw)
69
+ auth = Encoder[authenticator_encoding].decode(authenticator)
70
+ return false unless auth.bytesize == self.class::BYTES
71
+ verify_message(message, auth)
72
+ end
73
+
74
+ private
75
+ def compute_authenticator(message, authenticator); raise NotImplementedError; end
76
+ def verify_message(message, authenticator); raise NotImplementedError; end
77
+ end
78
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ class Auth
4
+ # Computes an authenticator using poly1305
5
+ #
6
+ # The authenticator can be used at a later time to verify the provenence of
7
+ # the message by recomputing the tag over the message and then comparing it to
8
+ # the provided authenticator. The class provides methods for generating
9
+ # signatures and also has a constant-time implementation for checking them.
10
+ #
11
+ # As the name suggests, this is a **ONE TIME** authenticator. Computing an
12
+ # authenticator for two messages using the same key probably gives an
13
+ # attacker enough information to forge further authenticators for the same
14
+ # key.
15
+ #
16
+ # This is a secret key authenticator, i.e. anyone who can verify signatures
17
+ # can also create them.
18
+ #
19
+ # @see http://nacl.cr.yp.to/onetimeauth.html
20
+ class OneTime < self
21
+ # Number of bytes in a valid key
22
+ KEYBYTES = NaCl::ONETIME_KEYBYTES
23
+
24
+ # Number of bytes in a valid authenticator
25
+ BYTES = NaCl::ONETIME_BYTES
26
+
27
+ private
28
+ def compute_authenticator(message, authenticator)
29
+ NaCl.crypto_auth_onetime(authenticator, message, message.bytesize, key)
30
+ end
31
+
32
+ def verify_message(message, authenticator)
33
+ NaCl.crypto_auth_onetime_verify(authenticator, message, message.bytesize, key)
34
+ end
35
+
36
+ end
37
+ end
38
+ end