func main() { flag.Parse() block, err := hex.DecodeString(*hexBlock) if err != nil { log.Println(err) flag.PrintDefaults() return } else if len(block) != 16 { log.Println("Block must be 128 bits.") flag.PrintDefaults() return } // Read key from disk and parse it. data, err := ioutil.ReadFile("./constr.key") if err != nil { log.Fatal(err) } else if len(data) != keySize { log.Fatalf("key wrong size: %v (should be %v)", len(data), keySize) } var key []byte inputLinear, outputLinear := matrix.Matrix{}, matrix.Matrix{} inputConst, outputConst := [16]byte{}, [16]byte{} key, data = data[:16], data[16:] for i := 0; i < 128; i++ { inputLinear, data = append(inputLinear, data[:16]), data[16:] } copy(inputConst[:], data) data = data[16:] for i := 0; i < 128; i++ { outputLinear, data = append(outputLinear, data[:16]), data[16:] } copy(outputConst[:], data) inputMask := encoding.NewBlockAffine(inputLinear, inputConst) outputMask := encoding.NewBlockAffine(outputLinear, outputConst) // Decrypt block and print as hex. temp := [16]byte{} copy(temp[:], block) temp = outputMask.Decode(temp) c, err := aes.NewCipher(key) if err != nil { log.Fatal(err) } c.Decrypt(temp[:], temp[:]) temp = inputMask.Decode(temp) fmt.Printf("%x\n", temp) }
// generateAffineMasks creates the random external masks for the construction. func generateAffineMasks(rs *random.Source) (inputMask, outputMask encoding.BlockAffine) { var inputLinear, outputLinear matrix.Matrix common.GenerateMasks(rs, common.IndependentMasks{common.RandomMask, common.RandomMask}, &inputLinear, &outputLinear) reader := rs.Stream(make([]byte, 16)) var inputConstant, outputConstant [16]byte reader.Read(inputConstant[:]) reader.Read(outputConstant[:]) inputMask = encoding.NewBlockAffine(inputLinear, inputConstant) outputMask = encoding.NewBlockAffine(outputLinear, outputConstant) return }
// Parse parses a byte array into a white-box construction. It returns an error if the byte slice isn't long enough. func Parse(in []byte) (constr Construction, err error) { if len(in) != fullSize { err = errors.New("Parsing the key failed.") return } for round := 0; round < 11; round++ { forwards := matrix.Matrix{} constant := [16]byte{} for row := 0; row < 128; row++ { forwards = append(forwards, matrix.Row(in[:16])) in = in[16:] } copy(constant[:], in[:16]) in = in[16:] constr[round] = encoding.NewBlockAffine(forwards, constant) } return }