Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
5dcbf6d4
Commit
5dcbf6d4
authored
Sep 16, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add SHA1 hash implementation
parent
ac0f23bc
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
391 additions
and
3 deletions
+391
-3
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+2
-1
libcaf_core/caf/hash/fnv.hpp
libcaf_core/caf/hash/fnv.hpp
+0
-2
libcaf_core/caf/hash/sha1.hpp
libcaf_core/caf/hash/sha1.hpp
+181
-0
libcaf_core/src/hash/sha1.cpp
libcaf_core/src/hash/sha1.cpp
+161
-0
libcaf_core/test/hash/sha1.cpp
libcaf_core/test/hash/sha1.cpp
+47
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
5dcbf6d4
...
...
@@ -106,7 +106,6 @@ add_library(libcaf_core_obj OBJECT ${CAF_CORE_HEADERS}
src/detail/thread_safe_actor_clock.cpp
src/detail/tick_emitter.cpp
src/detail/token_based_credit_controller.cpp
src/detail/token_based_credit_controller.cpp
src/detail/type_id_list_builder.cpp
src/downstream_manager.cpp
src/downstream_manager_base.cpp
...
...
@@ -118,6 +117,7 @@ add_library(libcaf_core_obj OBJECT ${CAF_CORE_HEADERS}
src/group.cpp
src/group_manager.cpp
src/group_module.cpp
src/hash/sha1.cpp
src/inbound_path.cpp
src/init_global_meta_objects.cpp
src/intrusive/inbox_result_strings.cpp
...
...
@@ -272,6 +272,7 @@ caf_add_test_suites(caf-core-test
fused_downstream_manager
handles
hash.fnv
hash.sha1
intrusive.drr_cached_queue
intrusive.drr_queue
intrusive.fifo_inbox
...
...
libcaf_core/caf/hash/fnv.hpp
View file @
5dcbf6d4
...
...
@@ -43,8 +43,6 @@ class fnv : public save_inspector_base<fnv<T>> {
public:
static_assert
(
sizeof
(
T
)
==
4
||
sizeof
(
T
)
==
8
);
using
super
=
save_inspector
;
constexpr
fnv
()
noexcept
:
result
(
init
())
{
// nop
}
...
...
libcaf_core/caf/hash/sha1.hpp
0 → 100644
View file @
5dcbf6d4
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include "caf/byte.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/save_inspector_base.hpp"
#include "caf/span.hpp"
#include "caf/string_view.hpp"
#include "caf/type_id.hpp"
#include <array>
namespace
caf
::
hash
{
/// US Secure Hash Algorithm 1 (SHA1) as defined in RFC 3174.
class
sha1
:
public
save_inspector_base
<
sha1
>
{
public:
/// Hash size in bytes.
static
constexpr
size_t
hash_size
=
20
;
/// Array type for storing a 160-bit hash.
using
result_type
=
std
::
array
<
byte
,
hash_size
>
;
sha1
()
noexcept
;
static
constexpr
bool
has_human_readable_format
()
noexcept
{
return
false
;
}
constexpr
bool
begin_object
(
string_view
)
{
return
true
;
}
constexpr
bool
end_object
()
{
return
true
;
}
bool
begin_field
(
string_view
)
{
return
true
;
}
bool
begin_field
(
string_view
,
bool
is_present
)
{
return
value
(
static_cast
<
uint8_t
>
(
is_present
));
}
bool
begin_field
(
string_view
,
span
<
const
type_id_t
>
,
size_t
index
)
{
return
value
(
index
);
}
bool
begin_field
(
string_view
,
bool
is_present
,
span
<
const
type_id_t
>
,
size_t
index
)
{
value
(
static_cast
<
uint8_t
>
(
is_present
));
if
(
is_present
)
value
(
index
);
return
true
;
}
constexpr
bool
end_field
()
{
return
true
;
}
constexpr
bool
begin_tuple
(
size_t
)
{
return
true
;
}
constexpr
bool
end_tuple
()
{
return
true
;
}
constexpr
bool
begin_key_value_pair
()
{
return
true
;
}
constexpr
bool
end_key_value_pair
()
{
return
true
;
}
constexpr
bool
begin_sequence
(
size_t
)
{
return
true
;
}
constexpr
bool
end_sequence
()
{
return
true
;
}
constexpr
bool
begin_associative_array
(
size_t
)
{
return
true
;
}
constexpr
bool
end_associative_array
()
{
return
true
;
}
template
<
class
Integral
>
std
::
enable_if_t
<
std
::
is_integral
<
Integral
>::
value
,
bool
>
value
(
Integral
x
)
noexcept
{
auto
begin
=
reinterpret_cast
<
const
uint8_t
*>
(
&
x
);
append
(
begin
,
begin
+
sizeof
(
Integral
));
return
true
;
}
bool
value
(
bool
x
)
noexcept
{
auto
tmp
=
static_cast
<
uint8_t
>
(
x
);
return
value
(
tmp
);
}
bool
value
(
float
x
)
noexcept
{
return
value
(
detail
::
pack754
(
x
));
}
bool
value
(
double
x
)
noexcept
{
return
value
(
detail
::
pack754
(
x
));
}
bool
value
(
string_view
x
)
noexcept
{
auto
begin
=
reinterpret_cast
<
const
uint8_t
*>
(
x
.
data
());
append
(
begin
,
begin
+
x
.
size
());
return
true
;
}
bool
value
(
span
<
const
byte
>
x
)
noexcept
{
auto
begin
=
reinterpret_cast
<
const
uint8_t
*>
(
x
.
data
());
append
(
begin
,
begin
+
x
.
size
());
return
true
;
}
/// Seals this SHA-1 context and returns the 160-bit message digest.
result_type
result
()
noexcept
;
/// Convenience function for computing a SHA-1 hash value for given arguments
/// in one shot.
template
<
class
...
Ts
>
static
result_type
compute
(
Ts
&&
...
xs
)
noexcept
{
using
detail
::
as_mutable_ref
;
sha1
f
;
auto
unused
=
f
.
apply_objects
(
xs
...);
static_cast
<
void
>
(
unused
);
// Always true.
return
f
.
result
();
}
private:
bool
append
(
const
uint8_t
*
begin
,
const
uint8_t
*
end
)
noexcept
;
void
process_message_block
();
void
pad_message
();
/// Stores whether `result()` has been called.
bool
sealed_
=
0
;
/// Stores the message digest so far.
std
::
array
<
uint32_t
,
hash_size
/
4
>
intermediate_
;
/// Stores the message length in bits.
uint64_t
length_
=
0
;
/// Stores the current index in `message_block_`.
int_least16_t
message_block_index_
=
0
;
/// Stores 512-bit message blocks.
std
::
array
<
uint8_t
,
64
>
message_block_
;
};
}
// namespace caf::hash
libcaf_core/src/hash/sha1.cpp
0 → 100644
View file @
5dcbf6d4
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/hash/sha1.hpp"
#include <cstring>
#define SHA1CircularShift(bits, word) \
(((word) << (bits)) | ((word) >> (32 - (bits))))
namespace
caf
::
hash
{
sha1
::
sha1
()
noexcept
{
intermediate_
[
0
]
=
0x67452301
;
intermediate_
[
1
]
=
0xEFCDAB89
;
intermediate_
[
2
]
=
0x98BADCFE
;
intermediate_
[
3
]
=
0x10325476
;
intermediate_
[
4
]
=
0xC3D2E1F0
;
memset
(
message_block_
.
data
(),
0
,
message_block_
.
size
());
}
sha1
::
result_type
sha1
::
result
()
noexcept
{
if
(
!
sealed_
)
{
pad_message
();
memset
(
message_block_
.
data
(),
0
,
message_block_
.
size
());
length_
=
0
;
sealed_
=
true
;
}
std
::
array
<
byte
,
sha1
::
hash_size
>
buf
;
for
(
size_t
i
=
0
;
i
<
hash_size
;
++
i
)
{
auto
tmp
=
intermediate_
[
i
>>
2
]
>>
8
*
(
3
-
(
i
&
0x03
));
buf
[
i
]
=
static_cast
<
byte
>
(
tmp
);
}
return
buf
;
}
bool
sha1
::
append
(
const
uint8_t
*
begin
,
const
uint8_t
*
end
)
noexcept
{
if
(
sealed_
)
{
emplace_error
(
sec
::
runtime_error
,
"cannot append to a sealed SHA-1 context"
);
return
false
;
}
for
(
auto
i
=
begin
;
i
!=
end
;
++
i
)
{
if
(
length_
>=
std
::
numeric_limits
<
uint64_t
>::
max
()
-
8
)
{
emplace_error
(
sec
::
runtime_error
,
"SHA-1 message too long"
);
return
false
;
}
message_block_
[
message_block_index_
++
]
=
*
i
;
length_
+=
8
;
if
(
message_block_index_
==
64
)
process_message_block
();
}
return
true
;
}
void
sha1
::
process_message_block
()
{
const
uint32_t
K
[]
=
{
0x5A827999
,
0x6ED9EBA1
,
0x8F1BBCDC
,
0xCA62C1D6
,
};
uint32_t
W
[
80
];
// Word sequence.
uint32_t
A
,
B
,
C
,
D
,
E
;
// Word buffers.
for
(
auto
t
=
0
;
t
<
16
;
t
++
)
{
W
[
t
]
=
message_block_
[
t
*
4
]
<<
24
;
W
[
t
]
|=
message_block_
[
t
*
4
+
1
]
<<
16
;
W
[
t
]
|=
message_block_
[
t
*
4
+
2
]
<<
8
;
W
[
t
]
|=
message_block_
[
t
*
4
+
3
];
}
for
(
auto
t
=
16
;
t
<
80
;
t
++
)
{
W
[
t
]
=
SHA1CircularShift
(
1
,
W
[
t
-
3
]
^
W
[
t
-
8
]
^
W
[
t
-
14
]
^
W
[
t
-
16
]);
}
A
=
intermediate_
[
0
];
B
=
intermediate_
[
1
];
C
=
intermediate_
[
2
];
D
=
intermediate_
[
3
];
E
=
intermediate_
[
4
];
for
(
auto
t
=
0
;
t
<
20
;
t
++
)
{
auto
tmp
=
SHA1CircularShift
(
5
,
A
)
+
((
B
&
C
)
|
((
~
B
)
&
D
))
+
E
+
W
[
t
]
+
K
[
0
];
E
=
D
;
D
=
C
;
C
=
SHA1CircularShift
(
30
,
B
);
B
=
A
;
A
=
tmp
;
}
for
(
auto
t
=
20
;
t
<
40
;
t
++
)
{
auto
tmp
=
SHA1CircularShift
(
5
,
A
)
+
(
B
^
C
^
D
)
+
E
+
W
[
t
]
+
K
[
1
];
E
=
D
;
D
=
C
;
C
=
SHA1CircularShift
(
30
,
B
);
B
=
A
;
A
=
tmp
;
}
for
(
auto
t
=
40
;
t
<
60
;
t
++
)
{
auto
tmp
=
SHA1CircularShift
(
5
,
A
)
+
((
B
&
C
)
|
(
B
&
D
)
|
(
C
&
D
))
+
E
+
W
[
t
]
+
K
[
2
];
E
=
D
;
D
=
C
;
C
=
SHA1CircularShift
(
30
,
B
);
B
=
A
;
A
=
tmp
;
}
for
(
auto
t
=
60
;
t
<
80
;
t
++
)
{
auto
tmp
=
SHA1CircularShift
(
5
,
A
)
+
(
B
^
C
^
D
)
+
E
+
W
[
t
]
+
K
[
3
];
E
=
D
;
D
=
C
;
C
=
SHA1CircularShift
(
30
,
B
);
B
=
A
;
A
=
tmp
;
}
intermediate_
[
0
]
+=
A
;
intermediate_
[
1
]
+=
B
;
intermediate_
[
2
]
+=
C
;
intermediate_
[
3
]
+=
D
;
intermediate_
[
4
]
+=
E
;
message_block_index_
=
0
;
}
void
sha1
::
pad_message
()
{
if
(
message_block_index_
>
55
)
{
message_block_
[
message_block_index_
++
]
=
0x80
;
while
(
message_block_index_
<
64
)
message_block_
[
message_block_index_
++
]
=
0
;
process_message_block
();
while
(
message_block_index_
<
56
)
message_block_
[
message_block_index_
++
]
=
0
;
}
else
{
message_block_
[
message_block_index_
++
]
=
0x80
;
while
(
message_block_index_
<
56
)
message_block_
[
message_block_index_
++
]
=
0
;
}
message_block_
[
56
]
=
static_cast
<
uint8_t
>
(
length_
>>
56
);
message_block_
[
57
]
=
static_cast
<
uint8_t
>
(
length_
>>
48
);
message_block_
[
58
]
=
static_cast
<
uint8_t
>
(
length_
>>
40
);
message_block_
[
59
]
=
static_cast
<
uint8_t
>
(
length_
>>
32
);
message_block_
[
60
]
=
static_cast
<
uint8_t
>
(
length_
>>
24
);
message_block_
[
61
]
=
static_cast
<
uint8_t
>
(
length_
>>
16
);
message_block_
[
62
]
=
static_cast
<
uint8_t
>
(
length_
>>
8
);
message_block_
[
63
]
=
static_cast
<
uint8_t
>
(
length_
);
process_message_block
();
}
}
// namespace caf::hash
libcaf_core/test/hash/sha1.cpp
0 → 100644
View file @
5dcbf6d4
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE hash.sha1
#include "caf/hash/sha1.hpp"
#include "caf/test/dsl.hpp"
using
namespace
caf
;
namespace
{
template
<
class
...
Ts
>
auto
make_hash
(
Ts
...
xs
)
{
static_assert
(
sizeof
...(
Ts
)
==
20
);
return
hash
::
sha1
::
result_type
{{
static_cast
<
byte
>
(
xs
)...}};
}
}
// namespace
#define CHECK_HASH_EQ(str, bytes) \
CAF_CHECK_EQUAL(hash::sha1::compute(string_view{str}), bytes);
CAF_TEST
(
strings
are
hashed
by
their
content
only
)
{
CHECK_HASH_EQ
(
"dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
,
make_hash
(
0xb3
,
0x7a
,
0x4f
,
0x2c
,
// Bytes 1 - 4
0xc0
,
0x62
,
0x4f
,
0x16
,
// 5 - 8
0x90
,
0xf6
,
0x46
,
0x06
,
// 9 - 12
0xcf
,
0x38
,
0x59
,
0x45
,
// 13 - 16
0xb2
,
0xbe
,
0xc4
,
0xea
));
// 17 - 20
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment