=======================
Cipher Mode Experiments
=======================

According to experiments, the provers have a much harder time
verifying the composition of a mode with equivalent block ciphers,
than simply verifying the equivalent block ciphers directly.

AES Experiments
===============

The miters used are

- tmp/miter.ecb.aes.aes.aig: compares ECB mode of LLVM AES
  implementation to itself.

- tmp/miter.ecb.aes-ref.aes-ref.aig: compares ECB mode of Cryptol AES
  implementation to itself.

- tmp/miter.ecb.aes.aes-ref.aig: compares ECB mode of LLVM AES to ECB
  mode of Cryptol AES implementation.

So far, no prover is able to verify tmp/miter.ecb.aes.aes-ref.aig.

Success
-------

Conclude that miter is unsat:

    iimc -v 1 tmp/miter.ecb.aes.aes.aig  12.78s user 0.37s system 99% cpu 13.153 total
    abc -c 'read tmp/miter.ecb.aes.aes.aig; dsec'  33.77s user 0.78s system 99% cpu 34.588 total
    abc -c 'read tmp/miter.ecb.aes.aes.aig; dprove'  148.83s user 20.61s system 99% cpu 2:50.86 total

    iimc -v 1 tmp/miter.ecb.aes-ref.aes-ref.aig  5.13s user 0.57s system 97% cpu 5.834 total
    abc -c 'read tmp/miter.ecb.aes-ref.aes-ref.aig; dsec'  7.68s user 0.20s system 99% cpu 7.929 total
    abc -c 'read tmp/miter.ecb.aes-ref.aes-ref.aig; dprove'  65.05s user 7.30s system 99% cpu 1:12.50 total

Failure
-------

By comparison, directly verifying the equivalence of the two AES
implementations using ABC's 'cec' in the LLVM tutorial takes about 15
minutes on conathan's machine, and about 4 minutes using ABC's 'bm'
command.

Killed with ^C:

    abc -c 'read tmp/miter.ecb.aes.aes.aig; pdr'  9209.58s user 0.68s system 99% cpu 2:33:31.21 total
    
    abc -c 'read tmp/miter.ecb.aes-ref.aes-ref.aig; pdr'  8981.07s user 1.03s system 99% cpu 2:29:43.67 total

    abc -c 'read tmp/miter.ecb.aes.aes-ref.aig; dprove -v -G 1000000000'  75800.85s user 25.00s system 99% cpu 21:11:49.71 total

    iimc tmp/miter.ecb.aes.aes-ref.aig  194689.22s user 83.56s system 299% cpu 18:04:58.47 total

