experimental hashing with oxcaml
at main 2.2 kB view raw
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}