LatticeChallenge.org - Submission Form Example

Complete Submission Guide for All Challenges

What You Submit (The Math)

For SVP & Ideal Lattice Challenges: Integer Coefficient Vector

NOT the actual short vector itself! You submit the integer coefficients that express your short vector as a linear combination of the original basis.

Mathematical explanation:

Given: Basis B = {b₁, b₂, ..., bₙ}
You found: Short vector v ∈ L(B)
Submit: Integer coefficients (c₁, c₂, ..., cₙ) such that:
        v = c₁·b₁ + c₂·b₂ + ... + cₙ·bₙ

Why? This proves you actually found a lattice vector (not just any short vector in ℝⁿ)

For LWE Challenge: The Secret Vector

You submit s ∈ ℤₙ (the secret vector you recovered)


Exact Submission Formats

1. SVP Challenge Format

File format: Plain text file with integers

Format of submission file:
- One integer per line
- Exactly n integers (dimension of the lattice)
- These are the coefficients c₁, c₂, ..., cₙ

Example: For a 40-dimensional challenge where you found v = 2b₁ - 3b₂ + 0b₃ + 1b₄ + ...

svp_solution.txt:
2
-3
0
1
5
-2
...
(40 lines total)

Julia code to generate this:

"""
Generate submission file for SVP/Ideal challenges
v: your short vector (the actual vector in ℝⁿ)
B: original basis from challenge file
"""
function generate_svp_submission(v::Vector{Float64}, B::Matrix{Int}, 
                                 output_file::String)
    # Solve: B^T · c = v  (find integer coefficients)
    # Note: B is n×n, each row is a basis vector
    
    # Convert basis to column vectors for solving
    B_matrix = transpose(B)  # Now columns are basis vectors
    
    # Solve the linear system
    c_float = B_matrix \ v
    
    # Round to integers
    c = round.(Int, c_float)
    
    # Verify the solution (important!)
    v_reconstructed = transpose(B) * c  # B^T has basis vectors as columns
    error = norm(v_reconstructed - v)
    
    if error > 1e-6
        error("Verification failed! Error = $error")
        println("This vector might not be in the lattice!")
        return false
    end
    
    # Write to file
    open(output_file, "w") do io
        for coeff in c
            println(io, coeff)
        end
    end
    
    println("✓ Submission file created: $output_file")
    println("  Vector norm: $(norm(v))")
    println("  Coefficients: $c")
    println("  Verification error: $error")
    
    return true
end

# Example usage:
# B = parse_challenge_file("svpchallenge-40-seed0.txt")
# v = B[1, :]  # Assume first basis vector is your short vector
# generate_svp_submission(v, B, "solution_40_seed0.txt")

What they verify:

  1. All coefficients are integers ✓
  2. v = Bc has the claimed norm ✓
  3. Norm is below the threshold ✓

2. Ideal Lattice Challenge Format

Exactly same as SVP Challenge!

Two separate submission portals though:

  • SVP Hall of Fame: If ||v|| < √(γₙ·n) where γₙ ≈ n/(2πe)
  • Approx-SVP Hall of Fame: If √(γₙ·n) ≤ ||v|| < √n · n^(1/4)

Same file format:

ideal_solution.txt:
<coefficient 1>
<coefficient 2>
...
<coefficient n>

Julia helper:

function generate_ideal_submission(v::Vector{Float64}, B::Matrix{Int},
                                   dimension::Int, index::Int, seed::Int,
                                   output_file::String)
    # Same as SVP submission
    success = generate_svp_submission(v, B, output_file)
    
    if !success
        return false
    end
    
    # Additional: Check which hall of fame
    n = dimension
    γ_n = n / (2 * π * ℯ)
    
    svp_threshold = sqrt(γ_n * n)
    approx_threshold = sqrt(n) * n^0.25
    
    norm_v = norm(v)
    
    println("\n" * "="^60)
    if norm_v < svp_threshold
        println("✓ ELIGIBLE for SVP Hall of Fame")
        println("  Norm: $norm_v < $svp_threshold")
        println("  Submit to: SVP section")
    elseif norm_v < approx_threshold
        println("✓ ELIGIBLE for Approx-SVP Hall of Fame")
        println("  Norm: $norm_v < $approx_threshold")
        println("  Submit to: Approx-SVP section")
    else
        println("✗ Not eligible for either hall of fame")
        println("  Norm: $norm_v")
        println("  Need: < $approx_threshold")
    end
    println("="^60)
    
    return true
end

3. LWE Challenge Format

File format: Plain text, one integer per line

