@riseandshaheen/libcma 0.1.0-alpha.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.
- package/ARCHITECTURE.md +348 -0
- package/LICENSE +21 -0
- package/README.md +157 -0
- package/binding.gyp +52 -0
- package/deps/machine-asset-tools/LICENSE +202 -0
- package/deps/machine-asset-tools/README.md +237 -0
- package/deps/machine-asset-tools/include/libcma/ledger.h +161 -0
- package/deps/machine-asset-tools/include/libcma/parser.h +305 -0
- package/deps/machine-asset-tools/include/libcma/types.h +22 -0
- package/deps/machine-guest-tools/LICENSE +202 -0
- package/deps/machine-guest-tools/README.md +57 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/README.md +130 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/abi.h +578 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/buf.h +82 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/io.h +168 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/keccak.h +131 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/merkle.h +118 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/rollup.h +260 -0
- package/deps/machine-guest-tools/sys-utils/libcmt/include/libcmt/util.h +34 -0
- package/lib/index.cjs +445 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.cts +156 -0
- package/lib/index.d.ts +156 -0
- package/lib/index.js +428 -0
- package/lib/index.js.map +1 -0
- package/native/addon.cc +268 -0
- package/native/ledger_backend.h +28 -0
- package/native/mock/ledger_mock.cc +185 -0
- package/native/real/ledger_real.cc +271 -0
- package/package.json +74 -0
- package/scripts/build-libcma-riscv64.sh +80 -0
- package/scripts/build-native-riscv64.sh +40 -0
- package/scripts/install-native.mjs +94 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* Copyright Cartesi and individual authors (see AUTHORS)
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** @file
|
|
17
|
+
* @defgroup libcmt_buf buf
|
|
18
|
+
* slice of contiguous memory
|
|
19
|
+
*
|
|
20
|
+
* @ingroup libcmt
|
|
21
|
+
* @{ */
|
|
22
|
+
#ifndef CMT_BUF_H
|
|
23
|
+
#define CMT_BUF_H
|
|
24
|
+
#include <stdbool.h>
|
|
25
|
+
#include <stddef.h>
|
|
26
|
+
#include <stdint.h>
|
|
27
|
+
|
|
28
|
+
/** A slice of contiguous memory from @b begin to @b end, as an open range.
|
|
29
|
+
* Size can be taken with: `end - begin`.
|
|
30
|
+
*
|
|
31
|
+
* `begin == end` indicate an empty buffer */
|
|
32
|
+
typedef struct {
|
|
33
|
+
uint8_t *begin; /**< begin of memory region */
|
|
34
|
+
uint8_t *end; /**< end of memory region */
|
|
35
|
+
} cmt_buf_t;
|
|
36
|
+
|
|
37
|
+
/** Initialize @p me buffer backed by @p data, @p length bytes in size
|
|
38
|
+
*
|
|
39
|
+
* @param [out] me a uninitialized instance
|
|
40
|
+
* @param [in] length size in bytes of @b data
|
|
41
|
+
* @param [in] data the backing memory to be used.
|
|
42
|
+
*
|
|
43
|
+
* @note @p data memory must outlive @p me.
|
|
44
|
+
* user must copy the contents otherwise */
|
|
45
|
+
void cmt_buf_init(cmt_buf_t *me, size_t length, void *data);
|
|
46
|
+
|
|
47
|
+
/** Split a buffer in two, @b lhs with @b lhs_length bytes and @b rhs with the rest
|
|
48
|
+
*
|
|
49
|
+
* @param [in,out] me initialized buffer
|
|
50
|
+
* @param [in] lhs_length bytes in @b lhs
|
|
51
|
+
* @param [out] lhs left hand side
|
|
52
|
+
* @param [out] rhs right hand side
|
|
53
|
+
*
|
|
54
|
+
* @return
|
|
55
|
+
* - 0 success
|
|
56
|
+
* - negative value on error. -ENOBUFS when length(me) < lhs_length. */
|
|
57
|
+
int cmt_buf_split(const cmt_buf_t *me, size_t lhs_length, cmt_buf_t *lhs, cmt_buf_t *rhs);
|
|
58
|
+
|
|
59
|
+
/** Length in bytes of @p me
|
|
60
|
+
*
|
|
61
|
+
* @param [in] me initialized buffer
|
|
62
|
+
*
|
|
63
|
+
* @return
|
|
64
|
+
* - size in bytes */
|
|
65
|
+
size_t cmt_buf_length(const cmt_buf_t *me);
|
|
66
|
+
|
|
67
|
+
/** Print the contents of @b me buffer to stdout
|
|
68
|
+
*
|
|
69
|
+
* @param [in] begin start of memory region
|
|
70
|
+
* @param [in] end end of memory region
|
|
71
|
+
* @param [in] bytes_per_line bytes per line (must be a power of 2). */
|
|
72
|
+
void cmt_buf_xxd(void *begin, void *end, int bytes_per_line);
|
|
73
|
+
|
|
74
|
+
/** Take the substring @p x from @p xs start to the first @p , (comma).
|
|
75
|
+
* @param [out] x substring
|
|
76
|
+
* @param [in,out] xs string (iterator)
|
|
77
|
+
*
|
|
78
|
+
* @note @p x points inside @p xs, make a copy if it outlives @p xs. */
|
|
79
|
+
bool cmt_buf_split_by_comma(cmt_buf_t *x, cmt_buf_t *xs);
|
|
80
|
+
|
|
81
|
+
#endif /* CMT_BUF_H */
|
|
82
|
+
/** @} */
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/* Copyright Cartesi and individual authors (see AUTHORS)
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** @file
|
|
17
|
+
* @defgroup libcmt_io_driver Cartesi Machine Input/Output Driver
|
|
18
|
+
* Low level abstraction of the Cartesi Machine kernel driver.
|
|
19
|
+
*
|
|
20
|
+
* Interaction is as follows:
|
|
21
|
+
* - Open the kernel device and mmap the shared memory ranges (tx and rx) with:
|
|
22
|
+
* @ref cmt_io_init.
|
|
23
|
+
* - Retrieve the memory regions from the library with: @ref cmt_io_get_tx and
|
|
24
|
+
* @ref cmt_io_get_rx.
|
|
25
|
+
* - Do requests (next input, emit output ...) by yielding the control back to
|
|
26
|
+
* the emulator with: @ref cmt_io_yield.
|
|
27
|
+
*
|
|
28
|
+
* Lets look at some code:
|
|
29
|
+
*
|
|
30
|
+
* @include examples/io.c
|
|
31
|
+
*
|
|
32
|
+
* There are two implementations provided: `ioctl` that interacts with the
|
|
33
|
+
* cartesi-machine linux driver and `mock` that reads and writes the host
|
|
34
|
+
* filesystem, used for testing.
|
|
35
|
+
*
|
|
36
|
+
* @section Environment variables
|
|
37
|
+
*
|
|
38
|
+
* this module exposes two environment variables: @p CMT_DEBUG and @p CMT_INPUTS.
|
|
39
|
+
*
|
|
40
|
+
* @p CMT_DEBUG prints runtime information during application execution.
|
|
41
|
+
*
|
|
42
|
+
* ```
|
|
43
|
+
* CMT_DEBUG=yes ./application
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @p CMT_INPUTS feeds inputs to the mock (ignored for ioctl).
|
|
47
|
+
*
|
|
48
|
+
* ```
|
|
49
|
+
* CMT_INPUTS=0:advance.bin,1:inspect.bin ./application
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @ingroup libcmt
|
|
53
|
+
* @{ */
|
|
54
|
+
#ifndef CMT_IO_H
|
|
55
|
+
#define CMT_IO_H
|
|
56
|
+
#include "buf.h"
|
|
57
|
+
#include <stdint.h>
|
|
58
|
+
|
|
59
|
+
/** Device */
|
|
60
|
+
enum {
|
|
61
|
+
HTIF_DEVICE_YIELD = 2, /**< Yield device */
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** Commands */
|
|
65
|
+
enum {
|
|
66
|
+
HTIF_YIELD_CMD_AUTOMATIC = 0, /**< Automatic yield */
|
|
67
|
+
HTIF_YIELD_CMD_MANUAL = 1, /**< Manual yield */
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/** Automatic reasons */
|
|
71
|
+
enum {
|
|
72
|
+
HTIF_YIELD_AUTOMATIC_REASON_PROGRESS = 1, /**< Progress */
|
|
73
|
+
HTIF_YIELD_AUTOMATIC_REASON_TX_OUTPUT = 2, /**< emit an output */
|
|
74
|
+
HTIF_YIELD_AUTOMATIC_REASON_TX_REPORT = 4, /**< emit a report */
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Manual reasons */
|
|
78
|
+
enum {
|
|
79
|
+
HTIF_YIELD_MANUAL_REASON_RX_ACCEPTED = 1, /**< Accept and load next input */
|
|
80
|
+
HTIF_YIELD_MANUAL_REASON_RX_REJECTED = 2, /**< Reject and revert */
|
|
81
|
+
HTIF_YIELD_MANUAL_REASON_TX_EXCEPTION = 4, /**< emit a exception and halt execution */
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** Reply reason when requesting @ref HTIF_YIELD_REASON_RX_ACCEPTED or HTIF_YIELD_REASON_RX_REJECTED */
|
|
85
|
+
enum {
|
|
86
|
+
HTIF_YIELD_REASON_ADVANCE = 0, /**< Input is advance */
|
|
87
|
+
HTIF_YIELD_REASON_INSPECT = 1, /**< Input is inspect */
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
typedef struct {
|
|
91
|
+
cmt_buf_t tx[1];
|
|
92
|
+
cmt_buf_t rx[1];
|
|
93
|
+
int fd;
|
|
94
|
+
} cmt_io_driver_ioctl_t;
|
|
95
|
+
|
|
96
|
+
typedef struct {
|
|
97
|
+
cmt_buf_t tx[1];
|
|
98
|
+
cmt_buf_t rx[1];
|
|
99
|
+
cmt_buf_t inputs_left;
|
|
100
|
+
|
|
101
|
+
int input_type;
|
|
102
|
+
char input_filename[128];
|
|
103
|
+
char input_fileext[16];
|
|
104
|
+
|
|
105
|
+
int input_seq;
|
|
106
|
+
int output_seq;
|
|
107
|
+
int report_seq;
|
|
108
|
+
int exception_seq;
|
|
109
|
+
int gio_seq;
|
|
110
|
+
} cmt_io_driver_mock_t;
|
|
111
|
+
|
|
112
|
+
/** Implementation specific cmio state. */
|
|
113
|
+
typedef union cmt_io_driver {
|
|
114
|
+
cmt_io_driver_ioctl_t ioctl;
|
|
115
|
+
cmt_io_driver_mock_t mock;
|
|
116
|
+
} cmt_io_driver_t;
|
|
117
|
+
|
|
118
|
+
/** yield struct cmt_io_yield */
|
|
119
|
+
typedef struct cmt_io_yield {
|
|
120
|
+
uint8_t dev;
|
|
121
|
+
uint8_t cmd;
|
|
122
|
+
uint16_t reason;
|
|
123
|
+
uint32_t data;
|
|
124
|
+
} cmt_io_yield_t;
|
|
125
|
+
|
|
126
|
+
/** Open the io device and initialize the driver. Release its resources with @ref cmt_io_fini.
|
|
127
|
+
*
|
|
128
|
+
* @param [in] me A uninitialized @ref cmt_io_driver state
|
|
129
|
+
*
|
|
130
|
+
* @return
|
|
131
|
+
* | | |
|
|
132
|
+
* |--:|-----------------------------|
|
|
133
|
+
* | 0| success |
|
|
134
|
+
* |< 0| failure with a -errno value | */
|
|
135
|
+
int cmt_io_init(cmt_io_driver_t *me);
|
|
136
|
+
|
|
137
|
+
/** Release the driver resources and close the io device.
|
|
138
|
+
*
|
|
139
|
+
* @param [in] me A successfully initialized state by @ref cmt_io_init
|
|
140
|
+
* @note usage of @p me after this call is a BUG and will cause undefined behaviour */
|
|
141
|
+
void cmt_io_fini(cmt_io_driver_t *me);
|
|
142
|
+
|
|
143
|
+
/** Retrieve the transmit buffer @p tx
|
|
144
|
+
*
|
|
145
|
+
* @param [in] me A successfully initialized state by @ref cmt_io_init
|
|
146
|
+
* @return
|
|
147
|
+
* - writable memory region as defined in the setup structure (check @ref cmt_buf_t)
|
|
148
|
+
* @note memory is valid until @ref cmt_io_fini is called. */
|
|
149
|
+
cmt_buf_t cmt_io_get_tx(cmt_io_driver_t *me);
|
|
150
|
+
|
|
151
|
+
/** Retrieve the receive buffer @p rx
|
|
152
|
+
*
|
|
153
|
+
* @param [in] me A successfully initialized state by @ref cmt_io_init
|
|
154
|
+
* @return
|
|
155
|
+
* - readable memory region as defined in the setup structure (check @ref cmt_buf_t)
|
|
156
|
+
* @note memory is valid until @ref cmt_io_fini is called. */
|
|
157
|
+
cmt_buf_t cmt_io_get_rx(cmt_io_driver_t *me);
|
|
158
|
+
|
|
159
|
+
/** Perform the yield encoded in @p rr.
|
|
160
|
+
*
|
|
161
|
+
* @param [in] me A successfully initialized state by @ref cmt_io_init
|
|
162
|
+
* @param [in,out] rr Request and Reply
|
|
163
|
+
* @return
|
|
164
|
+
* - 0 on success
|
|
165
|
+
* - negative errno code on error */
|
|
166
|
+
int cmt_io_yield(cmt_io_driver_t *me, cmt_io_yield_t *rr);
|
|
167
|
+
|
|
168
|
+
#endif /* CMT_IO_H */
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* Copyright Cartesi and individual authors (see AUTHORS)
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** @file
|
|
17
|
+
* @defgroup libcmt_keccak keccak
|
|
18
|
+
* Keccak 256 digest
|
|
19
|
+
*
|
|
20
|
+
* Data can be inserted in pieces:
|
|
21
|
+
* @code
|
|
22
|
+
* ...
|
|
23
|
+
* uint8_t h[CMT_KECCAK_LENGTH];
|
|
24
|
+
* cmt_keccak_t st[1];
|
|
25
|
+
*
|
|
26
|
+
* cmt_keccak_init(st);
|
|
27
|
+
* cmt_keccak_update(st, 1, "h");
|
|
28
|
+
* cmt_keccak_update(st, 1, "e");
|
|
29
|
+
* cmt_keccak_update(st, 1, "l");
|
|
30
|
+
* cmt_keccak_update(st, 1, "l");
|
|
31
|
+
* cmt_keccak_update(st, 1, "o");
|
|
32
|
+
* cmt_keccak_final(st, h);
|
|
33
|
+
* ...
|
|
34
|
+
* @endcode
|
|
35
|
+
*
|
|
36
|
+
* all at once:
|
|
37
|
+
* @code
|
|
38
|
+
* ...
|
|
39
|
+
* const char data[] = "hello";
|
|
40
|
+
* uint8_t h[CMT_KECCAK_LENGTH];
|
|
41
|
+
* cmt_keccak_data(h, sizeof(data)-1, data);
|
|
42
|
+
* ...
|
|
43
|
+
* @endcode
|
|
44
|
+
*
|
|
45
|
+
* or with a specialized call to generate @ref funsel data:
|
|
46
|
+
* @code
|
|
47
|
+
* ...
|
|
48
|
+
* uint32_t funsel = cmt_keccak_funsel("FunctionCall(address,bytes)");
|
|
49
|
+
* ...
|
|
50
|
+
* @endcode
|
|
51
|
+
*
|
|
52
|
+
* Code based on https://github.com/mjosaarinen/tiny_sha3 with the sha3 to
|
|
53
|
+
* keccak change as indicated by this comment:
|
|
54
|
+
* https://github.com/mjosaarinen/tiny_sha3#updated-07-aug-15
|
|
55
|
+
*
|
|
56
|
+
* @ingroup libcmtcmt
|
|
57
|
+
* @{ */
|
|
58
|
+
#ifndef CMT_KECCAK_H
|
|
59
|
+
#define CMT_KECCAK_H
|
|
60
|
+
#include <stddef.h>
|
|
61
|
+
#include <stdint.h>
|
|
62
|
+
|
|
63
|
+
enum {
|
|
64
|
+
CMT_KECCAK_LENGTH = 32, /**< Bytes in the hash digest */
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/** Opaque internal keccak state */
|
|
68
|
+
typedef union cmt_keccak_state {
|
|
69
|
+
uint8_t b[200];
|
|
70
|
+
uint64_t q[25];
|
|
71
|
+
} cmt_keccak_state_t;
|
|
72
|
+
|
|
73
|
+
/** Opaque Keccak state, used to do hash computations, initialize with:
|
|
74
|
+
* - @ref cmt_keccak_init
|
|
75
|
+
* - @ref CMT_KECCAK_INIT
|
|
76
|
+
* - @ref CMT_KECCAK_DECL */
|
|
77
|
+
typedef struct cmt_keccak {
|
|
78
|
+
cmt_keccak_state_t st;
|
|
79
|
+
int pt, rsiz;
|
|
80
|
+
} cmt_keccak_t;
|
|
81
|
+
|
|
82
|
+
/** Initialize a @ref cmt_keccak_t hasher state.
|
|
83
|
+
*
|
|
84
|
+
* @param [out] state uninitialized @ref cmt_keccak_t */
|
|
85
|
+
void cmt_keccak_init(cmt_keccak_t *state);
|
|
86
|
+
|
|
87
|
+
/** Hash @b n bytes of @b data
|
|
88
|
+
*
|
|
89
|
+
* @param [in,out] state initialize the hasher state
|
|
90
|
+
* @param [in] length bytes in @b data to process
|
|
91
|
+
* @param [in] data data to hash */
|
|
92
|
+
void cmt_keccak_update(cmt_keccak_t *state, size_t n, const void *data);
|
|
93
|
+
|
|
94
|
+
/** Finalize the hash calculation from @b state and store it in @b md
|
|
95
|
+
*
|
|
96
|
+
* @param [in] state initialize the hasher state (with all data already added to it)
|
|
97
|
+
* @param [out] md 32bytes to store the computed hash */
|
|
98
|
+
void cmt_keccak_final(cmt_keccak_t *state, void *md);
|
|
99
|
+
|
|
100
|
+
/** Hash all @b n bytes of @b data at once
|
|
101
|
+
*
|
|
102
|
+
* @param [in] length bytes in @b data to process
|
|
103
|
+
* @param [in] data data to hash
|
|
104
|
+
* @param [out] md 32bytes to store the computed hash
|
|
105
|
+
* @return pointer to @b md
|
|
106
|
+
*
|
|
107
|
+
* Equivalent to:
|
|
108
|
+
* @code
|
|
109
|
+
* cmt_keccak_t st = CMT_KECCAK_INIT(&st);
|
|
110
|
+
* cmt_keccak_update(&st, n, data);
|
|
111
|
+
* cmt_keccak_final(&st, md);
|
|
112
|
+
* return md;
|
|
113
|
+
* @endcode */
|
|
114
|
+
uint8_t *cmt_keccak_data(size_t length, const void *data, uint8_t md[CMT_KECCAK_LENGTH]);
|
|
115
|
+
|
|
116
|
+
/** Compute the function selector from the solidity declaration @p decl
|
|
117
|
+
*
|
|
118
|
+
* @param [in] decl solidity call declaration, without variable names
|
|
119
|
+
* @param [out] funsel function selector as described by @ref funsel
|
|
120
|
+
* @return A @p funsel value as if defined by @ref CMT_ABI_FUNSEL
|
|
121
|
+
*
|
|
122
|
+
* Example usage:
|
|
123
|
+
* @code
|
|
124
|
+
* ...
|
|
125
|
+
* uint32_t funsel = cmt_keccak_funsel("FunctionCall(address,bytes)");
|
|
126
|
+
* ...
|
|
127
|
+
* @endcode
|
|
128
|
+
*/
|
|
129
|
+
uint32_t cmt_keccak_funsel(const char *decl);
|
|
130
|
+
#endif /* CMT_KECCAK_H */
|
|
131
|
+
/** $@} */
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* Copyright Cartesi and individual authors (see AUTHORS)
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/** @file
|
|
17
|
+
* @defgroup libcmt_merkle merkle
|
|
18
|
+
* merkle tree of keccak256 hashes
|
|
19
|
+
*
|
|
20
|
+
* @ingroup libcmt
|
|
21
|
+
* @{ */
|
|
22
|
+
#ifndef CMT_MERKLE_H
|
|
23
|
+
#define CMT_MERKLE_H
|
|
24
|
+
#include "keccak.h"
|
|
25
|
+
|
|
26
|
+
enum {
|
|
27
|
+
CMT_MERKLE_TREE_HEIGHT = 63, /**< merkle tree height */
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/** Opaque Merkle tree state.
|
|
31
|
+
* initialize with: @ref cmt_merkle_init */
|
|
32
|
+
typedef struct {
|
|
33
|
+
uint64_t leaf_count; /**< number of leaves in tree */
|
|
34
|
+
uint8_t state[CMT_MERKLE_TREE_HEIGHT][CMT_KECCAK_LENGTH]; /**< hashes of complete subtrees */
|
|
35
|
+
} cmt_merkle_t;
|
|
36
|
+
|
|
37
|
+
/** Initialize a @ref cmt_merkle_t tree state.
|
|
38
|
+
*
|
|
39
|
+
* @param [in] me uninitialized state */
|
|
40
|
+
void cmt_merkle_init(cmt_merkle_t *me);
|
|
41
|
+
|
|
42
|
+
/** Resets a @ref cmt_merkle_t to pristine conditions.
|
|
43
|
+
*
|
|
44
|
+
* @param [in] me initialized state */
|
|
45
|
+
void cmt_merkle_reset(cmt_merkle_t *me);
|
|
46
|
+
|
|
47
|
+
/** Finalize a @ref cmt_merkle_t tree state.
|
|
48
|
+
*
|
|
49
|
+
* @param [in] me initialized state
|
|
50
|
+
*
|
|
51
|
+
* @note use of @p me after this call is undefined behavior. */
|
|
52
|
+
void cmt_merkle_fini(cmt_merkle_t *me);
|
|
53
|
+
|
|
54
|
+
/** Load the a @ref cmt_merkle_t tree from a @p file handle.
|
|
55
|
+
*
|
|
56
|
+
* @param [in] me either a initialized or uninitialized state
|
|
57
|
+
* @param [in] filepath which file to save the merkle state
|
|
58
|
+
*
|
|
59
|
+
* @return
|
|
60
|
+
* | | |
|
|
61
|
+
* |--:|-----------------------------|
|
|
62
|
+
* | 0| success |
|
|
63
|
+
* |< 0| failure with a -errno value | */
|
|
64
|
+
int cmt_merkle_load(cmt_merkle_t *me, const char *filepath);
|
|
65
|
+
|
|
66
|
+
/** Save the a @ref cmt_merkle_t tree to a @p file handle.
|
|
67
|
+
*
|
|
68
|
+
* @param [in] me either a initialized or uninitialized state
|
|
69
|
+
* @param [in] filepath which file to save the merkle state
|
|
70
|
+
*
|
|
71
|
+
* @return
|
|
72
|
+
* | | |
|
|
73
|
+
* |--:|-----------------------------|
|
|
74
|
+
* | 0| success |
|
|
75
|
+
* |< 0| failure with a -errno value | */
|
|
76
|
+
int cmt_merkle_save(cmt_merkle_t *me, const char *filepath);
|
|
77
|
+
|
|
78
|
+
/** Return number of leaves already in tree
|
|
79
|
+
*
|
|
80
|
+
* @param [in,out] me initialized state
|
|
81
|
+
* @return
|
|
82
|
+
* - leaf count */
|
|
83
|
+
uint64_t cmt_merkle_get_leaf_count(cmt_merkle_t *me);
|
|
84
|
+
|
|
85
|
+
/** Append a leaf node
|
|
86
|
+
*
|
|
87
|
+
* @param [in,out] me initialized state
|
|
88
|
+
* @param [in] hash value of the new leaf
|
|
89
|
+
*
|
|
90
|
+
* @return
|
|
91
|
+
* | | |
|
|
92
|
+
* |---------:|---------------------------------|
|
|
93
|
+
* | 0| success |
|
|
94
|
+
* | -ENOBUFS | indicates that the tree is full |
|
|
95
|
+
* | < 0| failure with a -errno value | */
|
|
96
|
+
int cmt_merkle_push_back(cmt_merkle_t *me, const uint8_t hash[CMT_KECCAK_LENGTH]);
|
|
97
|
+
|
|
98
|
+
/** Compute the keccak-256 hash of @p data and append it as a leaf node
|
|
99
|
+
*
|
|
100
|
+
* @param [in,out] me initialized state
|
|
101
|
+
* @param [in] length size of @p data in bytes
|
|
102
|
+
* @param [in] data array of bytes
|
|
103
|
+
*
|
|
104
|
+
* @return
|
|
105
|
+
* | | |
|
|
106
|
+
* |---------:|---------------------------------|
|
|
107
|
+
* | 0| success |
|
|
108
|
+
* | -ENOBUFS | indicates that the tree is full |
|
|
109
|
+
* | < 0| failure with a -errno value | */
|
|
110
|
+
int cmt_merkle_push_back_data(cmt_merkle_t *me, size_t length, const void *data);
|
|
111
|
+
|
|
112
|
+
/** Compute the root hash of the merkle tree
|
|
113
|
+
*
|
|
114
|
+
* @param [in] me initialized state
|
|
115
|
+
* @param [out] root root hash of the merkle tree */
|
|
116
|
+
void cmt_merkle_get_root_hash(cmt_merkle_t *me, uint8_t root[CMT_KECCAK_LENGTH]);
|
|
117
|
+
|
|
118
|
+
#endif /* CMT_MERKLE_H */
|