summaryrefslogtreecommitdiff
path: root/src/blk128.c
blob: 8e27773b1d31d7613904bdbf5c0ee0520dd506ae (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "blk128.h"
#include "blk256.h"

int blk128_cmp(blk128_t *x, blk128_t *y)
{
	if (x->hi != y->hi)
		return x->hi < y->hi ? -1 : 1;
	if (x->lo != y->lo)
		return x->lo < y->lo ? -1 : 1;
	return 0;
}

void blk128_add(blk128_t *rop, blk128_t *op1, blk128_t *op2)
{
	rop->hi = op1->hi + op2->hi;
	rop->lo = op1->lo + op2->lo;
	if (rop->lo < op2->lo)
		rop->hi++;
}

void blk128_sub(blk128_t *rop, blk128_t *op1, blk128_t *op2)
{
	rop->lo = op1->lo - op2->lo;
	rop->hi = op1->hi - op2->hi;
	if (rop->lo > op2->lo)
		rop->hi--;
}

void blk128_inc(blk128_t *i)
{
	if (!++i->lo)
		++i->hi;
}

void blk128_inc3(blk128_t *x)
{
	if ((x->lo += 3) < 3)
		x->hi++;
}

void blk128_dec3(blk128_t *x)
{
	if (x->lo < 3)
		x->hi--;
	x->lo -= 3;
}

void blk128_mul(blk256_t *rop, blk128_t *x, blk128_t *y)
{
	/**
	 * Result
	 */
	uint32_t w[8] = {0, 0, 0, 0, 0, 0, 0, 0};

	/**
	 * Represent ops as four 32-bit numbers
	 */
	uint32_t xt[4] = {lo(x->lo), hi(x->lo), lo(x->hi), hi(x->hi)};
	uint32_t yt[4] = {lo(y->lo), hi(y->lo), lo(y->hi), hi(y->hi)};

	int i, j;
	uint32_t c;
	uint64_t t;
	for (i=0; i<4; i++) {
		c = 0;
		for (j=0; j<4; j++) {
			t = w[i+j] + u64(xt[i]) * u64(yt[j]) + c;
			w[i+j] = lo(t);
			c = hi(t);
		}
		w[i+4] = c;
	}
	blk256_set(rop, 0,
		u64(w[7]) << 32 | u64(w[6]),
		u64(w[5]) << 32 | u64(w[4]),
		u64(w[3]) << 32 | u64(w[2]),
		u64(w[1]) << 32 | u64(w[0])
	);
}