hop-core 0.1.1

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, (xi_u64, yi)) in points.iter().enumerate() {
        let xi_f = Field::new(*xi_u64 as u128);
        let mut num = Field::one();
        let mut den = Field::one();
        for (j, (xj_u64, _)) in points.iter().enumerate() {
            if i == j { continue; }
            let xj_f = Field::new(*xj_u64 as u128);
            num = num.mul(Field::zero().sub(xj_f));      // -x_j
            den = den.mul(xi_f.sub(xj_f));               // x_i - x_j
        }
        if let Some(inv) = den.inv() {
            let li = num.mul(inv);
            acc = acc.add(yi.mul(li));
        } 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
    }
}