libaaruformat
1.0
Aaru Data Preservation Suite - Format Library
Toggle main menu visibility
Loading...
Searching...
No Matches
crc64.c
Go to the documentation of this file.
1
/*
2
* This file is part of the Aaru Data Preservation Suite.
3
* Copyright (c) 2019-2026 Natalia Portillo.
4
*
5
* This library is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU Lesser General Public License as
7
* published by the Free Software Foundation; either version 2.1 of the
8
* License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
#include <stdlib.h>
20
21
#include <
aaruformat.h
>
22
23
#include "
log.h
"
24
32
AARU_EXPORT
crc64_ctx
*
AARU_CALL
aaruf_crc64_init
(
void
)
33
{
34
TRACE
(
"Entering aaruf_crc64_init()"
);
35
crc64_ctx
*ctx = malloc(
sizeof
(
crc64_ctx
));
36
37
if
(!ctx)
return
NULL;
38
39
ctx->
crc
=
CRC64_ECMA_SEED
;
40
41
TRACE
(
"Exiting aaruf_crc64_init()"
);
42
return
ctx;
43
}
44
55
AARU_EXPORT
int
AARU_CALL
aaruf_crc64_update
(
crc64_ctx
*ctx,
const
uint8_t *data, uint32_t len)
56
{
57
TRACE
(
"Entering aaruf_crc64_update(%p, %p, %u)"
, ctx, data, len);
58
if
(!ctx || !data)
59
{
60
TRACE
(
"Exiting aaruf_crc64_update() = -1"
);
61
return
-1;
62
}
63
64
#if defined(__x86_64__) || defined(__amd64) || defined(_M_AMD64) || defined(_M_X64) || defined(__I386__) || \
65
defined(__i386__) || defined(__THW_INTEL) || defined(_M_IX86)
66
if
(have_clmul())
67
{
68
ctx->
crc
= ~aaruf_crc64_clmul(~ctx->
crc
, data, len);
69
70
TRACE
(
"Exiting aaruf_crc64_update() = 0"
);
71
return
0;
72
}
73
#endif
74
75
#if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM)
76
if
(have_neon())
77
{
78
ctx->
crc
= ~aaruf_crc64_vmull(~ctx->
crc
, data, len);
79
80
TRACE
(
"Exiting aaruf_crc64_update() = 0"
);
81
return
0;
82
}
83
#endif
84
85
// Unroll according to Intel slicing by uint8_t
86
// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
87
// http://sourceforge.net/projects/slicing-by-8/
88
89
aaruf_crc64_slicing
(&ctx->
crc
, data, len);
90
91
TRACE
(
"Exiting aaruf_crc64_update() = 0"
);
92
return
0;
93
}
94
102
AARU_EXPORT
void
AARU_CALL
aaruf_crc64_slicing
(uint64_t *previous_crc,
const
uint8_t *data, uint32_t len)
103
{
104
uint64_t c = *previous_crc;
105
106
if
(len > 4)
107
{
108
const
uint8_t *limit = NULL;
109
110
while
((uintptr_t)data & 3)
111
{
112
c =
crc64_table
[0][*data++ ^ c & 0xFF] ^ c >> 8;
113
--len;
114
}
115
116
limit = data + (len & ~(uint32_t)3);
117
len &= (uint32_t)3;
118
119
while
(data < limit)
120
{
121
const
uint32_t tmp = c ^ *(
const
uint32_t *)data;
122
data += 4;
123
124
c =
crc64_table
[3][(tmp & 0xFF)] ^
crc64_table
[2][(tmp >> 8 & 0xFF)] ^ c >> 32 ^
125
crc64_table
[1][(tmp >> 16 & 0xFF)] ^
crc64_table
[0][(tmp >> 24)];
126
}
127
}
128
129
while
(len-- != 0) c =
crc64_table
[0][*data++ ^ c & 0xFF] ^ c >> 8;
130
131
*previous_crc = c;
132
}
133
141
AARU_EXPORT
int
AARU_CALL
aaruf_crc64_final
(
crc64_ctx
*ctx, uint64_t *crc)
142
{
143
if
(!ctx)
return
-1;
144
145
*crc = ctx->
crc
^
CRC64_ECMA_SEED
;
146
147
return
0;
148
}
149
155
AARU_EXPORT
void
AARU_CALL
aaruf_crc64_free
(
crc64_ctx
*ctx)
156
{
157
if
(ctx) free(ctx);
158
}
159
160
AARU_EXPORT
uint64_t
AARU_CALL
aaruf_crc64_data
(
const
uint8_t *data,
const
uint32_t len)
161
{
162
crc64_ctx
*ctx =
aaruf_crc64_init
();
163
uint64_t crc = 0;
164
165
if
(!ctx)
return
crc;
166
167
aaruf_crc64_update
(ctx, data, len);
168
aaruf_crc64_final
(ctx, &crc);
169
aaruf_crc64_free
(ctx);
170
171
return
crc;
172
}
aaruformat.h
crc64_table
static const uint64_t crc64_table[4][256]
Precomputed slicing-by-4 ECMA-182 CRC64 lookup tables (4 * 256 * 8 = 8192 bytes).
Definition
crc64.h:66
CRC64_ECMA_SEED
#define CRC64_ECMA_SEED
ECMA-182 initial seed (all bits set).
Definition
crc64.h:280
AARU_CALL
#define AARU_CALL
Definition
decls.h:46
aaruf_crc64_data
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
Definition
crc64.c:160
aaruf_crc64_update
int aaruf_crc64_update(crc64_ctx *ctx, const uint8_t *data, uint32_t len)
Updates the CRC64 context with new data.
Definition
crc64.c:55
aaruf_crc64_free
void aaruf_crc64_free(crc64_ctx *ctx)
Frees a CRC64 context.
Definition
crc64.c:155
aaruf_crc64_slicing
void aaruf_crc64_slicing(uint64_t *previous_crc, const uint8_t *data, uint32_t len)
Updates a CRC64 value using the slicing-by-8 algorithm.
Definition
crc64.c:102
AARU_EXPORT
#define AARU_EXPORT
Definition
decls.h:55
aaruf_crc64_final
int aaruf_crc64_final(crc64_ctx *ctx, uint64_t *crc)
Computes the final CRC64 value from the context.
Definition
crc64.c:141
aaruf_crc64_init
crc64_ctx * aaruf_crc64_init(void)
Initializes a CRC64 context.
Definition
crc64.c:32
log.h
TRACE
#define TRACE(fmt,...)
Definition
log.h:25
crc64_ctx
Minimal ECMA-182 CRC64 incremental state container (running value only).
Definition
crc64.h:56
crc64_ctx::crc
uint64_t crc
Running CRC value (initialize to CRC64_ECMA_SEED before first update).
Definition
crc64.h:57
src
crc64
crc64.c
Generated by
1.18.0