foundry-mpc-rs 0.1.2

shamir-secret-sharing implementation forked from Lúcás C. Meier's cait_sith protocol and ZcashFoundation's frost
Documentation
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

use crate::point::Point256;

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]

pub struct KeysharePoints {
    keyshare_points: Vec<Point256>,
}

impl KeysharePoints {
    pub fn new(keyshare_points: Vec<Point256>) -> Result<Self, String> {
        if keyshare_points.len() < 2 {
            return Err("keyshare_points must have at least 2 points".to_string());
        }
        if !validate_x(&keyshare_points) {
            return Err("Duplicate x-coordinates found in keyshare_points".to_string());
        }
        Ok(Self { keyshare_points })
    }

    pub fn len(&self) -> usize {
        self.keyshare_points.len()
    }

    pub fn contain_point(&self, point: &Point256) -> bool {
        self.keyshare_points.contains(point)
    }

    pub fn to_point_vec(&self) -> Vec<Point256> {
        self.keyshare_points.clone()
    }
}

fn validate_x(keyshare_points: &Vec<Point256>) -> bool {
    let mut x_set = HashSet::new();
    for point in keyshare_points {
        if point.x == [0; 32] {
            return false;
        }
        if x_set.contains(&point.x) {
            return false;
        }
        x_set.insert(point.x);
    }
    true
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_check_duplicate_x() {
        let points = vec![
            Point256 {
                x: [0; 32],
                y: [0; 32],
            },
            Point256 {
                x: [0; 32],
                y: [0; 32],
            },
        ];
        assert!(!validate_x(&points));

        let points_2 = vec![
            Point256 {
                x: [1; 32],
                y: [0; 32],
            },
            Point256 {
                x: [0; 32],
                y: [0; 32],
            },
        ];
        assert!(!validate_x(&points_2));

        let points_3 = vec![
            Point256 {
                x: [1; 32],
                y: [0; 32],
            },
            Point256 {
                x: [2; 32],
                y: [0; 32],
            },
        ];
        assert!(validate_x(&points_3));
    }
}