arnaucube
arnaucube/keccak256-circomPublic Self-hosted repository
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 byteToBits(b byte) []bool {
 58	var bits []bool
 59	for j := 0; j < 8; j++ {
 60		bits = append(bits, b&(1<<j) > 0)
 61	}
 62	return bits
 63}
 64func bytesToBits(b []byte) []bool {
 65	var bits []bool
 66	for i := 0; i < len(b); i++ {
 67		for j := 0; j < 8; j++ {
 68			bits = append(bits, b[i]&(1<<j) > 0)
 69		}
 70	}
 71	return bits
 72}
 73func bitsToBytes(bits []bool) []byte {
 74	bytesLen := int(math.Ceil(float64(len(bits)) / 8))
 75	b := make([]byte, bytesLen)
 76	for i := 0; i < len(bits); i++ {
 77		if bits[i] {
 78			b[i/8] |= 1 << (i % 8)
 79		}
 80	}
 81	return b
 82}
 83
 84func leftShift(a []bool, n int) []bool {
 85	c := make([]bool, len(a))
 86	copy(c[n:], a[:])
 87	// c[0] = a[0]
 88	// for i := 1; i < len(a); i++ {
 89	//         if i < n {
 90	//                 c[i] = a[i]
 91	//         } else {
 92	//                 c[i] = a[i-1]
 93	//         }
 94	// }
 95	return c
 96}
 97
 98func rightShift(a []bool, n int) []bool {
 99	c := make([]bool, len(a))
100	copy(c[:], a[n:])
101	// for i := len(a) - 1 - n; i >= 0; i-- {
102	//         c[i] = a[i+1]
103	// }
104	return c
105}
106
107// TODO add unit tests
108func xorSingle(a []bool) []bool {
109	c := make([]bool, len(a))
110	for i := 0; i < len(a); i++ {
111		c[i] = !a[i]
112	}
113	return c
114}
115func xor(a, b []bool) []bool {
116	c := make([]bool, len(a))
117	for i := 0; i < len(a); i++ {
118		if a[i] != b[i] { // XOR
119			c[i] = true
120		}
121	}
122	return c
123}
124func or(a, b []bool) []bool {
125	c := make([]bool, len(a))
126	for i := 0; i < len(a); i++ {
127		if a[i] == false && b[i] == false { // OR
128			c[i] = false
129		} else {
130			c[i] = true
131		}
132	}
133	return c
134}
135func and(a, b []bool) []bool {
136	c := make([]bool, len(a))
137	for i := 0; i < len(a); i++ {
138		if a[i] == true && b[i] == true {
139			c[i] = true
140		}
141	}
142	return c
143}