hop-core 0.1.0

HOP core — finite-field companion-matrix stream primitives (prototype)
Documentation
// Copyright (c) 2025 Lex Luger. All Rights Reserved.
// This software (HOP-CORE) is proprietary and confidential.
// Unauthorized copying, distribution, or use is strictly prohibited
// without explicit written permission from the author.
// Commercial licenses are available. Contact: lexluger.dev@proton.me
use crate::modules::field::Field;
use std::ops::{Add, Sub, Mul};

/// Minimal Shamir-style VSS for prototype use only.
/// Shares a secret s (Field) into n shares with threshold t.
/// This is a toy helper for demonstration; not hardened for production.
use rand::Rng;

pub fn interpolate_at_zero(points: &[(u64, Field)]) -> Field {
    // Lagrange interpolation at x=0
    let mut acc = Field::zero();
    for i in 0..points.len() {
        let (xi, yi) = (points[i].0 as u128, points[i].1);
        let mut num = Field::one();
        let mut den = Field::one();
        for (j, (xj_u64, _yj)) in points.iter().enumerate() {
            if i == j { continue; }
            let xj = *xj_u64 as u128;
            let xi_f = Field::new(xi);
            let xj_f = Field::new(xj);
            num = num.mul(xj_f.mul(Field::one())); // x_j
            den = den.mul(xj_f.sub(xi_f)); // x_j - x_i
        }
        if let Some(inv) = den.inv() {
            acc = acc.add(yi.mul(num).mul(inv));
        } else {
            panic!("Denominator not invertible in interpolation");
        }
    }
    acc
}

pub struct ShamirVSS;

impl ShamirVSS {
    /// Create shares using random polynomial of degree t-1 with constant term secret
    pub fn share(secret: Field, n: usize, t: usize) -> Vec<(u64, Field)> {
        assert!(t <= n && t >= 1);
        let mut rng = rand::rng();
        let mut coeffs: Vec<Field> = Vec::with_capacity(t);
        coeffs.push(secret);
        for _ in 1..t {
            let r: u64 = rng.random_range(0..Field::MOD);
            coeffs.push(Field::new(r as u128));
        }
        let mut shares = Vec::with_capacity(n);
        for i in 1..=n {
            let x = Field::new(i as u128);
            let mut y = Field::zero();
            let mut pow = Field::one();
            for c in &coeffs {
                y = y.add(c .mul(pow));
                pow = pow.mul(x);
            }
            shares.push((i as u64, y));
        }
        shares
    }
}