experimental hashing with oxcaml
1/*
2 * OCaml bindings for SHA256 C implementation.
3 * Uses custom blocks and bigarrays for zero-copy performance.
4 */
5
6#include <string.h>
7#include <caml/mlvalues.h>
8#include <caml/memory.h>
9#include <caml/alloc.h>
10#include <caml/custom.h>
11#include <caml/fail.h>
12#include <caml/bigarray.h>
13
14#include "sha256.h"
15
16/* Custom block operations for SHA256_CTX */
17
18static void oxsha_ctx_finalize(value v_ctx)
19{
20 SHA256_CTX *ctx = (SHA256_CTX *)Data_custom_val(v_ctx);
21 /* Just clear the memory for security */
22 memset(ctx, 0, sizeof(SHA256_CTX));
23}
24
25static struct custom_operations oxsha_ctx_ops = {
26 "com.oxsha.sha256_ctx",
27 oxsha_ctx_finalize,
28 custom_compare_default,
29 custom_hash_default,
30 custom_serialize_default,
31 custom_deserialize_default,
32 custom_compare_ext_default,
33 custom_fixed_length_default
34};
35
36/* Allocate and wrap a SHA256_CTX in an OCaml custom block */
37static value alloc_oxsha_ctx(void)
38{
39 value v_ctx = caml_alloc_custom(&oxsha_ctx_ops, sizeof(SHA256_CTX), 0, 1);
40 return v_ctx;
41}
42
43/* Extract SHA256_CTX pointer from OCaml value */
44#define Oxsha_ctx_val(v) ((SHA256_CTX *)Data_custom_val(v))
45
46/* FFI Functions */
47
48/* oxsha_create : unit -> t */
49CAMLprim value oxsha_create(value unit)
50{
51 CAMLparam1(unit);
52 CAMLlocal1(v_ctx);
53
54 v_ctx = alloc_oxsha_ctx();
55 SHA256_CTX *ctx = Oxsha_ctx_val(v_ctx);
56 sha256_init(ctx);
57
58 CAMLreturn(v_ctx);
59}
60
61/* oxsha_update : t -> bigarray -> unit */
62CAMLprim value oxsha_update(value v_ctx, value v_data)
63{
64 CAMLparam2(v_ctx, v_data);
65
66 SHA256_CTX *ctx = Oxsha_ctx_val(v_ctx);
67
68 /* Extract bigarray data pointer and length */
69 unsigned char *data = (unsigned char *)Caml_ba_data_val(v_data);
70 size_t len = Caml_ba_array_val(v_data)->dim[0];
71
72 sha256_update(ctx, data, len);
73
74 CAMLreturn(Val_unit);
75}
76
77/* oxsha_final : t -> bytes */
78CAMLprim value oxsha_final(value v_ctx)
79{
80 CAMLparam1(v_ctx);
81 CAMLlocal1(v_digest);
82
83 SHA256_CTX *ctx = Oxsha_ctx_val(v_ctx);
84
85 /* Allocate bytes for the 32-byte digest */
86 v_digest = caml_alloc_string(SHA256_BLOCK_SIZE);
87 unsigned char *digest = (unsigned char *)String_val(v_digest);
88
89 sha256_final(ctx, digest);
90
91 CAMLreturn(v_digest);
92}