Exceeded resource limits:

    time abc -c 'read tmp/miter.ecb.aes.aes-ref.aig; dprove -v'
    ABC command line: "read tmp/miter.ecb.aes.aes-ref.aig; dprove -v".

    RESOURCE LIMITS: Iterations = 6. Rewriting = no. Fraiging = yes.
    Miter = 5000 (2.0).  Rwr = 3 (1.0).  Fraig = 2 (8.0).  Last = 0.
    ITERATION  1 : Confs =   5000. FraigBTL =   2. 
    SimWords = 32. Rounds = 3. Mem = 105.46 MB.  Classes: Beg = 8066. End = 8066.
    Proof = 0. Counter-example = 0. Fail = 0. FailReal = 0. Zero = 510.
    Final = 863396. Miter = 863396. Total = 863396. Mux = 0. (Exor = 0.) SatVars = 0.
    AIG simulation   =     0.19 sec
    AIG traversal    =     0.00 sec
    SAT solving      =     0.00 sec
        Unsat        =     0.00 sec
        Sat          =     0.00 sec
        Fail         =     0.00 sec
    Class refining   =     0.00 sec
    TOTAL RUNTIME    =     0.88 sec
    Nodes =  863396.  Levels = 1729.  Fraiging    =     0.88 sec
    Running "bmc2". AIG:  PI/PO/Reg = 256/1/258.  Node = 1601931. Lev =  4264.
    Params: FramesMax = 20. NodesDelta = 2000. ConfMaxOne = 2000. ConfMaxAll = 0.
       0 : F =    1. O =   0.  And = 1600551. Var =  468821. Conf =   2001.   12 MB     8.16 sec
    No output failed in 0 frames.  Time =     8.16 sec
    Reached local conflict limit (2000).
    Original miter:       Latches =   258. Nodes = 1601931.
    Sequential cleanup:   Latches =   257. Nodes = 1601803. Time =     0.64 sec
    Forward retiming:     Latches =   257. Nodes = 1601547. Time =     1.00 sec
    Latch-corr (I=  1):   Latches =   129. Nodes = 1600807. Time =     1.57 sec
    Fraiging:             Latches =   129. Nodes = 746282. Time =  1829.65 sec
    Min-reg retiming:     Latches =   129. Nodes = 746282. Time =     0.93 sec
    K-step (K= 1,I= 16):  Latches =   129. Nodes = 623443. Time =  7165.39 sec
    Min-reg retiming:     Latches =   129. Nodes = 623443. Time =     0.79 sec
    Rewriting:            Latches =   129. Nodes = 439305. Time =    58.95 sec
    Seq simulation  :     Latches =   129. Nodes = 439305. Time =     2.28 sec
    Global conflict limit (5000000) exceeded.
    Networks are UNDECIDED.   Time =  9062.05 sec
    abc -c 'read tmp/miter.ecb.aes.aes-ref.aig; dprove -v'  9123.75s user 15.00s system 99% cpu 2:32:18.96 total

Scaling Experiments
===================

In the scaling experiments, we compare a reference scaling function

    scale_ref n x = n * x

with an intentionally slow scaling function

    scale n x = x + ... + x    // n times

The point is to make the second circuit grow linearly in the scaling
factor 'n'.  As pointed out by Joe H., the complexity of the
multiplication circuit could depend heavily on how many one bits there
are in the scaling factor, if the multiplication by a constant
compiles to a sum of shifts.

In all of the following graphs, the first four columns are

    n    n-binary |n|      #n

where 'n' is the scaling factor, '|n|' is the number of 1-bits in 'n',
and '#n' is a bar of 'n'-many hashes.

Graphs of circuit complexity
----------------------------

For the reference implementation. The last two columns are

                                     a #(a/100)

where 'a' is the number of AND gates. Graph:

    0010 00001010 02       ## 01988.00 ####################
    0015 00001111 04     #### 02284.00 #######################
    0020 00010100 02       ## 01967.00 ####################
    0025 00011001 03      ### 02368.00 ########################
    0030 00011110 04     #### 02256.00 #######################
    0035 00100011 03      ### 02505.00 ##########################
    0040 00101000 02       ## 01942.00 ####################
    0045 00101101 04     #### 02583.00 ##########################
    0050 00110010 03      ### 02335.00 ########################
    0055 00110111 05    ##### 02642.00 ###########################
    0060 00111100 04     #### 02224.00 #######################
    0065 01000001 02       ## 02447.00 #########################
    0070 01000110 03      ### 02466.00 #########################
    0075 01001011 04     #### 02719.00 ############################
    0080 01010000 02       ## 01915.00 ####################
    0085 01010101 04     #### 02709.00 ############################
    0090 01011010 04     #### 02542.00 ##########################
    0095 01011111 06   ###### 02809.00 #############################
    0100 01100100 03      ### 02300.00 #######################

For the "stupid" implementation the last two columns are

                                     a #(a/1000)

(note we divide by 1000 this time, not 100) and the graph is

    0010 00001010 02       ## 01966.00 ##
    0015 00001111 04     #### 03222.00 ####
    0020 00010100 02       ## 04425.00 #####
    0025 00011001 03      ### 05680.00 ######
    0030 00011110 04     #### 06881.00 #######
    0035 00100011 03      ### 08137.00 #########
    0040 00101000 02       ## 09340.00 ##########
    0045 00101101 04     #### 10595.00 ###########
    0050 00110010 03      ### 11796.00 ############
    0055 00110111 05    ##### 13052.00 ##############
    0060 00111100 04     #### 14255.00 ###############
    0065 01000001 02       ## 15510.00 ################
    0070 01000110 03      ### 16711.00 #################
    0075 01001011 04     #### 17967.00 ##################
    0080 01010000 02       ## 19170.00 ####################
    0085 01010101 04     #### 20425.00 #####################
    0090 01011010 04     #### 21626.00 ######################
    0095 01011111 06   ###### 22882.00 #######################
    0100 01100100 03      ### 24085.00 #########################

