Esempio n. 1
0
def expand_key(key):
    """Key expansion routine to generate a key schedule.

    Expand a short key into a single array of round keys, each 4 words.

    The key expansion generates a total of Nb * (Nr + 1) 4-byte words:
    - 128 -> 4 * (10 + 1) -> 44
    - 192 -> 4 * (12 + 1) -> 52
    - 256 -> 4 * (14 + 1) -> 60

    This diverges from the specification in that they expanded key is
    *not* a parameter that can be modified and remember its state.
    Rather, it gets created here as an empty array and then filled.
    """

    # The first *nk* words of the expanded key are filled with
    # respective keys from the cipher key.  (Each word == 4 bytes)
    nk = int(key.size / 4)
    nr = numrounds(nk)
    nwords = NB * (nr + 1)
    w = np.empty((NB, nwords), dtype=uint8)
    w[:, :nk] = key
    # Now fill out the rest of w.
    # The dreaded loop:
    # It may be near-impossible to do this without a loop, since
    # we're dependent on the value w[i - nk]
    i = nk
    while i < nwords:
        # Starts on row 3
        temp = w[:, i - 1]
        if i % nk == 0:
            temp = xor(
                # XOR of a 4-byte word with length-4 lookup from RCON table
                sub_word(rot_word(temp)),
                RCON[int(i / nk)]
            )
        elif nk > 6 and i % nk == 4:
            temp = sub_word(temp)
        w[:, i] = xor(w[:, i - nk], temp)
        i += 1
    return w
Esempio n. 2
0
def decrypt_raw(state, key):
    """Decrypt a single ciphertext data block, `state`, using `key`.

    Modifies `state` in-place!

    Parameters
    ----------
    inp: np.ndarray
    key: np.ndarray

    Returns
    -------
    state: np.ndarray
    """
    nk = int(key.size / 4)
    nr = numrounds(nk)
    exkeys = expand_key(key)  # 4 rows, NB * (nr + 1) columns (words)
    exkeys = np.split(exkeys, exkeys.shape[1] / NB, axis=1)

    # First XOR is with just input + key (reverse order of roundkeys)
    # Last round doesn't get an InvMixColumns
    xor(state, exkeys[-1], out=state)
    inv_shift_rows(state, out=state)
    inv_sub_bytes(state, out=state)

    for ek in exkeys[nr - 1:0:-1]:
        xor(state, ek, out=state)
        inv_mix_columns(state, out=state)
        inv_shift_rows(state, out=state)
        inv_sub_bytes(state, out=state)

    # One final (inverse) xor
    xor(state, exkeys[0], out=state)
    return state
Esempio n. 3
0
def encrypt_raw(state, key):
    """Encrypt a single input data block, `state`, using `key`.

    Modifies `state` in-place!

    Parameters
    ----------
    inp: np.ndarray
    key: np.ndarray

    Returns
    -------
    state: np.ndarray
    """

    # We get the keys in "human form" and apply AES' column-based axis swap on them
    # (This should happen within `encrypt()`)
    # Retain the 'original' key for our expand_key methodology
    # key = key.swapaxes(0, 1)
    nk = int(key.size / 4)
    nr = numrounds(nk)
    exkeys = expand_key(key)  # 4 rows, NB * (nr + 1) columns (words)
    exkeys = np.split(exkeys, exkeys.shape[1] / NB, axis=1)

    # First XOR is with just input + key
    xor(state, exkeys[0], out=state)

    # Intermediate rounds
    for ek in exkeys[1:nr]:
        sub_bytes(state, out=state)
        shift_rows(state, out=state)
        mix_columns(state, out=state)
        xor(state, ek, out=state)

    # Final round before a final XOR.  No mixColumns here
    sub_bytes(state, out=state)
    shift_rows(state, out=state)
    xor(state, exkeys[-1], out=state)
    # TODO: this is returned in column-ordered format.
    # We will need to massage it back into row ordered before flattening
    return state
Esempio n. 4
0
    df = pd.DataFrame(
        product(*vars.values()),
        columns = vars.keys()
    )

    df['Pr'] = df.apply(lambda args: prob(*args), axis=1)

    return df

if __name__=='__main__':
    # Model 1: p=1/2, q=1/2
    # U ~ Ber(p) - True if allergic
    # X ~ Ber(q) - treatment
    # Y = U xor X - recovers
    model1 = lambda u, x, y: [1-p, p][u] * [1-q, q][x] * int(y==xor(u,x))

    # Model 2: p=1/2, q=1/4, r=3/4
    # U ~ Ber(p) - True if allergic
    # X ~ Ber(q if U else r) - treatment
    # Y = U xor X - recovers
    model2 = lambda u, x, y: [1-p, p][u] * [[1-r, 1-q], [r, q]][x][u] * int(y==xor(u,x))
    
    # Model variables
    vars_ = dict(zip(['U', 'X', 'Y'], [[False, True], [False, True], [False, True]]))

    # Model parameters
    p, q, r, = symbols('p q r', real=True, nonnegative=True)

    # Compute
    df1 = get_joint(model1, **vars_)
Esempio n. 5
0
def test_rcon_lookup(asw_to_axo):
    """Test of intermediate values from xor with RCON lookup."""
    for i, (asw, axo) in enumerate(asw_to_axo, 1):
        assert array_equal(xor(asw, RCON[i]), axo), i