Format:
- First n integers: the secret vector s
- Each integer in range [0, q)

Example: For n=40, q=1021, if you recovered s = [5, 923, 0, 1021, ...]

lwe_solution.txt:
5
923
0
1021
234
...
(40 lines total)

Julia code:

"""
Generate LWE submission file
s: recovered secret vector (length n)
A, b, q: original challenge parameters (for verification)
"""
function generate_lwe_submission(s::Vector{Int}, A::Matrix{Int}, 
                                b::Vector{Int}, q::Int,
                                output_file::String)
    n = length(s)
    m = length(b)
    
    # Reduce to [0, q) range
    s_mod = s .% q
    
    # CRITICAL VERIFICATION: Check As ≡ b (mod q)
    b_computed = (A * s_mod) .% q
    
    # Compute error
    error_vector = (b - b_computed) .% q
    
    # Normalize error to [-q/2, q/2] for better display
    error_vector = map(e -> e > q/2 ? e - q : e, error_vector)
    
    max_error = maximum(abs.(error_vector))
    rms_error = sqrt(mean(error_vector.^2))
    
    println("\n" * "="^60)
    println("LWE Solution Verification")
    println("="^60)
    println("Parameters: n=$n, m=$m, q=$q")
    println("Max error: $max_error")
    println("RMS error: $rms_error")
    
    # Determine if solution is correct
    # Small error = noise vector (correct!)
    # Large error = wrong solution
    
    expected_noise = sqrt(n) * 4  # Rough heuristic
    
    if max_error < min(50, q/10)
        println("✓ VERIFICATION PASSED - This looks correct!")
        println("  Error is consistent with noise vector")
        
        # Write to file
        open(output_file, "w") do io
            for val in s_mod
                println(io, val)
            end
        end
        
        println("\n✓ Submission file created: $output_file")
        return true
        
    else
        println("✗ VERIFICATION FAILED")
        println("  Error too large: $max_error (expected < $expected_noise)")
        println("  This is likely NOT the correct secret!")
        return false
    end
end

# Example usage:
# n, m, q, A, b = parse_lwe_challenge("lwe_challenge.txt")
# s = solve_lwe_lattice_attack("lwe_challenge.txt")
# generate_lwe_submission(s, A, b, q, "lwe_solution.txt")

What they verify:

  1. All values in [0, q) ✓
  2. Compute b' = As mod q ✓
  3. Check ||b - b'|| is small (consistent with noise) ✓

4. TU Darmstadt (Ajtai) Challenge Format

Same as SVP Challenge - integer coefficients

Format: One integer per line (n integers total)

How to Submit (The Process)

Method 1: Web Form (Recommended)

Each challenge has an online submission form:

SVP Challenge:

1. Go to: https://www.latticechallenge.org/svp-challenge/
2. Click green cell for your dimension/seed
3. Click "Submit Solution"
4. Fill out form:
   - Name/Affiliation
   - Email
   - Upload solution file OR paste coefficients
   - Method used (optional description)

Ideal Lattice:

1. Go to: https://www.latticechallenge.org/ideal-lattice-challenge/
2. Choose dimension/index/seed
3. Two submission buttons:
   - "Submit to SVP Hall" 
   - "Submit to Approx-SVP Hall"
4. Fill form similar to above

LWE Challenge:

1. Go to: https://www.latticechallenge.org/lwe-challenge/
2. Click the green cell for (n, α) pair
3. Fill submission form
4. Upload solution file

Method 2: Email (Backup)

If web form fails:

To: lattice-challenge@cdc.informatik.tu-darmstadt.de
Subject: Solution for [Challenge Type] - Dimension [n]

Body:
Name: Your Name
Affiliation: Your University
Challenge: SVP Challenge, n=120, seed=0
Method: BKZ-50 + sieving
Compute time: 48 hours on 16-core machine

Attachment: solution_120_seed0.txt

Complete Julia Workflow: From Solve to Submit

"""
Complete workflow: Solve and prepare submission
"""
function solve_and_submit(challenge_file::String, 
                         your_name::String, 
                         your_email::String,
                         method_description::String="BKZ + Julia")
    
    println("="^60)
    println("LATTICE CHALLENGE SOLVER & SUBMITTER")
    println("="^60)
    
    # Step 1: Detect challenge type
    if contains(challenge_file, "lwe")
        return solve_submit_lwe(challenge_file, your_name, your_email, method_description)
    elseif contains(challenge_file, "ideal")
        return solve_submit_ideal(challenge_file, your_name, your_email, method_description)
    else
        return solve_submit_svp(challenge_file, your_name, your_email, method_description)
    end
