uncle_blake3 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +27 -0
  3. data/README.md +89 -0
  4. data/ext/Rakefile +55 -0
  5. data/ext/binding/uncle_blake3.c +41 -0
  6. data/ext/blake3/c/Makefile.testing +82 -0
  7. data/ext/blake3/c/README.md +316 -0
  8. data/ext/blake3/c/blake3.c +616 -0
  9. data/ext/blake3/c/blake3.h +60 -0
  10. data/ext/blake3/c/blake3_avx2.c +326 -0
  11. data/ext/blake3/c/blake3_avx2_x86-64_unix.S +1815 -0
  12. data/ext/blake3/c/blake3_avx2_x86-64_windows_gnu.S +1817 -0
  13. data/ext/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +1828 -0
  14. data/ext/blake3/c/blake3_avx512.c +1207 -0
  15. data/ext/blake3/c/blake3_avx512_x86-64_unix.S +2585 -0
  16. data/ext/blake3/c/blake3_avx512_x86-64_windows_gnu.S +2615 -0
  17. data/ext/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +2634 -0
  18. data/ext/blake3/c/blake3_dispatch.c +276 -0
  19. data/ext/blake3/c/blake3_impl.h +282 -0
  20. data/ext/blake3/c/blake3_neon.c +351 -0
  21. data/ext/blake3/c/blake3_portable.c +160 -0
  22. data/ext/blake3/c/blake3_sse2.c +566 -0
  23. data/ext/blake3/c/blake3_sse2_x86-64_unix.S +2291 -0
  24. data/ext/blake3/c/blake3_sse2_x86-64_windows_gnu.S +2332 -0
  25. data/ext/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +2350 -0
  26. data/ext/blake3/c/blake3_sse41.c +560 -0
  27. data/ext/blake3/c/blake3_sse41_x86-64_unix.S +2028 -0
  28. data/ext/blake3/c/blake3_sse41_x86-64_windows_gnu.S +2069 -0
  29. data/ext/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +2089 -0
  30. data/ext/blake3/c/example.c +37 -0
  31. data/ext/blake3/c/main.c +166 -0
  32. data/ext/blake3/c/test.py +97 -0
  33. data/lib/uncle_blake3/binding.rb +20 -0
  34. data/lib/uncle_blake3/build/loader.rb +40 -0
  35. data/lib/uncle_blake3/build/platform.rb +37 -0
  36. data/lib/uncle_blake3/build.rb +4 -0
  37. data/lib/uncle_blake3/digest.rb +119 -0
  38. data/lib/uncle_blake3/version.rb +5 -0
  39. data/lib/uncle_blake3.rb +7 -0
  40. metadata +112 -0
