blake2 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +2 -0
- data/.gitignore +4 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +674 -0
- data/README.md +45 -0
- data/Rakefile +18 -0
- data/blake2.gemspec +26 -0
- data/certs/franckverrot.pem +21 -0
- data/checksums/0.1.0.sha512 +1 -0
- data/ext/blake2_ext/blake2-impl.h +136 -0
- data/ext/blake2_ext/blake2.h +156 -0
- data/ext/blake2_ext/blake2s-ref.c +383 -0
- data/ext/blake2_ext/extconf.rb +3 -0
- data/ext/blake2_ext/rbext.c +92 -0
- data/lib/blake2.rb +2 -0
- data/lib/blake2/key.rb +23 -0
- data/test/blake2/key_test.rb +18 -0
- data/test/blake2_test.rb +25 -0
- data/test/test_helper.rb +11 -0
- metadata +147 -0
- metadata.gz.sig +1 -0
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# BLAKE2 for Ruby
|
2
|
+
|
3
|
+
## SUMMARY
|
4
|
+
|
5
|
+
This gem is a C-extension for using BLAKE2 in Ruby.
|
6
|
+
|
7
|
+
For a detailed explanation about BLAKE2, [here's the offical website](https://blake2.net/).
|
8
|
+
|
9
|
+
## INSTALL
|
10
|
+
|
11
|
+
gem install blake2
|
12
|
+
|
13
|
+
|
14
|
+
## USAGE
|
15
|
+
|
16
|
+
out_len = 32
|
17
|
+
input = "hello world"
|
18
|
+
key = Key.from_string("foo bar baz") # or `Key.none`, or `Key.from_hex("0xDEADBEAF")`
|
19
|
+
|
20
|
+
digestor = Blake2.new(out_len, key)
|
21
|
+
|
22
|
+
digestor.digest(input, :to_hex) # => 9567...b180
|
23
|
+
digestor.digest(input, :to_bytes) # => [0x95, 0x67, <28 bytes later...>, 0xb1, 0x80]
|
24
|
+
|
25
|
+
|
26
|
+
## API
|
27
|
+
|
28
|
+
TODO
|
29
|
+
|
30
|
+
## TODO
|
31
|
+
|
32
|
+
* [ ] Documentation
|
33
|
+
* [ ] Improve controls/type checks in the `digest` methods
|
34
|
+
|
35
|
+
## CONTRIBUTE
|
36
|
+
|
37
|
+
1. Fork it ( https://github.com/franckverrot/blake2/fork )
|
38
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
41
|
+
5. Create new Pull Request
|
42
|
+
|
43
|
+
## LICENSE
|
44
|
+
|
45
|
+
Franck Verrot, Copyright 2014. See LICENSE.txt.
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rake/extensiontask'
|
2
|
+
spec = Gem::Specification.load('blake2.gemspec')
|
3
|
+
Rake::ExtensionTask.new('blake2_ext', spec) do |ext|
|
4
|
+
ext.source_pattern = "*.{c,h}"
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rake/testtask'
|
8
|
+
Rake::TestTask.new do |t|
|
9
|
+
t.libs << "test"
|
10
|
+
t.pattern = "test/**/*_test.rb"
|
11
|
+
t.verbose = true
|
12
|
+
t.warning = true
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => :full
|
16
|
+
|
17
|
+
desc "Run the full spec suite"
|
18
|
+
task :full => ["clean", "compile", "test"]
|
data/blake2.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
Gem::Specification.new do |spec|
|
3
|
+
spec.name = "blake2"
|
4
|
+
spec.version = "0.1.0"
|
5
|
+
spec.authors = ["Franck Verrot"]
|
6
|
+
spec.email = ["franck@verrot.fr"]
|
7
|
+
spec.homepage = "https://github.com/franckverrot/blake2"
|
8
|
+
spec.license = "GPLv3"
|
9
|
+
|
10
|
+
spec.summary = "BLAKE2 - fast secure hashing - for Ruby"
|
11
|
+
spec.description = spec.summary
|
12
|
+
spec.files = `git ls-files -z`.split("\x0")
|
13
|
+
|
14
|
+
spec.extensions << "ext/blake2_ext/extconf.rb"
|
15
|
+
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_development_dependency "rake-compiler"
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "minitest"
|
23
|
+
|
24
|
+
spec.cert_chain = ['certs/franckverrot.pem']
|
25
|
+
spec.signing_key = File.expand_path(ENV['RUBYGEMS_CERT_PATH']) if $0 =~ /gem\z/
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MQ8wDQYDVQQDDAZmcmFu
|
3
|
+
Y2sxFjAUBgoJkiaJk/IsZAEZFgZ2ZXJyb3QxEjAQBgoJkiaJk/IsZAEZFgJmcjAe
|
4
|
+
Fw0xNDA5MDcwODE4MDRaFw0xNTA5MDcwODE4MDRaMD0xDzANBgNVBAMMBmZyYW5j
|
5
|
+
azEWMBQGCgmSJomT8ixkARkWBnZlcnJvdDESMBAGCgmSJomT8ixkARkWAmZyMIIB
|
6
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw8Sqy/b4OzhODXkAqv/Ve7hp
|
7
|
+
oH5irjrS20ebbzWqefcHCybwqcmePUs4BtWnGMkGl+fe4Dxfh55m7EXbmbcLBqPJ
|
8
|
+
3Q5bqIgXqmkzHU6oBpkY/fdcP0dLyYBTAo8jZsx6XE1NoC5MBFfHQ8GFzEox7ca7
|
9
|
+
eoRPETTFkrlOU8fQQvRMZV8cO9XbzX8PFsJ9iE7CSrZ3+78oFBrj+WslkdU/pR5g
|
10
|
+
CYU7eNmWPBbJsgWy9T63K4QkwMElJRvlge3dzAZBEktaxdbiPTQeBtLugIZV2nWA
|
11
|
+
mNVMXQ9FzDeSFEhm3ICMuSjJdyEsl9/Su6WFFDaRW4ntRzThdh0+Zs5YEz3+swID
|
12
|
+
AQABo3MwcTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUjJzR97Cw
|
13
|
+
I8juLYc/MgodFZPIVYkwGwYDVR0RBBQwEoEQZnJhbmNrQHZlcnJvdC5mcjAbBgNV
|
14
|
+
HRIEFDASgRBmcmFuY2tAdmVycm90LmZyMA0GCSqGSIb3DQEBBQUAA4IBAQAkNGfg
|
15
|
+
9ysYJi/jrQ25GWgN3uJuvlscFYGPVmuyyOfsgm2NAkAV5Kn/rbeYxRecIRBU7HcZ
|
16
|
+
yVrHFaF36omjo5QIvNDNszHj4b/bwcW30QG0nNqzQlMTvAcsI9kwrDgoAd7qnSmb
|
17
|
+
Udf49ZrzniqaFR7OiBia2oXrYynD8Q4mRMzLTMdtdf8oy69DjCrrpzQvEcfHnxML
|
18
|
+
MY7zkhoLIwqbZ+/yfSm26+3h91WoEKEdK+caiHotdq1goqlBDIsLSR65siB2yna3
|
19
|
+
UeH0jxnbT6lYw622u74Z7Dd6iQfaOy1h+iJxnCQglf70rs9bS665Nr0QvvrbW8Hz
|
20
|
+
Vr/YT3S8RkdBsIdM
|
21
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1 @@
|
|
1
|
+
4faf052c6018bd3f17ab23c2cc6f5e2e7c9beaadd3fbb85652fc70cac785b1a6886ffa1a0d0c164607acf5bbf43881f7a17b75a3eba5647784d7c67c274574c4
|
@@ -0,0 +1,136 @@
|
|
1
|
+
/*
|
2
|
+
BLAKE2 reference source code package - reference C implementations
|
3
|
+
|
4
|
+
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
5
|
+
|
6
|
+
To the extent possible under law, the author(s) have dedicated all copyright
|
7
|
+
and related and neighboring rights to this software to the public domain
|
8
|
+
worldwide. This software is distributed without any warranty.
|
9
|
+
|
10
|
+
You should have received a copy of the CC0 Public Domain Dedication along with
|
11
|
+
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
12
|
+
*/
|
13
|
+
#pragma once
|
14
|
+
#ifndef __BLAKE2_IMPL_H__
|
15
|
+
#define __BLAKE2_IMPL_H__
|
16
|
+
|
17
|
+
#include <stdint.h>
|
18
|
+
|
19
|
+
static inline uint32_t load32( const void *src )
|
20
|
+
{
|
21
|
+
#if defined(NATIVE_LITTLE_ENDIAN)
|
22
|
+
uint32_t w;
|
23
|
+
memcpy(&w, src, sizeof w);
|
24
|
+
return w;
|
25
|
+
#else
|
26
|
+
const uint8_t *p = ( const uint8_t * )src;
|
27
|
+
uint32_t w = *p++;
|
28
|
+
w |= ( uint32_t )( *p++ ) << 8;
|
29
|
+
w |= ( uint32_t )( *p++ ) << 16;
|
30
|
+
w |= ( uint32_t )( *p++ ) << 24;
|
31
|
+
return w;
|
32
|
+
#endif
|
33
|
+
}
|
34
|
+
|
35
|
+
static inline uint64_t load64( const void *src )
|
36
|
+
{
|
37
|
+
#if defined(NATIVE_LITTLE_ENDIAN)
|
38
|
+
uint64_t w;
|
39
|
+
memcpy(&w, src, sizeof w);
|
40
|
+
return w;
|
41
|
+
#else
|
42
|
+
const uint8_t *p = ( const uint8_t * )src;
|
43
|
+
uint64_t w = *p++;
|
44
|
+
w |= ( uint64_t )( *p++ ) << 8;
|
45
|
+
w |= ( uint64_t )( *p++ ) << 16;
|
46
|
+
w |= ( uint64_t )( *p++ ) << 24;
|
47
|
+
w |= ( uint64_t )( *p++ ) << 32;
|
48
|
+
w |= ( uint64_t )( *p++ ) << 40;
|
49
|
+
w |= ( uint64_t )( *p++ ) << 48;
|
50
|
+
w |= ( uint64_t )( *p++ ) << 56;
|
51
|
+
return w;
|
52
|
+
#endif
|
53
|
+
}
|
54
|
+
|
55
|
+
static inline void store32( void *dst, uint32_t w )
|
56
|
+
{
|
57
|
+
#if defined(NATIVE_LITTLE_ENDIAN)
|
58
|
+
memcpy(dst, &w, sizeof w);
|
59
|
+
#else
|
60
|
+
uint8_t *p = ( uint8_t * )dst;
|
61
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
62
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
63
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
64
|
+
*p++ = ( uint8_t )w;
|
65
|
+
#endif
|
66
|
+
}
|
67
|
+
|
68
|
+
static inline void store64( void *dst, uint64_t w )
|
69
|
+
{
|
70
|
+
#if defined(NATIVE_LITTLE_ENDIAN)
|
71
|
+
memcpy(dst, &w, sizeof w);
|
72
|
+
#else
|
73
|
+
uint8_t *p = ( uint8_t * )dst;
|
74
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
75
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
76
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
77
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
78
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
79
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
80
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
81
|
+
*p++ = ( uint8_t )w;
|
82
|
+
#endif
|
83
|
+
}
|
84
|
+
|
85
|
+
static inline uint64_t load48( const void *src )
|
86
|
+
{
|
87
|
+
const uint8_t *p = ( const uint8_t * )src;
|
88
|
+
uint64_t w = *p++;
|
89
|
+
w |= ( uint64_t )( *p++ ) << 8;
|
90
|
+
w |= ( uint64_t )( *p++ ) << 16;
|
91
|
+
w |= ( uint64_t )( *p++ ) << 24;
|
92
|
+
w |= ( uint64_t )( *p++ ) << 32;
|
93
|
+
w |= ( uint64_t )( *p++ ) << 40;
|
94
|
+
return w;
|
95
|
+
}
|
96
|
+
|
97
|
+
static inline void store48( void *dst, uint64_t w )
|
98
|
+
{
|
99
|
+
uint8_t *p = ( uint8_t * )dst;
|
100
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
101
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
102
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
103
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
104
|
+
*p++ = ( uint8_t )w; w >>= 8;
|
105
|
+
*p++ = ( uint8_t )w;
|
106
|
+
}
|
107
|
+
|
108
|
+
static inline uint32_t rotl32( const uint32_t w, const unsigned c )
|
109
|
+
{
|
110
|
+
return ( w << c ) | ( w >> ( 32 - c ) );
|
111
|
+
}
|
112
|
+
|
113
|
+
static inline uint64_t rotl64( const uint64_t w, const unsigned c )
|
114
|
+
{
|
115
|
+
return ( w << c ) | ( w >> ( 64 - c ) );
|
116
|
+
}
|
117
|
+
|
118
|
+
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
|
119
|
+
{
|
120
|
+
return ( w >> c ) | ( w << ( 32 - c ) );
|
121
|
+
}
|
122
|
+
|
123
|
+
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
|
124
|
+
{
|
125
|
+
return ( w >> c ) | ( w << ( 64 - c ) );
|
126
|
+
}
|
127
|
+
|
128
|
+
/* prevents compiler optimizing out memset() */
|
129
|
+
static inline void secure_zero_memory( void *v, size_t n )
|
130
|
+
{
|
131
|
+
volatile uint8_t *p = ( volatile uint8_t * )v;
|
132
|
+
while( n-- ) *p++ = 0;
|
133
|
+
}
|
134
|
+
|
135
|
+
#endif
|
136
|
+
|
@@ -0,0 +1,156 @@
|
|
1
|
+
/*
|
2
|
+
BLAKE2 reference source code package - reference C implementations
|
3
|
+
|
4
|
+
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
5
|
+
|
6
|
+
To the extent possible under law, the author(s) have dedicated all copyright
|
7
|
+
and related and neighboring rights to this software to the public domain
|
8
|
+
worldwide. This software is distributed without any warranty.
|
9
|
+
|
10
|
+
You should have received a copy of the CC0 Public Domain Dedication along with
|
11
|
+
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
12
|
+
*/
|
13
|
+
#pragma once
|
14
|
+
#ifndef __BLAKE2_H__
|
15
|
+
#define __BLAKE2_H__
|
16
|
+
|
17
|
+
#include <stddef.h>
|
18
|
+
#include <stdint.h>
|
19
|
+
|
20
|
+
#if defined(_MSC_VER)
|
21
|
+
#define ALIGN(x) __declspec(align(x))
|
22
|
+
#else
|
23
|
+
#define ALIGN(x) __attribute__((aligned(x)))
|
24
|
+
#endif
|
25
|
+
|
26
|
+
#if defined(__cplusplus)
|
27
|
+
extern "C" {
|
28
|
+
#endif
|
29
|
+
|
30
|
+
enum blake2s_constant
|
31
|
+
{
|
32
|
+
BLAKE2S_BLOCKBYTES = 64,
|
33
|
+
BLAKE2S_OUTBYTES = 32,
|
34
|
+
BLAKE2S_KEYBYTES = 32,
|
35
|
+
BLAKE2S_SALTBYTES = 8,
|
36
|
+
BLAKE2S_PERSONALBYTES = 8
|
37
|
+
};
|
38
|
+
|
39
|
+
enum blake2b_constant
|
40
|
+
{
|
41
|
+
BLAKE2B_BLOCKBYTES = 128,
|
42
|
+
BLAKE2B_OUTBYTES = 64,
|
43
|
+
BLAKE2B_KEYBYTES = 64,
|
44
|
+
BLAKE2B_SALTBYTES = 16,
|
45
|
+
BLAKE2B_PERSONALBYTES = 16
|
46
|
+
};
|
47
|
+
|
48
|
+
#pragma pack(push, 1)
|
49
|
+
typedef struct __blake2s_param
|
50
|
+
{
|
51
|
+
uint8_t digest_length; // 1
|
52
|
+
uint8_t key_length; // 2
|
53
|
+
uint8_t fanout; // 3
|
54
|
+
uint8_t depth; // 4
|
55
|
+
uint32_t leaf_length; // 8
|
56
|
+
uint8_t node_offset[6];// 14
|
57
|
+
uint8_t node_depth; // 15
|
58
|
+
uint8_t inner_length; // 16
|
59
|
+
// uint8_t reserved[0];
|
60
|
+
uint8_t salt[BLAKE2S_SALTBYTES]; // 24
|
61
|
+
uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32
|
62
|
+
} blake2s_param;
|
63
|
+
|
64
|
+
ALIGN( 64 ) typedef struct __blake2s_state
|
65
|
+
{
|
66
|
+
uint32_t h[8];
|
67
|
+
uint32_t t[2];
|
68
|
+
uint32_t f[2];
|
69
|
+
uint8_t buf[2 * BLAKE2S_BLOCKBYTES];
|
70
|
+
size_t buflen;
|
71
|
+
uint8_t last_node;
|
72
|
+
} blake2s_state ;
|
73
|
+
|
74
|
+
typedef struct __blake2b_param
|
75
|
+
{
|
76
|
+
uint8_t digest_length; // 1
|
77
|
+
uint8_t key_length; // 2
|
78
|
+
uint8_t fanout; // 3
|
79
|
+
uint8_t depth; // 4
|
80
|
+
uint32_t leaf_length; // 8
|
81
|
+
uint64_t node_offset; // 16
|
82
|
+
uint8_t node_depth; // 17
|
83
|
+
uint8_t inner_length; // 18
|
84
|
+
uint8_t reserved[14]; // 32
|
85
|
+
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
|
86
|
+
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
|
87
|
+
} blake2b_param;
|
88
|
+
|
89
|
+
ALIGN( 64 ) typedef struct __blake2b_state
|
90
|
+
{
|
91
|
+
uint64_t h[8];
|
92
|
+
uint64_t t[2];
|
93
|
+
uint64_t f[2];
|
94
|
+
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
|
95
|
+
size_t buflen;
|
96
|
+
uint8_t last_node;
|
97
|
+
} blake2b_state;
|
98
|
+
|
99
|
+
typedef struct __blake2sp_state
|
100
|
+
{
|
101
|
+
blake2s_state S[8][1];
|
102
|
+
blake2s_state R[1];
|
103
|
+
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
104
|
+
size_t buflen;
|
105
|
+
} blake2sp_state;
|
106
|
+
|
107
|
+
typedef struct __blake2bp_state
|
108
|
+
{
|
109
|
+
blake2b_state S[4][1];
|
110
|
+
blake2b_state R[1];
|
111
|
+
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
112
|
+
size_t buflen;
|
113
|
+
} blake2bp_state;
|
114
|
+
#pragma pack(pop)
|
115
|
+
|
116
|
+
// Streaming API
|
117
|
+
int blake2s_init( blake2s_state *S, const uint8_t outlen );
|
118
|
+
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
119
|
+
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
120
|
+
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen );
|
121
|
+
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen );
|
122
|
+
|
123
|
+
int blake2b_init( blake2b_state *S, const uint8_t outlen );
|
124
|
+
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
125
|
+
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
126
|
+
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );
|
127
|
+
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );
|
128
|
+
|
129
|
+
int blake2sp_init( blake2sp_state *S, const uint8_t outlen );
|
130
|
+
int blake2sp_init_key( blake2sp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
131
|
+
int blake2sp_update( blake2sp_state *S, const uint8_t *in, uint64_t inlen );
|
132
|
+
int blake2sp_final( blake2sp_state *S, uint8_t *out, uint8_t outlen );
|
133
|
+
|
134
|
+
int blake2bp_init( blake2bp_state *S, const uint8_t outlen );
|
135
|
+
int blake2bp_init_key( blake2bp_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
|
136
|
+
int blake2bp_update( blake2bp_state *S, const uint8_t *in, uint64_t inlen );
|
137
|
+
int blake2bp_final( blake2bp_state *S, uint8_t *out, uint8_t outlen );
|
138
|
+
|
139
|
+
// Simple API
|
140
|
+
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
141
|
+
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
142
|
+
|
143
|
+
int blake2sp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
144
|
+
int blake2bp( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
|
145
|
+
|
146
|
+
static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
147
|
+
{
|
148
|
+
return blake2b( out, in, key, outlen, inlen, keylen );
|
149
|
+
}
|
150
|
+
|
151
|
+
#if defined(__cplusplus)
|
152
|
+
}
|
153
|
+
#endif
|
154
|
+
|
155
|
+
#endif
|
156
|
+
|
@@ -0,0 +1,383 @@
|
|
1
|
+
/*
|
2
|
+
BLAKE2 reference source code package - reference C implementations
|
3
|
+
|
4
|
+
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
|
5
|
+
|
6
|
+
To the extent possible under law, the author(s) have dedicated all copyright
|
7
|
+
and related and neighboring rights to this software to the public domain
|
8
|
+
worldwide. This software is distributed without any warranty.
|
9
|
+
|
10
|
+
You should have received a copy of the CC0 Public Domain Dedication along with
|
11
|
+
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
12
|
+
*/
|
13
|
+
|
14
|
+
#include <stdint.h>
|
15
|
+
#include <string.h>
|
16
|
+
#include <stdio.h>
|
17
|
+
|
18
|
+
#include "blake2.h"
|
19
|
+
#include "blake2-impl.h"
|
20
|
+
|
21
|
+
static const uint32_t blake2s_IV[8] =
|
22
|
+
{
|
23
|
+
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
24
|
+
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
25
|
+
};
|
26
|
+
|
27
|
+
static const uint8_t blake2s_sigma[10][16] =
|
28
|
+
{
|
29
|
+
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
|
30
|
+
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
|
31
|
+
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
|
32
|
+
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
|
33
|
+
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
|
34
|
+
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
|
35
|
+
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
|
36
|
+
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
|
37
|
+
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
|
38
|
+
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
|
39
|
+
};
|
40
|
+
|
41
|
+
static inline int blake2s_set_lastnode( blake2s_state *S )
|
42
|
+
{
|
43
|
+
S->f[1] = ~0U;
|
44
|
+
return 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
static inline int blake2s_clear_lastnode( blake2s_state *S )
|
48
|
+
{
|
49
|
+
S->f[1] = 0U;
|
50
|
+
return 0;
|
51
|
+
}
|
52
|
+
|
53
|
+
/* Some helper functions, not necessarily useful */
|
54
|
+
static inline int blake2s_set_lastblock( blake2s_state *S )
|
55
|
+
{
|
56
|
+
if( S->last_node ) blake2s_set_lastnode( S );
|
57
|
+
|
58
|
+
S->f[0] = ~0U;
|
59
|
+
return 0;
|
60
|
+
}
|
61
|
+
|
62
|
+
static inline int blake2s_clear_lastblock( blake2s_state *S )
|
63
|
+
{
|
64
|
+
if( S->last_node ) blake2s_clear_lastnode( S );
|
65
|
+
|
66
|
+
S->f[0] = 0U;
|
67
|
+
return 0;
|
68
|
+
}
|
69
|
+
|
70
|
+
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
71
|
+
{
|
72
|
+
S->t[0] += inc;
|
73
|
+
S->t[1] += ( S->t[0] < inc );
|
74
|
+
return 0;
|
75
|
+
}
|
76
|
+
|
77
|
+
// Parameter-related functions
|
78
|
+
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
|
79
|
+
{
|
80
|
+
P->digest_length = digest_length;
|
81
|
+
return 0;
|
82
|
+
}
|
83
|
+
|
84
|
+
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
|
85
|
+
{
|
86
|
+
P->fanout = fanout;
|
87
|
+
return 0;
|
88
|
+
}
|
89
|
+
|
90
|
+
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
|
91
|
+
{
|
92
|
+
P->depth = depth;
|
93
|
+
return 0;
|
94
|
+
}
|
95
|
+
|
96
|
+
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
|
97
|
+
{
|
98
|
+
store32( &P->leaf_length, leaf_length );
|
99
|
+
return 0;
|
100
|
+
}
|
101
|
+
|
102
|
+
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
|
103
|
+
{
|
104
|
+
store48( P->node_offset, node_offset );
|
105
|
+
return 0;
|
106
|
+
}
|
107
|
+
|
108
|
+
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
|
109
|
+
{
|
110
|
+
P->node_depth = node_depth;
|
111
|
+
return 0;
|
112
|
+
}
|
113
|
+
|
114
|
+
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
|
115
|
+
{
|
116
|
+
P->inner_length = inner_length;
|
117
|
+
return 0;
|
118
|
+
}
|
119
|
+
|
120
|
+
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
|
121
|
+
{
|
122
|
+
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
|
123
|
+
return 0;
|
124
|
+
}
|
125
|
+
|
126
|
+
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
|
127
|
+
{
|
128
|
+
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
|
129
|
+
return 0;
|
130
|
+
}
|
131
|
+
|
132
|
+
static inline int blake2s_init0( blake2s_state *S )
|
133
|
+
{
|
134
|
+
memset( S, 0, sizeof( blake2s_state ) );
|
135
|
+
|
136
|
+
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
137
|
+
|
138
|
+
return 0;
|
139
|
+
}
|
140
|
+
|
141
|
+
/* init2 xors IV with input parameter block */
|
142
|
+
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
143
|
+
{
|
144
|
+
blake2s_init0( S );
|
145
|
+
const uint32_t *p = ( const uint32_t * )( P );
|
146
|
+
|
147
|
+
/* IV XOR ParamBlock */
|
148
|
+
for( size_t i = 0; i < 8; ++i )
|
149
|
+
S->h[i] ^= load32( &p[i] );
|
150
|
+
|
151
|
+
return 0;
|
152
|
+
}
|
153
|
+
|
154
|
+
|
155
|
+
// Sequential blake2s initialization
|
156
|
+
int blake2s_init( blake2s_state *S, const uint8_t outlen )
|
157
|
+
{
|
158
|
+
blake2s_param P[1];
|
159
|
+
|
160
|
+
/* Move interval verification here? */
|
161
|
+
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
162
|
+
|
163
|
+
P->digest_length = outlen;
|
164
|
+
P->key_length = 0;
|
165
|
+
P->fanout = 1;
|
166
|
+
P->depth = 1;
|
167
|
+
store32( &P->leaf_length, 0 );
|
168
|
+
store48( &P->node_offset, 0 );
|
169
|
+
P->node_depth = 0;
|
170
|
+
P->inner_length = 0;
|
171
|
+
// memset(P->reserved, 0, sizeof(P->reserved) );
|
172
|
+
memset( P->salt, 0, sizeof( P->salt ) );
|
173
|
+
memset( P->personal, 0, sizeof( P->personal ) );
|
174
|
+
return blake2s_init_param( S, P );
|
175
|
+
}
|
176
|
+
|
177
|
+
int blake2s_init_key( blake2s_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
|
178
|
+
{
|
179
|
+
blake2s_param P[1];
|
180
|
+
|
181
|
+
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
182
|
+
|
183
|
+
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
184
|
+
|
185
|
+
P->digest_length = outlen;
|
186
|
+
P->key_length = keylen;
|
187
|
+
P->fanout = 1;
|
188
|
+
P->depth = 1;
|
189
|
+
store32( &P->leaf_length, 0 );
|
190
|
+
store48( &P->node_offset, 0 );
|
191
|
+
P->node_depth = 0;
|
192
|
+
P->inner_length = 0;
|
193
|
+
// memset(P->reserved, 0, sizeof(P->reserved) );
|
194
|
+
memset( P->salt, 0, sizeof( P->salt ) );
|
195
|
+
memset( P->personal, 0, sizeof( P->personal ) );
|
196
|
+
|
197
|
+
if( blake2s_init_param( S, P ) < 0 ) return -1;
|
198
|
+
|
199
|
+
{
|
200
|
+
uint8_t block[BLAKE2S_BLOCKBYTES];
|
201
|
+
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
202
|
+
memcpy( block, key, keylen );
|
203
|
+
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
204
|
+
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
205
|
+
}
|
206
|
+
return 0;
|
207
|
+
}
|
208
|
+
|
209
|
+
static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
|
210
|
+
{
|
211
|
+
uint32_t m[16];
|
212
|
+
uint32_t v[16];
|
213
|
+
|
214
|
+
for( size_t i = 0; i < 16; ++i )
|
215
|
+
m[i] = load32( block + i * sizeof( m[i] ) );
|
216
|
+
|
217
|
+
for( size_t i = 0; i < 8; ++i )
|
218
|
+
v[i] = S->h[i];
|
219
|
+
|
220
|
+
v[ 8] = blake2s_IV[0];
|
221
|
+
v[ 9] = blake2s_IV[1];
|
222
|
+
v[10] = blake2s_IV[2];
|
223
|
+
v[11] = blake2s_IV[3];
|
224
|
+
v[12] = S->t[0] ^ blake2s_IV[4];
|
225
|
+
v[13] = S->t[1] ^ blake2s_IV[5];
|
226
|
+
v[14] = S->f[0] ^ blake2s_IV[6];
|
227
|
+
v[15] = S->f[1] ^ blake2s_IV[7];
|
228
|
+
#define G(r,i,a,b,c,d) \
|
229
|
+
do { \
|
230
|
+
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
231
|
+
d = rotr32(d ^ a, 16); \
|
232
|
+
c = c + d; \
|
233
|
+
b = rotr32(b ^ c, 12); \
|
234
|
+
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
235
|
+
d = rotr32(d ^ a, 8); \
|
236
|
+
c = c + d; \
|
237
|
+
b = rotr32(b ^ c, 7); \
|
238
|
+
} while(0)
|
239
|
+
#define ROUND(r) \
|
240
|
+
do { \
|
241
|
+
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
242
|
+
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
243
|
+
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
244
|
+
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
245
|
+
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
246
|
+
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
247
|
+
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
248
|
+
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
249
|
+
} while(0)
|
250
|
+
ROUND( 0 );
|
251
|
+
ROUND( 1 );
|
252
|
+
ROUND( 2 );
|
253
|
+
ROUND( 3 );
|
254
|
+
ROUND( 4 );
|
255
|
+
ROUND( 5 );
|
256
|
+
ROUND( 6 );
|
257
|
+
ROUND( 7 );
|
258
|
+
ROUND( 8 );
|
259
|
+
ROUND( 9 );
|
260
|
+
|
261
|
+
for( size_t i = 0; i < 8; ++i )
|
262
|
+
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
263
|
+
|
264
|
+
#undef G
|
265
|
+
#undef ROUND
|
266
|
+
return 0;
|
267
|
+
}
|
268
|
+
|
269
|
+
|
270
|
+
int blake2s_update( blake2s_state *S, const uint8_t *in, uint64_t inlen )
|
271
|
+
{
|
272
|
+
while( inlen > 0 )
|
273
|
+
{
|
274
|
+
size_t left = S->buflen;
|
275
|
+
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
276
|
+
|
277
|
+
if( inlen > fill )
|
278
|
+
{
|
279
|
+
memcpy( S->buf + left, in, fill ); // Fill buffer
|
280
|
+
S->buflen += fill;
|
281
|
+
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
282
|
+
blake2s_compress( S, S->buf ); // Compress
|
283
|
+
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
|
284
|
+
S->buflen -= BLAKE2S_BLOCKBYTES;
|
285
|
+
in += fill;
|
286
|
+
inlen -= fill;
|
287
|
+
}
|
288
|
+
else // inlen <= fill
|
289
|
+
{
|
290
|
+
memcpy( S->buf + left, in, inlen );
|
291
|
+
S->buflen += inlen; // Be lazy, do not compress
|
292
|
+
in += inlen;
|
293
|
+
inlen -= inlen;
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
return 0;
|
298
|
+
}
|
299
|
+
|
300
|
+
int blake2s_final( blake2s_state *S, uint8_t *out, uint8_t outlen )
|
301
|
+
{
|
302
|
+
uint8_t buffer[BLAKE2S_OUTBYTES] = {0};
|
303
|
+
|
304
|
+
if( outlen > BLAKE2S_OUTBYTES )
|
305
|
+
return -1;
|
306
|
+
|
307
|
+
if( S->buflen > BLAKE2S_BLOCKBYTES )
|
308
|
+
{
|
309
|
+
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
310
|
+
blake2s_compress( S, S->buf );
|
311
|
+
S->buflen -= BLAKE2S_BLOCKBYTES;
|
312
|
+
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
|
313
|
+
}
|
314
|
+
|
315
|
+
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
316
|
+
blake2s_set_lastblock( S );
|
317
|
+
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
318
|
+
blake2s_compress( S, S->buf );
|
319
|
+
|
320
|
+
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
321
|
+
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
322
|
+
|
323
|
+
memcpy( out, buffer, outlen );
|
324
|
+
return 0;
|
325
|
+
}
|
326
|
+
|
327
|
+
int blake2s( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
|
328
|
+
{
|
329
|
+
blake2s_state S[1];
|
330
|
+
|
331
|
+
/* Verify parameters */
|
332
|
+
if ( NULL == in ) return -1;
|
333
|
+
|
334
|
+
if ( NULL == out ) return -1;
|
335
|
+
|
336
|
+
if ( NULL == key ) keylen = 0; /* Fail here instead if keylen != 0 and key == NULL? */
|
337
|
+
|
338
|
+
if( keylen > 0 )
|
339
|
+
{
|
340
|
+
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
341
|
+
}
|
342
|
+
else
|
343
|
+
{
|
344
|
+
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
345
|
+
}
|
346
|
+
|
347
|
+
blake2s_update( S, ( const uint8_t * )in, inlen );
|
348
|
+
blake2s_final( S, out, outlen );
|
349
|
+
return 0;
|
350
|
+
}
|
351
|
+
|
352
|
+
#if defined(BLAKE2S_SELFTEST)
|
353
|
+
#include <string.h>
|
354
|
+
#include "blake2-kat.h"
|
355
|
+
int main( int argc, char **argv )
|
356
|
+
{
|
357
|
+
uint8_t key[BLAKE2S_KEYBYTES];
|
358
|
+
uint8_t buf[KAT_LENGTH];
|
359
|
+
|
360
|
+
for( size_t i = 0; i < BLAKE2S_KEYBYTES; ++i )
|
361
|
+
key[i] = ( uint8_t )i;
|
362
|
+
|
363
|
+
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
364
|
+
buf[i] = ( uint8_t )i;
|
365
|
+
|
366
|
+
for( size_t i = 0; i < KAT_LENGTH; ++i )
|
367
|
+
{
|
368
|
+
uint8_t hash[BLAKE2S_OUTBYTES];
|
369
|
+
blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES );
|
370
|
+
|
371
|
+
if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
372
|
+
{
|
373
|
+
puts( "error" );
|
374
|
+
return -1;
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
puts( "ok" );
|
379
|
+
return 0;
|
380
|
+
}
|
381
|
+
#endif
|
382
|
+
|
383
|
+
|