end

"""
SVP/Ideal solving and submission
"""
function solve_submit_svp(challenge_file::String, name::String, 
                         email::String, method::String)
    
    # Parse challenge
    B = parse_challenge_file(challenge_file)
    n = size(B, 1)
    
    println("\nChallenge: $challenge_file")
    println("Dimension: $n")
    
    target = sqrt(4/3 * n)  # SVP challenge target
    println("Target norm: < $target")
    
    # Solve
    println("\nPhase 1: LLL reduction")
    B_reduced = deep_LLL(B, rounds=20)
    
    if norm(B_reduced[1, :]) < target
        println("✓ Deep LLL sufficient!")
    else
        println("\nPhase 2: BKZ reduction")
        B_reduced = progressive_BKZ(B_reduced, 
                                   block_sizes=[20, 30, 40, 50],
                                   tours_per_size=2)
    end
    
    shortest_vector = B_reduced[1, :]
    actual_norm = norm(shortest_vector)
    
    println("\n" * "="^60)
    println("RESULT")
    println("="^60)
    println("Shortest vector norm: $actual_norm")
    println("Target: < $target")
    
    if actual_norm >= target
        println("✗ Did not meet target. Need more reduction.")
        return nothing
    end
    
    println("✓ SUCCESS!")
    
    # Generate submission file
    submission_file = replace(challenge_file, ".txt" => "_SUBMIT.txt")
    
    success = generate_svp_submission(shortest_vector, B, submission_file)
    
    if !success
        return nothing
    end
    
    # Create submission metadata
    metadata_file = replace(submission_file, ".txt" => "_metadata.txt")
    open(metadata_file, "w") do io
        println(io, "Challenge: $challenge_file")
        println(io, "Name: $name")
        println(io, "Email: $email")
        println(io, "Dimension: $n")
        println(io, "Achieved norm: $actual_norm")
        println(io, "Target norm: $target")
        println(io, "Method: $method")
        println(io, "Date: $(now())")
    end
    
    println("\n" * "="^60)
    println("SUBMISSION READY")
    println("="^60)
    println("Solution file: $submission_file")
    println("Metadata: $metadata_file")
    println("\nNext steps:")
    println("1. Verify files look correct")
    println("2. Go to challenge website")
    println("3. Upload $submission_file")
    println("4. Include metadata in description box")
    
    return submission_file
end

"""
LWE solving and submission
"""
function solve_submit_lwe(challenge_file::String, name::String,
                         email::String, method::String)
    
    # Parse challenge
    n, m, q, A, b = parse_lwe_challenge(challenge_file)
    
    println("\nLWE Challenge: $challenge_file")
    println("Parameters: n=$n, m=$m, q=$q")
    
    # Solve using automatic method selection
    s = solve_lwe_challenge_auto(challenge_file)
    
    if isnothing(s)
        println("✗ Failed to solve challenge")
        return nothing
    end
    
    # Generate submission
    submission_file = replace(challenge_file, ".txt" => "_SUBMIT.txt")
    
    success = generate_lwe_submission(s, A, b, q, submission_file)
    
    if !success
        return nothing
    end
    
    # Metadata
    metadata_file = replace(submission_file, ".txt" => "_metadata.txt")
    open(metadata_file, "w") do io
        println(io, "Challenge: $challenge_file")
        println(io, "Name: $name")
        println(io, "Email: $email")
        println(io, "Parameters: n=$n, m=$m, q=$q")
        println(io, "Method: $method")
        println(io, "Date: $(now())")
    end
    
    println("\n✓ Submission ready: $submission_file")
    
    return submission_file
end

Pre-Submission Checklist

