commit 8cb4e6f3311178f0099f637ac1e2eb69a92987d1
parent 70fb50ba8ea67b45281813d6a3effb22fd2a4464
Author: William Casarin <jb55@jb55.com>
Date: Mon, 3 Jun 2019 10:27:38 -0700
some initial hashing stuff
Diffstat:
8 files changed, 69 insertions(+), 37 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,6 +7,9 @@ DEPS=script.c \
val.c \
alloc.c \
script_num.c \
+ sha256.c \
+ ripemd160.c \
+ compiler.c \
stack.c
CLIDEPS=parser.tab.c \
@@ -65,7 +68,7 @@ $(BIN): $(OBJS) $(CLIOBJS)
run_tests: $(OBJS) $(TESTOBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(TESTOBJS)
-test: run_tests $(BIN)
+check: run_tests $(BIN)
@./run_tests
clean:
diff --git a/alloc.c b/alloc.c
@@ -84,7 +84,7 @@ byte_pool_get(int ind, u32 *len) {
u32 *up;
vp = g_arenas.bytes_map.bottom + ind;
p = (u8*)(*vp);
- assert((g_arenas.bytes_top - g_arenas.bytes + *len) <= g_arenas.nbytes);
+ //assert((g_arenas.bytes_top - g_arenas.bytes + *len) <= g_arenas.nbytes);
assert(p);
up = (u32*)p;
*len = *up++;
diff --git a/consts.h b/consts.h
@@ -3,7 +3,7 @@
#define BTCS_CONSTS_H
// Maximum number of bytes pushable to the stack
-static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;
+#define MAX_SCRIPT_ELEMENT_SIZE 520
// Maximum number of non-push operations per script
static const int MAX_OPS_PER_SCRIPT = 201;
diff --git a/main.c b/main.c
@@ -51,7 +51,7 @@ int main(int argc, const char *argv[]) {
/* size = g_reader_buf_top - g_reader_buf; */
printf("script ");
script_print_vals(&g_reader_stack);
- script_serialize(&g_reader_stack, buf, bufsize, &compiled_len);
+ script_serialize_minimal(&g_reader_stack, buf, bufsize, &compiled_len);
script_eval(buf, compiled_len, &tmp_stack, &result);
printf("script_hex ");
diff --git a/script.c b/script.c
@@ -5,6 +5,8 @@
#include "stack.h"
#include "alloc.h"
#include "valstack.h"
+#include "sha256.h"
+#include "ripemd160.h"
#include <stdio.h>
/* #define SCRIPTERR(serr) script_add_error(c, opcode, serr) */
@@ -117,6 +119,7 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
const u8 *p = script;
const u8 *top = script + script_size;
static char tmpbuf[32];
+ static u8 tmpbytes[MAX_SCRIPT_ELEMENT_SIZE];
enum opcode opcode;
struct val val_true = val_from_int(1);
struct val val_false = val_from_int(0);
@@ -653,32 +656,42 @@ script_eval(const u8 *script, size_t script_size, struct stack *stack,
case OP_HASH160:
case OP_HASH256:
{
- SCRIPTERR("unhandled hash opcode");
// (in -- hash)
- /* if (stack_size(stack) < 1) */
- /* SCRIPTERR("script_err_invalid_stack_operation"); */
+ if (stack_size(stack) < 1)
+ SCRIPTERR("script_err_invalid_stack_operation");
+
+ u16 hashind;
+ u32 valsize;
+ u32 hashlen =
+ (opcode == OP_RIPEMD160 || opcode == OP_SHA1 ||
+ opcode == OP_HASH160) ? 20 : 32;
- /* u16 hashind; */
- /* u32 hashlen = */
- /* (opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) */
- /* ? 20 : 32; */
+ struct val v = stack_top_val(stack, -1);
- /* struct val val = stack_top_val(stack, -1); */
- /* struct val hash = byte_pool_new(hashlen, &hashind); */
+ val_bytes(v, &valsize, tmpbytes, sizeof(tmpbytes));
+ u8 *hash = byte_pool_new(hashlen, &hashind);
- /* if (opcode == OP_RIPEMD160) */
- /* ripemd160() */
+ if (opcode == OP_RIPEMD160) {
+ ripemd160((struct ripemd160*)hash, tmpbytes, valsize);
+ }
+ else if (opcode == OP_SHA256) {
+ sha256((struct sha256*)hash, tmpbytes, valsize);
+ }
+ else
+ SCRIPTERR("unhandled hash opcode");
/* cripemd160().write(vch.data(), vch.size()).finalize(vchhash.data()); */
/* else if (opcode == op_sha1) */
/* csha1().write(vch.data(), vch.size()).finalize(vchhash.data()); */
/* else if (opcode == op_sha256) */
/* csha256().write(vch.data(), vch.size()).finalize(vchhash.data()); */
- /* else if (opcode == op_hash160) */
- /* chash160().write(vch.data(), vch.size()).finalize(vchhash.data()); */
/* else if (opcode == op_hash256) */
/* chash256().write(vch.data(), vch.size()).finalize(vchhash.data()); */
- /* popstack(stack); */
- /* stack.push_back(vchhash); */
+
+ v.ind = hashind;
+ v.type = VT_RAW;
+
+ stack_pop(stack);
+ stack_push_val(stack, v);
}
break;
@@ -788,9 +801,9 @@ script_push_raw(struct stack *stack, const char *data) {
script_push_datastr(stack, data, 1);
}
-
-void
-script_serialize(struct stack *stack, u8 *buf, int buflen, int* len) {
+void script_serialize_(struct stack *stack, u8 *buf, int buflen,
+ int* len, int serialize_minimal)
+{
struct val *valp;
void **sp;
u8 *p = buf;
@@ -802,7 +815,8 @@ script_serialize(struct stack *stack, u8 *buf, int buflen, int* len) {
/* printf("%02x %02x %02x %02x | ", huh[0], huh[1], huh[2], huh[3]); */
/* printf("%d %d\n", val.type, val.ind); */
valp = (struct val*)sp;
- val_serialize(*valp, &valsize, p, buflen-(p-buf));
+ val_serialize(*valp, &valsize, p, buflen-(p-buf),
+ serialize_minimal);
p += valsize;
*len += valsize;
assert(p-buf <= buflen);
@@ -813,3 +827,13 @@ script_serialize(struct stack *stack, u8 *buf, int buflen, int* len) {
void
script_handle_input(struct stack *stack, const char *str) {
}
+
+void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len)
+{
+ script_serialize_(stack, buf, buflen, len, 0);
+}
+
+void script_serialize_minimal(struct stack *stack, u8 *buf, int buflen, int* len)
+{
+ script_serialize_(stack, buf, buflen, len, 1);
+}
diff --git a/script.h b/script.h
@@ -21,8 +21,8 @@ void script_push_str(struct stack *script, const char *str);
void script_push_raw(struct stack *, const char *str);
void script_push_datastr(struct stack *, const char *str, int israw);
-void
-script_serialize(struct stack *stack, u8 *buf, int buflen, int* len);
+void script_serialize(struct stack *stack, u8 *buf, int buflen, int* len);
+void script_serialize_minimal(struct stack *stack, u8 *buf, int buflen, int* len);
extern int g_silence_script_err;
extern int g_silence_script_warn;
diff --git a/val.c b/val.c
@@ -27,8 +27,15 @@ val_from_int(s64 intval) {
return val;
}
-void
-val_serialize(struct val val, u32 *len, u8 *buf, int bufsize) {
+// TODO maybe replace this with serialize
+void val_bytes(struct val val, u32 *len, u8 *buf, int bufsize) {
+ if (val.type == VT_DATA)
+ val.type = VT_RAW;
+ static const int serialize_minimal = 0;
+ val_serialize(val, len, buf, bufsize, serialize_minimal);
+}
+
+void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize, int serialize_minimal) {
struct num *sn;
int n;
u16 valsize;
@@ -37,8 +44,7 @@ val_serialize(struct val val, u32 *len, u8 *buf, int bufsize) {
sn = num_pool_get(val.ind);
assert(sn);
- /// TODO: if serialize_minimal
- if (1) {
+ if (serialize_minimal) {
if (sn->val == -1) { *len = 1; *buf = OP_1NEGATE; return; }
if (sn->val == 0 ) { *len = 1; *buf = 0; return; }
if (sn->val >= 1 && sn->val <= 16 ) {
@@ -47,10 +53,9 @@ val_serialize(struct val val, u32 *len, u8 *buf, int bufsize) {
return;
}
}
- sn_serialize(sn, buf+1, bufsize - 1, &valsize);
+ sn_serialize(sn, buf, bufsize, &valsize);
assert(valsize <= 0xFF);
- *buf = (u8)valsize;
- *len = valsize + 1;
+ *len = valsize;
return;
case VT_OP:
*len = 1;
@@ -125,8 +130,8 @@ val_eq(struct val a, struct val b, int require_minimal) {
// TODO: do I need to serialize to compare?
/* abytes = val_serialize(a, &alen, require_minimal); */
/* bbytes = val_serialize(b, &blen, require_minimal); */
- val_serialize(a, &alen, tmpa, tmpsize);
- val_serialize(b, &blen, tmpb, tmpsize);
+ val_serialize(a, &alen, tmpa, tmpsize, 0);
+ val_serialize(b, &blen, tmpb, tmpsize, 0);
// TODO: what if they're semantically equivalent? or does that matter
// (eg. minimal vs not miniminal)?
@@ -170,7 +175,7 @@ val_size(struct val val) {
switch (val.type) {
case VT_DATA: {
- u8 *data = byte_pool_get(val.ind, &len);
+ byte_pool_get(val.ind, &len);
return len;
}
default:
diff --git a/val.h b/val.h
@@ -38,8 +38,8 @@ u32 val_size(struct val val);
int
val_eq(struct val a, struct val b, int require_minimal);
-void
-val_serialize(struct val val, u32 *len, u8 *buf, int bufsize);
+void val_serialize(struct val val, u32 *len, u8 *buf, int bufsize, int serialize_minimal);
+void val_bytes(struct val val, u32 *len, u8 *buf, int bufsize);
struct val val_from_int(s64);