~shreyasminocha/haskell-crypto

fa361b791613a27912cd34f3610cc0b00ae94f04 — Shreyas Minocha 6 months ago f9a305d
Implement knapsack and GGH
2 files changed, 39 insertions(+), 0 deletions(-)

A Knapsack.hs
A ggh.py
A Knapsack.hs => Knapsack.hs +14 -0
@@ 0,0 1,14 @@
import LinearCongruences (baseSolution, inverse)

publicToPrivateSequence :: [Int] -> Int -> Int -> [Int]
publicToPrivateSequence m b a = map (flip (baseSolution b) a) m

decryptKnapsack :: [Int] -> Int -> Int -> Int -> [Int]
decryptKnapsack m b a s = solveKnapsack m (s * (inverse b a) `mod` b)

solveKnapsack :: [Int] -> Int -> [Int]
solveKnapsack [] _ = []
solveKnapsack mm s = (solveKnapsack ms ss) ++ [x]
    where (ms, m) = (init mm, last mm)
          ss = if s >= m then s - m else s
          x = if s >= m then 1 else 0

A ggh.py => ggh.py +25 -0
@@ 0,0 1,25 @@
import numpy as np
import numpy.linalg as LA
from operator import mul
from functools import reduce

def hadamard_ratio(basis):
    matrix = np.array(basis)
    vol = abs(LA.det(matrix))
    norm_product = reduce(mul, map(LA.norm, basis), 1)

    return (vol / norm_product) ** (1 / len(basis))

def babai_algorithm(w, good_basis):
    sol = LA.solve(np.transpose(np.array(good_basis)), np.array(w))
    rounded = np.array(list(map(round, sol)))

    return sum(map(mul, rounded, np.array(good_basis)))

def ggh_decrypt(ciphertext, public_basis, private_basis):
    closest = babai_algorithm(ciphertext, private_basis)
    sol = LA.solve(np.transpose(public_basis), closest)
    plaintext = np.array(list(map(round, sol)))
    print('r =', plaintext - sol)

    return plaintext