keccak256-circom/go-keccak256-bits-impl/utils.go
go-keccak256-bits-impl/utils.goRaw
1package keccak
2
3import (
4 "encoding/binary"
5 "fmt"
6 "math"
7)
8
9func bytesToU64(v []byte) uint64 {
10 return uint64(v[0]) |
11 uint64(v[1])<<8 |
12 uint64(v[2])<<16 |
13 uint64(v[3])<<24 |
14 uint64(v[4])<<32 |
15 uint64(v[5])<<40 |
16 uint64(v[6])<<48 |
17 uint64(v[7])<<56
18}
19func u64ToBytes(x uint64) []byte {
20 v := make([]byte, 8)
21 v[0] = byte(x)
22 v[1] = byte(x >> 8)
23 v[2] = byte(x >> 16)
24 v[3] = byte(x >> 24)
25 v[4] = byte(x >> 32)
26 v[5] = byte(x >> 40)
27 v[6] = byte(x >> 48)
28 v[7] = byte(x >> 56)
29 return v
30}
31
32func bitsToU64Array(b []bool) []uint64 {
33 r := make([]uint64, len(b)/64)
34 for i := 0; i < len(b)/64; i++ {
35 r[i] = bitsToU64(b[i*64 : i*64+64])
36 }
37 return r
38}
39func u64ArrayToBits(u []uint64) []bool {
40 r := make([]bool, len(u)*64)
41 for i := 0; i < len(u); i++ {
42 copy(r[i*64:i*64+64], u64ToBits(u[i]))
43 }
44 return r
45}
46func bitsToU64(b []bool) uint64 {
47 if len(b) != 64 {
48 panic(fmt.Errorf("len(b)=%d, max=64", len(b)))
49 }
50 by := bitsToBytes(b)
51 return binary.LittleEndian.Uint64(by)
52}
53func u64ToBits(u uint64) []bool {
54 by := u64ToBytes(u)
55 return bytesToBits(by)
56}
57func bytesToBits(b []byte) []bool {
58 var bits []bool
59 for i := 0; i < len(b); i++ {
60 for j := 0; j < 8; j++ {
61 bits = append(bits, b[i]&(1<<j) > 0)
62 }
63 }
64 return bits
65}
66func bitsToBytes(bits []bool) []byte {
67 bytesLen := int(math.Ceil(float64(len(bits)) / 8))
68 b := make([]byte, bytesLen)
69 for i := 0; i < len(bits); i++ {
70 if bits[i] {
71 b[i/8] |= 1 << (i % 8)
72 }
73 }
74 return b
75}
76
77func leftShift(a []bool, n int) []bool {
78 c := make([]bool, len(a))
79 copy(c[n:], a[:])
80 // c[0] = a[0]
81 // for i := 1; i < len(a); i++ {
82 // if i < n {
83 // c[i] = a[i]
84 // } else {
85 // c[i] = a[i-1]
86 // }
87 // }
88 return c
89}
90
91func rightShift(a []bool, n int) []bool {
92 c := make([]bool, len(a))
93 copy(c[:], a[n:])
94 // for i := len(a) - 1 - n; i >= 0; i-- {
95 // c[i] = a[i+1]
96 // }
97 return c
98}
99
100// TODO add unit tests
101func xorSingle(a []bool) []bool {
102 c := make([]bool, len(a))
103 for i := 0; i < len(a); i++ {
104 c[i] = !a[i]
105 }
106 return c
107}
108func xor(a, b []bool) []bool {
109 c := make([]bool, len(a))
110 for i := 0; i < len(a); i++ {
111 if a[i] != b[i] { // XOR
112 c[i] = true
113 }
114 }
115 return c
116}
117func or(a, b []bool) []bool {
118 c := make([]bool, len(a))
119 for i := 0; i < len(a); i++ {
120 if a[i] == false && b[i] == false { // OR
121 c[i] = false
122 } else {
123 c[i] = true
124 }
125 }
126 return c
127}
128func and(a, b []bool) []bool {
129 c := make([]bool, len(a))
130 for i := 0; i < len(a); i++ {
131 if a[i] == true && b[i] == true {
132 c[i] = true
133 }
134 }
135 return c
136}