Graphs of ABC run time
----------------------

ABC 'cec' experiments comparing scaling circuits. Command was

    for n in $(seq 10 5 100); do eval time abc -c "'cec tmp/scale.32.$n.aig tmp/scale-ref.32.$n.aig'" ; done

A graph of run times for *two* runs. The last two columns are

                                     t #t/50

for 't' the run time in seconds. Graph:

    0010 00001010 02       ## 00000.94 #
    0010 00001010 02       ## 00001.02 #
    0015 00001111 04     #### 00001.64 #
    0015 00001111 04     #### 00001.84 #
    0020 00010100 02       ## 00002.56 #
    0020 00010100 02       ## 00002.69 #
    0025 00011001 03      ### 00003.71 #
    0025 00011001 03      ### 00003.89 #
    0030 00011110 04     #### 00003.93 #
    0030 00011110 04     #### 00004.18 #
    0035 00100011 03      ### 00012.00 #
    0035 00100011 03      ### 00008.72 #
    0040 00101000 02       ## 00014.17 #
    0040 00101000 02       ## 00009.62 #
    0045 00101101 04     #### 00028.84 #
    0045 00101101 04     #### 00038.59 #
    0050 00110010 03      ### 00106.26 ###
    0050 00110010 03      ### 00163.95 ####
    0055 00110111 05    ##### 00258.04 ######
    0055 00110111 05    ##### 00405.27 #########
    0060 00111100 04     #### 00014.55 #
    0060 00111100 04     #### 00016.18 #
    0065 01000001 02       ## 00145.36 ###
    0065 01000001 02       ## 00099.36 ##
    0070 01000110 03      ### 00018.15 #
    0070 01000110 03      ### 00026.19 #
    0075 01001011 04     #### 00028.85 #
    0075 01001011 04     #### 00042.65 #
    0080 01010000 02       ## 00023.23 #
    0080 01010000 02       ## 00033.81 #
    0085 01010101 04     #### 00762.45 ################
    0085 01010101 04     #### 00770.57 ################
    0090 01011010 04     #### 01055.89 ######################
    0090 01011010 04     #### 01056.31 ######################
    0095 01011111 06   ###### 01717.43 ###################################
    0095 01011111 06   ###### 01920.33 #######################################
    0100 01100100 03      ### 01153.79 ########################
    0100 01100100 03      ### 01361.65 ############################

Doesn't seem to be much if any relationship between the runtime and
the number of one bits.

Now, comparing the corresponding ECB modes. The columns are the same,
and the command (run twice again) was

    for n in $(seq 10 5 100); do eval time nice abc -c "'read tmp/miter.ecb.scale.scale-ref.32.$n.aig; dprove'"; done

