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,56 @@
1
+ # encoding: binary
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'digest/sha2'
5
+
6
+ LIBSODIUM_VERSION = "0.2"
7
+
8
+ def sh_hidden(command)
9
+ STDERR.puts("*** Executing: #{command}")
10
+ output = `#{command}`
11
+
12
+ if !$?.success?
13
+ STDERR.puts "!!! Error executing: #{command}"
14
+ STDERR.puts output
15
+ exit 1
16
+ end
17
+ end
18
+
19
+ libsodium_tarball = "libsodium-#{LIBSODIUM_VERSION}.tar.gz"
20
+
21
+ file libsodium_tarball do
22
+ sh "curl -O http://download.dnscrypt.org/libsodium/releases/libsodium-#{LIBSODIUM_VERSION}.tar.gz"
23
+
24
+ digest = Digest::SHA256.hexdigest(File.read(libsodium_tarball))
25
+ if digest != "e99a6b69adc080a5acf6b8a49fdc74b61d6f3579b590e85c93446a8325dde100"
26
+ rm libsodium_tarball
27
+ raise "#{libsodium_tarball} failed checksum!"
28
+ end
29
+ end
30
+
31
+ file "libsodium" => "libsodium-#{LIBSODIUM_VERSION}.tar.gz" do
32
+ sh "tar xzf libsodium-#{LIBSODIUM_VERSION}.tar.gz"
33
+ mv "libsodium-#{LIBSODIUM_VERSION}", "libsodium"
34
+ end
35
+
36
+ file "libsodium/Makefile" => "libsodium" do
37
+ sh_hidden "cd libsodium && ./configure"
38
+ end
39
+
40
+ file "libsodium/src/libsodium/.libs/libsodium.a" => "libsodium/Makefile" do
41
+ sh_hidden "cd libsodium && make"
42
+ end
43
+
44
+ if `uname` == 'Darwin'
45
+ libsodium_lib = "libsodium.bundle"
46
+ else
47
+ libsodium_lib = "libsodium.so"
48
+ end
49
+
50
+ file "libsodium/src/libsodium/.libs/#{libsodium_lib}" => "libsodium/src/libsodium/.libs/libsodium.a"
51
+
52
+ task :build_libsodium => "libsodium/src/libsodium/.libs/#{libsodium_lib}" do
53
+ $LIBSODIUM_PATH = "libsodium/src/libsodium/.libs/#{libsodium_lib}"
54
+ end
55
+
56
+ CLEAN.add "libsodium", "libsodium-*.tar.gz"
@@ -0,0 +1,19 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Functions for random number generation
4
+ #
5
+ # This uses the underlying source of random number generation on the OS, so
6
+ # /dev/urandom on UNIX-like systems, and the MS crypto providor on windows.
7
+ module Random
8
+ # Returns a string of random bytes
9
+ #
10
+ # @param [Integer] n number of random bytes desired
11
+ #
12
+ # @return [String] random bytes.
13
+ def self.random_bytes(n=32)
14
+ buf = Crypto::Util.zeros(n)
15
+ NaCl.random_bytes(buf, n)
16
+ buf
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,109 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # The simplest nonce strategy that could possibly work
4
+ #
5
+ # This class implements the simplest possible nonce generation strategy to
6
+ # wrap a Crypto::Box or Crypto::SecretBox. A 24-byte random nonce is used
7
+ # for the encryption and is prepended to the message. When it is time to
8
+ # open the box, the message is split into nonce and ciphertext, and then the
9
+ # box is decrypted.
10
+ #
11
+ # Thanks to the size of the nonce, the chance of a collision is neglible. For
12
+ # example, after encrypting 2^64 messages, the odds of their having been
13
+ # repeated nonce is approximately 2^-64. As an additional convenience, the
14
+ # ciphertexts may be encoded or decoded by any of the encoders implemented in
15
+ # the library.
16
+ #
17
+ # The resulting ciphertexts are 40 bytes longer than the plain text (24 byte
18
+ # nonce plus a 16 byte authenticator). This might be annoying if you're
19
+ # encrypting tweets, but for files represents a fairly small overhead.
20
+ #
21
+ # Some caveats:
22
+ #
23
+ # * If your random source is broken, so is the security of the messages. You
24
+ # have bigger problems than just this library at that point, but it's worth
25
+ # saying.
26
+ # * The confidentiality of your messages is assured with this strategy, but
27
+ # there is no protection against messages being reordered and replayed by an
28
+ # active adversary.
29
+ class RandomNonceBox
30
+ # the size of the nonce
31
+ NONCEBYTES = NaCl::NONCEBYTES
32
+
33
+ # Create a new RandomNonceBox
34
+ #
35
+ # @param box [SecretBox, Box] the SecretBox or Box to use.
36
+ #
37
+ # @return [RandomNonceBox] Ready for use
38
+ def initialize(box)
39
+ @box = box
40
+ end
41
+
42
+ # Use a secret key to create a RandomNonceBox
43
+ #
44
+ # This is a convenience method. It takes a secret key and instantiates a
45
+ # SecretBox under the hood, then returns the new RandomNonceBox.
46
+ #
47
+ # @param secret_key [String] The secret key, 32 bytes long.
48
+ #
49
+ # @return [RandomNonceBox] Ready for use
50
+ def self.from_secret_key(secret_key)
51
+ new(SecretBox.new(secret_key))
52
+ end
53
+
54
+ # Use a pair of keys to create a RandomNonceBox
55
+ #
56
+ # This is a convenience method. It takes a pair of keys and instantiates a
57
+ # Box under the hood, then returns the new RandomNonceBox.
58
+ #
59
+ # @param private_key [PrivateKey, String] The RbNaCl private key, as class or string
60
+ # @param public_key [PublicKey, String] The RbNaCl public key, as class or string
61
+ #
62
+ # @return [RandomNonceBox] Ready for use
63
+ def self.from_keypair(private_key, public_key)
64
+ new(Box.new(private_key, public_key))
65
+ end
66
+
67
+ # Encrypts the message with a random nonce
68
+ #
69
+ # Encrypts the message with a random nonce, then returns the ciphertext with
70
+ # the nonce prepended. Optionally encodes the message using an encoder.
71
+ #
72
+ # @param message [String] The message to encrypt
73
+ # @param encoding [Symbol] Optional encoding for the returned ciphertext
74
+ #
75
+ # @return [String] The enciphered message
76
+ def box(message, encoding = :raw)
77
+ nonce = generate_nonce
78
+ cipher_text = @box.box(nonce, message)
79
+ Encoder[encoding].encode(nonce + cipher_text)
80
+ end
81
+
82
+ # Decrypts the ciphertext with a random nonce
83
+ #
84
+ # Takes a ciphertext, optionally decodes it, then splits the nonce off the
85
+ # front and uses this to decrypt. Returns the message.
86
+ #
87
+ # @param enciphered_message [String] The message to decrypt.
88
+ # @param encoding [Symbol] Optional decoding for the returned ciphertext
89
+ #
90
+ # @raise [CryptoError] If the message has been tampered with.
91
+ #
92
+ # @return [String] The decoded message
93
+ def open(enciphered_message, encoding = :raw)
94
+ decoded = Encoder[encoding].decode(enciphered_message)
95
+ nonce, ciphertext = *extract_nonce(decoded)
96
+ @box.open(nonce, ciphertext)
97
+ end
98
+
99
+ private
100
+ def generate_nonce
101
+ Random.random_bytes(NONCEBYTES)
102
+ end
103
+
104
+ def extract_nonce(bytes)
105
+ nonce = bytes.slice!(0, NONCEBYTES)
106
+ [nonce, bytes]
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # The SecretBox class boxes and unboxes messages
4
+ #
5
+ # This class uses the given secret key to encrypt and decrypt messages.
6
+ #
7
+ # It is VITALLY important that the nonce is a nonce, i.e. it is a number used
8
+ # only once for any given pair of keys. If you fail to do this, you
9
+ # compromise the privacy of the messages encrypted. Give your nonces a
10
+ # different prefix, or have one side use an odd counter and one an even counter.
11
+ # Just make sure they are different.
12
+ #
13
+ # The ciphertexts generated by this class include a 16-byte authenticator which
14
+ # is checked as part of the decryption. An invalid authenticator will cause
15
+ # the unbox function to raise. The authenticator is not a signature. Once
16
+ # you've looked in the box, you've demonstrated the ability to create
17
+ # arbitrary valid messages, so messages you send are repudiatable. For
18
+ # non-repudiatable messages, sign them before or after encryption.
19
+ class SecretBox
20
+ # Number of bytes for a secret key
21
+ KEYBYTES = NaCl::SECRETBOX_KEYBYTES
22
+
23
+ # Create a new SecretBox
24
+ #
25
+ # Sets up the Box with a secret key fro encrypting and decrypting messages.
26
+ #
27
+ # @param key [String] The key to encrypt and decrypt with
28
+ # @param encoding [Symbol] Parse key from the given encoding
29
+ #
30
+ # @raise [Crypto::LengthError] on invalid keys
31
+ #
32
+ # @return [Crypto::SecretBox] The new Box, ready to use
33
+ def initialize(key, encoding = :raw)
34
+ @key = Encoder[encoding].decode(key) if key
35
+ Util.check_length(@key, KEYBYTES, "Secret key")
36
+ end
37
+
38
+ # Encrypts a message
39
+ #
40
+ # Encrypts the message with the given nonce to the key set up when
41
+ # initializing the class. Make sure the nonce is unique for any given
42
+ # key, or you might as well just send plain text.
43
+ #
44
+ # This function takes care of the padding required by the NaCL C API.
45
+ #
46
+ # @param nonce [String] A 24-byte string containing the nonce.
47
+ # @param message [String] The message to be encrypted.
48
+ #
49
+ # @raise [Crypto::LengthError] If the nonce is not valid
50
+ #
51
+ # @return [String] The ciphertext without the nonce prepended (BINARY encoded)
52
+ def box(nonce, message)
53
+ Util.check_length(nonce, Crypto::NaCl::NONCEBYTES, "Nonce")
54
+ msg = Util.prepend_zeros(NaCl::ZEROBYTES, message)
55
+ ct = Util.zeros(msg.bytesize)
56
+
57
+ NaCl.crypto_secretbox(ct, msg, msg.bytesize, nonce, @key) || raise(CryptoError, "Encryption failed")
58
+ Util.remove_zeros(NaCl::BOXZEROBYTES, ct)
59
+ end
60
+ alias encrypt box
61
+
62
+ # Decrypts a ciphertext
63
+ #
64
+ # Decrypts the ciphertext with the given nonce using the key setup when
65
+ # initializing the class.
66
+ #
67
+ # This function takes care of the padding required by the NaCL C API.
68
+ #
69
+ # @param nonce [String] A 24-byte string containing the nonce.
70
+ # @param ciphertext [String] The message to be decrypted.
71
+ #
72
+ # @raise [Crypto::LengthError] If the nonce is not valid
73
+ # @raise [Crypto::CryptoError] If the ciphertext cannot be authenticated.
74
+ #
75
+ # @return [String] The decrypted message (BINARY encoded)
76
+ def open(nonce, ciphertext)
77
+ Util.check_length(nonce, Crypto::NaCl::NONCEBYTES, "Nonce")
78
+ ct = Util.prepend_zeros(NaCl::BOXZEROBYTES, ciphertext)
79
+ message = Util.zeros(ct.bytesize)
80
+
81
+ NaCl.crypto_secretbox_open(message, ct, ct.bytesize, nonce, @key) || raise(CryptoError, "Decryption failed. Ciphertext failed verification.")
82
+ Util.remove_zeros(NaCl::ZEROBYTES, message)
83
+ end
84
+ alias decrypt open
85
+ end
86
+ end
@@ -0,0 +1,118 @@
1
+ start = Time.now if $DEBUG
2
+
3
+ module Crypto
4
+ class SelfTestFailure < Crypto::CryptoError; end
5
+
6
+ module SelfTest
7
+ module_function
8
+
9
+ def box_test
10
+ alicepk = Crypto::PublicKey.new(TestVectors[:alice_public], :hex)
11
+ bobsk = Crypto::PrivateKey.new(TestVectors[:bob_private], :hex)
12
+
13
+ box = Crypto::Box.new(alicepk, bobsk)
14
+ box_common_test(box)
15
+ end
16
+
17
+ def secret_box_test
18
+ box = SecretBox.new(TestVectors[:secret_key], :hex)
19
+ box_common_test(box)
20
+ end
21
+
22
+ def box_common_test(box)
23
+ nonce = hexdecode_vector :box_nonce
24
+ message = hexdecode_vector :box_message
25
+ ciphertext = hexdecode_vector :box_ciphertext
26
+
27
+ unless box.encrypt(nonce, message) == ciphertext
28
+ raise SelfTestFailure, "failed to generate correct ciphertext"
29
+ end
30
+
31
+ unless box.decrypt(nonce, ciphertext) == message
32
+ raise SelfTestFailure, "failed to decrypt ciphertext correctly"
33
+ end
34
+
35
+ begin
36
+ passed = false
37
+ corrupt_ct = ciphertext.dup
38
+ corrupt_ct[23] = ' '
39
+ box.decrypt(nonce, corrupt_ct)
40
+ rescue CryptoError
41
+ passed = true
42
+ ensure
43
+ passed or raise SelfTestFailure, "failed to detect corrupt ciphertext"
44
+ end
45
+ end
46
+
47
+ def digital_signature_test
48
+ signing_key = SigningKey.new(TestVectors[:sign_private], :hex)
49
+ verify_key = signing_key.verify_key
50
+
51
+ unless verify_key.to_s(:hex) == TestVectors[:sign_public]
52
+ raise SelfTestFailure, "failed to generate verify key correctly"
53
+ end
54
+
55
+ message = hexdecode_vector :sign_message
56
+ signature = signing_key.sign(message, :hex)
57
+
58
+ unless signature == TestVectors[:sign_signature]
59
+ raise SelfTestFailure, "failed to generate correct signature"
60
+ end
61
+
62
+ unless verify_key.verify(message, signature, :hex)
63
+ raise SelfTestFailure, "failed to verify a valid signature"
64
+ end
65
+
66
+ bad_signature = signature[0,127] + '0'
67
+
68
+ unless verify_key.verify(message, bad_signature, :hex) == false
69
+ raise SelfTestFailure, "failed to detect an invalid signature"
70
+ end
71
+ end
72
+
73
+ def sha256_test
74
+ message = hexdecode_vector :sha256_message
75
+ digest = hexdecode_vector :sha256_digest
76
+
77
+ unless Crypto::Hash.sha256(message) == digest
78
+ raise SelfTestFailure, "failed to generate a correct SHA256 digest"
79
+ end
80
+ end
81
+
82
+ def hmac_test(klass, tag)
83
+ authenticator = klass.new(TestVectors[:auth_key], :hex)
84
+
85
+ message = hexdecode_vector :auth_message
86
+
87
+ unless authenticator.auth(message, :hex) == TestVectors[tag]
88
+ raise SelfTestFailure, "#{klass} failed to generate correct authentication tag"
89
+ end
90
+
91
+ unless authenticator.verify(message, TestVectors[tag], :hex)
92
+ raise SelfTestFailure, "#{klass} failed to verify correct authentication tag"
93
+ end
94
+
95
+ if authenticator.verify(message+' ', TestVectors[tag], :hex)
96
+ raise SelfTestFailure, "#{klass} failed to detect invalid authentication tag"
97
+ end
98
+ end
99
+
100
+ def hexdecode(string)
101
+ Encoder[:hex].decode(string)
102
+ end
103
+
104
+ def hexdecode_vector(name)
105
+ hexdecode TestVectors[name]
106
+ end
107
+ end
108
+ end
109
+
110
+ Crypto::SelfTest.box_test
111
+ Crypto::SelfTest.secret_box_test
112
+ Crypto::SelfTest.digital_signature_test
113
+ Crypto::SelfTest.sha256_test
114
+ Crypto::SelfTest.hmac_test Crypto::HMAC::SHA256, :auth_hmacsha256
115
+ Crypto::SelfTest.hmac_test Crypto::HMAC::SHA512256, :auth_hmacsha512256
116
+ Crypto::SelfTest.hmac_test Crypto::Auth::OneTime, :auth_onetime
117
+
118
+ puts "POST Completed in #{Time.now - start} s" if $DEBUG
@@ -0,0 +1,23 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Serialization features shared across all "key-like" classes
4
+ module Serializable
5
+ # Return a string representation of this key, possibly encoded into a
6
+ # given serialization format.
7
+ #
8
+ # @param encoding [String] string encoding format in which to encode the key
9
+ #
10
+ # @return [String] key encoded in the specified format
11
+ def to_s(encoding = :raw)
12
+ Encoder[encoding].encode(to_bytes)
13
+ end
14
+ alias_method :to_str, :to_s
15
+
16
+ # Inspect this key
17
+ #
18
+ # @return [String] a string representing this key
19
+ def inspect
20
+ "#<#{self.class}:#{to_s(:hex)[0,8]}>"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,69 @@
1
+ # encoding: binary
2
+ module Crypto
3
+ # Reference library of test vectors used to verify the software is correct
4
+ TestVectors = {
5
+ #
6
+ # Curve25519 test vectors
7
+ # Taken from the NaCl distribution
8
+ #
9
+ :alice_private => "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a",
10
+ :alice_public => "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a",
11
+ :bob_private => "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb",
12
+ :bob_public => "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f",
13
+ :alice_mult_bob => "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742",
14
+
15
+ #
16
+ # Box test vectors
17
+ # Taken from the NaCl distribution
18
+ #
19
+ :secret_key => "1b27556473e985d462cd51197a9a46c76009549eac6474f206c4ee0844f68389",
20
+ :box_nonce => "69696ee955b62b73cd62bda875fc73d68219e0036b7a0b37",
21
+ :box_message => "be075fc53c81f2d5cf141316ebeb0c7b5228c52a4c62cbd44b66849b64244ffc" +
22
+ "e5ecbaaf33bd751a1ac728d45e6c61296cdc3c01233561f41db66cce314adb31" +
23
+ "0e3be8250c46f06dceea3a7fa1348057e2f6556ad6b1318a024a838f21af1fde" +
24
+ "048977eb48f59ffd4924ca1c60902e52f0a089bc76897040e082f93776384864" +
25
+ "5e0705",
26
+
27
+ :box_ciphertext => "f3ffc7703f9400e52a7dfb4b3d3305d98e993b9f48681273c29650ba32fc76ce" +
28
+ "48332ea7164d96a4476fb8c531a1186ac0dfc17c98dce87b4da7f011ec48c972" +
29
+ "71d2c20f9b928fe2270d6fb863d51738b48eeee314a7cc8ab932164548e526ae" +
30
+ "90224368517acfeabd6bb3732bc0e9da99832b61ca01b6de56244a9e88d5f9b3" +
31
+ "7973f622a43d14a6599b1f654cb45a74e355a5",
32
+
33
+ #
34
+ # Ed25519 test vectors
35
+ # Taken from the Python test vectors: http://ed25519.cr.yp.to/python/sign.input
36
+ #
37
+ :sign_private => "b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd",
38
+ :sign_public => "77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb",
39
+ :sign_message => "916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171" +
40
+ "ce18a542b0b7f96c1691a3be6031522894a8634183eda38798a0c5d5d79fbd01" +
41
+ "dd04a8646d71873b77b221998a81922d8105f892316369d5224c9983372d2313" +
42
+ "c6b1f4556ea26ba49d46e8b561e0fc76633ac9766e68e21fba7edca93c4c7460" +
43
+ "376d7f3ac22ff372c18f613f2ae2e856af40",
44
+ :sign_signature => "6bd710a368c1249923fc7a1610747403040f0cc30815a00f9ff548a896bbda0b" +
45
+ "4eb2ca19ebcf917f0f34200a9edbad3901b64ab09cc5ef7b9bcc3c40c0ff7509",
46
+
47
+ #
48
+ # SHA256 test vectors
49
+ # Taken from the NSRL test vectors: http://www.nsrl.nist.gov/testdata/
50
+ :sha256_message => "6162636462636465636465666465666765666768666768696768696a68696a6b" +
51
+ "696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071",
52
+ :sha256_digest => "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1",
53
+
54
+ #
55
+ # Auth test vectors
56
+ # Taken from NaCl distribution
57
+ #
58
+ :auth_key => "eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880",
59
+ :auth_message => "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a" +
60
+ "c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738" +
61
+ "b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da" +
62
+ "99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74" +
63
+ "e355a5",
64
+ :auth_onetime => "f3ffc7703f9400e52a7dfb4b3d3305d9",
65
+ # self-created (FIXME: find standard test vectors)
66
+ :auth_hmacsha256 => "7f7b9b707e8790ca8620ff94df5e6533ddc8e994060ce310c9d7de04d44aabc3",
67
+ :auth_hmacsha512256 => "b2a31b8d4e01afcab2ee545b5caf4e3d212a99d7b3a116a97cec8e83c32e107d"
68
+ }
69
+ end