@@ -0,0 +1,37 @@
1
+ #include "blake3.h"
2
+ #include <errno.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+ #include <unistd.h>
7
+
8
+ int main() {
9
+ // Initialize the hasher.
10
+ blake3_hasher hasher;
11
+ blake3_hasher_init(&hasher);
12
+
13
+ // Read input bytes from stdin.
14
+ unsigned char buf[65536];
15
+ while (1) {
16
+ ssize_t n = read(STDIN_FILENO, buf, sizeof(buf));
17
+ if (n > 0) {
18
+ blake3_hasher_update(&hasher, buf, n);
19
+ } else if (n == 0) {
20
+ break; // end of file
21
+ } else {
22
+ fprintf(stderr, "read failed: %s\n", strerror(errno));
23
+ exit(1);
24
+ }
25
+ }
26
+
27
+ // Finalize the hash. BLAKE3_OUT_LEN is the default output length, 32 bytes.
28
+ uint8_t output[BLAKE3_OUT_LEN];
29
+ blake3_hasher_finalize(&hasher, output, BLAKE3_OUT_LEN);
30
+
31
+ // Print the hash as hexadecimal.
32
+ for (size_t i = 0; i < BLAKE3_OUT_LEN; i++) {
33
+ printf("%02x", output[i]);
34
+ }
35
+ printf("\n");
36
+ return 0;
37
+ }
@@ -0,0 +1,166 @@
1
+ /*
2
+ * This main file is intended for testing via `make test`. It does not build in
3
+ * other settings. See README.md in this directory for examples of how to build
4
+ * C code.
5
+ */
6
+
7
+ #include <assert.h>
8
+ #include <errno.h>
9
+ #include <stdbool.h>
10
+ #include <stdint.h>
11
+ #include <stdio.h>
12
+ #include <stdlib.h>
13
+
14
+ #include "blake3.h"
15
+ #include "blake3_impl.h"
16
+
17
+ #define HASH_MODE 0
18
+ #define KEYED_HASH_MODE 1
19
+ #define DERIVE_KEY_MODE 2
20
+
21
+ static void hex_char_value(uint8_t c, uint8_t *value, bool *valid) {
22
+ if ('0' <= c && c <= '9') {
23
+ *value = c - '0';
24
+ *valid = true;
25
+ } else if ('a' <= c && c <= 'f') {
26
+ *value = 10 + c - 'a';
27
+ *valid = true;
28
+ } else {
29
+ *valid = false;
30
+ }
31
+ }
32
+
33
+ static int parse_key(char *hex_key, uint8_t out[BLAKE3_KEY_LEN]) {
34
+ size_t hex_len = strlen(hex_key);
35
+ if (hex_len != 64) {
36
+ fprintf(stderr, "Expected a 64-char hexadecimal key, got %zu chars.\n",
37
+ hex_len);
38
+ return 1;
39
+ }
40
+ for (size_t i = 0; i < 64; i++) {
41
+ uint8_t value;
42
+ bool valid;
43
+ hex_char_value(hex_key[i], &value, &valid);
44
+ if (!valid) {
45
+ fprintf(stderr, "Invalid hex char.\n");
46
+ return 1;
47
+ }
48
+ if (i % 2 == 0) {
49
+ out[i / 2] = 0;
50
+ value <<= 4;
51
+ }
52
+ out[i / 2] += value;
53
+ }
54
+ return 0;
55
+ }
56
+
57
+ /* A little repetition here */
58
+ enum cpu_feature {
59
+ SSE2 = 1 << 0,
60
+ SSSE3 = 1 << 1,
61
+ SSE41 = 1 << 2,
62
+ AVX = 1 << 3,
63
+ AVX2 = 1 << 4,
64
+ AVX512F = 1 << 5,
65
+ AVX512VL = 1 << 6,
66
+ /* ... */
67
+ UNDEFINED = 1 << 30
68
+ };
69
+
70
+ extern enum cpu_feature g_cpu_features;
71
+ enum cpu_feature get_cpu_features(void);
72
+
73
+ int main(int argc, char **argv) {
74
+ size_t out_len = BLAKE3_OUT_LEN;
75
+ uint8_t key[BLAKE3_KEY_LEN];
76
+ char *context = "";
77
+ uint8_t mode = HASH_MODE;
78
+ while (argc > 1) {
79
+ if (argc <= 2) {
80
+ fprintf(stderr, "Odd number of arguments.\n");
81
+ return 1;
82
+ }
83
+ if (strcmp("--length", argv[1]) == 0) {
84
+ char *endptr = NULL;
85
+ errno = 0;
86
+ unsigned long long out_len_ll = strtoull(argv[2], &endptr, 10);
87
+ if (errno != 0 || out_len_ll > SIZE_MAX || endptr == argv[2] ||
88
+ *endptr != 0) {
89
+ fprintf(stderr, "Bad length argument.\n");
90
+ return 1;
91
+ }
92
+ out_len = (size_t)out_len_ll;
93
+ } else if (strcmp("--keyed", argv[1]) == 0) {
94
+ mode = KEYED_HASH_MODE;
95
+ int ret = parse_key(argv[2], key);
96
+ if (ret != 0) {
97
+ return ret;
98
+ }
99
+ } else if (strcmp("--derive-key", argv[1]) == 0) {
100
+ mode = DERIVE_KEY_MODE;
101
+ context = argv[2];
102
+ } else {
103
+ fprintf(stderr, "Unknown flag.\n");
104
+ return 1;
105
+ }
106
+ argc -= 2;
107
+ argv += 2;
108
+ }
109
+
110
+ /*
111
+ * We're going to hash the input multiple times, so we need to buffer it all.
112
+ * This is just for test cases, so go ahead and assume that the input is less
113
+ * than 1 MiB.
114
+ */
115
+ size_t buf_capacity = 1 << 20;
116
+ uint8_t *buf = malloc(buf_capacity);
117
+ assert(buf != NULL);
118
+ size_t buf_len = 0;
119
+ while (1) {
120
+ size_t n = fread(&buf[buf_len], 1, buf_capacity - buf_len, stdin);
121
+ if (n == 0) {
122
+ break;
123
+ }
124
+ buf_len += n;
125
+ assert(buf_len < buf_capacity);
126
+ }
127
+
128
+ const int mask = get_cpu_features();
129
+ int feature = 0;
130
+ do {
131
+ fprintf(stderr, "Testing 0x%08X\n", feature);
132
+ g_cpu_features = feature;
133
+ blake3_hasher hasher;
134
+ switch (mode) {
135
+ case HASH_MODE:
136
+ blake3_hasher_init(&hasher);
137
+ break;
138
+ case KEYED_HASH_MODE:
139
+ blake3_hasher_init_keyed(&hasher, key);
140
+ break;
141
+ case DERIVE_KEY_MODE:
142
+ blake3_hasher_init_derive_key(&hasher, context);
143
+ break;
144
+ default:
145
+ abort();
146
+ }
147
+
148
+ blake3_hasher_update(&hasher, buf, buf_len);
149
+
150
+ /* TODO: An incremental output reader API to avoid this allocation. */
151
+ uint8_t *out = malloc(out_len);
152
+ if (out_len > 0 && out == NULL) {
153
+ fprintf(stderr, "malloc() failed.\n");
154
+ return 1;
155
+ }
156
+ blake3_hasher_finalize(&hasher, out, out_len);
157
+ for (size_t i = 0; i < out_len; i++) {
158
+ printf("%02x", out[i]);
159
+ }
160
+ printf("\n");
161
+ free(out);
162
+ feature = (feature - mask) & mask;
163
+ } while (feature != 0);
164
+ free(buf);
165
+ return 0;
166
+ }
@@ -0,0 +1,97 @@
1
+ #! /usr/bin/env python3
2
+
3
+ from binascii import hexlify
4
+ import json
5
+ from os import path
6
+ import subprocess
7
+
8
+ HERE = path.dirname(__file__)
9
+ TEST_VECTORS_PATH = path.join(HERE, "..", "test_vectors", "test_vectors.json")
10
+ TEST_VECTORS = json.load(open(TEST_VECTORS_PATH))
11
+
12
+
13
+ def run_blake3(args, input):
14
+ output = subprocess.run([path.join(HERE, "blake3")] + args,
15
+ input=input,
16
+ stdout=subprocess.PIPE,
17
+ check=True)
18
+ return output.stdout.decode().strip()
19
+
20
+
21
+ # Fill the input with a repeating byte pattern. We use a cycle length of 251,
22
+ # because that's the largets prime number less than 256. This makes it unlikely
23
+ # to swapping any two adjacent input blocks or chunks will give the same
24
+ # answer.
25
+ def make_test_input(length):
26
+ i = 0
27
+ buf = bytearray()
28
+ while len(buf) < length:
29
+ buf.append(i)
30
+ i = (i + 1) % 251
31
+ return buf
32
+
33
+
34
+ def main():
35
+ for case in TEST_VECTORS["cases"]:
36
+ input_len = case["input_len"]
37
+ input = make_test_input(input_len)
38
+ hex_key = hexlify(TEST_VECTORS["key"].encode())
39
+ context_string = TEST_VECTORS["context_string"]
40
+ expected_hash_xof = case["hash"]
41
+ expected_hash = expected_hash_xof[:64]
42
+ expected_keyed_hash_xof = case["keyed_hash"]
43
+ expected_keyed_hash = expected_keyed_hash_xof[:64]
44
+ expected_derive_key_xof = case["derive_key"]
45
+ expected_derive_key = expected_derive_key_xof[:64]
46
+
47
+ # Test the default hash.
48
+ test_hash = run_blake3([], input)
49
+ for line in test_hash.splitlines():
50
+ assert expected_hash == line, \
51
+ "hash({}): {} != {}".format(input_len, expected_hash, line)
52
+
53
+ # Test the extended hash.
54
+ xof_len = len(expected_hash_xof) // 2
55
+ test_hash_xof = run_blake3(["--length", str(xof_len)], input)
56
+ for line in test_hash_xof.splitlines():
57
+ assert expected_hash_xof == line, \
58
+ "hash_xof({}): {} != {}".format(
59
+ input_len, expected_hash_xof, line)
60
+
61
+ # Test the default keyed hash.
62
+ test_keyed_hash = run_blake3(["--keyed", hex_key], input)
63
+ for line in test_keyed_hash.splitlines():
64
+ assert expected_keyed_hash == line, \
65
+ "keyed_hash({}): {} != {}".format(
66
+ input_len, expected_keyed_hash, line)
67
+
68
+ # Test the extended keyed hash.
69
+ xof_len = len(expected_keyed_hash_xof) // 2
70
+ test_keyed_hash_xof = run_blake3(
71
+ ["--keyed", hex_key, "--length",
72
+ str(xof_len)], input)
73
+ for line in test_keyed_hash_xof.splitlines():
74
+ assert expected_keyed_hash_xof == line, \
75
+ "keyed_hash_xof({}): {} != {}".format(
76
+ input_len, expected_keyed_hash_xof, line)
77
+
78
+ # Test the default derive key.
79
+ test_derive_key = run_blake3(["--derive-key", context_string], input)
80
+ for line in test_derive_key.splitlines():
81
+ assert expected_derive_key == line, \
82
+ "derive_key({}): {} != {}".format(
83
+ input_len, expected_derive_key, line)
84
+
85
+ # Test the extended derive key.
86
+ xof_len = len(expected_derive_key_xof) // 2
87
+ test_derive_key_xof = run_blake3(
88
+ ["--derive-key", context_string, "--length",
89
+ str(xof_len)], input)
90
+ for line in test_derive_key_xof.splitlines():
91
+ assert expected_derive_key_xof == line, \
92
+ "derive_key_xof({}): {} != {}".format(
93
+ input_len, expected_derive_key_xof, line)
94
+
95
+
96
+ if __name__ == "__main__":
97
+ main()
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'build/loader'
4
+
5
+ module UncleBlake3
6
+ module Binding
7
+ extend ::FFI::Library
8
+ ffi_lib Build::Loader.find('UncleBlake3')
9
+
10
+ attach_function :key_length, :UncleBlake3_KEY_LEN, %i[], :uint16
11
+ attach_function :default_output_length, :UncleBlake3_OUT_LEN, %i[], :uint16
12
+
13
+ attach_function :init, :UncleBlake3_Init, %i[], :pointer
14
+ attach_function :init_with_key, :UncleBlake3_InitWithKey, %i[pointer], :pointer
15
+ attach_function :init_with_key_seed, :UncleBlake3_InitWithKeySeed, %i[pointer size_t], :pointer
16
+ attach_function :update, :UncleBlake3_Update, %i[pointer pointer size_t], :int
17
+ attach_function :final, :UncleBlake3_Final, %i[pointer pointer size_t], :int
18
+ attach_function :destroy, :UncleBlake3_Destroy, %i[pointer], :void
19
+ end
20
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'pathname'
5
+ require_relative 'platform'
6
+
7
+ module UncleBlake3
8
+ module Build
9
+ # taken from:
10
+ # https://github.com/ffi/ffi-compiler/blob/master/lib/ffi-compiler/loader.rb
11
+ module Loader
12
+ def self.find(name, start_path = nil)
13
+ library = Platform.instance.map_library_name(name)
14
+ root = false
15
+ ::Pathname.new(start_path || caller_path(caller[0])).ascend do |path|
16
+ Dir.glob("#{path}/**/{#{::FFI::Platform::ARCH}-#{::FFI::Platform::OS}/#{library},#{library}}") do |f|
17
+ return f
18
+ end
19
+
20
+ break if root
21
+
22
+ # Next iteration will be the root of the gem if this is the lib/ dir - stop after that
23
+ root = ::File.basename(path) == 'lib'
24
+ end
25
+ raise ::LoadError, "cannot find '#{name}' library"
26
+ end
27
+
28
+ def self.caller_path(line = caller[0])
29
+ if ::FFI::Platform::OS == 'windows'
30
+ drive = line[0..1]
31
+ path = line[2..].split(/:/)[0]
32
+ full_path = drive + path
33
+ else
34
+ full_path = line.split(/:/)[0]
35
+ end
36
+ ::File.dirname full_path
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require 'singleton'
5
+
6
+ module UncleBlake3
7
+ module Build
8
+ # mostly taken from:
9
+ # https://github.com/ffi/ffi-compiler/blob/master/lib/ffi-compiler/platform.rb
10
+
11
+ class Platform
12
+ include ::Singleton
13
+
14
+ LIBSUFFIX = ::FFI::Platform.mac? ? 'bundle' : ::FFI::Platform::LIBSUFFIX
15
+
16
+ def map_library_name(name)
17
+ "#{::FFI::Platform::LIBPREFIX}#{name}.#{LIBSUFFIX}"
18
+ end
19
+
20
+ def arch
21
+ ::FFI::Platform::ARCH
22
+ end
23
+
24
+ def os
25
+ ::FFI::Platform::OS
26
+ end
27
+
28
+ def name
29
+ ::FFI::Platform.name
30
+ end
31
+
32
+ def mac?
33
+ ::FFI::Platform.mac?
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './build/platform'
4
+ require_relative './build/loader'
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'ffi'
5
+ require 'objspace'
6
+ require_relative 'binding'
7
+
8
+ module UncleBlake3
9
+ class Digest
10
+ KEY_LENGTH = Binding.key_length
11
+ DEFAULT_OUTPUT_LENGTH = Binding.default_output_length
12
+
13
+ module Error
14
+ end
15
+
16
+ class ArgumentError < ::ArgumentError
17
+ include Error
18
+ end
19
+
20
+ class TypeError < ::TypeError
21
+ include Error
22
+ end
23
+
24
+ def initialize(output_length: DEFAULT_OUTPUT_LENGTH, key: nil, key_seed: nil)
25
+ raise TypeError, 'Hash length is not an Integer' unless output_length.is_a?(::Integer)
26
+ raise ArgumentError, 'Hash length out of range' unless (1...(1 << 20)).include?(output_length)
27
+ raise TypeError, 'Key is not a String' if !key.nil? && !key.is_a?(::String)
28
+ raise ArgumentError, 'Key length mismatched' unless key.nil? || (key.bytesize == KEY_LENGTH)
29
+ raise TypeError, 'Key seed is not a String' if !key_seed.nil? && !key_seed.is_a?(::String)
30
+ @native_instance = if !key && !key_seed
31
+ Binding.init
32
+ elsif key && key_seed
33
+ raise ::ArgumentError, 'Both key and key_seed available at the same time; please pick only one.'
34
+ elsif key
35
+ key_buffer = ::FFI::MemoryPointer.new(:uint8, KEY_LENGTH)
36
+ key_buffer.put_bytes(0, key)
37
+ Binding.init_with_key(key_buffer)
38
+ elsif key_seed
39
+ seed_size = key_seed.bytesize
40
+ seed_buffer = ::FFI::MemoryPointer.new(:uint8, seed_size)
41
+ seed_buffer.put_bytes(0, key_seed)
42
+ Binding.init_with_key_seed(seed_buffer, seed_size)
43
+ else
44
+ raise ::ArgumentError, 'Unknown mode of operation'
45
+ end.tap do |pointer|
46
+ ::ObjectSpace.define_finalizer(self, self.class._create_finalizer(pointer))
47
+ end
48
+ @output_length = output_length
49
+ invalidate_cache
50
+ end
51
+
52
+ def update(data)
53
+ data_size = data.bytesize
54
+ data_buffer = ::FFI::MemoryPointer.new(:uint8, data_size)
55
+ data_buffer.put_bytes(0, data)
56
+ Binding.update(@native_instance, data_buffer, data_size)
57
+ self
58
+ ensure
59
+ invalidate_cache
60
+ end
61
+
62
+ def <<(*args, **kwargs)
63
+ update(*args, **kwargs)
64
+ end
65
+
66
+ def digest
67
+ @_digest_cache ||= begin
68
+ data_buffer = ::FFI::MemoryPointer.new(:uint8, @output_length)
69
+ Binding.final(@native_instance, data_buffer, @output_length)
70
+ data_buffer.get_bytes(0, @output_length)
71
+ end
72
+ end
73
+
74
+ def hexdigest
75
+ @_hexdigest_cache ||= digest.unpack1('H*')
76
+ end
77
+
78
+ def base64digest
79
+ @_base64digest_cache ||= ::Base64.strict_encode64(digest)
80
+ end
81
+
82
+ private
83
+
84
+ def invalidate_cache
85
+ @_digest_cache = nil
86
+ @_hexdigest_cache = nil
87
+ @_base64digest_cache = nil
88
+ end
89
+
90
+ class << self
91
+ # https://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
92
+ def _create_finalizer(instance)
93
+ proc {
94
+ Binding.destroy(instance)
95
+ }
96
+ end
97
+
98
+ def digest(*args, **kwargs)
99
+ _generic_digest(*args, **kwargs, &:digest)
100
+ end
101
+
102
+ def hexdigest(*args, **kwargs)
103
+ _generic_digest(*args, **kwargs, &:hexdigest)
104
+ end
105
+
106
+ def base64digest(*args, **kwargs)
107
+ _generic_digest(*args, **kwargs, &:base64digest)
108
+ end
109
+
110
+ private
111
+
112
+ def _generic_digest(data, output_length: nil, key: nil, key_seed: nil, &hash_finalizer)
113
+ instance = new(**{ output_length: output_length, key: key, key_seed: key_seed }.compact)
114
+ instance.update(data)
115
+ hash_finalizer.call(instance)
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UncleBlake3
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'uncle_blake3/version'
4
+ require_relative 'uncle_blake3/digest'
5
+
6
+ module UncleBlake3
7
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uncle_blake3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sarun Rattanasiri
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.15.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.15.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 13.0.6
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 13.0.6
41
+ description: This gem brought the hash algorithm, Blake3, to Ruby. It uses the official
42
+ Blake3 implementation which optimized and maintained by the original Blake3 team
43
+ themselves.
44
+ email: midnight_w@gmx.tw
45
+ executables: []
46
+ extensions:
47
+ - ext/Rakefile
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE.md
51
+ - README.md
52
+ - ext/Rakefile
53
+ - ext/binding/uncle_blake3.c
54
+ - ext/blake3/c/Makefile.testing
55
+ - ext/blake3/c/README.md
56
+ - ext/blake3/c/blake3.c
57
+ - ext/blake3/c/blake3.h
58
+ - ext/blake3/c/blake3_avx2.c
59
+ - ext/blake3/c/blake3_avx2_x86-64_unix.S
60
+ - ext/blake3/c/blake3_avx2_x86-64_windows_gnu.S
61
+ - ext/blake3/c/blake3_avx2_x86-64_windows_msvc.asm
62
+ - ext/blake3/c/blake3_avx512.c
63
+ - ext/blake3/c/blake3_avx512_x86-64_unix.S
64
+ - ext/blake3/c/blake3_avx512_x86-64_windows_gnu.S
65
+ - ext/blake3/c/blake3_avx512_x86-64_windows_msvc.asm
66
+ - ext/blake3/c/blake3_dispatch.c
67
+ - ext/blake3/c/blake3_impl.h
68
+ - ext/blake3/c/blake3_neon.c
69
+ - ext/blake3/c/blake3_portable.c
70
+ - ext/blake3/c/blake3_sse2.c
71
+ - ext/blake3/c/blake3_sse2_x86-64_unix.S
72
+ - ext/blake3/c/blake3_sse2_x86-64_windows_gnu.S
73
+ - ext/blake3/c/blake3_sse2_x86-64_windows_msvc.asm
74
+ - ext/blake3/c/blake3_sse41.c
75
+ - ext/blake3/c/blake3_sse41_x86-64_unix.S
76
+ - ext/blake3/c/blake3_sse41_x86-64_windows_gnu.S
77
+ - ext/blake3/c/blake3_sse41_x86-64_windows_msvc.asm
78
+ - ext/blake3/c/example.c
79
+ - ext/blake3/c/main.c
80
+ - ext/blake3/c/test.py
81
+ - lib/uncle_blake3.rb
82
+ - lib/uncle_blake3/binding.rb
83
+ - lib/uncle_blake3/build.rb
84
+ - lib/uncle_blake3/build/loader.rb
85
+ - lib/uncle_blake3/build/platform.rb
86
+ - lib/uncle_blake3/digest.rb
87
+ - lib/uncle_blake3/version.rb
88
+ homepage: https://github.com/the-cave/uncle-blake3
89
+ licenses: []
90
+ metadata:
91
+ homepage_uri: https://github.com/the-cave/uncle-blake3
92
+ source_code_uri: https://github.com/the-cave/uncle-blake3/tree/v0.0.1
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: 2.6.0
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubygems_version: 3.2.32
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: A binding of the Blake3 hash algorithm for Ruby
112
+ test_files: []