Beispiel #1
0
def verifier_search(cts, best_guess, use_n=64, net=net6):
    #print(best_guess);
    ck1 = best_guess[0] ^ low_weight
    ck2 = best_guess[1] ^ low_weight
    n = len(ck1)
    ck1 = np.repeat(ck1, n)
    keys1 = np.copy(ck1)
    ck2 = np.tile(ck2, n)
    keys2 = np.copy(ck2)
    ck1 = np.repeat(ck1, use_n)
    ck2 = np.repeat(ck2, use_n)
    ct0a = np.tile(cts[0][0:use_n], n * n)
    ct1a = np.tile(cts[1][0:use_n], n * n)
    ct0b = np.tile(cts[2][0:use_n], n * n)
    ct1b = np.tile(cts[3][0:use_n], n * n)
    pt0a, pt1a = sp.dec_one_round((ct0a, ct1a), ck1)
    pt0b, pt1b = sp.dec_one_round((ct0b, ct1b), ck1)
    pt0a, pt1a = sp.dec_one_round((pt0a, pt1a), ck2)
    pt0b, pt1b = sp.dec_one_round((pt0b, pt1b), ck2)
    X = sp.convert_to_binary([pt0a, pt1a, pt0b, pt1b])
    Z = net.predict(X, batch_size=10000)
    Z = Z / (1 - Z)
    Z = np.log2(Z)
    Z = Z.reshape(-1, use_n)
    v = np.mean(Z, axis=1) * len(cts[0])
    m = np.argmax(v)
    val = v[m]
    key1 = keys1[m]
    key2 = keys2[m]
    return (key1, key2, val)
def key_average(ct0a, ct1a, ct0b, ct1b, keys, net):
    n = len(keys)
    pt0a, pt1a = sp.dec_one_round((ct0a, ct1a), keys)
    pt0b, pt1b = sp.dec_one_round((ct0b, ct1b), keys)
    X = sp.convert_to_binary([pt0a, pt1a, pt0b, pt1b])
    Z = net.predict(X, batch_size=10000)
    Z = Z / (1 - Z)
    v = np.average(Z)
    v = v / (v + 1)
    return (v)
def key_rank_one_round(nr, dist, n_blocks=1, diff=(0x0040,0x0)):
  pt0a = np.frombuffer(urandom(2*n_blocks),dtype=np.uint16).reshape(n_blocks,-1);
  pt1a = np.frombuffer(urandom(2*n_blocks),dtype=np.uint16).reshape(n_blocks,-1);
  pt0b, pt1b = pt0a ^ diff[0], pt1a ^ diff[1];
  pt0a, pt1a = sp.dec_one_round((pt0a, pt1a),0);
  pt0b, pt1b = sp.dec_one_round((pt0b, pt1b),0);
  key = np.frombuffer(urandom(8),dtype=np.uint16);
  ks = sp.ex_key_test(key, nr); k1 = ks[nr-1];
  ct0a, ct1a = sp.enc_test((pt0a, pt1a), ks);
  ct0b, ct1b = sp.enc_test((pt0b, pt1b), ks);
  trial_keys = np.arange(2**16);
  c0a, c1a = sp.dec_one_round((ct0a, ct1a), trial_keys); c0b, c1b = sp.dec_one_round((ct0b, ct1b), trial_keys);
  d0,d1 = c0a ^ c0b, c1a ^ c1b;
  d = d0 ^ (d1.astype(np.uint32) << 16);
  Z = dist[d]; Z = np.log2(Z); Z = np.sum(Z,axis=0);
  rank0 = np.sum(Z > Z[k1]); rank1 = np.sum(Z >= Z[k1]);
  return(rank0, rank1);
Beispiel #4
0
def gen_challenge(n,
                  nr,
                  diff=(0x211, 0xa04),
                  neutral_bits=[20, 21, 22, 14, 15, 23],
                  keyschedule='real'):
    pt0, pt1 = gen_plain(n)
    pt0a, pt1a, pt0b, pt1b = make_structure(pt0,
                                            pt1,
                                            diff=diff,
                                            neutral_bits=neutral_bits)
    pt0a, pt1a = sp.dec_one_round((pt0a, pt1a), 0)
    pt0b, pt1b = sp.dec_one_round((pt0b, pt1b), 0)
    key = gen_key(nr)
    if (keyschedule is 'free'):
        key = np.frombuffer(urandom(2 * nr), dtype=np.uint16)
    ct0a, ct1a = sp.encrypt((pt0a, pt1a), key)
    ct0b, ct1b = sp.encrypt((pt0b, pt1b), key)
    return ([ct0a, ct1a, ct0b, ct1b], key)
