CryptoBook
  • CryptoBook
  • Book Plan
  • Style Guide
    • Sample Page
  • Contributors
  • Fundamentals
    • Mathematical Notation
    • Division and Greatest common divisor
      • Euclidean Algorithm
    • Modular Arithmetic
      • Theorems of Wilson, Euler, and Fermat
        • Fermat's Little Theorem in Detail
        • Euler's Theorem in Detail
      • Quadratic Residues
    • Continued Fractions
  • Number Theory
  • Ideals
  • Polynomials With Shared Roots
  • Integer Factorization
    • Pollard rho
    • Sieves
  • Abstract algebra
    • Groups
      • Another take on groups
      • Discrete Log Problem
    • Rings
    • Fields
    • Polynomials
  • Elliptic Curves
    • Untitled
  • Lattices
    • Introduction
    • LLL reduction
      • Gram-Schmidt Orthogonalization
      • Lagrange's algorithm
      • LLL reduction
    • Lattice reduction
      • Minkowski reduced
      • HKZ reduced
      • LLL reduced
    • Applications
      • Coppersmith algorithm
      • Extensions of Coppersmith algorithm
    • Hard lattice problems
    • Lattices of interest
    • Cryptographic lattice problems
      • Short integer solutions (SIS)
      • Learning with errors (LWE)
      • Ring-LWE
      • NTRU
    • Interactive fun
    • Resources and notations
  • Asymmetric Cryptography
  • RSA
    • Proof of correctness
    • RSA application
    • Low Private Component Attacks
      • Wiener's Attack
      • Boneh-Durfee Attack
    • Common Modulus Attack
    • Recovering the Modulus
  • Diffie-Hellman
    • MITM
  • Elliptic Curve Cryptography
  • Symmetric Cryptography
    • Encryption
    • The One Time Pad
    • AES
      • Rijndael Finite Field
      • Round Transformations
  • Hashes
    • Introduction / overview
    • The Birthday paradox / attack
  • Isogeny Based Cryptography
    • Introduction to Isogeny Cryptography
    • Isogenies
    • Isogeny and Ramanujan Graphs
  • Appendices
    • Sets and Functions
    • Probability Theory
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Lattices

Interactive fun

PreviousNTRUNextResources and notations

Last updated 3 years ago

Was this helpful?

Inspired by:

Lattice + LLL + Fundamental mesh plot

@interact
def draw_lattice(v1x = input_box(label = "v1 x =", default = 1),
                 v1y = input_box(label = "v1 y =", default = 0),
                 v2x = input_box(label = "v2 x =", default = 0),
                 v2y = input_box(label = "v2 y =", default = 1),
                 box = 5, search = 10,
                 plot_LLL = True,
                 plot_C = True,
                 plot_F = True):

    v1 = vector((v1x, v1y))
    v2 = vector((v2x, v2y))
    vecs = []
    # Generate vectors
    for i in range(-search,search):
        for j in range(-search,search):
            vecs.append(i*v1 + j*v2)
    # Plot stuff
    G = Graphics()
    for p1 in vecs:
        x1, y1 = p1
        if x1 > -box and x1 < box and y1 > -box and y1 < box:
            G += point(p1, color = 'green', size = 30)
            G += line([p1, p1 + v2], linestyle = '--', alpha = .20)
            G += line([p1, p1 + v1], linestyle = '--', alpha = .20)
    G+= arrow((0, 0), v1, color = 'red', arrowsize = 2)
    G+= arrow((0, 0), v2, color = 'red', arrowsize = 2)
    G+= text('v1', v1 + .2 * v1, color = 'red')
    G+= text('v2', v2 + .2 * v2, color = 'red')
    
    # LLL
    if plot_LLL:
        v1_, v2_ = matrix([v1, v2]).LLL()
        G+= arrow((0, 0), v1_, color = 'purple', arrowsize = 2)
        G+= arrow((0, 0), v2_, color = 'purple', arrowsize = 2)
        if plot_C:
            G += circle(center = (0, 0), radius = norm(v1_) if norm(v1_) > norm(v2_) else norm(v2_), alpha = .5, color = 'purple')
    # Fundamental mesh
    if plot_F:
        F = polygon([[0, 0], v1, v1 + v2, v2], color='red', alpha = .1)
        G += F
    G.show(axes = False, figsize = (7, 7))

