// StretchedKey implements BES' key schedule. It returns the 11 round keys derived from the master key. func (constr *Construction) StretchedKey() [11]gfmatrix.Row { var ( i int = 0 stretched [4 * 11]gfmatrix.Row split [11]gfmatrix.Row ) for ; i < 4; i++ { stretched[i] = constr.Key[32*i : 32*(i+1)] } for ; i < (4 * 11); i++ { temp := stretched[i-1] if (i % 4) == 0 { temp = append(temp[8:], temp[:8]...) temp = constr.subBytes(temp) temp = wordSubBytes.Mul(temp).Add(wordSubBytesConst) temp = temp.Add(Expand([]byte{powx[i/4-1], 0, 0, 0})) } stretched[i] = stretched[i-4].Add(temp) } for j := 0; j < 11; j++ { split[j] = gfmatrix.NewRow(128) for k := 0; k < 4; k++ { copy(split[j][32*k:32*(k+1)], stretched[4*j+k]) } } return split }
// subBytes rewrites each byte of the state with the S-Box. unSubBytes and subBytes are the same. func (constr *Construction) subBytes(in gfmatrix.Row) gfmatrix.Row { out := gfmatrix.NewRow(in.Size()) for pos := 0; pos < in.Size(); pos++ { out[pos] = in[pos].Invert() } return out }
// Decrypt decrypts the first block in src into dst. Dst and src may point at the same memory. func (constr Construction) Decrypt(dst, src []byte) { state := gfmatrix.NewRow(128) for pos := 0; pos < 128; pos++ { state[pos] = number.ByteFieldElem(src[pos]) } state = constr.decrypt(state) for pos := 0; pos < 128; pos++ { dst[pos] = byte(state[pos]) } }
// Expand takes a value from AES's space and embeds it in BES's space. func Expand(in []byte) gfmatrix.Row { out := gfmatrix.NewRow(8 * len(in)) for k, v := range in { num := number.ByteFieldElem(v) for pos := 0; pos < 8; pos++ { out[8*k+pos] = num num = num.Mul(num) } } return out }