Beispiel #5
0
def bayesian_key_recovery(cts,
                          net=net7,
                          m=m7,
                          s=s7,
                          num_cand=32,
                          num_iter=5,
                          seed=None):
    n = len(cts[0])
    keys = np.random.choice(2**(WORD_SIZE - 2), num_cand, replace=False)
    scores = 0
    best = 0
    if (not seed is None):
        keys = np.copy(seed)
    ct0a, ct1a, ct0b, ct1b = np.tile(cts[0], num_cand), np.tile(
        cts[1], num_cand), np.tile(cts[2],
                                   num_cand), np.tile(cts[3], num_cand)
    scores = np.zeros(2**(WORD_SIZE - 2))
    used = np.zeros(2**(WORD_SIZE - 2))
    all_keys = np.zeros(num_cand * num_iter, dtype=np.uint16)
    all_v = np.zeros(num_cand * num_iter)
    for i in range(num_iter):
        k = np.repeat(keys, n)
        c0a, c1a = sp.dec_one_round((ct0a, ct1a), k)
        c0b, c1b = sp.dec_one_round((ct0b, ct1b), k)
        X = sp.convert_to_binary([c0a, c1a, c0b, c1b])
        Z = net.predict(X, batch_size=10000)
        Z = Z.reshape(num_cand, -1)
        means = np.mean(Z, axis=1)
        Z = Z / (1 - Z)
        Z = np.log2(Z)
        v = np.sum(Z, axis=1)
        all_v[i * num_cand:(i + 1) * num_cand] = v
        all_keys[i * num_cand:(i + 1) * num_cand] = np.copy(keys)
        scores = bayesian_rank_kr(keys, means, m=m, s=s)
        tmp = np.argpartition(scores + used, num_cand)
        keys = tmp[0:num_cand]
        r = np.random.randint(0, 4, num_cand, dtype=np.uint16)
        r = r << 14
        keys = keys ^ r
    return (all_keys, scores, all_v)
Beispiel #6
0
def wrong_key_decryption(n, diff=(0x0040, 0x0), nr=7, net=net7):
    means = np.zeros(2**16)
    sig = np.zeros(2**16)
    for i in range(2**16):
        keys = np.frombuffer(urandom(8 * n), dtype=np.uint16).reshape(4, -1)
        ks = sp.expand_key(keys, nr + 1)
        #ks[nr-1] = 17123;
        pt0a = np.frombuffer(urandom(2 * n), dtype=np.uint16)
        pt1a = np.frombuffer(urandom(2 * n), dtype=np.uint16)
        pt0b, pt1b = pt0a ^ diff[0], pt1a ^ diff[1]
        ct0a, ct1a = sp.encrypt((pt0a, pt1a), ks)
        ct0b, ct1b = sp.encrypt((pt0b, pt1b), ks)
        rsubkeys = i ^ ks[nr]
        #rsubkeys = rdiff ^ 0;
        c0a, c1a = sp.dec_one_round((ct0a, ct1a), rsubkeys)
        c0b, c1b = sp.dec_one_round((ct0b, ct1b), rsubkeys)
        X = sp.convert_to_binary([c0a, c1a, c0b, c1b])
        Z = net.predict(X, batch_size=10000)
        Z = Z.flatten()
        means[i] = np.mean(Z)
        sig[i] = np.std(Z)
    return (means, sig)
Beispiel #7
0
def key_rank_one_round(nr, net, n_blocks=1, diff=(0x0040, 0x0)):
    pt0a = np.frombuffer(urandom(2 * n_blocks),
                         dtype=np.uint16).reshape(n_blocks, -1)
    pt1a = np.frombuffer(urandom(2 * n_blocks),
                         dtype=np.uint16).reshape(n_blocks, -1)
    pt0b, pt1b = pt0a ^ diff[0], pt1a ^ diff[1]
    pt0a, pt1a = sp.dec_one_round((pt0a, pt1a), 0)
    pt0b, pt1b = sp.dec_one_round((pt0b, pt1b), 0)
    key = np.frombuffer(urandom(8), dtype=np.uint16)
    ks = sp.expand_key(key, nr)
    k1 = ks[nr - 1]
    ct0a, ct1a = sp.encrypt((pt0a, pt1a), ks)
    ct0b, ct1b = sp.encrypt((pt0b, pt1b), ks)
    trial_keys = np.arange(2**16)
    c0a, c1a = sp.dec_one_round((ct0a, ct1a), trial_keys)
    c0b, c1b = sp.dec_one_round((ct0b, ct1b), trial_keys)
    c1a = np.tile(c1a, 2**16)
    c1b = np.tile(c1b, 2**16)
    #the next two lines are the only bits of this function that change
    #if instead of a neural network the difference distribution table is used for inference
    #in particular, in this case, conversion to network input is replaced by calculation of trial decryption differences
    #Z is then calculated simply by looking up the relevant transition probabilities in the ddt
    #instead of a neural net, the function then expects as second input a table of size 2**32
    X = sp.convert_to_binary(
        [c0a.flatten(),
         c1a.flatten(),
         c0b.flatten(),
         c1b.flatten()])
    Z = net.predict(X, batch_size=10000)
    Z = Z / (1 - Z)
    Z = np.log2(Z)
    Z = Z.reshape(n_blocks, -1)
    Z = np.sum(Z, axis=0)
    rank0 = np.sum(Z > Z[k1])
    rank1 = np.sum(Z >= Z[k1])
    return (rank0, rank1)
