Skip to content

Commit a27c334

Browse files
committed
Tweak interface to have separate files for different bytearray hash sizes
1 parent f6f771d commit a27c334

File tree

6 files changed

+332
-349
lines changed

6 files changed

+332
-349
lines changed

lib/aiken/crypto/bitwise.ak

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use aiken/builtin
2+
3+
pub opaque type State<t> {
4+
inner: Int,
5+
}
6+
7+
pub const zero_intermediary = State { inner: 0 }
8+
9+
pub const one_intermediary = State { inner: 1 }
10+
11+
pub fn add_bits(scalar: Int, big_endian: Bool) {
12+
fn(intermediate: State<t>, bytes: ByteArray) -> State<t> {
13+
builtin.bytearray_to_integer(big_endian, bytes)
14+
|> builtin.add_integer(intermediate.inner)
15+
|> builtin.mod_integer(scalar)
16+
|> State
17+
}
18+
}
19+
20+
pub fn add_int(scalar: Int) {
21+
fn(intermediate: State<t>, int: Int) -> State<t> {
22+
intermediate.inner + int
23+
|> builtin.mod_integer(scalar)
24+
|> State
25+
}
26+
}
27+
28+
pub fn add_intermediary(scalar: Int) {
29+
fn(intermediate: State<t>, other: State<t>) -> State<t> {
30+
intermediate.inner + other.inner
31+
|> builtin.mod_integer(scalar)
32+
|> State
33+
}
34+
}
35+
36+
pub fn sub_bits(scalar: Int, big_endian: Bool) {
37+
fn(intermediate: State<t>, bytes: ByteArray) -> State<t> {
38+
builtin.bytearray_to_integer(big_endian, bytes)
39+
|> builtin.subtract_integer(intermediate.inner)
40+
|> builtin.mod_integer(scalar)
41+
|> State
42+
}
43+
}
44+
45+
pub fn sub_int(scalar: Int) {
46+
fn(intermediate: State<t>, int: Int) -> State<t> {
47+
intermediate.inner - int
48+
|> builtin.mod_integer(scalar)
49+
|> State
50+
}
51+
}
52+
53+
pub fn sub_intermediary(scalar: Int) {
54+
fn(intermediate: State<t>, other: State<t>) -> State<t> {
55+
intermediate.inner - other.inner
56+
|> builtin.mod_integer(scalar)
57+
|> State
58+
}
59+
}
60+
61+
pub fn mul_bits(scalar: Int, big_endian: Bool) {
62+
fn(intermediate: State<t>, bytes: ByteArray) -> State<t> {
63+
builtin.bytearray_to_integer(big_endian, bytes)
64+
|> builtin.multiply_integer(intermediate.inner)
65+
|> builtin.mod_integer(scalar)
66+
|> State
67+
}
68+
}
69+
70+
pub fn mul_int(scalar: Int) {
71+
fn(intermediate: State<t>, int: Int) -> State<t> {
72+
intermediate.inner * int
73+
|> builtin.mod_integer(scalar)
74+
|> State
75+
}
76+
}
77+
78+
pub fn mul_intermediary(scalar: Int) {
79+
fn(intermediate: State<t>, other: State<t>) -> State<t> {
80+
intermediate.inner * other.inner
81+
|> builtin.mod_integer(scalar)
82+
|> State
83+
}
84+
}
85+
86+
pub fn scale(self: State<t>, e: Int, scalar: Int) -> State<t> {
87+
if e < 0 {
88+
zero_intermediary
89+
} else if e == 0 {
90+
one_intermediary
91+
} else if e % 2 == 0 {
92+
scale(mul_intermediary(scalar)(self, self), e / 2, scalar)
93+
} else {
94+
mul_intermediary(scalar)(
95+
self,
96+
scale(mul_intermediary(scalar)(self, self), ( e - 1 ) / 2, scalar),
97+
)
98+
}
99+
}
100+
101+
/// A faster version of `scale` for the case where the exponent is a power of two.
102+
/// That is, the exponent `e = 2^k` for some non-negative integer `k`. Which is used alot in zk-SNARKs.
103+
pub fn scale2(scalar: Int) {
104+
fn(self: State<t>, k: Int) -> State<t> {
105+
if k == 0 {
106+
self
107+
} else {
108+
do_scale2(mul_intermediary(scalar)(self, self), k - 1, scalar)
109+
}
110+
}
111+
}
112+
113+
fn do_scale2(self: State<t>, k: Int, scalar) -> State<t> {
114+
if k == 0 {
115+
self
116+
} else {
117+
do_scale2(mul_intermediary(scalar)(self, self), k - 1, scalar)
118+
}
119+
}
120+
121+
pub fn neg(scalar: Int) {
122+
fn(intermediate: State<t>) -> State<t> {
123+
scalar - intermediate.inner
124+
|> State
125+
}
126+
}
127+
128+
pub fn to_int(intermediate: State<t>) -> Int {
129+
intermediate.inner
130+
}
131+
132+
pub fn from_int(int: Int, field: Int) -> State<t> {
133+
int % field
134+
|> State
135+
}

