module Crypto.Symmetric.AES module ST = FStar.HyperStack.ST open FStar.HyperStack.All // FIPS197 ? // TODO factor it out in terms of https://en.wikipedia.org/wiki/AES_instruction_set // see also https://software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf // TODO this is AES256; // we also need AES128 (nk=4ul, nr=10) and maybe AES192 (nk=6ul,nr=12). open FStar.Mul open FStar.Ghost open FStar.HyperStack open FStar.UInt8 open FStar.Int.Cast open FStar.Buffer (* Module abbreviations *) module HS = FStar.HyperStack module U8 = FStar.UInt8 module U32 = FStar.UInt32 module H8 = FStar.UInt8 module H32 = FStar.UInt32 type bytes = FStar.Buffer.buffer byte type lbytes l = b:bytes {length b = l} noextract let v (x:UInt32.t) : nat = UInt32.v x (* Parameters for AES-256 *) private inline_for_extraction let nb = 4ul private inline_for_extraction let nk = 8ul // 4, 6, or 8 private inline_for_extraction let nr = 14ul // 10, 12, or 14 private inline_for_extraction let blocklen = U32.(4ul *^ nb) private inline_for_extraction let keylen = U32.(4ul *^ nk) private inline_for_extraction let xkeylen = U32.(4ul *^ nb *^ (nr +^ 1ul)) // 176, 208, or 240 type block = lbytes (v blocklen) type skey = lbytes (v keylen) type xkey = lbytes (v xkeylen) type rnd = r:UInt32.t{v r <= v nr} type idx_16 = ctr:UInt32.t{v ctr <= 16} private inline_for_extraction val xtime: b:byte -> Tot byte let xtime b = (b <<^ 1ul) ^^ (((b >>^ 7ul) &^ 1uy) *%^ 0x1buy) private val multiply: a:byte -> b:byte -> Tot byte let multiply a b = ((a *%^ (b &^ 1uy)) ^^ (xtime a *%^ ((b >>^ 1ul) &^ 1uy)) ^^ (xtime (xtime a) *%^ ((b >>^ 2ul) &^ 1uy)) ^^ (xtime (xtime (xtime a)) *%^ ((b >>^ 3ul) &^ 1uy)) ^^ (xtime (xtime (xtime (xtime a))) *%^ ((b >>^ 4ul) &^ 1uy)) ^^ (xtime (xtime (xtime (xtime (xtime a)))) *%^ ((b >>^ 5ul) &^ 1uy)) ^^ (xtime (xtime (xtime (xtime (xtime (xtime a))))) *%^ ((b >>^ 6ul) &^ 1uy)) ^^ (xtime (xtime (xtime (xtime (xtime (xtime (xtime a)))))) *%^ ((b >>^ 7ul) &^ 1uy))) #set-options "--lax" // tables for S-box and inv-S-box, derived from GF256 specification. type sbox = lbytes 256 (* val mk_sbox: unit -> StackInline sbox *) (* (requires (fun _ -> True)) *) (* (ensures (fun h0 s h1 -> live h1 s /\ modifies_0 h0 h1 /\ ~(contains h0 s))) *) (* let mk_sbox () = *) (* createL [ *) (* 0x52uy, 0x09uy, 0x6auy, 0xd5uy, *) (* 0x30uy, 0x36uy, 0xa5uy, 0x38uy, *) (* 0xbfuy, 0x40uy, 0xa3uy, 0x9euy, *) (* 0x81uy, 0xf3uy, 0xd7uy, 0xfbuy, *) (* 0x7cuy, 0xe3uy, 0x39uy, 0x82uy, *) (* 0x9buy, 0x2fuy, 0xffuy, 0x87uy, *) (* 0x34uy, 0x8euy, 0x43uy, 0x44uy, *) (* 0xc4uy, 0xdeuy, 0xe9uy, 0xcbuy, *) (* 0x54uy, 0x7buy, 0x94uy, 0x32uy, *) (* 0xa6uy, 0xc2uy, 0x23uy, 0x3duy, *) (* 0xeeuy, 0x4cuy, 0x95uy, 0x0buy, *) (* 0x42uy, 0xfauy, 0xc3uy, 0x4euy, *) (* 0x08uy, 0x2euy, 0xa1uy, 0x66uy, *) (* 0x28uy, 0xd9uy, 0x24uy, 0xb2uy, *) (* 0x76uy, 0x5buy, 0xa2uy, 0x49uy, *) (* 0x6duy, 0x8buy, 0xd1uy, 0x25uy, *) (* 0x72uy, 0xf8uy, 0xf6uy, 0x64uy, *) (* 0x86uy, 0x68uy, 0x98uy, 0x16uy, *) (* 0xd4uy, 0xa4uy, 0x5cuy, 0xccuy, *) (* 0x5duy, 0x65uy, 0xb6uy, 0x92uy, *) (* 0x6cuy, 0x70uy, 0x48uy, 0x50uy, *) (* 0xfduy, 0xeduy, 0xb9uy, 0xdauy, *) (* 0x5euy, 0x15uy, 0x46uy, 0x57uy, *) (* 0xa7uy, 0x8duy, 0x9duy, 0x84uy, *) (* 0x90uy, 0xd8uy, 0xabuy, 0x00uy, *) (* 0x8cuy, 0xbcuy, 0xd3uy, 0x0auy, *) (* 0xf7uy, 0xe4uy, 0x58uy, 0x05uy, *) (* 0xb8uy, 0xb3uy, 0x45uy, 0x06uy, *) (* 0xd0uy, 0x2cuy, 0x1euy, 0x8fuy, *) (* 0xcauy, 0x3fuy, 0x0fuy, 0x02uy, *) (* 0xc1uy, 0xafuy, 0xbduy, 0x03uy, *) (* 0x01uy, 0x13uy, 0x8auy, 0x6buy, *) (* 0x3auy, 0x91uy, 0x11uy, 0x41uy, *) (* 0x4fuy, 0x67uy, 0xdcuy, 0xeauy, *) (* 0x97uy, 0xf2uy, 0xcfuy, 0xceuy, *) (* 0xf0uy, 0xb4uy, 0xe6uy, 0x73uy, *) (* 0x96uy, 0xacuy, 0x74uy, 0x22uy, *) (* 0xe7uy, 0xaduy, 0x35uy, 0x85uy, *) (* 0xe2uy, 0xf9uy, 0x37uy, 0xe8uy, *) (* 0x1cuy, 0x75uy, 0xdfuy, 0x6euy, *) (* 0x47uy, 0xf1uy, 0x1auy, 0x71uy, *) (* 0x1duy, 0x29uy, 0xc5uy, 0x89uy, *) (* 0x6fuy, 0xb7uy, 0x62uy, 0x0euy, *) (* 0xaauy, 0x18uy, 0xbeuy, 0x1buy, *) (* 0xfcuy, 0x56uy, 0x3euy, 0x4buy, *) (* 0xc6uy, 0xd2uy, 0x79uy, 0x20uy, *) (* 0x9auy, 0xdbuy, 0xc0uy, 0xfeuy, *) (* 0x78uy, 0xcduy, 0x5auy, 0xf4uy, *) (* 0x1fuy, 0xdduy, 0xa8uy, 0x33uy, *) (* 0x88uy, 0x07uy, 0xc7uy, 0x31uy, *) (* 0xb1uy, 0x12uy, 0x10uy, 0x59uy, *) (* 0x27uy, 0x80uy, 0xecuy, 0x5fuy, *) (* 0x60uy, 0x51uy, 0x7fuy, 0xa9uy, *) (* 0x19uy, 0xb5uy, 0x4auy, 0x0duy, *) (* 0x2duy, 0xe5uy, 0x7auy, 0x9fuy, *) (* 0x93uy, 0xc9uy, 0x9cuy, 0xefuy, *) (* 0xa0uy, 0xe0uy, 0x3buy, 0x4duy, *) (* 0xaeuy, 0x2auy, 0xf5uy, 0xb0uy, *) (* 0xc8uy, 0xebuy, 0xbbuy, 0x3cuy, *) (* 0x83uy, 0x53uy, 0x99uy, 0x61uy, *) (* 0x17uy, 0x2buy, 0x04uy, 0x7euy, *) (* 0xbauy, 0x77uy, 0xd6uy, 0x26uy, *) (* 0xe1uy, 0x69uy, 0x14uy, 0x63uy, *) (* 0x55uy, 0x21uy, 0x0cuy, 0x7duy *) (* ] *) (* val mk_inv_sbox: unit -> StackInline sbox *) (* (requires (fun _ -> True)) *) (* (ensures (fun h0 s h1 -> live h1 s /\ modifies_0 h0 h1 /\ ~(contains h0 s))) *) (* let mk_inv_sbox () = *) (* 0x52uy; 0x09uy; 0x6auy; 0xd5uy; *) (* 0x30uy; 0x36uy; 0xa5uy; 0x38uy; *) (* 0xbfuy; 0x40uy; 0xa3uy; 0x9euy; *) (* 0x81uy; 0xf3uy; 0xd7uy; 0xfbuy; *) (* 0x7cuy; 0xe3uy; 0x39uy; 0x82uy; *) (* 0x9buy; 0x2fuy; 0xffuy; 0x87uy; *) (* 0x34uy; 0x8euy; 0x43uy; 0x44uy; *) (* 0xc4uy; 0xdeuy; 0xe9uy; 0xcbuy; *) (* 0x54uy; 0x7buy; 0x94uy; 0x32uy; *) (* 0xa6uy; 0xc2uy; 0x23uy; 0x3duy; *) (* 0xeeuy; 0x4cuy; 0x95uy; 0x0buy; *) (* 0x42uy; 0xfauy; 0xc3uy; 0x4euy; *) (* 0x08uy; 0x2euy; 0xa1uy; 0x66uy; *) (* 0x28uy; 0xd9uy; 0x24uy; 0xb2uy; *) (* 0x76uy; 0x5buy; 0xa2uy; 0x49uy; *) (* 0x6duy; 0x8buy; 0xd1uy; 0x25uy; *) (* 0x72uy; 0xf8uy; 0xf6uy; 0x64uy; *) (* 0x86uy; 0x68uy; 0x98uy; 0x16uy; *) (* 0xd4uy; 0xa4uy; 0x5cuy; 0xccuy; *) (* 0x5duy; 0x65uy; 0xb6uy; 0x92uy; *) (* 0x6cuy; 0x70uy; 0x48uy; 0x50uy; *) (* 0xfduy; 0xeduy; 0xb9uy; 0xdauy; *) (* 0x5euy; 0x15uy; 0x46uy; 0x57uy; *) (* 0xa7uy; 0x8duy; 0x9duy; 0x84uy; *) (* 0x90uy; 0xd8uy; 0xabuy; 0x00uy; *) (* 0x8cuy; 0xbcuy; 0xd3uy; 0x0auy; *) (* 0xf7uy; 0xe4uy; 0x58uy; 0x05uy; *) (* 0xb8uy; 0xb3uy; 0x45uy; 0x06uy; *) (* 0xd0uy; 0x2cuy; 0x1euy; 0x8fuy; *) (* 0xcauy; 0x3fuy; 0x0fuy; 0x02uy; *) (* 0xc1uy; 0xafuy; 0xbduy; 0x03uy; *) (* 0x01uy; 0x13uy; 0x8auy; 0x6buy; *) (* 0x3auy; 0x91uy; 0x11uy; 0x41uy; *) (* 0x4fuy; 0x67uy; 0xdcuy; 0xeauy; *) (* 0x97uy; 0xf2uy; 0xcfuy; 0xceuy; *) (* 0xf0uy; 0xb4uy; 0xe6uy; 0x73uy; *) (* 0x96uy; 0xacuy; 0x74uy; 0x22uy; *) (* 0xe7uy; 0xaduy; 0x35uy; 0x85uy; *) (* 0xe2uy; 0xf9uy; 0x37uy; 0xe8uy; *) (* 0x1cuy; 0x75uy; 0xdfuy; 0x6euy; *) (* 0x47uy; 0xf1uy; 0x1auy; 0x71uy; *) (* 0x1duy; 0x29uy; 0xc5uy; 0x89uy; *) (* 0x6fuy; 0xb7uy; 0x62uy; 0x0euy; *) (* 0xaauy; 0x18uy; 0xbeuy; 0x1buy; *) (* 0xfcuy; 0x56uy; 0x3euy; 0x4buy; *) (* 0xc6uy; 0xd2uy; 0x79uy; 0x20uy; *) (* 0x9auy; 0xdbuy; 0xc0uy; 0xfeuy; *) (* 0x78uy; 0xcduy; 0x5auy; 0xf4uy; *) (* 0x1fuy; 0xdduy; 0xa8uy; 0x33uy; *) (* 0x88uy; 0x07uy; 0xc7uy; 0x31uy; *) (* 0xb1uy; 0x12uy; 0x10uy; 0x59uy; *) (* 0x27uy; 0x80uy; 0xecuy; 0x5fuy; *) (* 0x60uy; 0x51uy; 0x7fuy; 0xa9uy; *) (* 0x19uy; 0xb5uy; 0x4auy; 0x0duy; *) (* 0x2duy; 0xe5uy; 0x7auy; 0x9fuy; *) (* 0x93uy; 0xc9uy; 0x9cuy; 0xefuy; *) (* 0xa0uy; 0xe0uy; 0x3buy; 0x4duy; *) (* 0xaeuy; 0x2auy; 0xf5uy; 0xb0uy; *) (* 0xc8uy; 0xebuy; 0xbbuy; 0x3cuy; *) (* 0x83uy; 0x53uy; 0x99uy; 0x61uy; *) (* 0x17uy; 0x2buy; 0x04uy; 0x7euy; *) (* 0xbauy; 0x77uy; 0xd6uy; 0x26uy; *) (* 0xe1uy; 0x69uy; 0x14uy; 0x63uy; *) (* 0x55uy; 0x21uy; 0x0cuy; 0x7duy *) val mk_sbox: sb:sbox -> STL unit (requires (fun h -> live h sb)) (ensures (fun h0 _ h1 -> live h1 sb /\ modifies_1 sb h0 h1)) let mk_sbox sbox = sbox.(0ul) <- 0x63uy; sbox.(1ul) <- 0x7cuy; sbox.(2ul) <- 0x77uy; sbox.(3ul) <- 0x7buy; sbox.(4ul) <- 0xf2uy; sbox.(5ul) <- 0x6buy; sbox.(6ul) <- 0x6fuy; sbox.(7ul) <- 0xc5uy; sbox.(8ul) <- 0x30uy; sbox.(9ul) <- 0x01uy; sbox.(10ul) <- 0x67uy; sbox.(11ul) <- 0x2buy; sbox.(12ul) <- 0xfeuy; sbox.(13ul) <- 0xd7uy; sbox.(14ul) <- 0xabuy; sbox.(15ul) <- 0x76uy; sbox.(16ul) <- 0xcauy; sbox.(17ul) <- 0x82uy; sbox.(18ul) <- 0xc9uy; sbox.(19ul) <- 0x7duy; sbox.(20ul) <- 0xfauy; sbox.(21ul) <- 0x59uy; sbox.(22ul) <- 0x47uy; sbox.(23ul) <- 0xf0uy; sbox.(24ul) <- 0xaduy; sbox.(25ul) <- 0xd4uy; sbox.(26ul) <- 0xa2uy; sbox.(27ul) <- 0xafuy; sbox.(28ul) <- 0x9cuy; sbox.(29ul) <- 0xa4uy; sbox.(30ul) <- 0x72uy; sbox.(31ul) <- 0xc0uy; sbox.(32ul) <- 0xb7uy; sbox.(33ul) <- 0xfduy; sbox.(34ul) <- 0x93uy; sbox.(35ul) <- 0x26uy; sbox.(36ul) <- 0x36uy; sbox.(37ul) <- 0x3fuy; sbox.(38ul) <- 0xf7uy; sbox.(39ul) <- 0xccuy; sbox.(40ul) <- 0x34uy; sbox.(41ul) <- 0xa5uy; sbox.(42ul) <- 0xe5uy; sbox.(43ul) <- 0xf1uy; sbox.(44ul) <- 0x71uy; sbox.(45ul) <- 0xd8uy; sbox.(46ul) <- 0x31uy; sbox.(47ul) <- 0x15uy; sbox.(48ul) <- 0x04uy; sbox.(49ul) <- 0xc7uy; sbox.(50ul) <- 0x23uy; sbox.(51ul) <- 0xc3uy; sbox.(52ul) <- 0x18uy; sbox.(53ul) <- 0x96uy; sbox.(54ul) <- 0x05uy; sbox.(55ul) <- 0x9auy; sbox.(56ul) <- 0x07uy; sbox.(57ul) <- 0x12uy; sbox.(58ul) <- 0x80uy; sbox.(59ul) <- 0xe2uy; sbox.(60ul) <- 0xebuy; sbox.(61ul) <- 0x27uy; sbox.(62ul) <- 0xb2uy; sbox.(63ul) <- 0x75uy; sbox.(64ul) <- 0x09uy; sbox.(65ul) <- 0x83uy; sbox.(66ul) <- 0x2cuy; sbox.(67ul) <- 0x1auy; sbox.(68ul) <- 0x1buy; sbox.(69ul) <- 0x6euy; sbox.(70ul) <- 0x5auy; sbox.(71ul) <- 0xa0uy; sbox.(72ul) <- 0x52uy; sbox.(73ul) <- 0x3buy; sbox.(74ul) <- 0xd6uy; sbox.(75ul) <- 0xb3uy; sbox.(76ul) <- 0x29uy; sbox.(77ul) <- 0xe3uy; sbox.(78ul) <- 0x2fuy; sbox.(79ul) <- 0x84uy; sbox.(80ul) <- 0x53uy; sbox.(81ul) <- 0xd1uy; sbox.(82ul) <- 0x00uy; sbox.(83ul) <- 0xeduy; sbox.(84ul) <- 0x20uy; sbox.(85ul) <- 0xfcuy; sbox.(86ul) <- 0xb1uy; sbox.(87ul) <- 0x5buy; sbox.(88ul) <- 0x6auy; sbox.(89ul) <- 0xcbuy; sbox.(90ul) <- 0xbeuy; sbox.(91ul) <- 0x39uy; sbox.(92ul) <- 0x4auy; sbox.(93ul) <- 0x4cuy; sbox.(94ul) <- 0x58uy; sbox.(95ul) <- 0xcfuy; sbox.(96ul) <- 0xd0uy; sbox.(97ul) <- 0xefuy; sbox.(98ul) <- 0xaauy; sbox.(99ul) <- 0xfbuy; sbox.(100ul) <- 0x43uy; sbox.(101ul) <- 0x4duy; sbox.(102ul) <- 0x33uy; sbox.(103ul) <- 0x85uy; sbox.(104ul) <- 0x45uy; sbox.(105ul) <- 0xf9uy; sbox.(106ul) <- 0x02uy; sbox.(107ul) <- 0x7fuy; sbox.(108ul) <- 0x50uy; sbox.(109ul) <- 0x3cuy; sbox.(110ul) <- 0x9fuy; sbox.(111ul) <- 0xa8uy; sbox.(112ul) <- 0x51uy; sbox.(113ul) <- 0xa3uy; sbox.(114ul) <- 0x40uy; sbox.(115ul) <- 0x8fuy; sbox.(116ul) <- 0x92uy; sbox.(117ul) <- 0x9duy; sbox.(118ul) <- 0x38uy; sbox.(119ul) <- 0xf5uy; sbox.(120ul) <- 0xbcuy; sbox.(121ul) <- 0xb6uy; sbox.(122ul) <- 0xdauy; sbox.(123ul) <- 0x21uy; sbox.(124ul) <- 0x10uy; sbox.(125ul) <- 0xffuy; sbox.(126ul) <- 0xf3uy; sbox.(127ul) <- 0xd2uy; sbox.(128ul) <- 0xcduy; sbox.(129ul) <- 0x0cuy; sbox.(130ul) <- 0x13uy; sbox.(131ul) <- 0xecuy; sbox.(132ul) <- 0x5fuy; sbox.(133ul) <- 0x97uy; sbox.(134ul) <- 0x44uy; sbox.(135ul) <- 0x17uy; sbox.(136ul) <- 0xc4uy; sbox.(137ul) <- 0xa7uy; sbox.(138ul) <- 0x7euy; sbox.(139ul) <- 0x3duy; sbox.(140ul) <- 0x64uy; sbox.(141ul) <- 0x5duy; sbox.(142ul) <- 0x19uy; sbox.(143ul) <- 0x73uy; sbox.(144ul) <- 0x60uy; sbox.(145ul) <- 0x81uy; sbox.(146ul) <- 0x4fuy; sbox.(147ul) <- 0xdcuy; sbox.(148ul) <- 0x22uy; sbox.(149ul) <- 0x2auy; sbox.(150ul) <- 0x90uy; sbox.(151ul) <- 0x88uy; sbox.(152ul) <- 0x46uy; sbox.(153ul) <- 0xeeuy; sbox.(154ul) <- 0xb8uy; sbox.(155ul) <- 0x14uy; sbox.(156ul) <- 0xdeuy; sbox.(157ul) <- 0x5euy; sbox.(158ul) <- 0x0buy; sbox.(159ul) <- 0xdbuy; sbox.(160ul) <- 0xe0uy; sbox.(161ul) <- 0x32uy; sbox.(162ul) <- 0x3auy; sbox.(163ul) <- 0x0auy; sbox.(164ul) <- 0x49uy; sbox.(165ul) <- 0x06uy; sbox.(166ul) <- 0x24uy; sbox.(167ul) <- 0x5cuy; sbox.(168ul) <- 0xc2uy; sbox.(169ul) <- 0xd3uy; sbox.(170ul) <- 0xacuy; sbox.(171ul) <- 0x62uy; sbox.(172ul) <- 0x91uy; sbox.(173ul) <- 0x95uy; sbox.(174ul) <- 0xe4uy; sbox.(175ul) <- 0x79uy; sbox.(176ul) <- 0xe7uy; sbox.(177ul) <- 0xc8uy; sbox.(178ul) <- 0x37uy; sbox.(179ul) <- 0x6duy; sbox.(180ul) <- 0x8duy; sbox.(181ul) <- 0xd5uy; sbox.(182ul) <- 0x4euy; sbox.(183ul) <- 0xa9uy; sbox.(184ul) <- 0x6cuy; sbox.(185ul) <- 0x56uy; sbox.(186ul) <- 0xf4uy; sbox.(187ul) <- 0xeauy; sbox.(188ul) <- 0x65uy; sbox.(189ul) <- 0x7auy; sbox.(190ul) <- 0xaeuy; sbox.(191ul) <- 0x08uy; sbox.(192ul) <- 0xbauy; sbox.(193ul) <- 0x78uy; sbox.(194ul) <- 0x25uy; sbox.(195ul) <- 0x2euy; sbox.(196ul) <- 0x1cuy; sbox.(197ul) <- 0xa6uy; sbox.(198ul) <- 0xb4uy; sbox.(199ul) <- 0xc6uy; sbox.(200ul) <- 0xe8uy; sbox.(201ul) <- 0xdduy; sbox.(202ul) <- 0x74uy; sbox.(203ul) <- 0x1fuy; sbox.(204ul) <- 0x4buy; sbox.(205ul) <- 0xbduy; sbox.(206ul) <- 0x8buy; sbox.(207ul) <- 0x8auy; sbox.(208ul) <- 0x70uy; sbox.(209ul) <- 0x3euy; sbox.(210ul) <- 0xb5uy; sbox.(211ul) <- 0x66uy; sbox.(212ul) <- 0x48uy; sbox.(213ul) <- 0x03uy; sbox.(214ul) <- 0xf6uy; sbox.(215ul) <- 0x0euy; sbox.(216ul) <- 0x61uy; sbox.(217ul) <- 0x35uy; sbox.(218ul) <- 0x57uy; sbox.(219ul) <- 0xb9uy; sbox.(220ul) <- 0x86uy; sbox.(221ul) <- 0xc1uy; sbox.(222ul) <- 0x1duy; sbox.(223ul) <- 0x9euy; sbox.(224ul) <- 0xe1uy; sbox.(225ul) <- 0xf8uy; sbox.(226ul) <- 0x98uy; sbox.(227ul) <- 0x11uy; sbox.(228ul) <- 0x69uy; sbox.(229ul) <- 0xd9uy; sbox.(230ul) <- 0x8euy; sbox.(231ul) <- 0x94uy; sbox.(232ul) <- 0x9buy; sbox.(233ul) <- 0x1euy; sbox.(234ul) <- 0x87uy; sbox.(235ul) <- 0xe9uy; sbox.(236ul) <- 0xceuy; sbox.(237ul) <- 0x55uy; sbox.(238ul) <- 0x28uy; sbox.(239ul) <- 0xdfuy; sbox.(240ul) <- 0x8cuy; sbox.(241ul) <- 0xa1uy; sbox.(242ul) <- 0x89uy; sbox.(243ul) <- 0x0duy; sbox.(244ul) <- 0xbfuy; sbox.(245ul) <- 0xe6uy; sbox.(246ul) <- 0x42uy; sbox.(247ul) <- 0x68uy; sbox.(248ul) <- 0x41uy; sbox.(249ul) <- 0x99uy; sbox.(250ul) <- 0x2duy; sbox.(251ul) <- 0x0fuy; sbox.(252ul) <- 0xb0uy; sbox.(253ul) <- 0x54uy; sbox.(254ul) <- 0xbbuy; sbox.(255ul) <- 0x16uy val mk_inv_sbox: sb:sbox -> STL unit (requires (fun h -> live h sb)) (ensures (fun h0 _ h1 -> live h1 sb /\ modifies_1 sb h0 h1)) let mk_inv_sbox sbox = sbox.(0ul) <- 0x52uy; sbox.(1ul) <- 0x09uy; sbox.(2ul) <- 0x6auy; sbox.(3ul) <- 0xd5uy; sbox.(4ul) <- 0x30uy; sbox.(5ul) <- 0x36uy; sbox.(6ul) <- 0xa5uy; sbox.(7ul) <- 0x38uy; sbox.(8ul) <- 0xbfuy; sbox.(9ul) <- 0x40uy; sbox.(10ul) <- 0xa3uy; sbox.(11ul) <- 0x9euy; sbox.(12ul) <- 0x81uy; sbox.(13ul) <- 0xf3uy; sbox.(14ul) <- 0xd7uy; sbox.(15ul) <- 0xfbuy; sbox.(16ul) <- 0x7cuy; sbox.(17ul) <- 0xe3uy; sbox.(18ul) <- 0x39uy; sbox.(19ul) <- 0x82uy; sbox.(20ul) <- 0x9buy; sbox.(21ul) <- 0x2fuy; sbox.(22ul) <- 0xffuy; sbox.(23ul) <- 0x87uy; sbox.(24ul) <- 0x34uy; sbox.(25ul) <- 0x8euy; sbox.(26ul) <- 0x43uy; sbox.(27ul) <- 0x44uy; sbox.(28ul) <- 0xc4uy; sbox.(29ul) <- 0xdeuy; sbox.(30ul) <- 0xe9uy; sbox.(31ul) <- 0xcbuy; sbox.(32ul) <- 0x54uy; sbox.(33ul) <- 0x7buy; sbox.(34ul) <- 0x94uy; sbox.(35ul) <- 0x32uy; sbox.(36ul) <- 0xa6uy; sbox.(37ul) <- 0xc2uy; sbox.(38ul) <- 0x23uy; sbox.(39ul) <- 0x3duy; sbox.(40ul) <- 0xeeuy; sbox.(41ul) <- 0x4cuy; sbox.(42ul) <- 0x95uy; sbox.(43ul) <- 0x0buy; sbox.(44ul) <- 0x42uy; sbox.(45ul) <- 0xfauy; sbox.(46ul) <- 0xc3uy; sbox.(47ul) <- 0x4euy; sbox.(48ul) <- 0x08uy; sbox.(49ul) <- 0x2euy; sbox.(50ul) <- 0xa1uy; sbox.(51ul) <- 0x66uy; sbox.(52ul) <- 0x28uy; sbox.(53ul) <- 0xd9uy; sbox.(54ul) <- 0x24uy; sbox.(55ul) <- 0xb2uy; sbox.(56ul) <- 0x76uy; sbox.(57ul) <- 0x5buy; sbox.(58ul) <- 0xa2uy; sbox.(59ul) <- 0x49uy; sbox.(60ul) <- 0x6duy; sbox.(61ul) <- 0x8buy; sbox.(62ul) <- 0xd1uy; sbox.(63ul) <- 0x25uy; sbox.(64ul) <- 0x72uy; sbox.(65ul) <- 0xf8uy; sbox.(66ul) <- 0xf6uy; sbox.(67ul) <- 0x64uy; sbox.(68ul) <- 0x86uy; sbox.(69ul) <- 0x68uy; sbox.(70ul) <- 0x98uy; sbox.(71ul) <- 0x16uy; sbox.(72ul) <- 0xd4uy; sbox.(73ul) <- 0xa4uy; sbox.(74ul) <- 0x5cuy; sbox.(75ul) <- 0xccuy; sbox.(76ul) <- 0x5duy; sbox.(77ul) <- 0x65uy; sbox.(78ul) <- 0xb6uy; sbox.(79ul) <- 0x92uy; sbox.(80ul) <- 0x6cuy; sbox.(81ul) <- 0x70uy; sbox.(82ul) <- 0x48uy; sbox.(83ul) <- 0x50uy; sbox.(84ul) <- 0xfduy; sbox.(85ul) <- 0xeduy; sbox.(86ul) <- 0xb9uy; sbox.(87ul) <- 0xdauy; sbox.(88ul) <- 0x5euy; sbox.(89ul) <- 0x15uy; sbox.(90ul) <- 0x46uy; sbox.(91ul) <- 0x57uy; sbox.(92ul) <- 0xa7uy; sbox.(93ul) <- 0x8duy; sbox.(94ul) <- 0x9duy; sbox.(95ul) <- 0x84uy; sbox.(96ul) <- 0x90uy; sbox.(97ul) <- 0xd8uy; sbox.(98ul) <- 0xabuy; sbox.(99ul) <- 0x00uy; sbox.(100ul) <- 0x8cuy; sbox.(101ul) <- 0xbcuy; sbox.(102ul) <- 0xd3uy; sbox.(103ul) <- 0x0auy; sbox.(104ul) <- 0xf7uy; sbox.(105ul) <- 0xe4uy; sbox.(106ul) <- 0x58uy; sbox.(107ul) <- 0x05uy; sbox.(108ul) <- 0xb8uy; sbox.(109ul) <- 0xb3uy; sbox.(110ul) <- 0x45uy; sbox.(111ul) <- 0x06uy; sbox.(112ul) <- 0xd0uy; sbox.(113ul) <- 0x2cuy; sbox.(114ul) <- 0x1euy; sbox.(115ul) <- 0x8fuy; sbox.(116ul) <- 0xcauy; sbox.(117ul) <- 0x3fuy; sbox.(118ul) <- 0x0fuy; sbox.(119ul) <- 0x02uy; sbox.(120ul) <- 0xc1uy; sbox.(121ul) <- 0xafuy; sbox.(122ul) <- 0xbduy; sbox.(123ul) <- 0x03uy; sbox.(124ul) <- 0x01uy; sbox.(125ul) <- 0x13uy; sbox.(126ul) <- 0x8auy; sbox.(127ul) <- 0x6buy; sbox.(128ul) <- 0x3auy; sbox.(129ul) <- 0x91uy; sbox.(130ul) <- 0x11uy; sbox.(131ul) <- 0x41uy; sbox.(132ul) <- 0x4fuy; sbox.(133ul) <- 0x67uy; sbox.(134ul) <- 0xdcuy; sbox.(135ul) <- 0xeauy; sbox.(136ul) <- 0x97uy; sbox.(137ul) <- 0xf2uy; sbox.(138ul) <- 0xcfuy; sbox.(139ul) <- 0xceuy; sbox.(140ul) <- 0xf0uy; sbox.(141ul) <- 0xb4uy; sbox.(142ul) <- 0xe6uy; sbox.(143ul) <- 0x73uy; sbox.(144ul) <- 0x96uy; sbox.(145ul) <- 0xacuy; sbox.(146ul) <- 0x74uy; sbox.(147ul) <- 0x22uy; sbox.(148ul) <- 0xe7uy; sbox.(149ul) <- 0xaduy; sbox.(150ul) <- 0x35uy; sbox.(151ul) <- 0x85uy; sbox.(152ul) <- 0xe2uy; sbox.(153ul) <- 0xf9uy; sbox.(154ul) <- 0x37uy; sbox.(155ul) <- 0xe8uy; sbox.(156ul) <- 0x1cuy; sbox.(157ul) <- 0x75uy; sbox.(158ul) <- 0xdfuy; sbox.(159ul) <- 0x6euy; sbox.(160ul) <- 0x47uy; sbox.(161ul) <- 0xf1uy; sbox.(162ul) <- 0x1auy; sbox.(163ul) <- 0x71uy; sbox.(164ul) <- 0x1duy; sbox.(165ul) <- 0x29uy; sbox.(166ul) <- 0xc5uy; sbox.(167ul) <- 0x89uy; sbox.(168ul) <- 0x6fuy; sbox.(169ul) <- 0xb7uy; sbox.(170ul) <- 0x62uy; sbox.(171ul) <- 0x0euy; sbox.(172ul) <- 0xaauy; sbox.(173ul) <- 0x18uy; sbox.(174ul) <- 0xbeuy; sbox.(175ul) <- 0x1buy; sbox.(176ul) <- 0xfcuy; sbox.(177ul) <- 0x56uy; sbox.(178ul) <- 0x3euy; sbox.(179ul) <- 0x4buy; sbox.(180ul) <- 0xc6uy; sbox.(181ul) <- 0xd2uy; sbox.(182ul) <- 0x79uy; sbox.(183ul) <- 0x20uy; sbox.(184ul) <- 0x9auy; sbox.(185ul) <- 0xdbuy; sbox.(186ul) <- 0xc0uy; sbox.(187ul) <- 0xfeuy; sbox.(188ul) <- 0x78uy; sbox.(189ul) <- 0xcduy; sbox.(190ul) <- 0x5auy; sbox.(191ul) <- 0xf4uy; sbox.(192ul) <- 0x1fuy; sbox.(193ul) <- 0xdduy; sbox.(194ul) <- 0xa8uy; sbox.(195ul) <- 0x33uy; sbox.(196ul) <- 0x88uy; sbox.(197ul) <- 0x07uy; sbox.(198ul) <- 0xc7uy; sbox.(199ul) <- 0x31uy; sbox.(200ul) <- 0xb1uy; sbox.(201ul) <- 0x12uy; sbox.(202ul) <- 0x10uy; sbox.(203ul) <- 0x59uy; sbox.(204ul) <- 0x27uy; sbox.(205ul) <- 0x80uy; sbox.(206ul) <- 0xecuy; sbox.(207ul) <- 0x5fuy; sbox.(208ul) <- 0x60uy; sbox.(209ul) <- 0x51uy; sbox.(210ul) <- 0x7fuy; sbox.(211ul) <- 0xa9uy; sbox.(212ul) <- 0x19uy; sbox.(213ul) <- 0xb5uy; sbox.(214ul) <- 0x4auy; sbox.(215ul) <- 0x0duy; sbox.(216ul) <- 0x2duy; sbox.(217ul) <- 0xe5uy; sbox.(218ul) <- 0x7auy; sbox.(219ul) <- 0x9fuy; sbox.(220ul) <- 0x93uy; sbox.(221ul) <- 0xc9uy; sbox.(222ul) <- 0x9cuy; sbox.(223ul) <- 0xefuy; sbox.(224ul) <- 0xa0uy; sbox.(225ul) <- 0xe0uy; sbox.(226ul) <- 0x3buy; sbox.(227ul) <- 0x4duy; sbox.(228ul) <- 0xaeuy; sbox.(229ul) <- 0x2auy; sbox.(230ul) <- 0xf5uy; sbox.(231ul) <- 0xb0uy; sbox.(232ul) <- 0xc8uy; sbox.(233ul) <- 0xebuy; sbox.(234ul) <- 0xbbuy; sbox.(235ul) <- 0x3cuy; sbox.(236ul) <- 0x83uy; sbox.(237ul) <- 0x53uy; sbox.(238ul) <- 0x99uy; sbox.(239ul) <- 0x61uy; sbox.(240ul) <- 0x17uy; sbox.(241ul) <- 0x2buy; sbox.(242ul) <- 0x04uy; sbox.(243ul) <- 0x7euy; sbox.(244ul) <- 0xbauy; sbox.(245ul) <- 0x77uy; sbox.(246ul) <- 0xd6uy; sbox.(247ul) <- 0x26uy; sbox.(248ul) <- 0xe1uy; sbox.(249ul) <- 0x69uy; sbox.(250ul) <- 0x14uy; sbox.(251ul) <- 0x63uy; sbox.(252ul) <- 0x55uy; sbox.(253ul) <- 0x21uy; sbox.(254ul) <- 0x0cuy; sbox.(255ul) <- 0x7duy #reset-options private let rec access_aux: sb:sbox -> byte -> ctr:UInt32.t{v ctr <= 256} -> byte -> STL byte (requires (fun h -> live h sb)) (ensures (fun h0 _ h1 -> h1 == h0)) = fun sbox i ctr tmp -> if ctr = 256ul then tmp else let mask = eq_mask i (uint32_to_uint8 ctr) in let tmp = tmp |^ (mask &^ sbox.(ctr)) in access_aux sbox i (U32.(ctr +^ 1ul)) tmp private val access: sb:sbox -> idx:byte -> STL byte (requires (fun h -> live h sb)) (ensures (fun h0 _ h1 -> h1 == h0)) [@ (CPrologue "#ifdef _MSC_VER\n// Work around a /Ox code-gen bug in AES key expansion, in the MSVC compiler\n#pragma optimize(\"\", off)\n#pragma optimize(\"s\", on)\n#endif") (CEpilogue "#ifdef _MSC_VER\n#pragma optimize(\"\", on)\n#endif") ] let access sbox i = if Flag.aes_ct then access_aux sbox i 0ul 0uy else sbox.(Int.Cast.uint8_to_uint32 i) // ENCRYPTION private val subBytes_aux_sbox: state:block -> sb:sbox{disjoint state sb} -> ctr:idx_16 -> STL unit (requires (fun h -> live h state /\ live h sb)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let rec subBytes_aux_sbox state sbox ctr = if ctr <> 16ul then begin let si = state.(ctr) in let si' = access sbox si in state.(ctr) <- si'; subBytes_aux_sbox state sbox (U32.(ctr +^ 1ul)) end private val subBytes_sbox: state:block -> sbox:sbox{disjoint state sbox} -> STL unit (requires (fun h -> live h state /\ live h sbox)) (ensures (fun h0 _ h1 -> modifies_1 state h0 h1 /\ live h1 state)) let subBytes_sbox state sbox = subBytes_aux_sbox state sbox 0ul #push-options "--z3rlimit 100" private val shiftRows: state:block -> STL unit (requires (fun h -> live h state)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let shiftRows state = let open FStar.UInt32 in let i = 1ul in let tmp = state.(i) in state.(i) <- state.(i+^ 4ul); state.(i+^ 4ul) <- state.(i+^ 8ul); state.(i+^ 8ul) <- state.(i+^12ul); state.(i+^12ul) <- tmp; let i = 2ul in let tmp = state.(i) in state.(i) <- state.(i+^8ul); state.(i+^ 8ul) <- tmp; let tmp = state.(i+^4ul) in state.(i+^ 4ul) <- state.(i+^12ul); state.(i+^12ul) <- tmp; let i = 3ul in let tmp = state.(i) in state.(i) <- state.(i+^12ul); state.(i+^12ul) <- state.(i+^ 8ul); state.(i+^ 8ul) <- state.(i+^ 4ul); state.(i+^ 4ul) <- tmp #pop-options private val mixColumns_: state:block -> c:UInt32.t{v c < 4} -> STL unit (requires (fun h -> live h state)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let mixColumns_ state c = let s = Buffer.sub state (H32.(4ul*^c)) 4ul in let s0 = s.(0ul) in let s1 = s.(1ul) in let s2 = s.(2ul) in let s3 = s.(3ul) in s.(0ul) <- H8.(multiply 0x2uy s0 ^^ multiply 0x3uy s1 ^^ s2 ^^ s3); s.(1ul) <- H8.(multiply 0x2uy s1 ^^ multiply 0x3uy s2 ^^ s3 ^^ s0); s.(2ul) <- H8.(multiply 0x2uy s2 ^^ multiply 0x3uy s3 ^^ s0 ^^ s1); s.(3ul) <- H8.(multiply 0x2uy s3 ^^ multiply 0x3uy s0 ^^ s1 ^^ s2) #reset-options "--initial_fuel 0 --max_fuel 0" private val mixColumns: state:block -> STL unit (requires (fun h -> live h state)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let mixColumns state = mixColumns_ state 0ul; mixColumns_ state 1ul; mixColumns_ state 2ul; mixColumns_ state 3ul #reset-options "--z3rlimit 10 --initial_fuel 0 --max_fuel 0" private val addRoundKey_: state:block -> w:xkey{disjoint state w} -> rnd -> c:UInt32.t{v c < 4} -> STL unit (requires (fun h -> live h state /\ live h w)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let addRoundKey_ state w round c = let open FStar.UInt32 in let target = Buffer.sub state (4ul*^c) 4ul in let subkey = Buffer.sub w (blocklen*^round +^ 4ul*^c) 4ul in let open FStar.UInt8 in target.(0ul) <- target.(0ul) ^^ subkey.(0ul); target.(1ul) <- target.(1ul) ^^ subkey.(1ul); target.(2ul) <- target.(2ul) ^^ subkey.(2ul); target.(3ul) <- target.(3ul) ^^ subkey.(3ul) private val addRoundKey: state:block -> w:xkey{disjoint state w} -> round:rnd -> STL unit (requires (fun h -> live h state /\ live h w)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let addRoundKey state w round = addRoundKey_ state w round 0ul; addRoundKey_ state w round 1ul; addRoundKey_ state w round 2ul; addRoundKey_ state w round 3ul private val cipher_loop: state:block -> w:xkey{disjoint state w} -> sb:sbox{disjoint sb state} -> round:rnd -> STL unit (requires (fun h -> live h state /\ live h w /\ live h sb)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let rec cipher_loop state w sbox round = let open FStar.UInt32 in if round <> nr then begin subBytes_sbox state sbox; shiftRows state; mixColumns state; addRoundKey state w round; cipher_loop state w sbox (round+^1ul) end #reset-options "--initial_fuel 0 --max_fuel 0 --z3rlimit 20" val cipher: out:block -> input:block -> w:xkey -> sb:sbox -> STL unit (requires (fun h -> live h out /\ live h input /\ live h w /\ live h sb /\ disjoint out input /\ disjoint out w /\ disjoint out sb)) (ensures (fun h0 _ h1 -> live h1 out /\ modifies_1 out h0 h1)) let cipher out input w sbox = push_frame(); let state = create 0uy blocklen in // could we use output instead? alignment? blit input 0ul state 0ul blocklen; addRoundKey state w 0ul; cipher_loop state w sbox 1ul; subBytes_sbox state sbox; shiftRows state; addRoundKey state w nr; blit state 0ul out 0ul blocklen; pop_frame() // KEY EXPANSION private val rotWord: word:lbytes 4 -> STL unit (requires (fun h -> live h word)) (ensures (fun h0 _ h1 -> live h1 word /\ modifies_1 word h0 h1)) let rotWord word = let w0 = word.(0ul) in let w1 = word.(1ul) in let w2 = word.(2ul) in let w3 = word.(3ul) in word.(0ul) <- w1; word.(1ul) <- w2; word.(2ul) <- w3; word.(3ul) <- w0 private val subWord: word:lbytes 4 -> sbox:sbox -> STL unit (requires (fun h -> live h word /\ live h sbox /\ disjoint word sbox)) (ensures (fun h0 _ h1 -> live h1 word /\ modifies_1 word h0 h1)) let subWord word sbox = word.(0ul) <- access sbox word.(0ul); word.(1ul) <- access sbox word.(1ul); word.(2ul) <- access sbox word.(2ul); word.(3ul) <- access sbox word.(3ul) #reset-options "--z3rlimit 40 --initial_fuel 0 --max_fuel 0" private val rcon: i:UInt32.t{v i >= 1} -> byte -> Tot byte (decreases (v i)) let rec rcon i tmp = if i = 1ul then tmp else begin let tmp = multiply 0x2uy tmp in rcon (U32.(i-^1ul)) tmp end #reset-options "--z3rlimit 100 --initial_fuel 0 --max_fuel 0 --max_ifuel 0" private val keyExpansion_aux_0:w:xkey -> temp:lbytes 4 -> sbox:sbox -> i:UInt32.t{v i < (v xkeylen / 4) /\ v i >= v nk} -> STL unit (requires (fun h -> live h w /\ live h temp /\ live h sbox /\ disjoint w temp /\ disjoint w sbox /\ disjoint temp sbox)) (ensures (fun h0 _ h1 -> live h1 temp /\ modifies_1 temp h0 h1)) let keyExpansion_aux_0 w temp sbox j = let open FStar.UInt32 in let h0 = ST.get() in assume false; //NS: added this on Feb 7, 2019: Flaky proof, not worth restoring blit w (4ul *^ j -^ 4ul) temp 0ul 4ul; if j %^ nk = 0ul then ( rotWord temp; subWord temp sbox; let t0 = temp.(0ul) in let rc = rcon (j/^nk) 1uy in let z = H8.(t0 ^^ rc) in temp.(0ul) <- z ) else if j %^ nk = 4ul then subWord temp sbox #reset-options "--z3rlimit 50 --initial_fuel 0 --max_fuel 0" private val keyExpansion_aux_1: w:xkey -> temp:lbytes 4 -> sbox:sbox -> i:UInt32.t{v i < (v xkeylen / 4) /\ v i >= v nk} -> STL unit (requires (fun h -> live h w /\ live h temp /\ live h sbox /\ disjoint w temp /\ disjoint w sbox /\ disjoint temp sbox)) (ensures (fun h0 _ h1 -> live h1 w /\ modifies_1 w h0 h1)) let keyExpansion_aux_1 w temp sbox j = let open FStar.UInt32 in let i = 4ul *^ j in let w0 = w.(i +^ 0ul -^ keylen) in let w1 = w.(i +^ 1ul -^ keylen) in let w2 = w.(i +^ 2ul -^ keylen) in let w3 = w.(i +^ 3ul -^ keylen) in let t0 = temp.(0ul) in let t1 = temp.(1ul) in let t2 = temp.(2ul) in let t3 = temp.(3ul) in w.(i+^0ul) <- H8.(t0 ^^ w0); w.(i+^1ul) <- H8.(t1 ^^ w1); w.(i+^2ul) <- H8.(t2 ^^ w2); w.(i+^3ul) <- H8.(t3 ^^ w3) private val keyExpansion_aux: w:xkey -> temp:lbytes 4 -> sbox:sbox -> i:UInt32.t{v i <= (v xkeylen / 4) /\ v i >= v nk} -> STL unit (requires (fun h -> live h w /\ live h temp /\ live h sbox /\ disjoint w temp /\ disjoint w sbox /\ disjoint temp sbox)) (ensures (fun h0 _ h1 -> live h1 temp /\ live h1 w /\ modifies_2 temp w h0 h1)) let rec keyExpansion_aux w temp sbox j = let open FStar.UInt32 in let h0 = ST.get() in if j <^ (xkeylen /^ 4ul) then begin keyExpansion_aux_0 w temp sbox j; keyExpansion_aux_1 w temp sbox j; keyExpansion_aux w temp sbox (j +^ 1ul) end val keyExpansion: key:skey -> w:xkey -> sb:sbox -> STL unit (requires (fun h -> live h key /\ live h w /\ live h sb /\ disjoint key w /\ disjoint w sb)) (ensures (fun h0 _ h1 -> live h1 w /\ modifies_1 w h0 h1)) let keyExpansion key w sbox = let open FStar.UInt32 in push_frame(); let temp = create 0uy 4ul in blit key 0ul w 0ul keylen; keyExpansion_aux w temp sbox nk; pop_frame() // DECRYPTION private val invSubBytes_aux_sbox: state:block -> sbox:sbox -> ctr:idx_16 -> STL unit (requires (fun h -> live h state /\ live h sbox /\ disjoint state sbox)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let rec invSubBytes_aux_sbox state sbox ctr = if ctr = 16ul then () else begin let si = state.(ctr) in let si' = access sbox si in state.(ctr) <- si'; invSubBytes_aux_sbox state sbox (U32.(ctr+^1ul)) end private val invSubBytes_sbox: state:block -> sbox:sbox -> STL unit (requires (fun h -> live h state /\ live h sbox /\ disjoint state sbox)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let invSubBytes_sbox state sbox = invSubBytes_aux_sbox state sbox 0ul private val invShiftRows: state:block -> STL unit (requires (fun h -> live h state)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1)) let invShiftRows state = let open FStar.UInt32 in let i = 3ul in let tmp = state.(i) in state.(i) <- state.(i+^4ul); state.(i+^4ul) <- state.(i+^8ul); state.(i+^8ul) <- state.(i+^12ul); state.(i+^12ul) <- tmp; let i = 2ul in let tmp = state.(i) in state.(i) <- state.(i+^8ul); state.(i+^8ul) <- tmp; let tmp = state.(i+^4ul) in state.(i+^4ul) <- state.(i+^12ul); state.(i+^12ul) <- tmp; let i = 1ul in let tmp = state.(i) in state.(i) <- state.(i+^12ul); state.(i+^12ul) <- state.(i+^8ul); state.(i+^8ul) <- state.(i+^4ul); state.(i+^4ul) <- tmp private val invMixColumns_: state:block -> c:UInt32.t{v c < 4} -> STL unit (requires (fun h -> live h state)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1 )) let invMixColumns_ state c = let s = Buffer.sub state (H32.(4ul*^c)) 4ul in let s0 = s.(0ul) in let s1 = s.(1ul) in let s2 = s.(2ul) in let s3 = s.(3ul) in let mix x0 x1 x2 x3 = H8.(multiply 0xeuy x0 ^^ multiply 0xbuy x1 ^^ multiply 0xduy x2 ^^ multiply 0x9uy x3) in s.(0ul) <- mix s0 s1 s2 s3; s.(1ul) <- mix s1 s2 s3 s0; s.(2ul) <- mix s2 s3 s0 s1; s.(3ul) <- mix s3 s0 s1 s2 #reset-options "--initial_fuel 0 --max_fuel 0" private val invMixColumns: state:block -> STL unit (requires (fun h -> live h state)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1 )) let invMixColumns state = invMixColumns_ state 0ul; invMixColumns_ state 1ul; invMixColumns_ state 2ul; invMixColumns_ state 3ul private val inv_cipher_loop: state:block -> w:xkey -> sb:sbox -> round:UInt32.t{v round <= v nr - 1} -> STL unit (requires (fun h -> live h state /\ live h w /\ live h sb /\ disjoint state w /\ disjoint state sb /\ disjoint sb w)) (ensures (fun h0 _ h1 -> live h1 state /\ modifies_1 state h0 h1 )) let rec inv_cipher_loop state w sbox round = let open FStar.UInt32 in if round <> 0ul then begin invShiftRows state; invSubBytes_sbox state sbox; addRoundKey state w round; invMixColumns state; inv_cipher_loop state w sbox (round -^ 1ul) end val inv_cipher: out:block -> input:block -> w:xkey -> sb:sbox -> STL unit (requires (fun h -> live h out /\ live h input /\ live h w /\ live h sb /\ disjoint out input /\ disjoint out w /\ disjoint out sb /\ disjoint sb w)) (ensures (fun h0 _ h1 -> live h1 out /\ modifies_1 out h0 h1)) let inv_cipher out input w sbox = push_frame(); let state = create 0uy blocklen in blit input 0ul state 0ul blocklen; addRoundKey state w nr; inv_cipher_loop state w sbox (U32.(nr -^ 1ul)); invShiftRows state; invSubBytes_sbox state sbox; addRoundKey state w 0ul; blit state 0ul out 0ul blocklen; pop_frame()