Skip to content

Instantly share code, notes, and snippets.

@gballet
Last active February 8, 2019 14:53
Show Gist options
  • Save gballet/f14d11053d8f846bfbb3687581b0eecb to your computer and use it in GitHub Desktop.
Save gballet/f14d11053d8f846bfbb3687581b0eecb to your computer and use it in GitHub Desktop.
Zokrates WASM version of Rust helpers
#define WASM_EXPORT __attribute__((visibility("default")))
typedef unsigned long int uint32_t;
typedef long int int32_t;
typedef unsigned char field_t[32];
/* List of exports */
WASM_EXPORT
const int32_t field_size = sizeof(field_t); /* Maximum accepted number of bytes to encode a field */
WASM_EXPORT
const int32_t min_inputs = 1; /* Expected number of inputs */
WASM_EXPORT
const int32_t min_outputs = 254; /* Expected number of outputs */
field_t input; /* Place to store the single input */
field_t output[254]; /* Place to recover the output from */
WASM_EXPORT
uint32_t get_inputs_off()
{
return (uint32_t)&input;
}
void zero_out(unsigned char *field, int size)
{
for (int i=0; i<size; i++)
field[i] = 0;
}
WASM_EXPORT
uint32_t solve()
{
/* Make sure that memory is zeroed-out */
zero_out((unsigned char *) &output, 32*254);
/* Loop over all the field's bits */
for (int i=0; i<254; i++) {
/* Byte index of the current bit */
int byte = i / 8;
/* Bit index of the current bit */
unsigned char mask = 1 << (i % 8);
/* Store the bit, assuming little endian */
output[i][0] = input[byte] & mask ? 1 : 0;
}
return (uint32_t)&output;
}
#define WASM_EXPORT __attribute__((visibility("default")))
WASM_EXPORT
const int field_size = 32;
WASM_EXPORT
const int min_inputs = 1;
WASM_EXPORT
const int min_outputs = 254;
unsigned char input[field_size];
unsigned char output[min_outputs][field_size];
WASM_EXPORT
int get_inputs_off() {
return (int) &input;
}
WASM_EXPORT
int solve(void) {
for (int i=min_outputs-1; i>=0; i--) {
output[min_outputs-i-1 /* BE */][0 /* LE */] = (input[i/8] & (1 << (i % 8))) ? 1 : 0;
}
return (int) &output;
}
(module
(type $0 (func (result i32)))
(global $global$0 i32 (i32.const 1))
(global $global$1 i32 (i32.const 1))
(global $global$2 i32 (i32.const 32))
(global $global$3 (mut i32) (i32.const 0))
(memory $0 1)
(data (i32.const 0) "\ff\ff\ff\ff\00\00\00\00\00\00\00\00\00\00\00\00\ff\ff\ff\ff\00\00\00\00\00\00\00\00\00\00\00\00")
(data (i32.const 32) "\de\ad\be\ef\00\00\00\00\00\00\00\00\00\00\00\00\de\ad\be\ef\00\00\00\00\00\00\00\00\00\00\00\00")
(export "memory" (memory $0))
(export "get_inputs_off" (func $1))
(export "solve" (func $0))
(export "min_inputs" (global $global$0))
(export "min_outputs" (global $global$1))
(export "field_size" (global $global$2))
(func $0 (; 0 ;) (type $0) (result i32)
(loop $label$1
(i32.store
(i32.add
(i32.const 32)
(get_global $global$3)
)
(i32.load
(i32.add
(i32.const 0)
(get_global $global$3)
)
)
)
(set_global $global$3
(i32.add
(get_global $global$3)
(i32.const 1)
)
)
(br_if $label$1
(i32.ne
(get_global $global$3)
(get_global $global$2)
)
)
)
; Set loop counter back to 0 for next function call
(set_global $global$3
(i32.const 0)
)
(i32.const 32)
)
(func $1 (; 1 ;) (type $0) (result i32)
(i32.const 0)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment