Add PEL seed/run tools and quickstart README
This commit is contained in:
parent
a7ff4ec25a
commit
441b0191e8
|
|
@ -149,6 +149,27 @@ target_link_libraries(amduat_asl_cli
|
||||||
)
|
)
|
||||||
set_target_properties(amduat_asl_cli PROPERTIES OUTPUT_NAME amduat-asl)
|
set_target_properties(amduat_asl_cli PROPERTIES OUTPUT_NAME amduat-asl)
|
||||||
|
|
||||||
|
add_executable(amduat_pel_seed src/tools/amduat_pel_seed.c)
|
||||||
|
target_include_directories(amduat_pel_seed
|
||||||
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
PRIVATE ${AMDUAT_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(amduat_pel_seed
|
||||||
|
PRIVATE amduat_asl_store_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util
|
||||||
|
)
|
||||||
|
set_target_properties(amduat_pel_seed PROPERTIES OUTPUT_NAME amduat-pel-seed)
|
||||||
|
|
||||||
|
add_executable(amduat_pel_run src/tools/amduat_pel_run.c)
|
||||||
|
target_include_directories(amduat_pel_run
|
||||||
|
PRIVATE ${AMDUAT_INTERNAL_DIR}
|
||||||
|
PRIVATE ${AMDUAT_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(amduat_pel_run
|
||||||
|
PRIVATE amduat_pel amduat_asl_store_fs amduat_asl amduat_enc
|
||||||
|
amduat_hash_asl1 amduat_util
|
||||||
|
)
|
||||||
|
set_target_properties(amduat_pel_run PROPERTIES OUTPUT_NAME amduat-pel-run)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
add_executable(amduat_test_pel_program_dag tests/enc/test_pel_program_dag.c)
|
add_executable(amduat_test_pel_program_dag tests/enc/test_pel_program_dag.c)
|
||||||
|
|
|
||||||
98
README.md
Normal file
98
README.md
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
# Amduat (PEL quickstart)
|
||||||
|
|
||||||
|
This repo contains the PEL/1 stack and small CLI tools to seed and run
|
||||||
|
PEL/PROGRAM-DAG/1 programs against an ASL store.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Initialize an ASL store
|
||||||
|
|
||||||
|
```
|
||||||
|
amduat-asl init --root .amduat-asl
|
||||||
|
```
|
||||||
|
|
||||||
|
## Seed a PEL program artifact
|
||||||
|
|
||||||
|
`amduat-pel-seed` creates a Program DAG in memory, encodes it under
|
||||||
|
`ENC/PEL-PROGRAM-DAG/1`, tags it as `TYPE_TAG_PEL_PROGRAM_DAG_1`, and
|
||||||
|
stores it in ASL.
|
||||||
|
|
||||||
|
```
|
||||||
|
concat1_ref=$(amduat-pel-seed --seed concat1 --root .amduat-asl --quiet)
|
||||||
|
```
|
||||||
|
|
||||||
|
Available seeds:
|
||||||
|
|
||||||
|
- `const` (const "hello", no inputs)
|
||||||
|
- `concat` (concat input 0 + input 1)
|
||||||
|
- `concat1` (identity: concat input 0 only)
|
||||||
|
- `slice` (slice input 0, offset=1 length=3)
|
||||||
|
- `hash` (HASH-ASL1-256 of input 0)
|
||||||
|
- `const-hash` (const "hello" then hash)
|
||||||
|
|
||||||
|
## Store an input artifact
|
||||||
|
|
||||||
|
```
|
||||||
|
input_ref=$(printf 'hello' | amduat-asl put --root .amduat-asl --input - --quiet)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run a program and print output bytes
|
||||||
|
|
||||||
|
`amduat-pel-run` executes a Program via `PEL/1-SURF`, writes outputs and
|
||||||
|
result artifacts to the store, and can stream an output artifact's bytes
|
||||||
|
to stdout (like `amduat-asl get`).
|
||||||
|
|
||||||
|
```
|
||||||
|
amduat-pel-run --root .amduat-asl \
|
||||||
|
--program-ref "$concat1_ref" \
|
||||||
|
--input-ref "$input_ref" \
|
||||||
|
--output-raw --quiet
|
||||||
|
```
|
||||||
|
|
||||||
|
The command above prints `hello` to stdout. Without `--quiet`, execution
|
||||||
|
status and refs are printed to stderr.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Program artifacts are standard ASL artifacts whose bytes are encoded
|
||||||
|
`ProgramBytes` (`ENC/PEL-PROGRAM-DAG/1`) and whose type tag is
|
||||||
|
`TYPE_TAG_PEL_PROGRAM_DAG_1` (`0x00000101`).
|
||||||
|
- `amduat-pel-run` reports `result_ref`, `trace_ref`, and `output_ref[N]`
|
||||||
|
when not using `--output-raw`.
|
||||||
|
|
||||||
|
## PEL reference
|
||||||
|
|
||||||
|
- Scheme ref (PEL/PROGRAM-DAG/1): `amduat_pel_program_dag_scheme_ref()`
|
||||||
|
- Type tags:
|
||||||
|
- Program DAG: `0x00000101` (`TYPE_TAG_PEL_PROGRAM_DAG_1`)
|
||||||
|
- Trace DAG: `0x00000102` (`TYPE_TAG_PEL_TRACE_DAG_1`)
|
||||||
|
- Surface result: `0x00000103` (`TYPE_TAG_PEL1_RESULT_1`)
|
||||||
|
- Encoding profile IDs:
|
||||||
|
- Program DAG: `0x0101` (`PEL_ENC_PROGRAM_DAG_V1`)
|
||||||
|
- Trace DAG: `0x0102` (`PEL_ENC_TRACE_DAG_V1`)
|
||||||
|
- Surface result: `0x0103` (`PEL_ENC_EXECUTION_RESULT_V1`)
|
||||||
|
|
||||||
|
## TGK handoff (stub)
|
||||||
|
|
||||||
|
TGK should consume PEL surface artifacts (result + trace) and their refs to
|
||||||
|
construct provenance graphs and overlays. Inputs to expect:
|
||||||
|
|
||||||
|
- `result_ref`: a `PEL/1-SURF` execution result artifact.
|
||||||
|
- `trace_ref`: a `PEL/TRACE-DAG/1` trace artifact (optional but recommended).
|
||||||
|
- `program_ref` + `input_refs`: available inside result/trace payloads.
|
||||||
|
|
||||||
|
Recommended next step: map trace nodes/outputs to TGK nodes/edges and build
|
||||||
|
overlay indexes (e.g., lookup by artifact ref, program ref, op name).
|
||||||
|
|
||||||
|
## Common mistakes
|
||||||
|
|
||||||
|
- Passing a **program ref** as an input ref. Program artifacts are encoded DAGs,
|
||||||
|
so printing their bytes yields strings like `pel.bytes.const` plus embedded
|
||||||
|
params (e.g. `hello`), not the intended data.
|
||||||
|
- Forgetting that `concat1` is identity: output bytes match input bytes.
|
||||||
|
- Expecting `params_ref` to affect DAG execution (it is accepted by the surface
|
||||||
|
API but not used in the current DAG executor).
|
||||||
455
src/tools/amduat_pel_run.c
Normal file
455
src/tools/amduat_pel_run.c
Normal file
|
|
@ -0,0 +1,455 @@
|
||||||
|
#include "amduat/asl/asl_store_fs.h"
|
||||||
|
#include "amduat/asl/asl_store_fs_meta.h"
|
||||||
|
#include "amduat/asl/io.h"
|
||||||
|
#include "amduat/asl/parse.h"
|
||||||
|
#include "amduat/asl/ref_text.h"
|
||||||
|
#include "amduat/asl/store.h"
|
||||||
|
#include "amduat/enc/pel1_result.h"
|
||||||
|
#include "amduat/pel/program_dag_desc.h"
|
||||||
|
#include "amduat/pel/surf.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_RUN_EXIT_OK = 0,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_USAGE = 2,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_IO = 3,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_NOT_FOUND = 4,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_STORE = 5,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_UNSUPPORTED = 6,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_CODEC = 7,
|
||||||
|
AMDUAT_PEL_RUN_EXIT_CONFIG = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const AMDUAT_PEL_RUN_DEFAULT_ROOT = ".amduat-asl";
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *root;
|
||||||
|
const char *program_ref;
|
||||||
|
const char *params_ref;
|
||||||
|
const char **input_refs;
|
||||||
|
size_t input_refs_len;
|
||||||
|
size_t output_index;
|
||||||
|
bool output_raw;
|
||||||
|
bool has_params_ref;
|
||||||
|
bool quiet;
|
||||||
|
} amduat_pel_run_opts_t;
|
||||||
|
|
||||||
|
static void amduat_pel_run_print_usage(FILE *stream) {
|
||||||
|
fprintf(stream,
|
||||||
|
"usage:\n"
|
||||||
|
" amduat-pel-run --program-ref REF [--input-ref REF ...]\n"
|
||||||
|
" [--params-ref REF] [--output-raw]\n"
|
||||||
|
" [--output-index N] [--root PATH] [--quiet]\n"
|
||||||
|
"\n"
|
||||||
|
"defaults:\n"
|
||||||
|
" --root %s\n"
|
||||||
|
" --output-index 0\n"
|
||||||
|
"\n"
|
||||||
|
"notes:\n"
|
||||||
|
" REF values are ASL reference hex strings.\n"
|
||||||
|
" --output-raw writes output bytes to stdout and exec result to stderr.\n",
|
||||||
|
AMDUAT_PEL_RUN_DEFAULT_ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *amduat_pel_run_store_error_str(
|
||||||
|
amduat_asl_store_error_t err) {
|
||||||
|
switch (err) {
|
||||||
|
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
|
||||||
|
return "not found";
|
||||||
|
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
|
||||||
|
return "unsupported";
|
||||||
|
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
|
||||||
|
return "integrity";
|
||||||
|
case AMDUAT_ASL_STORE_OK:
|
||||||
|
return "ok";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amduat_pel_run_map_store_error(amduat_asl_store_error_t err) {
|
||||||
|
switch (err) {
|
||||||
|
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_NOT_FOUND;
|
||||||
|
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_UNSUPPORTED;
|
||||||
|
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_STORE;
|
||||||
|
case AMDUAT_ASL_STORE_OK:
|
||||||
|
default:
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_STORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_pel_run_free_reference(amduat_reference_t *ref) {
|
||||||
|
if (ref == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free((void *)ref->digest.data);
|
||||||
|
ref->digest.data = NULL;
|
||||||
|
ref->digest.len = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_pel_run_free_artifact(amduat_artifact_t *artifact) {
|
||||||
|
if (artifact == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free((void *)artifact->bytes.data);
|
||||||
|
artifact->bytes.data = NULL;
|
||||||
|
artifact->bytes.len = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_pel_run_free_refs(amduat_reference_t *refs,
|
||||||
|
size_t refs_len) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (refs == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < refs_len; ++i) {
|
||||||
|
amduat_pel_run_free_reference(&refs[i]);
|
||||||
|
}
|
||||||
|
free(refs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *amduat_pel_run_status_name(
|
||||||
|
amduat_pel_execution_status_t status) {
|
||||||
|
switch (status) {
|
||||||
|
case AMDUAT_PEL_EXEC_STATUS_OK:
|
||||||
|
return "OK";
|
||||||
|
case AMDUAT_PEL_EXEC_STATUS_SCHEME_UNSUPPORTED:
|
||||||
|
return "SCHEME_UNSUPPORTED";
|
||||||
|
case AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM:
|
||||||
|
return "INVALID_PROGRAM";
|
||||||
|
case AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS:
|
||||||
|
return "INVALID_INPUTS";
|
||||||
|
case AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED:
|
||||||
|
return "RUNTIME_FAILED";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *amduat_pel_run_error_kind_name(
|
||||||
|
amduat_pel_execution_error_kind_t kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case AMDUAT_PEL_EXEC_ERROR_NONE:
|
||||||
|
return "NONE";
|
||||||
|
case AMDUAT_PEL_EXEC_ERROR_SCHEME:
|
||||||
|
return "SCHEME";
|
||||||
|
case AMDUAT_PEL_EXEC_ERROR_PROGRAM:
|
||||||
|
return "PROGRAM";
|
||||||
|
case AMDUAT_PEL_EXEC_ERROR_INPUTS:
|
||||||
|
return "INPUTS";
|
||||||
|
case AMDUAT_PEL_EXEC_ERROR_RUNTIME:
|
||||||
|
return "RUNTIME";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
amduat_pel_run_opts_t opts;
|
||||||
|
amduat_asl_store_fs_config_t cfg;
|
||||||
|
amduat_asl_store_fs_t fs;
|
||||||
|
amduat_asl_store_t store;
|
||||||
|
amduat_reference_t program_ref;
|
||||||
|
amduat_reference_t params_ref;
|
||||||
|
amduat_reference_t *input_refs = NULL;
|
||||||
|
amduat_reference_t *output_refs = NULL;
|
||||||
|
size_t output_refs_len = 0;
|
||||||
|
amduat_reference_t result_ref;
|
||||||
|
amduat_artifact_t result_artifact;
|
||||||
|
amduat_pel_surface_execution_result_t result_value;
|
||||||
|
bool has_result_value = false;
|
||||||
|
bool has_trace_ref = false;
|
||||||
|
amduat_reference_t trace_ref;
|
||||||
|
amduat_artifact_t output_artifact;
|
||||||
|
bool has_output_artifact = false;
|
||||||
|
int exit_code = AMDUAT_PEL_RUN_EXIT_OK;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
opts.root = AMDUAT_PEL_RUN_DEFAULT_ROOT;
|
||||||
|
opts.output_index = 0u;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
if (strcmp(argv[i], "--root") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --root requires a path\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
opts.root = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "--program-ref") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --program-ref requires a value\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
opts.program_ref = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "--input-ref") == 0) {
|
||||||
|
const char **next_inputs;
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --input-ref requires a value\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
next_inputs = (const char **)realloc(
|
||||||
|
opts.input_refs,
|
||||||
|
(opts.input_refs_len + 1u) * sizeof(*opts.input_refs));
|
||||||
|
if (next_inputs == NULL) {
|
||||||
|
fprintf(stderr, "error: out of memory\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_STORE;
|
||||||
|
}
|
||||||
|
opts.input_refs = next_inputs;
|
||||||
|
opts.input_refs[opts.input_refs_len++] = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "--params-ref") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --params-ref requires a value\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
opts.params_ref = argv[++i];
|
||||||
|
opts.has_params_ref = true;
|
||||||
|
} else if (strcmp(argv[i], "--output-raw") == 0) {
|
||||||
|
opts.output_raw = true;
|
||||||
|
} else if (strcmp(argv[i], "--output-index") == 0) {
|
||||||
|
uint32_t index = 0;
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --output-index requires a value\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
if (!amduat_asl_parse_u32(argv[++i], &index)) {
|
||||||
|
fprintf(stderr, "error: invalid --output-index\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
opts.output_index = (size_t)index;
|
||||||
|
} else if (strcmp(argv[i], "--quiet") == 0) {
|
||||||
|
opts.quiet = true;
|
||||||
|
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||||
|
amduat_pel_run_print_usage(stdout);
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_OK;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.program_ref == NULL) {
|
||||||
|
fprintf(stderr, "error: --program-ref is required\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_asl_store_fs_load_config(opts.root, &cfg)) {
|
||||||
|
fprintf(stderr, "error: failed to load store config: %s\n", opts.root);
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_CONFIG;
|
||||||
|
}
|
||||||
|
if (!amduat_asl_store_fs_init(&fs, cfg.config, opts.root)) {
|
||||||
|
fprintf(stderr, "error: failed to initialize store\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_CONFIG;
|
||||||
|
}
|
||||||
|
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
|
||||||
|
|
||||||
|
memset(&program_ref, 0, sizeof(program_ref));
|
||||||
|
if (!amduat_asl_ref_decode_hex(opts.program_ref, &program_ref)) {
|
||||||
|
fprintf(stderr, "error: invalid --program-ref\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.has_params_ref) {
|
||||||
|
memset(¶ms_ref, 0, sizeof(params_ref));
|
||||||
|
if (!amduat_asl_ref_decode_hex(opts.params_ref, ¶ms_ref)) {
|
||||||
|
amduat_pel_run_free_reference(&program_ref);
|
||||||
|
fprintf(stderr, "error: invalid --params-ref\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memset(¶ms_ref, 0, sizeof(params_ref));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.input_refs_len > 0) {
|
||||||
|
input_refs = (amduat_reference_t *)calloc(
|
||||||
|
opts.input_refs_len, sizeof(*input_refs));
|
||||||
|
if (input_refs == NULL) {
|
||||||
|
amduat_pel_run_free_reference(&program_ref);
|
||||||
|
if (opts.has_params_ref) {
|
||||||
|
amduat_pel_run_free_reference(¶ms_ref);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "error: out of memory\n");
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_STORE;
|
||||||
|
}
|
||||||
|
for (i = 0; i < (int)opts.input_refs_len; ++i) {
|
||||||
|
if (!amduat_asl_ref_decode_hex(opts.input_refs[i], &input_refs[i])) {
|
||||||
|
size_t j;
|
||||||
|
fprintf(stderr, "error: invalid --input-ref\n");
|
||||||
|
for (j = 0; j <= (size_t)i; ++j) {
|
||||||
|
amduat_pel_run_free_reference(&input_refs[j]);
|
||||||
|
}
|
||||||
|
free(input_refs);
|
||||||
|
amduat_pel_run_free_reference(&program_ref);
|
||||||
|
if (opts.has_params_ref) {
|
||||||
|
amduat_pel_run_free_reference(¶ms_ref);
|
||||||
|
}
|
||||||
|
return AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&result_ref, 0, sizeof(result_ref));
|
||||||
|
if (!amduat_pel_surf_run(
|
||||||
|
&store,
|
||||||
|
amduat_pel_program_dag_scheme_ref(),
|
||||||
|
program_ref,
|
||||||
|
input_refs,
|
||||||
|
opts.input_refs_len,
|
||||||
|
opts.has_params_ref,
|
||||||
|
params_ref,
|
||||||
|
&output_refs,
|
||||||
|
&output_refs_len,
|
||||||
|
&result_ref)) {
|
||||||
|
fprintf(stderr, "error: PEL surface execution failed\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_STORE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&trace_ref, 0, sizeof(trace_ref));
|
||||||
|
memset(&result_artifact, 0, sizeof(result_artifact));
|
||||||
|
memset(&output_artifact, 0, sizeof(output_artifact));
|
||||||
|
if (amduat_asl_store_get(&store, result_ref, &result_artifact) ==
|
||||||
|
AMDUAT_ASL_STORE_OK) {
|
||||||
|
if (amduat_enc_pel1_result_decode_v1(result_artifact.bytes,
|
||||||
|
&result_value)) {
|
||||||
|
has_result_value = true;
|
||||||
|
if (result_value.has_trace_ref) {
|
||||||
|
trace_ref = result_value.trace_ref;
|
||||||
|
has_trace_ref = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.output_raw) {
|
||||||
|
if (opts.output_index >= output_refs_len) {
|
||||||
|
fprintf(stderr, "error: output index out of range\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_USAGE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (amduat_asl_store_get(&store, output_refs[opts.output_index],
|
||||||
|
&output_artifact) != AMDUAT_ASL_STORE_OK) {
|
||||||
|
fprintf(stderr, "error: failed to load output artifact\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_STORE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
has_output_artifact = true;
|
||||||
|
if (!amduat_asl_write_stream(stdout,
|
||||||
|
output_artifact.bytes.data,
|
||||||
|
output_artifact.bytes.len)) {
|
||||||
|
fprintf(stderr, "error: failed to write output bytes\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_IO;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (!opts.quiet) {
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
fprintf(stderr, "status=%s(%u)\n",
|
||||||
|
has_result_value
|
||||||
|
? amduat_pel_run_status_name(result_value.core_result.status)
|
||||||
|
: "UNKNOWN",
|
||||||
|
has_result_value ? (unsigned int)result_value.core_result.status
|
||||||
|
: 0u);
|
||||||
|
fprintf(stderr, "error_kind=%s(%u)\n",
|
||||||
|
has_result_value
|
||||||
|
? amduat_pel_run_error_kind_name(
|
||||||
|
result_value.core_result.summary.kind)
|
||||||
|
: "UNKNOWN",
|
||||||
|
has_result_value
|
||||||
|
? (unsigned int)result_value.core_result.summary.kind
|
||||||
|
: 0u);
|
||||||
|
fprintf(stderr, "status_code=%u\n",
|
||||||
|
has_result_value
|
||||||
|
? (unsigned int)result_value.core_result.summary.status_code
|
||||||
|
: 0u);
|
||||||
|
if (amduat_asl_ref_encode_hex(result_ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "result_ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
if (has_trace_ref && amduat_asl_ref_encode_hex(trace_ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "trace_ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
if (amduat_asl_ref_encode_hex(output_refs[opts.output_index], &hex_ref)) {
|
||||||
|
fprintf(stderr, "output_ref[%zu]=%s\n", opts.output_index, hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!opts.quiet) {
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
fprintf(stderr, "root=%s\n", opts.root);
|
||||||
|
if (amduat_asl_ref_encode_hex(program_ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "program_ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
if (opts.has_params_ref &&
|
||||||
|
amduat_asl_ref_encode_hex(params_ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "params_ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
if (!amduat_asl_ref_encode_hex(result_ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "error: failed to encode result ref\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_CODEC;
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "result_ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_trace_ref) {
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
if (!amduat_asl_ref_encode_hex(trace_ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "error: failed to encode trace ref\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_CODEC;
|
||||||
|
} else {
|
||||||
|
fprintf(stdout, "trace_ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < (int)output_refs_len; ++i) {
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
if (!amduat_asl_ref_encode_hex(output_refs[i], &hex_ref)) {
|
||||||
|
fprintf(stderr, "error: failed to encode output ref\n");
|
||||||
|
exit_code = AMDUAT_PEL_RUN_EXIT_CODEC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stdout, "output_ref[%d]=%s\n", i, hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (has_result_value) {
|
||||||
|
amduat_enc_pel1_result_free(&result_value);
|
||||||
|
}
|
||||||
|
if (has_output_artifact) {
|
||||||
|
amduat_pel_run_free_artifact(&output_artifact);
|
||||||
|
}
|
||||||
|
if (output_refs != NULL) {
|
||||||
|
amduat_pel_surf_free_refs(output_refs, output_refs_len);
|
||||||
|
}
|
||||||
|
amduat_pel_surf_free_ref(&result_ref);
|
||||||
|
amduat_pel_run_free_artifact(&result_artifact);
|
||||||
|
if (input_refs != NULL) {
|
||||||
|
amduat_pel_run_free_refs(input_refs, opts.input_refs_len);
|
||||||
|
}
|
||||||
|
if (opts.has_params_ref) {
|
||||||
|
amduat_pel_run_free_reference(¶ms_ref);
|
||||||
|
}
|
||||||
|
amduat_pel_run_free_reference(&program_ref);
|
||||||
|
free(opts.input_refs);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
676
src/tools/amduat_pel_seed.c
Normal file
676
src/tools/amduat_pel_seed.c
Normal file
|
|
@ -0,0 +1,676 @@
|
||||||
|
#include "amduat/asl/asl_store_fs.h"
|
||||||
|
#include "amduat/asl/asl_store_fs_meta.h"
|
||||||
|
#include "amduat/asl/io.h"
|
||||||
|
#include "amduat/asl/ref_text.h"
|
||||||
|
#include "amduat/asl/store.h"
|
||||||
|
#include "amduat/enc/asl1_core_codec.h"
|
||||||
|
#include "amduat/enc/pel_program_dag.h"
|
||||||
|
#include "amduat/pel/opreg_kernel.h"
|
||||||
|
#include "amduat/pel/program_dag_desc.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AMDUAT_PEL_SEED_EXIT_OK = 0,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_USAGE = 2,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_IO = 3,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_NOT_FOUND = 4,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_STORE = 5,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_UNSUPPORTED = 6,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_CODEC = 7,
|
||||||
|
AMDUAT_PEL_SEED_EXIT_CONFIG = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const AMDUAT_PEL_SEED_DEFAULT_ROOT = ".amduat-asl";
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AMDUAT_PEL_SEED_REF_HEX = 0,
|
||||||
|
AMDUAT_PEL_SEED_REF_BYTES = 1
|
||||||
|
} amduat_pel_seed_ref_format_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AMDUAT_PEL_SEED_CONST = 0,
|
||||||
|
AMDUAT_PEL_SEED_CONCAT = 1,
|
||||||
|
AMDUAT_PEL_SEED_CONCAT1 = 2,
|
||||||
|
AMDUAT_PEL_SEED_SLICE = 3,
|
||||||
|
AMDUAT_PEL_SEED_HASH = 4,
|
||||||
|
AMDUAT_PEL_SEED_CONST_HASH = 5
|
||||||
|
} amduat_pel_seed_kind_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
amduat_pel_program_t program;
|
||||||
|
amduat_pel_node_t *nodes;
|
||||||
|
amduat_pel_root_ref_t *roots;
|
||||||
|
amduat_pel_dag_input_t **inputs;
|
||||||
|
amduat_octets_t *params;
|
||||||
|
size_t nodes_len;
|
||||||
|
size_t roots_len;
|
||||||
|
} amduat_pel_seed_program_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *root;
|
||||||
|
const char *output_path;
|
||||||
|
amduat_pel_seed_kind_t seed;
|
||||||
|
amduat_pel_seed_ref_format_t ref_format;
|
||||||
|
bool quiet;
|
||||||
|
bool list_only;
|
||||||
|
} amduat_pel_seed_opts_t;
|
||||||
|
|
||||||
|
static void amduat_pel_seed_print_usage(FILE *stream) {
|
||||||
|
fprintf(stream,
|
||||||
|
"usage:\n"
|
||||||
|
" amduat-pel-seed [--root PATH] [--seed NAME]\n"
|
||||||
|
" [--ref-format hex|bytes] [--output PATH|-]\n"
|
||||||
|
" [--quiet]\n"
|
||||||
|
" amduat-pel-seed --list\n"
|
||||||
|
"\n"
|
||||||
|
"defaults:\n"
|
||||||
|
" --root %s\n"
|
||||||
|
" --seed const\n"
|
||||||
|
" --ref-format hex\n"
|
||||||
|
" --output -\n",
|
||||||
|
AMDUAT_PEL_SEED_DEFAULT_ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_pel_seed_print_list(FILE *stream) {
|
||||||
|
fprintf(stream,
|
||||||
|
"seeds:\n"
|
||||||
|
" const Constant bytes \"hello\" (no inputs)\n"
|
||||||
|
" concat Concatenate external inputs 0 and 1\n"
|
||||||
|
" concat1 Concatenate external input 0 (identity)\n"
|
||||||
|
" slice Slice external input 0 (offset=1 length=3)\n"
|
||||||
|
" hash Hash external input 0 (HASH-ASL1-256)\n"
|
||||||
|
" const-hash Const \"hello\" then hash (no inputs)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_parse_ref_format(
|
||||||
|
const char *text,
|
||||||
|
amduat_pel_seed_ref_format_t *out_fmt) {
|
||||||
|
if (text == NULL || out_fmt == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "hex") == 0) {
|
||||||
|
*out_fmt = AMDUAT_PEL_SEED_REF_HEX;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "bytes") == 0) {
|
||||||
|
*out_fmt = AMDUAT_PEL_SEED_REF_BYTES;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_parse_kind(const char *text,
|
||||||
|
amduat_pel_seed_kind_t *out_kind) {
|
||||||
|
if (text == NULL || out_kind == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "const") == 0) {
|
||||||
|
*out_kind = AMDUAT_PEL_SEED_CONST;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "concat") == 0) {
|
||||||
|
*out_kind = AMDUAT_PEL_SEED_CONCAT;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "concat1") == 0) {
|
||||||
|
*out_kind = AMDUAT_PEL_SEED_CONCAT1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "slice") == 0) {
|
||||||
|
*out_kind = AMDUAT_PEL_SEED_SLICE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "hash") == 0) {
|
||||||
|
*out_kind = AMDUAT_PEL_SEED_HASH;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (strcmp(text, "const-hash") == 0) {
|
||||||
|
*out_kind = AMDUAT_PEL_SEED_CONST_HASH;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *amduat_pel_seed_kind_name(amduat_pel_seed_kind_t kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case AMDUAT_PEL_SEED_CONST:
|
||||||
|
return "const";
|
||||||
|
case AMDUAT_PEL_SEED_CONCAT:
|
||||||
|
return "concat";
|
||||||
|
case AMDUAT_PEL_SEED_CONCAT1:
|
||||||
|
return "concat1";
|
||||||
|
case AMDUAT_PEL_SEED_SLICE:
|
||||||
|
return "slice";
|
||||||
|
case AMDUAT_PEL_SEED_HASH:
|
||||||
|
return "hash";
|
||||||
|
case AMDUAT_PEL_SEED_CONST_HASH:
|
||||||
|
return "const-hash";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *amduat_pel_seed_store_error_str(
|
||||||
|
amduat_asl_store_error_t err) {
|
||||||
|
switch (err) {
|
||||||
|
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
|
||||||
|
return "not found";
|
||||||
|
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
|
||||||
|
return "unsupported";
|
||||||
|
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
|
||||||
|
return "integrity";
|
||||||
|
case AMDUAT_ASL_STORE_OK:
|
||||||
|
return "ok";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int amduat_pel_seed_map_store_error(amduat_asl_store_error_t err) {
|
||||||
|
switch (err) {
|
||||||
|
case AMDUAT_ASL_STORE_ERR_NOT_FOUND:
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_NOT_FOUND;
|
||||||
|
case AMDUAT_ASL_STORE_ERR_UNSUPPORTED:
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_UNSUPPORTED;
|
||||||
|
case AMDUAT_ASL_STORE_ERR_INTEGRITY:
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_STORE;
|
||||||
|
case AMDUAT_ASL_STORE_OK:
|
||||||
|
default:
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_STORE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_pel_seed_free_reference(amduat_reference_t *ref) {
|
||||||
|
if (ref == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free((void *)ref->digest.data);
|
||||||
|
ref->digest.data = NULL;
|
||||||
|
ref->digest.len = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_store_u16_be(uint8_t *out, uint16_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[1] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_store_u64_be(uint8_t *out, uint64_t value) {
|
||||||
|
out[0] = (uint8_t)((value >> 56) & 0xffu);
|
||||||
|
out[1] = (uint8_t)((value >> 48) & 0xffu);
|
||||||
|
out[2] = (uint8_t)((value >> 40) & 0xffu);
|
||||||
|
out[3] = (uint8_t)((value >> 32) & 0xffu);
|
||||||
|
out[4] = (uint8_t)((value >> 24) & 0xffu);
|
||||||
|
out[5] = (uint8_t)((value >> 16) & 0xffu);
|
||||||
|
out[6] = (uint8_t)((value >> 8) & 0xffu);
|
||||||
|
out[7] = (uint8_t)(value & 0xffu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static amduat_octets_t amduat_make_const_params(const uint8_t *bytes,
|
||||||
|
size_t len) {
|
||||||
|
size_t total = 1u + 8u + len;
|
||||||
|
uint8_t *buffer = (uint8_t *)malloc(total);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return amduat_octets(NULL, 0);
|
||||||
|
}
|
||||||
|
buffer[0] = 0x00u;
|
||||||
|
amduat_store_u64_be(buffer + 1, (uint64_t)len);
|
||||||
|
if (len != 0 && bytes != NULL) {
|
||||||
|
memcpy(buffer + 1 + 8, bytes, len);
|
||||||
|
}
|
||||||
|
return amduat_octets(buffer, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
static amduat_octets_t amduat_make_slice_params(uint64_t offset,
|
||||||
|
uint64_t length) {
|
||||||
|
uint8_t *buffer = (uint8_t *)malloc(16u);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return amduat_octets(NULL, 0);
|
||||||
|
}
|
||||||
|
amduat_store_u64_be(buffer, offset);
|
||||||
|
amduat_store_u64_be(buffer + 8, length);
|
||||||
|
return amduat_octets(buffer, 16u);
|
||||||
|
}
|
||||||
|
|
||||||
|
static amduat_octets_t amduat_make_hash_params(uint16_t hash_id) {
|
||||||
|
uint8_t *buffer = (uint8_t *)malloc(2u);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
return amduat_octets(NULL, 0);
|
||||||
|
}
|
||||||
|
amduat_store_u16_be(buffer, hash_id);
|
||||||
|
return amduat_octets(buffer, 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_program_init(amduat_pel_seed_program_t *seed,
|
||||||
|
size_t nodes_len,
|
||||||
|
size_t roots_len) {
|
||||||
|
if (seed == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(seed, 0, sizeof(*seed));
|
||||||
|
seed->nodes = (amduat_pel_node_t *)calloc(nodes_len, sizeof(*seed->nodes));
|
||||||
|
seed->roots = (amduat_pel_root_ref_t *)calloc(roots_len,
|
||||||
|
sizeof(*seed->roots));
|
||||||
|
seed->inputs = (amduat_pel_dag_input_t **)calloc(nodes_len,
|
||||||
|
sizeof(*seed->inputs));
|
||||||
|
seed->params = (amduat_octets_t *)calloc(nodes_len, sizeof(*seed->params));
|
||||||
|
if (seed->nodes == NULL || seed->roots == NULL ||
|
||||||
|
seed->inputs == NULL || seed->params == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seed->nodes_len = nodes_len;
|
||||||
|
seed->roots_len = roots_len;
|
||||||
|
seed->program.nodes = seed->nodes;
|
||||||
|
seed->program.nodes_len = nodes_len;
|
||||||
|
seed->program.roots = seed->roots;
|
||||||
|
seed->program.roots_len = roots_len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amduat_pel_seed_program_free(amduat_pel_seed_program_t *seed) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (seed == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 0; i < seed->nodes_len; ++i) {
|
||||||
|
free(seed->inputs[i]);
|
||||||
|
if (seed->params[i].data != NULL) {
|
||||||
|
free((void *)seed->params[i].data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(seed->inputs);
|
||||||
|
free(seed->params);
|
||||||
|
free(seed->nodes);
|
||||||
|
free(seed->roots);
|
||||||
|
memset(seed, 0, sizeof(*seed));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build_const(amduat_pel_seed_program_t *seed) {
|
||||||
|
static const uint8_t k_const_bytes[] = {'h', 'e', 'l', 'l', 'o'};
|
||||||
|
const char *op_const = AMDUAT_PEL_KERNEL_OP_CONST_NAME;
|
||||||
|
amduat_octets_t params;
|
||||||
|
|
||||||
|
if (!amduat_pel_seed_program_init(seed, 1u, 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
params = amduat_make_const_params(k_const_bytes, sizeof(k_const_bytes));
|
||||||
|
if (params.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seed->params[0] = params;
|
||||||
|
|
||||||
|
seed->nodes[0].id = 1u;
|
||||||
|
seed->nodes[0].op.name = amduat_octets(op_const, strlen(op_const));
|
||||||
|
seed->nodes[0].op.version = 1u;
|
||||||
|
seed->nodes[0].inputs = NULL;
|
||||||
|
seed->nodes[0].inputs_len = 0u;
|
||||||
|
seed->nodes[0].params = params;
|
||||||
|
|
||||||
|
seed->roots[0].node_id = 1u;
|
||||||
|
seed->roots[0].output_index = 0u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build_concat(amduat_pel_seed_program_t *seed) {
|
||||||
|
const char *op_concat = AMDUAT_PEL_KERNEL_OP_CONCAT_NAME;
|
||||||
|
amduat_pel_dag_input_t *inputs;
|
||||||
|
|
||||||
|
if (!amduat_pel_seed_program_init(seed, 1u, 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs = (amduat_pel_dag_input_t *)calloc(2u, sizeof(*inputs));
|
||||||
|
if (inputs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
inputs[0].value.external.input_index = 0u;
|
||||||
|
inputs[1].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
inputs[1].value.external.input_index = 1u;
|
||||||
|
seed->inputs[0] = inputs;
|
||||||
|
|
||||||
|
seed->nodes[0].id = 1u;
|
||||||
|
seed->nodes[0].op.name = amduat_octets(op_concat, strlen(op_concat));
|
||||||
|
seed->nodes[0].op.version = 1u;
|
||||||
|
seed->nodes[0].inputs = inputs;
|
||||||
|
seed->nodes[0].inputs_len = 2u;
|
||||||
|
seed->nodes[0].params = amduat_octets(NULL, 0u);
|
||||||
|
seed->params[0] = seed->nodes[0].params;
|
||||||
|
|
||||||
|
seed->roots[0].node_id = 1u;
|
||||||
|
seed->roots[0].output_index = 0u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build_concat1(amduat_pel_seed_program_t *seed) {
|
||||||
|
const char *op_concat = AMDUAT_PEL_KERNEL_OP_CONCAT_NAME;
|
||||||
|
amduat_pel_dag_input_t *inputs;
|
||||||
|
|
||||||
|
if (!amduat_pel_seed_program_init(seed, 1u, 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs = (amduat_pel_dag_input_t *)calloc(1u, sizeof(*inputs));
|
||||||
|
if (inputs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
inputs[0].value.external.input_index = 0u;
|
||||||
|
seed->inputs[0] = inputs;
|
||||||
|
|
||||||
|
seed->nodes[0].id = 1u;
|
||||||
|
seed->nodes[0].op.name = amduat_octets(op_concat, strlen(op_concat));
|
||||||
|
seed->nodes[0].op.version = 1u;
|
||||||
|
seed->nodes[0].inputs = inputs;
|
||||||
|
seed->nodes[0].inputs_len = 1u;
|
||||||
|
seed->nodes[0].params = amduat_octets(NULL, 0u);
|
||||||
|
seed->params[0] = seed->nodes[0].params;
|
||||||
|
|
||||||
|
seed->roots[0].node_id = 1u;
|
||||||
|
seed->roots[0].output_index = 0u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build_slice(amduat_pel_seed_program_t *seed) {
|
||||||
|
const char *op_slice = AMDUAT_PEL_KERNEL_OP_SLICE_NAME;
|
||||||
|
amduat_pel_dag_input_t *inputs;
|
||||||
|
amduat_octets_t params;
|
||||||
|
|
||||||
|
if (!amduat_pel_seed_program_init(seed, 1u, 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
params = amduat_make_slice_params(1u, 3u);
|
||||||
|
if (params.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seed->params[0] = params;
|
||||||
|
|
||||||
|
inputs = (amduat_pel_dag_input_t *)calloc(1u, sizeof(*inputs));
|
||||||
|
if (inputs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
inputs[0].value.external.input_index = 0u;
|
||||||
|
seed->inputs[0] = inputs;
|
||||||
|
|
||||||
|
seed->nodes[0].id = 1u;
|
||||||
|
seed->nodes[0].op.name = amduat_octets(op_slice, strlen(op_slice));
|
||||||
|
seed->nodes[0].op.version = 1u;
|
||||||
|
seed->nodes[0].inputs = inputs;
|
||||||
|
seed->nodes[0].inputs_len = 1u;
|
||||||
|
seed->nodes[0].params = params;
|
||||||
|
|
||||||
|
seed->roots[0].node_id = 1u;
|
||||||
|
seed->roots[0].output_index = 0u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build_hash(amduat_pel_seed_program_t *seed) {
|
||||||
|
const char *op_hash = AMDUAT_PEL_KERNEL_OP_HASH_ASL1_NAME;
|
||||||
|
amduat_pel_dag_input_t *inputs;
|
||||||
|
amduat_octets_t params;
|
||||||
|
|
||||||
|
if (!amduat_pel_seed_program_init(seed, 1u, 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
params = amduat_make_hash_params(0x0001u);
|
||||||
|
if (params.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seed->params[0] = params;
|
||||||
|
|
||||||
|
inputs = (amduat_pel_dag_input_t *)calloc(1u, sizeof(*inputs));
|
||||||
|
if (inputs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
|
||||||
|
inputs[0].value.external.input_index = 0u;
|
||||||
|
seed->inputs[0] = inputs;
|
||||||
|
|
||||||
|
seed->nodes[0].id = 1u;
|
||||||
|
seed->nodes[0].op.name = amduat_octets(op_hash, strlen(op_hash));
|
||||||
|
seed->nodes[0].op.version = 1u;
|
||||||
|
seed->nodes[0].inputs = inputs;
|
||||||
|
seed->nodes[0].inputs_len = 1u;
|
||||||
|
seed->nodes[0].params = params;
|
||||||
|
|
||||||
|
seed->roots[0].node_id = 1u;
|
||||||
|
seed->roots[0].output_index = 0u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build_const_hash(amduat_pel_seed_program_t *seed) {
|
||||||
|
static const uint8_t k_const_bytes[] = {'h', 'e', 'l', 'l', 'o'};
|
||||||
|
const char *op_const = AMDUAT_PEL_KERNEL_OP_CONST_NAME;
|
||||||
|
const char *op_hash = AMDUAT_PEL_KERNEL_OP_HASH_ASL1_NAME;
|
||||||
|
amduat_pel_dag_input_t *inputs;
|
||||||
|
amduat_octets_t const_params;
|
||||||
|
amduat_octets_t hash_params;
|
||||||
|
|
||||||
|
if (!amduat_pel_seed_program_init(seed, 2u, 1u)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_params = amduat_make_const_params(k_const_bytes,
|
||||||
|
sizeof(k_const_bytes));
|
||||||
|
if (const_params.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seed->params[0] = const_params;
|
||||||
|
|
||||||
|
hash_params = amduat_make_hash_params(0x0001u);
|
||||||
|
if (hash_params.data == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
seed->params[1] = hash_params;
|
||||||
|
|
||||||
|
seed->nodes[0].id = 1u;
|
||||||
|
seed->nodes[0].op.name = amduat_octets(op_const, strlen(op_const));
|
||||||
|
seed->nodes[0].op.version = 1u;
|
||||||
|
seed->nodes[0].inputs = NULL;
|
||||||
|
seed->nodes[0].inputs_len = 0u;
|
||||||
|
seed->nodes[0].params = const_params;
|
||||||
|
|
||||||
|
inputs = (amduat_pel_dag_input_t *)calloc(1u, sizeof(*inputs));
|
||||||
|
if (inputs == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inputs[0].kind = AMDUAT_PEL_DAG_INPUT_NODE;
|
||||||
|
inputs[0].value.node.node_id = 1u;
|
||||||
|
inputs[0].value.node.output_index = 0u;
|
||||||
|
seed->inputs[1] = inputs;
|
||||||
|
|
||||||
|
seed->nodes[1].id = 2u;
|
||||||
|
seed->nodes[1].op.name = amduat_octets(op_hash, strlen(op_hash));
|
||||||
|
seed->nodes[1].op.version = 1u;
|
||||||
|
seed->nodes[1].inputs = inputs;
|
||||||
|
seed->nodes[1].inputs_len = 1u;
|
||||||
|
seed->nodes[1].params = hash_params;
|
||||||
|
|
||||||
|
seed->roots[0].node_id = 2u;
|
||||||
|
seed->roots[0].output_index = 0u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool amduat_pel_seed_build(amduat_pel_seed_kind_t kind,
|
||||||
|
amduat_pel_seed_program_t *out_seed) {
|
||||||
|
switch (kind) {
|
||||||
|
case AMDUAT_PEL_SEED_CONST:
|
||||||
|
return amduat_pel_seed_build_const(out_seed);
|
||||||
|
case AMDUAT_PEL_SEED_CONCAT:
|
||||||
|
return amduat_pel_seed_build_concat(out_seed);
|
||||||
|
case AMDUAT_PEL_SEED_CONCAT1:
|
||||||
|
return amduat_pel_seed_build_concat1(out_seed);
|
||||||
|
case AMDUAT_PEL_SEED_SLICE:
|
||||||
|
return amduat_pel_seed_build_slice(out_seed);
|
||||||
|
case AMDUAT_PEL_SEED_HASH:
|
||||||
|
return amduat_pel_seed_build_hash(out_seed);
|
||||||
|
case AMDUAT_PEL_SEED_CONST_HASH:
|
||||||
|
return amduat_pel_seed_build_const_hash(out_seed);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
amduat_pel_seed_opts_t opts;
|
||||||
|
amduat_asl_store_fs_config_t cfg;
|
||||||
|
amduat_asl_store_fs_t fs;
|
||||||
|
amduat_asl_store_t store;
|
||||||
|
amduat_pel_seed_program_t seed_program;
|
||||||
|
amduat_octets_t encoded;
|
||||||
|
amduat_artifact_t artifact;
|
||||||
|
amduat_reference_t ref;
|
||||||
|
amduat_octets_t encoded_ref;
|
||||||
|
int exit_code = AMDUAT_PEL_SEED_EXIT_OK;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
opts.root = AMDUAT_PEL_SEED_DEFAULT_ROOT;
|
||||||
|
opts.output_path = "-";
|
||||||
|
opts.seed = AMDUAT_PEL_SEED_CONST;
|
||||||
|
opts.ref_format = AMDUAT_PEL_SEED_REF_HEX;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; ++i) {
|
||||||
|
if (strcmp(argv[i], "--root") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --root requires a path\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
opts.root = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "--seed") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --seed requires a value\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
if (!amduat_pel_seed_parse_kind(argv[++i], &opts.seed)) {
|
||||||
|
fprintf(stderr, "error: invalid seed\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[i], "--ref-format") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --ref-format requires a value\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
if (!amduat_pel_seed_parse_ref_format(argv[++i], &opts.ref_format)) {
|
||||||
|
fprintf(stderr, "error: invalid ref-format\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[i], "--output") == 0) {
|
||||||
|
if (i + 1 >= argc) {
|
||||||
|
fprintf(stderr, "error: --output requires a path or -\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
opts.output_path = argv[++i];
|
||||||
|
} else if (strcmp(argv[i], "--quiet") == 0) {
|
||||||
|
opts.quiet = true;
|
||||||
|
} else if (strcmp(argv[i], "--list") == 0) {
|
||||||
|
opts.list_only = true;
|
||||||
|
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
|
||||||
|
amduat_pel_seed_print_usage(stdout);
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_OK;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_USAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.list_only) {
|
||||||
|
amduat_pel_seed_print_list(stdout);
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!amduat_asl_store_fs_load_config(opts.root, &cfg)) {
|
||||||
|
fprintf(stderr, "error: failed to load store config: %s\n", opts.root);
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_CONFIG;
|
||||||
|
}
|
||||||
|
if (!amduat_asl_store_fs_init(&fs, cfg.config, opts.root)) {
|
||||||
|
fprintf(stderr, "error: failed to initialize store\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_CONFIG;
|
||||||
|
}
|
||||||
|
amduat_asl_store_init(&store, cfg.config, amduat_asl_store_fs_ops(), &fs);
|
||||||
|
|
||||||
|
memset(&seed_program, 0, sizeof(seed_program));
|
||||||
|
if (!amduat_pel_seed_build(opts.seed, &seed_program)) {
|
||||||
|
amduat_pel_seed_program_free(&seed_program);
|
||||||
|
fprintf(stderr, "error: failed to build seed program\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded = amduat_octets(NULL, 0);
|
||||||
|
if (!amduat_enc_pel_program_dag_encode_v1(&seed_program.program, &encoded)) {
|
||||||
|
amduat_pel_seed_program_free(&seed_program);
|
||||||
|
fprintf(stderr, "error: failed to encode program\n");
|
||||||
|
return AMDUAT_PEL_SEED_EXIT_CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
artifact = amduat_artifact_with_type(
|
||||||
|
encoded, amduat_type_tag(AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1));
|
||||||
|
memset(&ref, 0, sizeof(ref));
|
||||||
|
{
|
||||||
|
amduat_asl_store_error_t err =
|
||||||
|
amduat_asl_store_put(&store, artifact, &ref);
|
||||||
|
if (err != AMDUAT_ASL_STORE_OK) {
|
||||||
|
fprintf(stderr, "error: store put failed: %s\n",
|
||||||
|
amduat_pel_seed_store_error_str(err));
|
||||||
|
exit_code = amduat_pel_seed_map_store_error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exit_code == AMDUAT_PEL_SEED_EXIT_OK) {
|
||||||
|
if (opts.ref_format == AMDUAT_PEL_SEED_REF_HEX) {
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
if (!amduat_asl_ref_encode_hex(ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "error: failed to encode reference\n");
|
||||||
|
exit_code = AMDUAT_PEL_SEED_EXIT_CODEC;
|
||||||
|
} else {
|
||||||
|
if (!amduat_asl_write_text_line(opts.output_path, hex_ref)) {
|
||||||
|
fprintf(stderr, "error: failed to write output: %s\n",
|
||||||
|
opts.output_path);
|
||||||
|
exit_code = AMDUAT_PEL_SEED_EXIT_IO;
|
||||||
|
}
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!amduat_enc_asl1_core_encode_reference_v1(ref, &encoded_ref)) {
|
||||||
|
fprintf(stderr, "error: failed to encode reference\n");
|
||||||
|
exit_code = AMDUAT_PEL_SEED_EXIT_CODEC;
|
||||||
|
} else {
|
||||||
|
if (!amduat_asl_write_path(opts.output_path,
|
||||||
|
encoded_ref.data,
|
||||||
|
encoded_ref.len)) {
|
||||||
|
fprintf(stderr, "error: failed to write output: %s\n",
|
||||||
|
opts.output_path);
|
||||||
|
exit_code = AMDUAT_PEL_SEED_EXIT_IO;
|
||||||
|
}
|
||||||
|
free((void *)encoded_ref.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exit_code == AMDUAT_PEL_SEED_EXIT_OK && !opts.quiet) {
|
||||||
|
char *hex_ref = NULL;
|
||||||
|
fprintf(stderr, "root=%s\n", opts.root);
|
||||||
|
fprintf(stderr, "seed=%s\n", amduat_pel_seed_kind_name(opts.seed));
|
||||||
|
fprintf(stderr, "bytes=%zu\n", encoded.len);
|
||||||
|
fprintf(stderr, "type_tag=0x%08x\n",
|
||||||
|
(unsigned int)artifact.type_tag.tag_id);
|
||||||
|
if (amduat_asl_ref_encode_hex(ref, &hex_ref)) {
|
||||||
|
fprintf(stderr, "ref=%s\n", hex_ref);
|
||||||
|
free(hex_ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amduat_pel_seed_program_free(&seed_program);
|
||||||
|
free((void *)encoded.data);
|
||||||
|
amduat_pel_seed_free_reference(&ref);
|
||||||
|
return exit_code;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue