pq_crypto-seal 0.1.0
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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +66 -0
- data/CHANGELOG.md +44 -0
- data/FORMAT.md +139 -0
- data/GET_STARTED.md +30 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +215 -0
- data/RELEASING.md +34 -0
- data/Rakefile +19 -0
- data/SECURITY.md +85 -0
- data/VENDORING.md +14 -0
- data/ext/pq_crypto_seal/aegis_unused_stubs.c +20 -0
- data/ext/pq_crypto_seal/extconf.rb +296 -0
- data/ext/pq_crypto_seal/pq_crypto_seal.c +390 -0
- data/ext/pq_crypto_seal/vendor/libaegis/LICENSE +21 -0
- data/ext/pq_crypto_seal/vendor/libaegis/TREE_SHA256 +1 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l.c +246 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.c +73 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.c +70 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_common.h +691 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.c +77 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.c +86 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_neon_sha3.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.c +63 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/aegis128l_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128l/implementations.h +40 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2.c +247 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.c +108 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.c +103 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.c +79 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_common.h +795 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.c +111 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.c +96 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/aegis128x2_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x2/implementations.h +40 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4.c +252 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.c +117 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.c +111 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.c +112 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.c +85 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_avx512.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_common.h +808 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.c +119 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.c +104 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/aegis128x4_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis128x4/implementations.h +41 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256.c +240 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.c +68 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.c +68 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_common.h +673 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.c +75 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.c +58 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/aegis256_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256/implementations.h +39 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2.c +247 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.c +103 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.c +101 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.c +74 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_common.h +790 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.c +109 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.c +91 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/aegis256x2_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x2/implementations.h +41 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4.c +252 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.c +112 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_aesni.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.c +109 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_altivec.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.c +107 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx2.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.c +79 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_avx512.h +11 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_common.h +805 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.c +117 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_neon_aes.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.c +99 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/aegis256x4_soft.h +9 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/aegis256x4/implementations.h +42 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/common.c +81 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/common.h +144 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.c +378 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/cpu.h +34 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.c +187 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/keccak.h +13 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.c +338 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/common/softaes.h +69 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis.h +77 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128l.h +311 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x2.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis128x4.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256.h +311 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x2.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis256x4.h +313 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/include/aegis_raf.h +580 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf.c +87 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128l.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x2.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis128x4.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x2.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_aegis256x4.c +20 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_internal.h +152 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.c +268 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_merkle.h +165 -0
- data/ext/pq_crypto_seal/vendor/libaegis/src/raf/raf_variant.h +1119 -0
- data/fuzz/decrypt_fuzz.rb +119 -0
- data/lib/pq_crypto/seal/binary.rb +62 -0
- data/lib/pq_crypto/seal/core.rb +398 -0
- data/lib/pq_crypto/seal/errors.rb +15 -0
- data/lib/pq_crypto/seal/format.rb +275 -0
- data/lib/pq_crypto/seal/io.rb +336 -0
- data/lib/pq_crypto/seal/native.rb +13 -0
- data/lib/pq_crypto/seal/padding.rb +47 -0
- data/lib/pq_crypto/seal/version.rb +6 -0
- data/lib/pq_crypto/seal.rb +32 -0
- data/pq_crypto-seal.gemspec +37 -0
- data/script/vendor_libs.rb +79 -0
- data/test/aegis_vectors_test.rb +54 -0
- data/test/golden_vectors_test.rb +183 -0
- data/test/io_test.rb +125 -0
- data/test/native_test.rb +36 -0
- data/test/seal_test.rb +238 -0
- data/test/test_helper.rb +6 -0
- metadata +244 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "raf_internal.h"
|
|
5
|
+
|
|
6
|
+
#include "../include/aegis128x2.h"
|
|
7
|
+
|
|
8
|
+
#define VARIANT aegis128x2
|
|
9
|
+
#define KEYBYTES aegis128x2_KEYBYTES
|
|
10
|
+
#define NPUBBYTES aegis128x2_NPUBBYTES
|
|
11
|
+
#define ALG_ID AEGIS_RAF_ALG_128X2
|
|
12
|
+
|
|
13
|
+
#define VARIANT_encrypt_detached aegis128x2_encrypt_detached
|
|
14
|
+
#define VARIANT_decrypt_detached aegis128x2_decrypt_detached
|
|
15
|
+
#define VARIANT_mac_init aegis128x2_mac_init
|
|
16
|
+
#define VARIANT_mac_update aegis128x2_mac_update
|
|
17
|
+
#define VARIANT_mac_final aegis128x2_mac_final
|
|
18
|
+
#define VARIANT_mac_verify aegis128x2_mac_verify
|
|
19
|
+
|
|
20
|
+
#include "raf_variant.h"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "raf_internal.h"
|
|
5
|
+
|
|
6
|
+
#include "../include/aegis128x4.h"
|
|
7
|
+
|
|
8
|
+
#define VARIANT aegis128x4
|
|
9
|
+
#define KEYBYTES aegis128x4_KEYBYTES
|
|
10
|
+
#define NPUBBYTES aegis128x4_NPUBBYTES
|
|
11
|
+
#define ALG_ID AEGIS_RAF_ALG_128X4
|
|
12
|
+
|
|
13
|
+
#define VARIANT_encrypt_detached aegis128x4_encrypt_detached
|
|
14
|
+
#define VARIANT_decrypt_detached aegis128x4_decrypt_detached
|
|
15
|
+
#define VARIANT_mac_init aegis128x4_mac_init
|
|
16
|
+
#define VARIANT_mac_update aegis128x4_mac_update
|
|
17
|
+
#define VARIANT_mac_final aegis128x4_mac_final
|
|
18
|
+
#define VARIANT_mac_verify aegis128x4_mac_verify
|
|
19
|
+
|
|
20
|
+
#include "raf_variant.h"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "raf_internal.h"
|
|
5
|
+
|
|
6
|
+
#include "../include/aegis256.h"
|
|
7
|
+
|
|
8
|
+
#define VARIANT aegis256
|
|
9
|
+
#define KEYBYTES aegis256_KEYBYTES
|
|
10
|
+
#define NPUBBYTES aegis256_NPUBBYTES
|
|
11
|
+
#define ALG_ID AEGIS_RAF_ALG_256
|
|
12
|
+
|
|
13
|
+
#define VARIANT_encrypt_detached aegis256_encrypt_detached
|
|
14
|
+
#define VARIANT_decrypt_detached aegis256_decrypt_detached
|
|
15
|
+
#define VARIANT_mac_init aegis256_mac_init
|
|
16
|
+
#define VARIANT_mac_update aegis256_mac_update
|
|
17
|
+
#define VARIANT_mac_final aegis256_mac_final
|
|
18
|
+
#define VARIANT_mac_verify aegis256_mac_verify
|
|
19
|
+
|
|
20
|
+
#include "raf_variant.h"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "raf_internal.h"
|
|
5
|
+
|
|
6
|
+
#include "../include/aegis256x2.h"
|
|
7
|
+
|
|
8
|
+
#define VARIANT aegis256x2
|
|
9
|
+
#define KEYBYTES aegis256x2_KEYBYTES
|
|
10
|
+
#define NPUBBYTES aegis256x2_NPUBBYTES
|
|
11
|
+
#define ALG_ID AEGIS_RAF_ALG_256X2
|
|
12
|
+
|
|
13
|
+
#define VARIANT_encrypt_detached aegis256x2_encrypt_detached
|
|
14
|
+
#define VARIANT_decrypt_detached aegis256x2_decrypt_detached
|
|
15
|
+
#define VARIANT_mac_init aegis256x2_mac_init
|
|
16
|
+
#define VARIANT_mac_update aegis256x2_mac_update
|
|
17
|
+
#define VARIANT_mac_final aegis256x2_mac_final
|
|
18
|
+
#define VARIANT_mac_verify aegis256x2_mac_verify
|
|
19
|
+
|
|
20
|
+
#include "raf_variant.h"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "raf_internal.h"
|
|
5
|
+
|
|
6
|
+
#include "../include/aegis256x4.h"
|
|
7
|
+
|
|
8
|
+
#define VARIANT aegis256x4
|
|
9
|
+
#define KEYBYTES aegis256x4_KEYBYTES
|
|
10
|
+
#define NPUBBYTES aegis256x4_NPUBBYTES
|
|
11
|
+
#define ALG_ID AEGIS_RAF_ALG_256X4
|
|
12
|
+
|
|
13
|
+
#define VARIANT_encrypt_detached aegis256x4_encrypt_detached
|
|
14
|
+
#define VARIANT_decrypt_detached aegis256x4_decrypt_detached
|
|
15
|
+
#define VARIANT_mac_init aegis256x4_mac_init
|
|
16
|
+
#define VARIANT_mac_update aegis256x4_mac_update
|
|
17
|
+
#define VARIANT_mac_final aegis256x4_mac_final
|
|
18
|
+
#define VARIANT_mac_verify aegis256x4_mac_verify
|
|
19
|
+
|
|
20
|
+
#include "raf_variant.h"
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#ifndef raf_internal_H
|
|
2
|
+
#define raf_internal_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#include "../common/common.h"
|
|
8
|
+
#include "../include/aegis_raf.h"
|
|
9
|
+
#include "raf_merkle.h"
|
|
10
|
+
|
|
11
|
+
#ifndef EBADMSG
|
|
12
|
+
# define EBADMSG 77
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
#ifndef EINVAL
|
|
16
|
+
# define EINVAL 22
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
#ifndef EEXIST
|
|
20
|
+
# define EEXIST 17
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
#ifndef ENOENT
|
|
24
|
+
# define ENOENT 2
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
#ifndef ENOMEM
|
|
28
|
+
# define ENOMEM 12
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
#ifndef EOVERFLOW
|
|
32
|
+
# define EOVERFLOW 75
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
#ifndef ENOTSUP
|
|
36
|
+
# define ENOTSUP 95
|
|
37
|
+
#endif
|
|
38
|
+
|
|
39
|
+
static const uint8_t AEGIS_RAF_MAGIC[8] = { 'A', 'E', 'G', 'I', 'S', 'R', 'A', 'F' };
|
|
40
|
+
|
|
41
|
+
#define AEGIS_RAF_VERSION 1
|
|
42
|
+
|
|
43
|
+
typedef struct aegis_raf_ctx_internal {
|
|
44
|
+
aegis_raf_io io;
|
|
45
|
+
aegis_raf_rng rng;
|
|
46
|
+
uint8_t *scratch_buf;
|
|
47
|
+
size_t scratch_len;
|
|
48
|
+
uint8_t *record_buf;
|
|
49
|
+
uint8_t *chunk_buf;
|
|
50
|
+
size_t record_buf_size;
|
|
51
|
+
size_t chunk_buf_size;
|
|
52
|
+
size_t keybytes;
|
|
53
|
+
size_t npubbytes;
|
|
54
|
+
aegis_raf_merkle_config merkle_cfg;
|
|
55
|
+
uint64_t file_size;
|
|
56
|
+
uint8_t enc_key[32];
|
|
57
|
+
uint8_t hdr_key[32];
|
|
58
|
+
uint8_t file_id[AEGIS_RAF_FILE_ID_BYTES];
|
|
59
|
+
uint32_t chunk_size;
|
|
60
|
+
int merkle_enabled;
|
|
61
|
+
uint8_t alg_id;
|
|
62
|
+
uint8_t version;
|
|
63
|
+
} aegis_raf_ctx_internal;
|
|
64
|
+
|
|
65
|
+
#define LOAD64_LE(SRC) load64_le(SRC)
|
|
66
|
+
static inline uint64_t
|
|
67
|
+
load64_le(const uint8_t src[8])
|
|
68
|
+
{
|
|
69
|
+
#ifdef NATIVE_LITTLE_ENDIAN
|
|
70
|
+
uint64_t w;
|
|
71
|
+
memcpy(&w, src, sizeof w);
|
|
72
|
+
return w;
|
|
73
|
+
#else
|
|
74
|
+
uint64_t w = (uint64_t) src[0];
|
|
75
|
+
w |= (uint64_t) src[1] << 8;
|
|
76
|
+
w |= (uint64_t) src[2] << 16;
|
|
77
|
+
w |= (uint64_t) src[3] << 24;
|
|
78
|
+
w |= (uint64_t) src[4] << 32;
|
|
79
|
+
w |= (uint64_t) src[5] << 40;
|
|
80
|
+
w |= (uint64_t) src[6] << 48;
|
|
81
|
+
w |= (uint64_t) src[7] << 56;
|
|
82
|
+
return w;
|
|
83
|
+
#endif
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
#define STORE64_LE(DST, W) store64_le((DST), (W))
|
|
87
|
+
static inline void
|
|
88
|
+
store64_le(uint8_t dst[8], uint64_t w)
|
|
89
|
+
{
|
|
90
|
+
#ifdef NATIVE_LITTLE_ENDIAN
|
|
91
|
+
memcpy(dst, &w, sizeof w);
|
|
92
|
+
#else
|
|
93
|
+
dst[0] = (uint8_t) w;
|
|
94
|
+
w >>= 8;
|
|
95
|
+
dst[1] = (uint8_t) w;
|
|
96
|
+
w >>= 8;
|
|
97
|
+
dst[2] = (uint8_t) w;
|
|
98
|
+
w >>= 8;
|
|
99
|
+
dst[3] = (uint8_t) w;
|
|
100
|
+
w >>= 8;
|
|
101
|
+
dst[4] = (uint8_t) w;
|
|
102
|
+
w >>= 8;
|
|
103
|
+
dst[5] = (uint8_t) w;
|
|
104
|
+
w >>= 8;
|
|
105
|
+
dst[6] = (uint8_t) w;
|
|
106
|
+
w >>= 8;
|
|
107
|
+
dst[7] = (uint8_t) w;
|
|
108
|
+
#endif
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#define STORE16_LE(DST, W) store16_le((DST), (W))
|
|
112
|
+
static inline void
|
|
113
|
+
store16_le(uint8_t dst[2], uint16_t w)
|
|
114
|
+
{
|
|
115
|
+
dst[0] = (uint8_t) w;
|
|
116
|
+
dst[1] = (uint8_t) (w >> 8);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#define LOAD16_LE(SRC) load16_le(SRC)
|
|
120
|
+
static inline uint16_t
|
|
121
|
+
load16_le(const uint8_t src[2])
|
|
122
|
+
{
|
|
123
|
+
return (uint16_t) src[0] | ((uint16_t) src[1] << 8);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
#define AAD_BYTES (AEGIS_RAF_FILE_ID_BYTES + 8 + 4)
|
|
127
|
+
|
|
128
|
+
static inline void
|
|
129
|
+
build_aad(uint8_t aad[AAD_BYTES], const uint8_t file_id[AEGIS_RAF_FILE_ID_BYTES],
|
|
130
|
+
uint64_t chunk_idx, uint32_t chunk_size)
|
|
131
|
+
{
|
|
132
|
+
memcpy(aad, file_id, AEGIS_RAF_FILE_ID_BYTES);
|
|
133
|
+
STORE64_LE(aad + AEGIS_RAF_FILE_ID_BYTES, chunk_idx);
|
|
134
|
+
STORE32_LE(aad + AEGIS_RAF_FILE_ID_BYTES + 8, chunk_size);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static inline void
|
|
138
|
+
build_commitment_context(uint8_t out[AEGIS_RAF_COMMITMENT_CONTEXT_BYTES],
|
|
139
|
+
uint8_t version,
|
|
140
|
+
uint8_t alg_id,
|
|
141
|
+
uint32_t chunk_size,
|
|
142
|
+
const uint8_t file_id[AEGIS_RAF_FILE_ID_BYTES])
|
|
143
|
+
{
|
|
144
|
+
out[0] = version;
|
|
145
|
+
out[1] = alg_id;
|
|
146
|
+
STORE32_LE(out + 2, chunk_size);
|
|
147
|
+
memcpy(out + 6, file_id, AEGIS_RAF_FILE_ID_BYTES);
|
|
148
|
+
out[30] = 0;
|
|
149
|
+
out[31] = 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
#endif
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#include "raf_merkle.h"
|
|
2
|
+
#include "raf_internal.h"
|
|
3
|
+
|
|
4
|
+
uint64_t
|
|
5
|
+
raf_merkle_level_node_count(uint64_t max_chunks, uint32_t level)
|
|
6
|
+
{
|
|
7
|
+
uint64_t count = max_chunks;
|
|
8
|
+
uint32_t i = 0;
|
|
9
|
+
|
|
10
|
+
if (max_chunks == 0) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
while (1) {
|
|
15
|
+
if (i == level) {
|
|
16
|
+
return count;
|
|
17
|
+
}
|
|
18
|
+
if (count <= 1) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
count = (count + 1) / 2;
|
|
22
|
+
i++;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
size_t
|
|
27
|
+
aegis_raf_merkle_buffer_size(const aegis_raf_merkle_config *cfg)
|
|
28
|
+
{
|
|
29
|
+
uint64_t total_nodes = 0;
|
|
30
|
+
uint64_t count;
|
|
31
|
+
uint64_t size;
|
|
32
|
+
|
|
33
|
+
if (cfg == NULL || cfg->max_chunks == 0 || cfg->hash_len == 0) {
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
count = cfg->max_chunks;
|
|
38
|
+
while (count > 0) {
|
|
39
|
+
if (total_nodes > UINT64_MAX - count) {
|
|
40
|
+
return SIZE_MAX;
|
|
41
|
+
}
|
|
42
|
+
total_nodes += count;
|
|
43
|
+
if (count == 1) {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
count = (count + 1) / 2;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (total_nodes > SIZE_MAX / cfg->hash_len) {
|
|
50
|
+
return SIZE_MAX;
|
|
51
|
+
}
|
|
52
|
+
size = total_nodes * cfg->hash_len;
|
|
53
|
+
if (size > SIZE_MAX) {
|
|
54
|
+
return SIZE_MAX;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return (size_t) size;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
size_t
|
|
61
|
+
raf_merkle_level_offset(uint64_t max_chunks, uint32_t hash_len, uint32_t level)
|
|
62
|
+
{
|
|
63
|
+
size_t offset = 0;
|
|
64
|
+
uint64_t count = max_chunks;
|
|
65
|
+
uint32_t i;
|
|
66
|
+
|
|
67
|
+
if (max_chunks == 0 || hash_len == 0) {
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (i = 0; i < level && count > 0; i++) {
|
|
72
|
+
offset += (size_t) (count * hash_len);
|
|
73
|
+
if (count == 1) {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
count = (count + 1) / 2;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return offset;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
size_t
|
|
83
|
+
raf_merkle_node_offset(uint64_t max_chunks, uint32_t hash_len, uint32_t level, uint64_t node_idx)
|
|
84
|
+
{
|
|
85
|
+
size_t level_off = raf_merkle_level_offset(max_chunks, hash_len, level);
|
|
86
|
+
return level_off + (size_t) (node_idx * hash_len);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static size_t
|
|
90
|
+
aegis_raf_merkle_leaf_offset(const aegis_raf_merkle_config *cfg, uint64_t chunk_idx)
|
|
91
|
+
{
|
|
92
|
+
if (cfg == NULL || chunk_idx >= cfg->max_chunks) {
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
return (size_t) (chunk_idx * cfg->hash_len);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
int
|
|
99
|
+
aegis_raf_merkle_config_validate(const aegis_raf_merkle_config *cfg)
|
|
100
|
+
{
|
|
101
|
+
size_t required;
|
|
102
|
+
|
|
103
|
+
if (cfg == NULL) {
|
|
104
|
+
errno = EINVAL;
|
|
105
|
+
return -1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (cfg->buf == NULL || cfg->max_chunks == 0) {
|
|
109
|
+
errno = EINVAL;
|
|
110
|
+
return -1;
|
|
111
|
+
}
|
|
112
|
+
if (cfg->hash_len < AEGIS_RAF_MERKLE_HASH_MIN || cfg->hash_len > AEGIS_RAF_MERKLE_HASH_MAX) {
|
|
113
|
+
errno = EINVAL;
|
|
114
|
+
return -1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (cfg->hash_leaf == NULL || cfg->hash_parent == NULL || cfg->hash_empty == NULL ||
|
|
118
|
+
cfg->hash_commitment == NULL) {
|
|
119
|
+
errno = EINVAL;
|
|
120
|
+
return -1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
required = aegis_raf_merkle_buffer_size(cfg);
|
|
124
|
+
if (required == SIZE_MAX || cfg->len < required) {
|
|
125
|
+
errno = EINVAL;
|
|
126
|
+
return -1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
int
|
|
133
|
+
raf_merkle_update_leaf(const aegis_raf_merkle_config *cfg, const uint8_t *chunk_data,
|
|
134
|
+
size_t chunk_len, uint64_t chunk_idx)
|
|
135
|
+
{
|
|
136
|
+
size_t leaf_off;
|
|
137
|
+
|
|
138
|
+
if (cfg == NULL || chunk_idx >= cfg->max_chunks) {
|
|
139
|
+
errno = EINVAL;
|
|
140
|
+
return -1;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
leaf_off = aegis_raf_merkle_leaf_offset(cfg, chunk_idx);
|
|
144
|
+
|
|
145
|
+
return cfg->hash_leaf(cfg->user, cfg->buf + leaf_off, cfg->hash_len, chunk_data, chunk_len,
|
|
146
|
+
chunk_idx);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
int
|
|
150
|
+
raf_merkle_clear_leaf(const aegis_raf_merkle_config *cfg, uint64_t chunk_idx)
|
|
151
|
+
{
|
|
152
|
+
size_t leaf_off;
|
|
153
|
+
|
|
154
|
+
if (cfg == NULL || chunk_idx >= cfg->max_chunks) {
|
|
155
|
+
errno = EINVAL;
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
leaf_off = aegis_raf_merkle_leaf_offset(cfg, chunk_idx);
|
|
160
|
+
|
|
161
|
+
return cfg->hash_empty(cfg->user, cfg->buf + leaf_off, cfg->hash_len, 0, chunk_idx);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
int
|
|
165
|
+
raf_merkle_update_parents(const aegis_raf_merkle_config *cfg, uint64_t first_chunk,
|
|
166
|
+
uint64_t last_chunk)
|
|
167
|
+
{
|
|
168
|
+
uint32_t levels;
|
|
169
|
+
uint32_t level;
|
|
170
|
+
uint64_t first_idx;
|
|
171
|
+
uint64_t last_idx;
|
|
172
|
+
uint64_t level_count;
|
|
173
|
+
uint64_t i;
|
|
174
|
+
size_t left_off;
|
|
175
|
+
size_t right_off;
|
|
176
|
+
size_t parent_off;
|
|
177
|
+
uint8_t empty_hash[AEGIS_RAF_MERKLE_HASH_MAX];
|
|
178
|
+
int ret;
|
|
179
|
+
|
|
180
|
+
if (cfg == NULL || first_chunk > last_chunk || last_chunk >= cfg->max_chunks) {
|
|
181
|
+
errno = EINVAL;
|
|
182
|
+
return -1;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
levels = aegis_raf_merkle_level_count(cfg);
|
|
186
|
+
if (levels <= 1) {
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
first_idx = first_chunk;
|
|
191
|
+
last_idx = last_chunk;
|
|
192
|
+
|
|
193
|
+
for (level = 0; level < levels - 1; level++) {
|
|
194
|
+
level_count = raf_merkle_level_node_count(cfg->max_chunks, level);
|
|
195
|
+
|
|
196
|
+
first_idx = first_idx / 2;
|
|
197
|
+
last_idx = last_idx / 2;
|
|
198
|
+
|
|
199
|
+
for (i = first_idx; i <= last_idx; i++) {
|
|
200
|
+
uint64_t left_child = i * 2;
|
|
201
|
+
uint64_t right_child = i * 2 + 1;
|
|
202
|
+
|
|
203
|
+
left_off = raf_merkle_node_offset(cfg->max_chunks, cfg->hash_len, level, left_child);
|
|
204
|
+
|
|
205
|
+
if (right_child < level_count) {
|
|
206
|
+
right_off =
|
|
207
|
+
raf_merkle_node_offset(cfg->max_chunks, cfg->hash_len, level, right_child);
|
|
208
|
+
|
|
209
|
+
parent_off = raf_merkle_node_offset(cfg->max_chunks, cfg->hash_len, level + 1, i);
|
|
210
|
+
|
|
211
|
+
ret = cfg->hash_parent(cfg->user, cfg->buf + parent_off, cfg->hash_len,
|
|
212
|
+
cfg->buf + left_off, cfg->buf + right_off, level, i);
|
|
213
|
+
} else {
|
|
214
|
+
ret = cfg->hash_empty(cfg->user, empty_hash, cfg->hash_len, level, right_child);
|
|
215
|
+
if (ret != 0) {
|
|
216
|
+
return ret;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
parent_off = raf_merkle_node_offset(cfg->max_chunks, cfg->hash_len, level + 1, i);
|
|
220
|
+
|
|
221
|
+
ret = cfg->hash_parent(cfg->user, cfg->buf + parent_off, cfg->hash_len,
|
|
222
|
+
cfg->buf + left_off, empty_hash, level, i);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (ret != 0) {
|
|
226
|
+
return ret;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
int
|
|
235
|
+
raf_merkle_update_chunk(const aegis_raf_merkle_config *cfg, const uint8_t *chunk_data,
|
|
236
|
+
size_t chunk_len, uint64_t chunk_idx)
|
|
237
|
+
{
|
|
238
|
+
int ret;
|
|
239
|
+
|
|
240
|
+
ret = raf_merkle_update_leaf(cfg, chunk_data, chunk_len, chunk_idx);
|
|
241
|
+
if (ret != 0) {
|
|
242
|
+
return ret;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return raf_merkle_update_parents(cfg, chunk_idx, chunk_idx);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
int
|
|
249
|
+
raf_merkle_clear_range(const aegis_raf_merkle_config *cfg, uint64_t first_chunk,
|
|
250
|
+
uint64_t last_chunk)
|
|
251
|
+
{
|
|
252
|
+
uint64_t i;
|
|
253
|
+
int ret;
|
|
254
|
+
|
|
255
|
+
if (cfg == NULL || first_chunk > last_chunk || last_chunk >= cfg->max_chunks) {
|
|
256
|
+
errno = EINVAL;
|
|
257
|
+
return -1;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
for (i = first_chunk; i <= last_chunk; i++) {
|
|
261
|
+
ret = raf_merkle_clear_leaf(cfg, i);
|
|
262
|
+
if (ret != 0) {
|
|
263
|
+
return ret;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return raf_merkle_update_parents(cfg, first_chunk, last_chunk);
|
|
268
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#ifndef raf_merkle_H
|
|
2
|
+
#define raf_merkle_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
#include "../common/common.h"
|
|
8
|
+
#include "../include/aegis_raf.h"
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Internal Merkle tree helpers for RAF.
|
|
12
|
+
*
|
|
13
|
+
* The Merkle buffer stores nodes level by level:
|
|
14
|
+
* Level 0: max_chunks leaves (one per chunk)
|
|
15
|
+
* Level 1: ceil(max_chunks / 2) nodes
|
|
16
|
+
* ...
|
|
17
|
+
* Level L-1: 1 node (root)
|
|
18
|
+
*
|
|
19
|
+
* Each node is hash_len bytes. Levels are stored consecutively without padding.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Returns the number of nodes at the given level for a tree with max_chunks leaves.
|
|
24
|
+
* Level 0 has max_chunks nodes; each subsequent level has ceil(prev / 2).
|
|
25
|
+
*/
|
|
26
|
+
uint64_t raf_merkle_level_node_count(uint64_t max_chunks, uint32_t level);
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Returns the byte offset of the start of the given level within the buffer.
|
|
30
|
+
*/
|
|
31
|
+
size_t raf_merkle_level_offset(uint64_t max_chunks, uint32_t hash_len, uint32_t level);
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* Returns the byte offset of a specific node within the buffer.
|
|
35
|
+
* node_idx is relative to the start of the level.
|
|
36
|
+
*/
|
|
37
|
+
size_t raf_merkle_node_offset(uint64_t max_chunks, uint32_t hash_len, uint32_t level,
|
|
38
|
+
uint64_t node_idx);
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
* Update a single leaf hash. Computes hash_leaf for the given chunk data and
|
|
42
|
+
* stores it at the appropriate position in the buffer.
|
|
43
|
+
*
|
|
44
|
+
* chunk_data: Plaintext chunk contents (may be less than chunk_size for final chunk).
|
|
45
|
+
* chunk_len: Actual length of chunk data (plaintext bytes in this chunk).
|
|
46
|
+
* chunk_idx: Index of the chunk (0-based).
|
|
47
|
+
* cfg: Merkle configuration with buffer and callbacks.
|
|
48
|
+
*
|
|
49
|
+
* Returns 0 on success, -1 on error.
|
|
50
|
+
*/
|
|
51
|
+
int raf_merkle_update_leaf(const aegis_raf_merkle_config *cfg, const uint8_t *chunk_data,
|
|
52
|
+
size_t chunk_len, uint64_t chunk_idx);
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
* Mark a leaf as empty. Computes hash_empty for the given chunk index and
|
|
56
|
+
* stores it at the appropriate position in the buffer.
|
|
57
|
+
*
|
|
58
|
+
* chunk_idx: Index of the chunk to mark as empty.
|
|
59
|
+
* cfg: Merkle configuration with buffer and callbacks.
|
|
60
|
+
*
|
|
61
|
+
* Returns 0 on success, -1 on error.
|
|
62
|
+
*/
|
|
63
|
+
int raf_merkle_clear_leaf(const aegis_raf_merkle_config *cfg, uint64_t chunk_idx);
|
|
64
|
+
|
|
65
|
+
/*
|
|
66
|
+
* Update parents from the given range of leaves up to the root.
|
|
67
|
+
* Call this after updating one or more consecutive leaves.
|
|
68
|
+
*
|
|
69
|
+
* first_chunk: First leaf index in the updated range.
|
|
70
|
+
* last_chunk: Last leaf index in the updated range (inclusive).
|
|
71
|
+
* cfg: Merkle configuration with buffer and callbacks.
|
|
72
|
+
*
|
|
73
|
+
* Returns 0 on success, -1 on error.
|
|
74
|
+
*/
|
|
75
|
+
int raf_merkle_update_parents(const aegis_raf_merkle_config *cfg, uint64_t first_chunk,
|
|
76
|
+
uint64_t last_chunk);
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Update a single leaf and propagate changes to the root.
|
|
80
|
+
* Convenience wrapper that calls update_leaf then update_parents.
|
|
81
|
+
*
|
|
82
|
+
* Returns 0 on success, -1 on error.
|
|
83
|
+
*/
|
|
84
|
+
int raf_merkle_update_chunk(const aegis_raf_merkle_config *cfg, const uint8_t *chunk_data,
|
|
85
|
+
size_t chunk_len, uint64_t chunk_idx);
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* Clear a range of leaves (mark as empty) and propagate changes to the root.
|
|
89
|
+
* Used when shrinking a file to invalidate leaves beyond the new EOF.
|
|
90
|
+
*
|
|
91
|
+
* first_chunk: First leaf index to clear.
|
|
92
|
+
* last_chunk: Last leaf index to clear (inclusive).
|
|
93
|
+
* cfg: Merkle configuration with buffer and callbacks.
|
|
94
|
+
*
|
|
95
|
+
* Returns 0 on success, -1 on error.
|
|
96
|
+
*/
|
|
97
|
+
int raf_merkle_clear_range(const aegis_raf_merkle_config *cfg, uint64_t first_chunk,
|
|
98
|
+
uint64_t last_chunk);
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* Validate a Merkle configuration. Returns 0 if valid, -1 with errno set if not.
|
|
102
|
+
* Checks that buf is non-NULL, hash_len > 0, max_chunks > 0, all callbacks are
|
|
103
|
+
* provided, and the buffer is large enough.
|
|
104
|
+
*/
|
|
105
|
+
int aegis_raf_merkle_config_validate(const aegis_raf_merkle_config *cfg);
|
|
106
|
+
|
|
107
|
+
static inline uint32_t
|
|
108
|
+
aegis_raf_merkle_level_count(const aegis_raf_merkle_config *cfg)
|
|
109
|
+
{
|
|
110
|
+
uint32_t levels = 0;
|
|
111
|
+
uint64_t count;
|
|
112
|
+
|
|
113
|
+
if (cfg == NULL || cfg->max_chunks == 0) {
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
count = cfg->max_chunks;
|
|
118
|
+
while (count > 0) {
|
|
119
|
+
levels++;
|
|
120
|
+
if (count == 1) {
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
count = (count + 1) / 2;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return levels;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static inline int
|
|
130
|
+
aegis_raf_merkle_root(const aegis_raf_merkle_config *cfg, uint8_t *out, size_t out_len,
|
|
131
|
+
const uint8_t *ctx, size_t ctx_len, uint64_t file_size)
|
|
132
|
+
{
|
|
133
|
+
uint32_t levels;
|
|
134
|
+
size_t root_offset;
|
|
135
|
+
const uint8_t *structural_root;
|
|
136
|
+
|
|
137
|
+
if (cfg == NULL || cfg->buf == NULL || cfg->max_chunks == 0) {
|
|
138
|
+
errno = EINVAL;
|
|
139
|
+
return -1;
|
|
140
|
+
}
|
|
141
|
+
if (out == NULL || out_len < cfg->hash_len) {
|
|
142
|
+
errno = EINVAL;
|
|
143
|
+
return -1;
|
|
144
|
+
}
|
|
145
|
+
if (cfg->hash_commitment == NULL) {
|
|
146
|
+
errno = EINVAL;
|
|
147
|
+
return -1;
|
|
148
|
+
}
|
|
149
|
+
if (ctx == NULL && ctx_len > 0) {
|
|
150
|
+
errno = EINVAL;
|
|
151
|
+
return -1;
|
|
152
|
+
}
|
|
153
|
+
if (ctx_len == 0) {
|
|
154
|
+
ctx = NULL;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
levels = aegis_raf_merkle_level_count(cfg);
|
|
158
|
+
root_offset = raf_merkle_level_offset(cfg->max_chunks, cfg->hash_len, levels - 1);
|
|
159
|
+
structural_root = cfg->buf + root_offset;
|
|
160
|
+
|
|
161
|
+
return cfg->hash_commitment(cfg->user, out, cfg->hash_len, structural_root, ctx, ctx_len,
|
|
162
|
+
file_size);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
#endif
|