Graph:

                                     t #t/25

    0010 00001010 02       ## 00000.83 #
    0010 00001010 02       ## 00000.91 #
    0015 00001111 04     #### 00001.48 #
    0015 00001111 04     #### 00001.50 #
    0020 00010100 02       ## 00002.41 #
    0020 00010100 02       ## 00002.46 #
    0025 00011001 03      ### 00003.71 #
    0025 00011001 03      ### 00003.91 #
    0030 00011110 04     #### 00003.70 #
    0030 00011110 04     #### 00003.83 #
    0035 00100011 03      ### 00007.94 #
    0035 00100011 03      ### 00008.05 #
    0040 00101000 02       ## 00008.32 #
    0040 00101000 02       ## 00008.37 #
    0045 00101101 04     #### 00026.13 ##
    0045 00101101 04     #### 00026.72 ##
    0050 00110010 03      ### 00048.71 ##
    0050 00110010 03      ### 00049.48 ##
    0055 00110111 05    ##### 00229.16 ##########
    0055 00110111 05    ##### 00231.65 ##########
    0060 00111100 04     #### 00013.51 #
    0060 00111100 04     #### 00014.25 #
    0065 01000001 02       ## 00029.95 ##
    0065 01000001 02       ## 00031.20 ##
    0070 01000110 03      ### 00016.51 #
    0070 01000110 03      ### 00016.56 #
    0075 01001011 04     #### 00037.58 ##
    0075 01001011 04     #### 00038.07 ##
    0080 01010000 02       ## 00020.33 #
    0080 01010000 02       ## 00021.17 #
    0085 01010101 04     #### 00238.76 ##########
    0085 01010101 04     #### 00243.94 ##########
    0090 01011010 04     #### 00330.52 ##############
    0090 01011010 04     #### 00334.81 ##############
    0095 01011111 06   ###### 00738.46 ##############################
    0095 01011111 06   ###### 00756.66 ###############################
    0100 01100100 03      ### 00197.20 ########
    0100 01100100 03      ### 00199.14 ########

Strangely, the 'dprove' is faster than the 'cec'!?

And 'dsec' is even faster than 'dprove', although it fails sometimes.

Command:

    for n in $(seq 10 5 100); do eval time abc -c "'dsec tmp/ecb.scale.32.$n.aig tmp/ecb.scale-ref.32.$n.aig'" ; done

Graph:

                                     t #t/10

    0010 00001010 02       ## 00000.08 #
    0015 00001111 04     #### 00000.76 #
    0020 00010100 02       ## 00000.61 #
    0025 00011001 03      ### 00001.95 #
    0030 00011110 04     #### 00002.31 #
    0035 00100011 03      ### 00007.99 #
    0040 00101000 02       ## 00006.73 #
    0045 00101101 04     #### 00023.74 ###
    0050 00110010 03      ### 00018.42 ##
    0055 00110111 05    ##### 00128.00 #############
    0060 00111100 04     #### 00013.60 ##
    0065 01000001 02       ## 00033.29 ####
    0070 01000110 03      ### 00014.98 ##
    0075 01001011 04     #### 00027.46 ###
    0080 01010000 02       ## 00019.52 ##
    0085 01010101 04     #### 00206.41 #####################
(*) 0090 01011010 04     #### 00153.47 ################
(*) 0095 01011111 06   ###### 00360.17 #####################################
    0100 01100100 03      ### 00102.59 ###########

In the cases marked with '(*)' -- the 'n = 90' and 'n = 95' cases
above -- ABC output "undecided", not "equivalent".

Using the '&cec' command, with command line

    for n in $(seq 10 5 100); do eval time abc -c "'&r tmp/scale.32.$n.aig; &cec tmp/scale-ref.32.$n.aig'" ; done

Graph:

                                     t #t/100

    0010 00001010 02       ## 00000.60 #
    0015 00001111 04     #### 00001.67 #
    0020 00010100 02       ## 00001.74 #
    0025 00011001 03      ### 00002.47 #
    0030 00011110 04     #### 00006.52 #
    0035 00100011 03      ### 00072.99 #
    0040 00101000 02       ## 00047.19 #
    0045 00101101 04     #### 01112.07 ############
    0050 00110010 03      ### 00115.96 ##
    0055 00110111 05    ##### 00038.85 #
    0060 00111100 04     #### 00145.96 ##
    0065 01000001 02       ## 00811.98 #########
    0070 01000110 03      ### 01491.35 ###############
    0075 01001011 04     #### 00303.40 ####
    0080 01010000 02       ## 00143.90 ##
    0085 01010101 04     #### 00783.83 ########
    0090 01011010 04     #### 01057.84 ###########
(*) 0095 01011111 06   ###### 04425.43 #############################################
    0100 01100100 03      ### 01396.55 ##############

Here '(*)' means "undecided" again.