Lattice + CVP

@interact
def draw_cvp(v1x = input_box(label = "v1 x =", default = 1),
             v1y = input_box(label = "v1 y =", default = 0),
             v2x = input_box(label = "v2 x =", default = 0),
             v2y = input_box(label = "v2 y =", default = 1),
             wx = input_box(label = "w x =", default = 1.8),
             wy = input_box(label = "w y =", default = 1.7),
             box = 5, search = 10):

    v1 = vector((v1x, v1y))
    v2 = vector((v2x, v2y))
    print(v1, v2)
    vecs = []
    # Generate vectors
    for i in range(-search,search):
        for j in range(-search,search):
            vecs.append(i*v1 + j*v2)
    # Plot stuff
    G = Graphics()
    for p1 in vecs:
        x1, y1 = p1
        if x1 > -box and x1 < box and y1 > -box and y1 < box:
            G += point(p1, color = 'green', size = 30)
            G += line([p1, p1 + v2], linestyle = '--', alpha = .20)
            G += line([p1, p1 + v1], linestyle = '--', alpha = .20)
    G+= arrow((0, 0), v1, color = 'red', arrowsize = 2)
    G+= arrow((0, 0), v2, color = 'red', arrowsize = 2)
    G+= text('v1', v1 + .2 * v1, color = 'red')
    G+= text('v2', v2 + .2 * v2, color = 'red')         
    
    # Cvp
    L = IntegerLattice(matrix([v1, v2]))
    w = vector((wx, wy))
    t = L.closest_vector(w)
    G += point(w, color = 'purple', size = 30)
    G+= text('w', w + .2 * v1, color = 'purple')         

    G += point(t, color = 'red', size = 30)
    G+= text('t', t + .2 * v1, color = 'red')         
    G+= circle(center = w, radius=norm(t - w), color = 'purple', alpha = .5)
    G.show(axes = False, figsize = (7, 7))
@interact
def draw_dual(v1x = input_box(label = "v1 x =", default = 1),
                 v1y = input_box(label = "v1 y =", default = 0),
                 v2x = input_box(label = "v2 x =", default = 0),
                 v2y = input_box(label = "v2 y =", default = 1),
                 box = 3, search = 6,
                 plot_lattice_points = True,
                 plot_lattice_lines = True,
                 plot_dual_points = True,
                 plot_dual_lines = True):

    v1 = vector((v1x, v1y))
    v2 = vector((v2x, v2y))
    vecs = []
    v1_, v2_ = matrix([v1,v2]).inverse().T
    vecs_ = []
    # Generate vectors
    for i in range(-search,search):
        for j in range(-search,search):
            vecs.append(i*v1 + j*v2)
    for i in range(-search,search):
        for j in range(-search,search):
            vecs_.append(i*v1_ + j*v2_)
    # Plot stuff
    G = Graphics()
    for p1 in vecs:
        x1, y1 = p1
        if x1 > -box and x1 < box and y1 > -box and y1 < box:
            if plot_lattice_points:
                G += point(p1, color = 'green', size = 70)
            if plot_lattice_lines:
                G += line([p1, p1 + v2], linestyle = '--', alpha = .20, color = 'green')
                G += line([p1, p1 + v1], linestyle = '--', alpha = .20, color = 'green')
    if plot_lattice_lines:
        G+= arrow((0, 0), v1, color = 'green', arrowsize = 2)
        G+= arrow((0, 0), v2, color = 'green', arrowsize = 2)
        G+= text('v1', v1 + .2 * v1, color = 'green')
        G+= text('v2', v2 + .2 * v2, color = 'green')
    
    # Dual
    for p1 in vecs_:
        x1, y1 = p1
        if x1 > -box and x1 < box and y1 > -box and y1 < box:
            if plot_dual_points:
                G += point(p1, color = 'red', size = 25)
            if plot_dual_lines:
                G += line([p1, p1 + v2_], linestyle = '--', alpha = .20, color = 'red')
                G += line([p1, p1 + v1_], linestyle = '--', alpha = .20, color = 'red')
    if plot_dual_lines:
        G+= arrow((0, 0), v1_, color = 'red', arrowsize = 2)
        G+= arrow((0, 0), v2_, color = 'red', arrowsize = 2)
        G+= text('v1\'', v1_ + .2 * v1, color = 'red')
        G+= text('v2\'', v2_ + .2 * v2, color = 'red')
    
    G.show(axes = False, figsize = (7, 7))

