136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
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]
|
|
}
|