Beispiel #8
0
def test_bayes(cts,
               it=1,
               cutoff1=10,
               cutoff2=10,
               net=net7,
               net_help=net6,
               m_main=m7,
               m_help=m6,
               s_main=s7,
               s_help=s6,
               verify_breadth=None):
    n = len(cts[0])
    if (verify_breadth is None): verify_breadth = len(cts[0][0])
    alpha = sqrt(n)
    best_val = -100.0
    best_key = (0, 0)
    best_pod = 0
    bp = 0
    bv = -100.0
    keys = np.random.choice(2**WORD_SIZE, 32, replace=False)
    eps = 0.001
    local_best = np.full(n, -10)
    num_visits = np.full(n, eps)
    guess_count = np.zeros(2**16, dtype=np.uint16)
    for j in range(it):
        priority = local_best + alpha * np.sqrt(log2(j + 1) / num_visits)
        i = np.argmax(priority)
        num_visits[i] = num_visits[i] + 1
        if (best_val > cutoff2):
            improvement = (verify_breadth > 0)
            while improvement:
                k1, k2, val = verifier_search([
                    cts[0][best_pod], cts[1][best_pod], cts[2][best_pod],
                    cts[3][best_pod]
                ],
                                              best_key,
                                              net=net_help,
                                              use_n=verify_breadth)
                improvement = (val > best_val)
                if (improvement):
                    best_key = (k1, k2)
                    best_val = val
            return (best_key, j)
        keys, scores, v = bayesian_key_recovery(
            [cts[0][i], cts[1][i], cts[2][i], cts[3][i]],
            num_cand=32,
            num_iter=5,
            net=net,
            m=m_main,
            s=s_main)
        vtmp = np.max(v)
        if (vtmp > local_best[i]): local_best[i] = vtmp
        if (vtmp > bv):
            bv = vtmp
            bp = i
        if (vtmp > cutoff1):
            l2 = [i for i in range(len(keys)) if v[i] > cutoff1]
            for i2 in l2:
                c0a, c1a = sp.dec_one_round((cts[0][i], cts[1][i]), keys[i2])
                c0b, c1b = sp.dec_one_round((cts[2][i], cts[3][i]), keys[i2])
                keys2, scores2, v2 = bayesian_key_recovery(
                    [c0a, c1a, c0b, c1b],
                    num_cand=32,
                    num_iter=5,
                    m=m6,
                    s=s6,
                    net=net_help)
                vtmp2 = np.max(v2)
                if (vtmp2 > best_val):
                    best_val = vtmp2
                    best_key = (keys[i2], keys2[np.argmax(v2)])
                    best_pod = i
    improvement = (verify_breadth > 0)
    while improvement:
        k1, k2, val = verifier_search([
            cts[0][best_pod], cts[1][best_pod], cts[2][best_pod],
            cts[3][best_pod]
        ],
                                      best_key,
                                      net=net_help,
                                      use_n=verify_breadth)
        improvement = (val > best_val)
        if (improvement):
            best_key = (k1, k2)
            best_val = val
    return (best_key, it)
def evaluate_ciphertexts(ct):
    ct4, ct5 = sp.dec_one_round((ct[0], ct[1]), 0)
    ct6, ct7 = sp.dec_one_round((ct[2], ct[3]), 0)
    X = sp.convert_to_binary([ct[0], ct[1], ct[2], ct[3], ct4, ct5, ct6, ct7])
    Z = model.predict(X, batch_size=10000)
    return (Z.flatten())