Q-ary plots

# I'm not sure this does what is supposed to do
# but the plots are nice

from sage.modules.free_module_integer import IntegerLattice
@interact
def draw_qary(v1x = input_box(label = "v1 x =", default = 1),
                 v1y = input_box(label = "v1 y =", default = 0),
                 v2x = input_box(label = "v2 x =", default = 0),
                 v2y = input_box(label = "v2 y =", default = 1),
                 q = input_box(label = "q =", default = 5),
                 box = 7, search = 6,
                 plot_lattice_points = True,
                 plot_lattice_lines = True,
                 plot_qary_points = True,
                 plot_qary_lines = True):

    v1 = vector((v1x, v1y))
    v2 = vector((v2x, v2y))
    L = IntegerLattice(matrix([v1, v2]))
    vecs = []
    v1_ = v1.change_ring(Zmod(q))
    v2_ = v2.change_ring(Zmod(q))
    vecs_ = []
    # Generate vectors
    for i in range(-search,search):
        for j in range(-search,search):
            v = i*v1 + j*v2
            vecs.append(v)
            v = v.change_ring(Zmod(q)).change_ring(ZZ)
            if v not in vecs_:
                vecs_.append(v)
                
    # Lattice
    G = Graphics()
    for p1 in vecs:
        x1, y1 = p1
        if x1 > -box and x1 < box and y1 > -box and y1 < box:
            if plot_lattice_points:
                G += point(p1, color = 'green', size = 70)
            if plot_lattice_lines:
                G += line([p1, p1 + v2], linestyle = '--', alpha = .20, color = 'green')
                G += line([p1, p1 + v1], linestyle = '--', alpha = .20, color = 'green')
    if plot_lattice_lines:
        G+= arrow((0, 0), v1, color = 'green', arrowsize = 2)
        G+= arrow((0, 0), v2, color = 'green', arrowsize = 2)
        G+= text('v1', v1 + .2 * v1, color = 'green')
        G+= text('v2', v2 + .2 * v2, color = 'green')
    
    # qary
    for p1 in vecs_:
        p1 = p1
        x1, y1 = p1
        if x1 > -box and x1 < box and y1 > -box and y1 < box:
            if plot_qary_points:
                G += point(p1, color = 'red', size = 25)
            if plot_qary_lines:
                G += line([p1, p1 + v2_], linestyle = '--', alpha = .20, color = 'red')
                G += line([p1, p1 + v1_], linestyle = '--', alpha = .20, color = 'red')
    if plot_qary_lines:
        G+= arrow((0, 0), v1_, color = 'purple', arrowsize = 2)
        G+= arrow((0, 0), v2_, color = 'purple', arrowsize = 2)
        G+= text('v1\'', v1_.change_ring(ZZ) + .2 * v1, color = 'purple')
        G+= text('v2\'', v2_.change_ring(ZZ) + .2 * v2, color = 'purple')
    
    G.show(axes = False, figsize = (10, 10))
https://crypto.katestange.net/lattice-tools/