arcium-primitives 0.5.0

Arcium primitives
Documentation
use std::{fmt::Debug, hint::black_box, ops::Mul};

use typenum::{Logarithm2, PowerOfTwo};

use crate::{
    algebra::{
        field::FieldExtension,
        multivariate_ring::{Evaluation, MultivariateRing},
    },
    types::{HeapArray, Positive},
};

/// Domain-separated seed for deterministic derivation of the public QA-SD elements.
/// First 32 bytes of π (hex), reused as a nothing-up-my-sleeve value.
pub const QASD_PUBLIC_ELEMENT_SEED: [u8; 32] = [
    0x24, 0x3F, 0x6A, 0x88, 0x85, 0xA3, 0x08, 0xD3, 0x13, 0x19, 0x8A, 0x2E, 0x03, 0x70, 0x73, 0x44,
    0xA4, 0x09, 0x38, 0x22, 0x29, 0x9F, 0x31, 0xD0, 0x08, 0x2E, 0xFA, 0x98, 0xEC, 0x4E, 0x6C, 0x89,
];

/// Trait grouping core parameters and helpers for the Quasi-Abelian Syndrome Decoding (QA-SD)
/// assumption with regular SPFSS noise.
/// Protocol parameters extend this trait with protocol-specific constants.
pub trait QasdParams: Send + Unpin + Debug + Clone {
    /// Prime field
    type F: FieldExtension<Subfield = Self::F>;

    /// Output size (= BlockSize * T).
    type M: Positive + PowerOfTwo; // BlockSize * T

    /// Block size (= 2^N). SPFSS output size.
    type BlockSize: Positive + PowerOfTwo + Logarithm2<Output = Self::N>;

    /// log2 of the block size (lowercase `n` in [LLXY+26]).
    type N: Positive;

    /// Hamming weight of the error vector (lowercase `t` in the [LLXY+26]).
    /// The `Mul<U9/U3/U4>` bounds mirror `round_based_op::dpf::params::BatchSize`
    /// (T singlet/triple/Input* pools), which `primitives` cannot name directly.
    type T: Positive
        + Mul<typenum::U9, Output: Positive>
        + Mul<typenum::U3, Output: Positive>
        + Mul<typenum::U4, Output: Positive>
        + Mul<Self::T, Output = Self::TSquared>;

    /// Compression factor (lowercase `c` in the [LLXY+26]).
    type C: Positive + Mul<Self::C, Output = Self::CSquared>;

    /// T^2.
    type TSquared: Positive + Mul<Self::CSquared, Output: Positive>;

    /// C^2 · T^2.
    type K: Positive;

    /// C^2.
    type CSquared: Positive;

    /// C^2 · T.
    type TCSquared: Positive;

    /// Public QA-SD expansion elements: `(1, a_1, ..., a_{c-1})`, where `1` is the
    /// multiplicative identity and each `a_i` is a deterministically derived random
    /// ring element. Cached after the first call so every caller observes the same
    /// value.
    fn qasd_public_elements() -> HeapArray<MultivariateRing<Self::F, Self::M, Evaluation>, Self::C>;

    /// Warm up the cached QA-SD public elements so the first protocol run doesn't
    /// pay for the one-time derivation.
    fn warm_up() {
        black_box(Self::qasd_public_elements());
    }
}