package experiment // return x·y func DotProd(x, y []byte) byte { var z byte for i := 0; i < len(x); i++ { z ^= x[i] & y[i] } return z } var M1 = [][]byte{ {0, 0, 1, 1, 0, 0, 1, 0}, {0, 0, 0, 1, 0, 1, 0, 0}, {1, 0, 1, 1, 1, 1, 1, 0}, {1, 0, 0, 1, 1, 1, 0, 1}, {0, 1, 0, 1, 1, 0, 0, 0}, {0, 1, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0}, {1, 0, 1, 1, 1, 0, 1, 0}, } var M2 = [][]byte{ {0, 0, 0, 1, 0, 0, 1, 0}, {0, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 1, 0}, {1, 1, 1, 0, 0, 0, 1, 0}, {1, 0, 1, 0, 0, 1, 1, 0}, {1, 0, 1, 1, 1, 0, 0, 0}, {0, 1, 0, 1, 1, 1, 0, 1}, {1, 1, 0, 0, 1, 0, 1, 1}, } var A = [][]byte{ {1, 0, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 0, 1, 1, 1}, {1, 1, 1, 0, 0, 0, 1, 1}, {1, 1, 1, 1, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 0, 0}, {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 0, 1, 1, 1, 1, 1}, } var M2A = [][]byte{ {1, 1, 0, 0, 1, 1, 1, 1}, {1, 1, 0, 1, 0, 1, 0, 1}, {0, 0, 1, 0, 1, 1, 0, 0}, {1, 0, 0, 1, 0, 1, 0, 1}, {0, 0, 1, 0, 1, 1, 1, 0}, {0, 1, 1, 0, 0, 1, 0, 1}, {1, 0, 1, 0, 1, 1, 0, 1}, {1, 0, 0, 1, 0, 0, 0, 1}, } var c = []byte{1, 1, 0, 0, 0, 1, 1, 0} var c2 = []byte{0, 0, 1, 1, 0, 1, 1, 0} var c3 = []byte{1, 1, 0, 0, 1, 0, 1, 1} func MatrixMulVector(M [][]byte, N []byte) []byte { r := make([]byte, 8) for i := 0; i < 8; i++ { r[i] = DotProd(M[i], N) } return r } func MatrixMul(M, N [][]byte) [][]byte { R := make([][]byte, 8) for i := 0; i < 8; i++ { R[i] = make([]byte, 8) } for i := 0; i < 8; i++ { for j := 0; j < 8; j++ { s := byte(0) for k := 0; k < 8; k++ { s += M[i][k] * N[k][j] } R[i][j] = s % 2 } } return R } // 8*4 func CreatTable(M [][]byte, D byte) ([]byte, []byte) { var ml, mh [16]byte for i := byte(0); i < 16; i++ { var buf = []byte{i & 1, (i >> 1) & 1, (i >> 2) & 1, (i >> 3) & 1} // ml[i] = ((DotProd(M[0][:4], buf) << 0) | (DotProd(M[1][:4], buf) << 1) | // (DotProd(M[2][:4], buf) << 2) | (DotProd(M[3][:4], buf) << 3) | // (DotProd(M[4][:4], buf) << 4) | (DotProd(M[5][:4], buf) << 5) | // (DotProd(M[6][:4], buf) << 6) | (DotProd(M[7][:4], buf) << 7)) ^ 0x0e // C1=[0, 1, 1, 1, 1, 1, 0, 0] // mh[i] = ((DotProd(M[0][4:], buf) << 0) | (DotProd(M[1][4:], buf) << 1) | // (DotProd(M[2][4:], buf) << 2) | (DotProd(M[3][4:], buf) << 3) | // (DotProd(M[4][4:], buf) << 4) | (DotProd(M[5][4:], buf) << 5) | // (DotProd(M[6][4:], buf) << 6) | (DotProd(M[7][4:], buf) << 7)) ^ 0x30 // C1=[0, 1, 1, 1, 1, 1, 0, 0] ml[i] = ((DotProd(M[0][:4], buf) << 0) | (DotProd(M[1][:4], buf) << 1) | (DotProd(M[2][:4], buf) << 2) | (DotProd(M[3][:4], buf) << 3) | (DotProd(M[4][:4], buf) << 4) | (DotProd(M[5][:4], buf) << 5) | (DotProd(M[6][:4], buf) << 6) | (DotProd(M[7][:4], buf) << 7)) ^ (D & 0xf) mh[i] = ((DotProd(M[0][4:], buf) << 0) | (DotProd(M[1][4:], buf) << 1) | (DotProd(M[2][4:], buf) << 2) | (DotProd(M[3][4:], buf) << 3) | (DotProd(M[4][4:], buf) << 4) | (DotProd(M[5][4:], buf) << 5) | (DotProd(M[6][4:], buf) << 6) | (DotProd(M[7][4:], buf) << 7)) ^ (D & 0xf0) } return ml[:], mh[:] } // return A*v in GF(2)^8 func Transform(A [][]byte, in *ffe) *ffe { r := new(ffe) for i := 0; i < 8; i++ { for j := 0; j < 8; j++ { r.v[i] += A[i][j] * in.v[j] } r.v[i] = r.v[i] % 2 } return r } func M1Transform(a byte) byte { var M1 = [][]byte{ {0, 0, 1, 1, 0, 0, 1, 0}, {0, 0, 0, 1, 0, 1, 0, 0}, {1, 0, 1, 1, 1, 1, 1, 0}, {1, 0, 0, 1, 1, 1, 0, 1}, {0, 1, 0, 1, 1, 0, 0, 0}, {0, 1, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0}, {1, 0, 1, 1, 1, 0, 1, 0}, } ml, mh := CreatTable(M1, 0x3e) return ml[a&0xf] ^ mh[a>>4] }