Esempio n. 1
0
// RecoverEncodings returns the full affine output encoding of affine-encoded f at the given position, as well as the
// input affine encodings for all neighboring bytes up to a key byte.  Returns (out, []in)
func RecoverEncodings(constr *chow.Construction, round, pos int) (encoding.ByteAffine, []encoding.ByteAffine) {
	Ps := make([]encoding.ByteAffine, 4)  // Approximate input encodings.
	Ds := make([]number.ByteFieldElem, 4) // Array of gamma * MC coefficient
	q := byte(0x00)                       // The constant part of the output encoding.

	L := RecoverL(constr, round, pos)
	Atilde := FindAtilde(constr, L)
	AtildeInv, _ := Atilde.Invert()

	for i := 0; i < 4; i++ {
		j := pos/4*4 + i

		inEnc, _ := RecoverAffineEncoded(constr, encoding.IdentityByte{}, round-1, unshiftRows(j), unshiftRows(j))
		_, f := RecoverAffineEncoded(constr, inEnc, round, j, pos)

		var c byte
		Ds[i], c, Ps[i] = FindPartialEncoding(constr, f, L, AtildeInv)
		q ^= c

		if i == 0 {
			q ^= f.Get(0x00)
		}
	}

	DInv, _ := DecomposeAffineEncoding(encoding.ByteMultiplication(FindDuplicate(Ds).Invert()))
	A := Atilde.Compose(DInv)

	return encoding.ByteAffine{encoding.ByteLinear(A), q}, Ps
}
Esempio n. 2
0
// FindPartialEncoding takes an affine encoded F and finds the values that strip its output encoding.  It returns the
// parameters it finds and the input encoding of f up to a key byte.
func FindPartialEncoding(constr *chow.Construction, f table.Byte, L, AtildeInv matrix.Matrix) (number.ByteFieldElem, byte, encoding.ByteAffine) {
	fInv := table.Invert(f)
	id := encoding.ByteLinear(matrix.GenerateIdentity(8))

	SInv := table.InvertibleTable(chow.InvTBox{saes.Construction{}, 0x00, 0x00})
	S := table.Invert(SInv)

	// Brute force the constant part of the output encoding and the beta in Atilde = A_i <- D(beta)
	for c := 0; c < 256; c++ {
		for d := 1; d < 256; d++ {
			cand := encoding.ComposedBytes{
				TableAsEncoding{f, fInv},
				encoding.ByteAffine{id, byte(c)},
				encoding.ByteLinear(AtildeInv),
				encoding.ByteMultiplication(byte(d)), // D below
				TableAsEncoding{SInv, S},
			}

			if isAffine(cand) {
				a, b := DecomposeAffineEncoding(cand)
				return number.ByteFieldElem(d), byte(c), encoding.ByteAffine{encoding.ByteLinear(a), byte(b)}
			}
		}
	}

	panic("Failed to strip output encodings!")
}
Esempio n. 3
0
// FindAtilde calculates a non-trivial matrix Atilde s.t. L <- Atilde = Atilde <- D(beta), where
// L = A_i <- D(beta) <- A_i^(-1)
func FindAtilde(constr *chow.Construction, L matrix.Matrix) matrix.Matrix {
	beta := CharToBeta[FindCharacteristic(L)]
	D, _ := DecomposeAffineEncoding(encoding.ByteMultiplication(beta))

	x := L.RightStretch().Add(D.LeftStretch()).NullSpace()

	m := matrix.Matrix(make([]matrix.Row, len(x)))
	for i, e := range x {
		m[i] = matrix.Row{e}
	}

	return m
}
Esempio n. 4
0
func TestFindAtilde(t *testing.T) {
	fastConstr := fastTestConstruction()

	L := RecoverL(fastConstr, 1, 0)
	Atilde := FindAtilde(fastConstr, L)

	beta := CharToBeta[FindCharacteristic(L)]
	D, _ := DecomposeAffineEncoding(encoding.ByteMultiplication(beta))

	left, right := L.Compose(Atilde), Atilde.Compose(D)

	for i, _ := range left {
		if len(left[i]) != 1 || len(right[i]) != 1 || left[i][0] != right[i][0] {
			t.Fatalf("L * Atilde != Atilde * D(beta)!\nL = %x\nR = %x\n", left, right)
		}
	}
}
Esempio n. 5
0
func TestRecoverL(t *testing.T) {
	MC := [][]number.ByteFieldElem{
		[]number.ByteFieldElem{0x02, 0x01, 0x01, 0x03},
		[]number.ByteFieldElem{0x03, 0x02, 0x01, 0x01},
	}

	constr, _ := testConstruction()
	fastConstr := fastTestConstruction()

	for i := 0; i < 16; i++ {
		L := RecoverL(fastConstr, 1, i)

		outAff := getOutputAffineEncoding(constr, fastConstr, 1, i)

		// L is supposed to equal A_i <- D(beta) <- A_i^(-1)
		// We strip the conjugation by A_i and check that D(beta) is multiplication by an element of GF(2^8).
		DEnc := encoding.ComposedBytes{
			outAff,
			encoding.ByteLinear(L),
			encoding.InverseByte{outAff},
		}
		D, _ := DecomposeAffineEncoding(DEnc)
		Dstr := fmt.Sprintf("%x", D)

		// Calculate what beta should be.
		pos0, pos1 := i%4, (i+1)%4
		beta := MC[0][pos0].Mul(MC[1][pos1]).Mul(MC[0][pos1].Mul(MC[1][pos0]).Invert())

		// Calculate the matrix of multiplication by beta and check that it equals what we derived in D.
		E, _ := DecomposeAffineEncoding(encoding.ByteMultiplication(beta))
		Estr := fmt.Sprintf("%x", E)

		if Dstr != Estr {
			t.Fatalf("A_i^(-1) * L * A_i doesn't equal D(beta)! i = %v\nL = %2.2x\nD = %2.2x\nE = %2.2x\n", i, L, D, E)
		}
	}
}