"""
Validate your submission before uploading
"""
function validate_submission(solution_file::String, challenge_file::String)
    
    println("="^60)
    println("VALIDATING SUBMISSION")
    println("="^60)
    
    # Read solution
    coeffs = parse.(Int, readlines(solution_file))
    
    # Read original challenge
    if contains(challenge_file, "lwe")
        # LWE validation
        n, m, q, A, b = parse_lwe_challenge(challenge_file)
        
        if length(coeffs) != n
            println("✗ FAIL: Wrong number of coefficients")
            println("  Expected: $n, Got: $(length(coeffs))")
            return false
        end
        
        # Check range
        if !all(0 .<= coeffs .< q)
            println("✗ FAIL: Coefficients out of range [0, $q)")
            return false
        end
        
        # Verify solution
        s = coeffs
        b_computed = (A * s) .% q
        error = norm((b - b_computed) .% q)
        
        println("✓ Format correct: $n integers in [0, $q)")
        println("✓ Verification error: $error")
        
        if error > min(100, q/5)
            println("⚠ Warning: Large error, solution might be wrong")
        else
            println("✓ Solution appears correct!")
        end
        
    else
        # SVP/Ideal validation
        B = parse_challenge_file(challenge_file)
        n = size(B, 1)
        
        if length(coeffs) != n
            println("✗ FAIL: Wrong number of coefficients")
            return false
        end
        
        # Reconstruct vector
        v = transpose(B) * coeffs
        v_norm = norm(v)
        
        # Check target
        target = sqrt(4/3 * n)
        
        println("✓ Format correct: $n integer coefficients")
        println("✓ Reconstructed vector norm: $v_norm")
        println("  Target: < $target")
        
        if v_norm >= target
            println("✗ FAIL: Norm too large!")
            return false
        else
            println("✓ Meets target!")
        end
    end
    
    println("\n✓ VALIDATION PASSED - Ready to submit!")
    return true
end

# Example:
# validate_submission("solution_120_seed0_SUBMIT.txt", 
#                    "svpchallenge-120-seed0.txt")

What Happens After Submission

Their Verification Process:

  1. Automated checks:

    • File format correct? ✓
    • Right number of coefficients? ✓
    • All integers? ✓
  2. Mathematical verification:

    • SVP/Ideal: Compute v = Bc, check norm
    • LWE: Compute As mod q, check error
  3. Ranking:

    • Compare to existing solutions
    • Update hall of fame if you:
      • Solved new dimension, OR
      • Found shorter vector in existing dimension
  4. Notification:

    • Email confirmation (success/failure)
    • Hall of fame updated within 24-48 hours

Common Submission Errors

"""
Debug common submission issues
"""
function debug_submission(solution_file::String)
    
    println("Debugging: $solution_file\n")
    
    lines = readlines(solution_file)
    
    # Check 1: Blank lines
    if any(isempty.(strip.(lines)))
        println("⚠ Found blank lines - remove them!")
    end
    
    # Check 2: Non-integer values
    try
        coeffs = parse.(Int, lines)
    catch e
        println("✗ Error: Non-integer values found")
        println("  Make sure all lines are integers")
        return false
    end
    
    # Check 3: Scientific notation
    if any(contains.(lines, "e") .|| contains.(lines, "E"))
        println("✗ Error: Scientific notation detected")
        println("  Use plain integers: 12345 not 1.2345e4")
        return false
    end
    
    # Check 4: Floating point
    if any(contains.(lines, "."))
        println("✗ Error: Decimal points detected")
        println("  All coefficients must be integers")
        return false
    end
    
    println("✓ Format looks good!")
    return true
end

Quick Reference Card

╔══════════════════════════════════════════════════════════╗
║           LATTICE CHALLENGE SUBMISSION CHEAT SHEET       ║
╠══════════════════════════════════════════════════════════╣
║ WHAT TO SUBMIT:                                          ║
║                                                          ║
║ SVP/Ideal:      Integer coefficients (c₁, c₂, ..., cₙ)  ║
║                 such that v = c₁b₁ + c₂b₂ + ... + cₙbₙ  ║
║                                                          ║
║ LWE:            Secret vector s = (s₁, s₂, ..., sₙ)     ║
║                 where each sᵢ ∈ [0, q)                   ║
║                                                          ║
║ FORMAT:         Plain text, one integer per line        ║
║                                                          ║
║ VERIFICATION:                                            ║
║   SVP/Ideal:    ||Bc|| < threshold                       ║
║   LWE:          ||As - b||_∞ small (noise level)        ║
║                                                          ║
║ SUBMIT VIA:     Web form (preferred) or email           ║
╚══════════════════════════════════════════════════════════╝

Final Example: Complete Workflow

# Download challenge
download("https://www.latticechallenge.org/svp-challenge/...", 
         "challenge.txt")

# Solve and prepare submission
solve_and_submit(
    "challenge.txt",
    "Your Name",
    "your.email@university.edu",
    "Progressive BKZ-50 on 32-core AMD EPYC, 12 hours runtime"
)

# This creates:
# - challenge_SUBMIT.txt (your solution)
# - challenge_SUBMIT_metadata.txt (description)

# Validate before uploading
validate_submission("challenge_SUBMIT.txt", "challenge.txt")

# If validation passes:
# 1. Go to website
# 2. Upload challenge_SUBMIT.txt
# 3. Copy metadata into description field
# 4. Submit! 

That's it! The submission format is actually quite simple - just integers in a text file. The hard part is finding those integers that represent a short vector!