lib/aiken/crypto/int224.ak

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use aiken/builtin
2+
use aiken/crypto/bitwise.{
3+
State, add_bits as addbit, add_int as addint, mul_bits as mulbit,
4+
mul_int as mulint, neg as negbit, sub_bits as subbit, sub_int as subint,
5+
}
6+
7+
pub type Hash224 =
8+
ByteArray
9+
10+
pub const hash224_field =
11+
builtin.replicate_byte(28, 0)
12+
|> builtin.cons_bytearray(1, _)
13+
|> builtin.bytearray_to_integer(True, _)
14+
15+
pub fn to_bytes(intermediate: State<Hash224>) -> ByteArray {
16+
bitwise.to_int(intermediate)
17+
|> builtin.integer_to_bytearray(True, 28, _)
18+
}
19+
20+
pub fn to_int(intermediate: State<Hash224>) -> Int {
21+
bitwise.to_int(intermediate)
22+
}
23+
24+
pub fn from_bytes(bytes: Hash224) -> State<Hash224> {
25+
bytes
26+
|> builtin.bytearray_to_integer(True, _)
27+
|> bitwise.from_int(hash224_field)
28+
}
29+
30+
pub fn from_int(int: Int) -> State<Hash224> {
31+
bitwise.from_int(int, hash224_field)
32+
}
33+
34+
type Bitwise224Bytes =
35+
fn(State<Hash224>, ByteArray) -> State<Hash224>
36+
37+
type Bitwise224Int =
38+
fn(State<Hash224>, Int) -> State<Hash224>
39+
40+
const add_bit224: Bitwise224Bytes = addbit(hash224_field, True)
41+
42+
pub fn add_bytes(
43+
intermediate: State<Hash224>,
44+
bytes: ByteArray,
45+
) -> State<Hash224> {
46+
add_bit224(intermediate, bytes)
47+
}
48+
49+
const add_i224: Bitwise224Int = addint(hash224_field)
50+
51+
pub fn add_int(intermediate: State<Hash224>, int: Int) -> State<Hash224> {
52+
add_i224(intermediate, int)
53+
}
54+
55+
const sub_i224: Bitwise224Int = subint(hash224_field)
56+
57+
pub fn sub_int(intermediate: State<Hash224>, int: Int) -> State<Hash224> {
58+
sub_i224(intermediate, int)
59+
}
60+
61+
const sub_bit224: Bitwise224Bytes = subbit(hash224_field, True)
62+
63+
pub fn sub_bytes(
64+
intermediate: State<Hash224>,
65+
bytes: ByteArray,
66+
) -> State<Hash224> {
67+
sub_bit224(intermediate, bytes)
68+
}
69+
70+
const mul_bit224: Bitwise224Bytes = mulbit(hash224_field, True)
71+
72+
pub fn mul_bytes(
73+
intermediate: State<Hash224>,
74+
bytes: ByteArray,
75+
) -> State<Hash224> {
76+
mul_bit224(intermediate, bytes)
77+
}
78+
79+
const mul_i224: Bitwise224Int = mulint(hash224_field)
80+
81+
pub fn mul_int(intermediate: State<Hash224>, int: Int) -> State<Hash224> {
82+
mul_i224(intermediate, int)
83+
}
84+
85+
const neg224: fn(State<Hash224>) -> State<Hash224> = negbit(hash224_field)
86+
87+
pub fn neg(intermediate: State<Hash224>) -> State<Hash224> {
88+
neg224(intermediate)
89+
}

