forked from cryptape/omnilock
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bcd9b58
commit 261283c
Showing
8 changed files
with
363 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
|
||
#ifndef __BLAKE2B_DECL_ONLY_H__ | ||
#define __BLAKE2B_DECL_ONLY_H__ | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
|
||
#define BLAKE2_PACKED(x) x __attribute__((packed)) | ||
|
||
enum blake2b_constant { | ||
BLAKE2B_BLOCKBYTES = 128, | ||
BLAKE2B_OUTBYTES = 64, | ||
BLAKE2B_KEYBYTES = 64, | ||
BLAKE2B_SALTBYTES = 16, | ||
BLAKE2B_PERSONALBYTES = 16 | ||
}; | ||
BLAKE2_PACKED(struct blake2b_param__ { | ||
uint8_t digest_length; /* 1 */ | ||
uint8_t key_length; /* 2 */ | ||
uint8_t fanout; /* 3 */ | ||
uint8_t depth; /* 4 */ | ||
uint32_t leaf_length; /* 8 */ | ||
uint32_t node_offset; /* 12 */ | ||
uint32_t xof_length; /* 16 */ | ||
uint8_t node_depth; /* 17 */ | ||
uint8_t inner_length; /* 18 */ | ||
uint8_t reserved[14]; /* 32 */ | ||
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ | ||
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ | ||
}); | ||
|
||
typedef struct blake2b_param__ blake2b_param; | ||
|
||
typedef struct blake2b_state__ { | ||
uint64_t h[8]; | ||
uint64_t t[2]; | ||
uint64_t f[2]; | ||
uint8_t buf[BLAKE2B_BLOCKBYTES]; | ||
size_t buflen; | ||
size_t outlen; | ||
uint8_t last_node; | ||
} blake2b_state; | ||
|
||
/* Streaming API */ | ||
int ckb_blake2b_init(blake2b_state *S, size_t outlen); | ||
int blake2b_init(blake2b_state *S, size_t outlen); | ||
int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, | ||
size_t keylen); | ||
int blake2b_update(blake2b_state *S, const void *in, size_t inlen); | ||
int blake2b_final(blake2b_state *S, void *out, size_t outlen); | ||
/* Simple API */ | ||
int blake2b(void *out, size_t outlen, const void *in, size_t inlen, | ||
const void *key, size_t keylen); | ||
|
||
/* This is simply an alias for blake2b */ | ||
int blake2(void *out, size_t outlen, const void *in, size_t inlen, | ||
const void *key, size_t keylen); | ||
|
||
int blake2b_init_param(blake2b_state *S, const blake2b_param *P); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
// clang-format off | ||
#define CKB_DECLARATION_ONLY | ||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include "cobuild.h" | ||
|
||
#define MOLECULEC_C2_DECLARATION_ONLY | ||
#define MOLECULEC2_VERSION 6001 | ||
#define MOLECULE2_API_VERSION_MIN 5000 | ||
#include "molecule2_reader.h" | ||
|
||
#include "blake2b_decl_only.h" | ||
#include "ckb_consts.h" | ||
#include "ckb_syscall_apis.h" | ||
// clang-format on | ||
|
||
#define CHECK2(cond, code) \ | ||
do { \ | ||
if (!(cond)) { \ | ||
printf("error at %s:%d, error code %d", __FILE__, __LINE__, code); \ | ||
err = code; \ | ||
ASSERT(0); \ | ||
goto exit; \ | ||
} \ | ||
} while (0) | ||
|
||
#define CHECK(_code) \ | ||
do { \ | ||
int code = (_code); \ | ||
if (code != 0) { \ | ||
printf("error at %s:%d, error code %d", __FILE__, __LINE__, code); \ | ||
err = code; \ | ||
ASSERT(0); \ | ||
goto exit; \ | ||
} \ | ||
} while (0) | ||
|
||
enum CobuildErrorCode { | ||
// cobuild error code is from 110 | ||
ERROR_GENERAL = 110, | ||
ERROR_HASH, | ||
ERROR_NONEMPTY_WITNESS, | ||
}; | ||
|
||
const char *PERSONAL_SIGHASH_ALL = "ckb-tcob-sighash"; | ||
const char *PERSONAL_SIGHASH_ALL_ONLY = "ckb-tcob-sgohash"; | ||
const char *PERSONAL_OTX = "ckb-tcob-otxhash"; | ||
|
||
static void store32(void *dst, uint32_t w) { | ||
uint8_t *p = (uint8_t *)dst; | ||
p[0] = (uint8_t)(w >> 0); | ||
p[1] = (uint8_t)(w >> 8); | ||
p[2] = (uint8_t)(w >> 16); | ||
p[3] = (uint8_t)(w >> 24); | ||
} | ||
|
||
int ckb_blake2b_init_personal(blake2b_state *S, size_t outlen, | ||
const char *personal) { | ||
blake2b_param P[1]; | ||
|
||
if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1; | ||
|
||
P->digest_length = (uint8_t)outlen; | ||
P->key_length = 0; | ||
P->fanout = 1; | ||
P->depth = 1; | ||
store32(&P->leaf_length, 0); | ||
store32(&P->node_offset, 0); | ||
store32(&P->xof_length, 0); | ||
P->node_depth = 0; | ||
P->inner_length = 0; | ||
memset(P->reserved, 0, sizeof(P->reserved)); | ||
memset(P->salt, 0, sizeof(P->salt)); | ||
memset(P->personal, 0, sizeof(P->personal)); | ||
for (int i = 0; i < BLAKE2B_PERSONALBYTES; ++i) { | ||
(P->personal)[i] = personal[i]; | ||
} | ||
return blake2b_init_param(S, P); | ||
} | ||
|
||
int new_sighash_all_blake2b(blake2b_state *S) { | ||
return ckb_blake2b_init_personal(S, 32, PERSONAL_SIGHASH_ALL); | ||
} | ||
|
||
int new_sighash_all_only_blake2b(blake2b_state *S) { | ||
return ckb_blake2b_init_personal(S, 32, PERSONAL_SIGHASH_ALL_ONLY); | ||
} | ||
|
||
int new_otx_blake2b(blake2b_state *S) { | ||
return ckb_blake2b_init_personal(S, 32, PERSONAL_OTX); | ||
} | ||
|
||
typedef int (*load_function_t)(void *, uint64_t *, size_t, size_t, size_t); | ||
#define BATCH_SIZE 1024 | ||
|
||
int streaming_hash(blake2b_state *ctx, size_t start, size_t total_len, | ||
size_t index, size_t source, load_function_t f) { | ||
int err = ERROR_GENERAL; | ||
uint8_t temp[BATCH_SIZE]; | ||
uint64_t len = BATCH_SIZE; | ||
size_t remaining_len = total_len; | ||
|
||
int ret = f(temp, &len, start, index, source); | ||
CHECK(ret); | ||
|
||
uint64_t offset = (len > BATCH_SIZE) ? BATCH_SIZE : len; | ||
if (remaining_len >= offset) { | ||
blake2b_update(ctx, temp, offset); | ||
remaining_len -= offset; | ||
} else { | ||
blake2b_update(ctx, temp, remaining_len); | ||
return CKB_SUCCESS; | ||
} | ||
|
||
while (offset < len) { | ||
uint64_t current_len = BATCH_SIZE; | ||
ret = f(temp, ¤t_len, start + offset, index, source); | ||
CHECK(err); | ||
uint64_t current_read = | ||
(current_len > BATCH_SIZE) ? BATCH_SIZE : current_len; | ||
if (remaining_len >= current_read) { | ||
blake2b_update(ctx, temp, current_read); | ||
} else { | ||
blake2b_update(ctx, temp, remaining_len); | ||
return CKB_SUCCESS; | ||
} | ||
offset += current_read; | ||
} | ||
|
||
exit: | ||
return err; | ||
} | ||
|
||
int ckb_hash_cell_data(blake2b_state *ctx, size_t index) { | ||
size_t source = CKB_SOURCE_INPUT; | ||
uint64_t cell_len = 0; | ||
int err = ckb_load_cell_data(0, &cell_len, 0, index, source); | ||
if (err) return err; | ||
uint32_t cell_len2 = (uint32_t)cell_len; | ||
// cobuild requires length = 4 | ||
blake2b_update(ctx, &cell_len2, sizeof(cell_len2)); | ||
return streaming_hash(ctx, 0, cell_len, index, source, ckb_load_cell_data); | ||
} | ||
|
||
int ckb_hash_witness(blake2b_state *ctx, size_t index) { | ||
size_t source = CKB_SOURCE_INPUT; | ||
uint64_t witness_len = 0; | ||
int err = ckb_load_witness(0, &witness_len, 0, index, source); | ||
if (err) return err; | ||
// cobuild requires length = 4 | ||
uint32_t witness_len2 = (uint32_t)witness_len; | ||
blake2b_update(ctx, &witness_len2, sizeof(witness_len2)); | ||
return streaming_hash(ctx, 0, witness_len, index, source, ckb_load_witness); | ||
} | ||
|
||
// for lock script with message, the other witness in script group except first | ||
// one should be empty | ||
int ckb_check_others_in_group() { | ||
int err = ERROR_GENERAL; | ||
for (size_t index = 1;; index++) { | ||
uint64_t witness_len = 0; | ||
err = ckb_load_witness(0, &witness_len, 0, index, CKB_SOURCE_GROUP_INPUT); | ||
if (err == CKB_INDEX_OUT_OF_BOUND) { | ||
err = CKB_SUCCESS; | ||
break; | ||
} | ||
CHECK(err); | ||
CHECK2(witness_len > 0, ERROR_NONEMPTY_WITNESS); | ||
} | ||
|
||
exit: | ||
return err; | ||
} | ||
|
||
int ckb_fetch_message(bool *has_message, size_t *index, size_t *start, | ||
size_t *len) { | ||
return 0; | ||
} | ||
|
||
static uint32_t read_from_witness(uintptr_t arg[], uint8_t *ptr, uint32_t len, | ||
uint32_t offset) { | ||
int err; | ||
uint64_t output_len = len; | ||
err = ckb_load_witness(ptr, &output_len, offset, arg[0], arg[1]); | ||
if (err != 0) { | ||
return 0; | ||
} | ||
if (output_len > len) { | ||
return len; | ||
} else { | ||
return (uint32_t)output_len; | ||
} | ||
} | ||
|
||
static uint8_t g_witness_data_source[DEFAULT_DATA_SOURCE_LENGTH]; | ||
static int make_cobuild_witness(mol2_cursor_t *witness) { | ||
int err = 0; | ||
uint64_t witness_len = 0; | ||
size_t source = CKB_SOURCE_GROUP_INPUT; | ||
err = ckb_load_witness(NULL, &witness_len, 0, 0, source); | ||
if (err != 0) { | ||
return err; | ||
} | ||
mol2_cursor_t cur; | ||
|
||
cur.offset = 0; | ||
cur.size = (uint32_t)witness_len; | ||
|
||
mol2_data_source_t *ptr = (mol2_data_source_t *)g_witness_data_source; | ||
|
||
ptr->read = read_from_witness; | ||
ptr->total_size = (uint32_t)witness_len; | ||
// pass index and source as args | ||
ptr->args[0] = 0; | ||
ptr->args[1] = source; | ||
|
||
ptr->cache_size = 0; | ||
ptr->start_point = 0; | ||
ptr->max_cache_size = MAX_CACHE_SIZE; | ||
cur.data_source = ptr; | ||
|
||
*witness = cur; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef __COBUILD_H__ | ||
#define __COBUILD_H__ | ||
|
||
#include <stdbool.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "blake2b_decl_only.h" | ||
|
||
// return a blake2b instance with personalization for SighashAll | ||
int new_sighash_all_blake2b(blake2b_state *S); | ||
|
||
// return a blake2b instance with personalization for SighashAllOnly | ||
int new_sighash_all_only_blake2b(blake2b_state *S); | ||
|
||
// return a blake2b instance with personalization for OTX | ||
int new_otx_blake2b(blake2b_state *S); | ||
|
||
// hash whole cell data with source = INPUT | ||
int ckb_hash_cell_data(blake2b_state *ctx, size_t index); | ||
// hash whole witness with source = INPUT | ||
int ckb_hash_witness(blake2b_state *ctx, size_t index); | ||
int ckb_check_others_in_group(); | ||
|
||
// fetch message from input witness. *has_message = false if it doesn't exist. | ||
// when *has_message = true, *start and *len together specify the slice in | ||
// witness with *index. | ||
int ckb_fetch_message(bool *has_message, size_t *index, size_t *start, | ||
size_t *len); | ||
#endif |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.