package keccak import ( "encoding/binary" "fmt" "math" ) func bytesToU64(v []byte) uint64 { return uint64(v[0]) | uint64(v[1])<<8 | uint64(v[2])<<16 | uint64(v[3])<<24 | uint64(v[4])<<32 | uint64(v[5])<<40 | uint64(v[6])<<48 | uint64(v[7])<<56 } func u64ToBytes(x uint64) []byte { v := make([]byte, 8) v[0] = byte(x) v[1] = byte(x >> 8) v[2] = byte(x >> 16) v[3] = byte(x >> 24) v[4] = byte(x >> 32) v[5] = byte(x >> 40) v[6] = byte(x >> 48) v[7] = byte(x >> 56) return v } func bitsToU64Array(b []bool) []uint64 { r := make([]uint64, len(b)/64) for i := 0; i < len(b)/64; i++ { r[i] = bitsToU64(b[i*64 : i*64+64]) } return r } func u64ArrayToBits(u []uint64) []bool { r := make([]bool, len(u)*64) for i := 0; i < len(u); i++ { copy(r[i*64:i*64+64], u64ToBits(u[i])) } return r } func bitsToU64(b []bool) uint64 { if len(b) != 64 { panic(fmt.Errorf("len(b)=%d, max=64", len(b))) } by := bitsToBytes(b) return binary.LittleEndian.Uint64(by) } func u64ToBits(u uint64) []bool { by := u64ToBytes(u) return bytesToBits(by) } func byteToBits(b byte) []bool { var bits []bool for j := 0; j < 8; j++ { bits = append(bits, b&(1< 0) } return bits } func bytesToBits(b []byte) []bool { var bits []bool for i := 0; i < len(b); i++ { for j := 0; j < 8; j++ { bits = append(bits, b[i]&(1< 0) } } return bits } func bitsToBytes(bits []bool) []byte { bytesLen := int(math.Ceil(float64(len(bits)) / 8)) b := make([]byte, bytesLen) for i := 0; i < len(bits); i++ { if bits[i] { b[i/8] |= 1 << (i % 8) } } return b } func leftShift(a []bool, n int) []bool { c := make([]bool, len(a)) copy(c[n:], a[:]) // c[0] = a[0] // for i := 1; i < len(a); i++ { // if i < n { // c[i] = a[i] // } else { // c[i] = a[i-1] // } // } return c } func rightShift(a []bool, n int) []bool { c := make([]bool, len(a)) copy(c[:], a[n:]) // for i := len(a) - 1 - n; i >= 0; i-- { // c[i] = a[i+1] // } return c } // TODO add unit tests func xorSingle(a []bool) []bool { c := make([]bool, len(a)) for i := 0; i < len(a); i++ { c[i] = !a[i] } return c } func xor(a, b []bool) []bool { c := make([]bool, len(a)) for i := 0; i < len(a); i++ { if a[i] != b[i] { // XOR c[i] = true } } return c } func or(a, b []bool) []bool { c := make([]bool, len(a)) for i := 0; i < len(a); i++ { if a[i] == false && b[i] == false { // OR c[i] = false } else { c[i] = true } } return c } func and(a, b []bool) []bool { c := make([]bool, len(a)) for i := 0; i < len(a); i++ { if a[i] == true && b[i] == true { c[i] = true } } return c }