lib/aiken/crypto/int256.ak

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use aiken/builtin
2+
use aiken/crypto/bitwise.{
3+
State, add_bits as addbit, add_int as addint, mul_bits as mulbit,
4+
mul_int as mulint, neg as negbit, sub_bits as subbit, sub_int as subint,
5+
}
6+
7+
pub type Hash256 =
8+
ByteArray
9+
10+
pub const hash256_field =
11+
builtin.replicate_byte(32, 0)
12+
|> builtin.cons_bytearray(1, _)
13+
|> builtin.bytearray_to_integer(True, _)
14+
15+
pub fn to_bytes(intermediate: State<Hash256>) -> ByteArray {
16+
bitwise.to_int(intermediate)
17+
|> builtin.integer_to_bytearray(True, 32, _)
18+
}
19+
20+
pub fn to_int(intermediate: State<Hash256>) -> Int {
21+
bitwise.to_int(intermediate)
22+
}
23+
24+
pub fn from_bytes(bytes: Hash256) -> State<Hash256> {
25+
bytes
26+
|> builtin.bytearray_to_integer(True, _)
27+
|> bitwise.from_int(hash256_field)
28+
}
29+
30+
pub fn from_int(int: Int) -> State<Hash256> {
31+
bitwise.from_int(int, hash256_field)
32+
}
33+
34+
type Bitwise256Bytes =
35+
fn(State<Hash256>, ByteArray) -> State<Hash256>
36+
37+
type Bitwise256Int =
38+
fn(State<Hash256>, Int) -> State<Hash256>
39+
40+
const add_bit256: Bitwise256Bytes = addbit(hash256_field, True)
41+
42+
pub fn add_bytes(
43+
intermediate: State<Hash256>,
44+
bytes: ByteArray,
45+
) -> State<Hash256> {
46+
add_bit256(intermediate, bytes)
47+
}
48+
49+
const add_i256: Bitwise256Int = addint(hash256_field)
50+
51+
pub fn add_int(intermediate: State<Hash256>, int: Int) -> State<Hash256> {
52+
add_i256(intermediate, int)
53+
}
54+
55+
const sub_i256: Bitwise256Int = subint(hash256_field)
56+
57+
pub fn sub_int(intermediate: State<Hash256>, int: Int) -> State<Hash256> {
58+
sub_i256(intermediate, int)
59+
}
60+
61+
const sub_bit256: Bitwise256Bytes = subbit(hash256_field, True)
62+
63+
pub fn sub_bytes(
64+
intermediate: State<Hash256>,
65+
bytes: ByteArray,
66+
) -> State<Hash256> {
67+
sub_bit256(intermediate, bytes)
68+
}
69+
70+
const mul_bit256: Bitwise256Bytes = mulbit(hash256_field, True)
71+
72+
pub fn mul_bytes(
73+
intermediate: State<Hash256>,
74+
bytes: ByteArray,
75+
) -> State<Hash256> {
76+
mul_bit256(intermediate, bytes)
77+
}
78+
79+
const mul_i256: Bitwise256Int = mulint(hash256_field)
80+
81+
pub fn mul_int(intermediate: State<Hash256>, int: Int) -> State<Hash256> {
82+
mul_i256(intermediate, int)
83+
}
84+
85+
const neg256: fn(State<Hash256>) -> State<Hash256> = negbit(hash256_field)
86+
87+
pub fn neg(intermediate: State<Hash256>) -> State<Hash256> {
88+
neg256(intermediate)
89+
}

lib/aiken/math/bitwise.tests.ak renamed to lib/aiken/crypto/int256.tests.ak

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
use aiken/math/bitwise.{add_bits256, bits256_to_intermediary, to_bits256}
1+
use aiken/crypto/int256.{add_bytes, from_bytes, to_bytes}
22

33
test equal_pad_for_addition() {
44
let a: ByteArray = #"acab"
55
let b: ByteArray = #"cafe"
66

77
let x =
88
a
9-
|> bits256_to_intermediary
10-
|> add_bits256(b)
11-
|> to_bits256
9+
|> from_bytes
10+
|> add_bytes(b)
11+
|> to_bytes
1212

1313
x == #"00000000000000000000000000000000000000000000000000000000000177a9"
1414
}
@@ -19,9 +19,9 @@ test unequal_pad_for_addition() {
1919

2020
let x =
2121
a
22-
|> bits256_to_intermediary
23-
|> add_bits256(b)
24-
|> to_bits256
22+
|> from_bytes
23+
|> add_bytes(b)
24+
|> to_bytes
2525

2626
x == #"0000000000000000000000000000000000000000000000000000acabbef0c5cc"
2727
}

0 commit comments

Comments
 (0)