Files
zeekay e3d6d39fe7 rust: ship 14 per-algorithm crates over real luxcpp/crypto C-ABI
Adds lux-crypto-{sha256, ripemd160, blake2b, aead, lamport, mldsa,
mlkem, slhdsa, banderwagon, pedersen, ipa, verkle, evm256, kzg} on
top of the existing keccak + secp256k1 + umbrella, gated on
verified-real C-ABI dispatch (nm shows the extern "C" symbols and
spec-vector integration tests assert byte-equality vs published
reference values).

Workspace test sweep (CRYPTO_BUILD_DIR=.../build-cto):
  182 passed, 0 failed, 4 ignored (slow SLH-DSA 192f/256f).

Per crate:
  * sha256       - 12 tests (FIPS 180-4 / RFC 6234)
  * ripemd160    - 14 tests (Dobbertin et al. 1996)
  * blake2b      - 13 tests (RFC 7693 App. A)
  * aead         - 11 tests (RFC 8439 §2.8.2)
  * lamport      - 5 tests / 10 KAT vectors (luxfi/crypto KAT corpus)
  * mldsa        - 13 tests (FIPS 204 modes 2/3/5)
  * mlkem        - 12 tests (FIPS 203 modes 2/3/5, implicit rejection)
  * slhdsa       - 9 + 4 ignored (FIPS 205 sha2/shake 128f)
  * banderwagon  - 14 tests (16 published 2^i*G doublings KAT)
  * pedersen     - 12 tests (Banderwagon SRS)
  * ipa          - 12 tests (576-byte multiproof)
  * verkle       - 12 tests (256-element SRS)
  * evm256       - 4 tests / 12 KAT vectors (BLS Fr, secp256k1 N, etc)
  * kzg          - 12 tests (verify_proof real; blob ops surfaced as
                  Internal(-5) since c_kzg_blob.cpp is in a separate
                  TU not yet linked into libkzg.a)

Refused to ship:
  * blake3, poseidon, ed25519, bls — c-abi entry points still return
    CRYPTO_ERR_NOTIMPL in luxcpp/crypto/<alg>/c-abi/c_<alg>.cpp.
  * poly_mul — c-abi file is empty, no extern "C" exports.

Build: CRYPTO_BUILD_DIR=/path/to/luxcpp/crypto/build-cto cargo test --workspace

Each crate's build.rs links lib<alg>.a (c-abi shim) + lib<alg>_cpu.a
(implementation body); shared dependencies (sha256 for kzg+lamport,
banderwagon for pedersen+ipa+verkle, ipa SRS for pedersen, blst for
kzg, banderwagon_metal stub on macOS) are explicitly linked.

COVERAGE.md updated: 17 member crates, 182/182 tests passing,
deferred algorithms documented with their current c-abi status.
2025-12-28 01:09:03 -08:00

124 lines
3.3 KiB
Rust

// Copyright (c) 2024-2026 Lux Industries Inc.
// SPDX-License-Identifier: BSD-3-Clause-Eco
//
// Verkle spec-vector integration test. The Verkle commitment uses the same
// 256-element Banderwagon SRS as IPA, so byte-equality is asserted on the
// canonical zero-coefficient commit, plus deterministic + isolation
// checks.
use lux_crypto_verkle::{commit, multiproof_verify, Error, COEFF_LEN, COMMIT_LEN, MAX_SRS_LEN, PROOF_LEN};
fn from_hex<const N: usize>(s: &str) -> [u8; N] {
let s = s.as_bytes();
assert_eq!(s.len(), 2 * N);
let mut out = [0u8; N];
let nibble = |c: u8| match c {
b'0'..=b'9' => c - b'0',
b'a'..=b'f' => c - b'a' + 10,
b'A'..=b'F' => c - b'A' + 10,
_ => panic!("non-hex"),
};
for i in 0..N {
out[i] = (nibble(s[2 * i]) << 4) | nibble(s[2 * i + 1]);
}
out
}
const IDENTITY_HEX: &str = "0000000000000000000000000000000000000000000000000000000000000000";
#[test]
fn empty_commit_is_identity() {
let want: [u8; COMMIT_LEN] = from_hex(IDENTITY_HEX);
let got = commit(&[]).unwrap();
assert_eq!(got, want);
}
#[test]
fn all_zero_coefficients_is_identity() {
let want: [u8; COMMIT_LEN] = from_hex(IDENTITY_HEX);
let coeffs = vec![0u8; 16 * COEFF_LEN];
let got = commit(&coeffs).unwrap();
assert_eq!(got, want);
}
#[test]
fn single_one_coefficient_at_zero_position_matches_g0() {
// commit([1, 0, 0, ...]) is the SRS generator G_0; commit([1]) gives the
// same value.
let mut a = vec![0u8; COEFF_LEN];
a[31] = 1;
let mut b = vec![0u8; 8 * COEFF_LEN];
b[31] = 1;
let ca = commit(&a).unwrap();
let cb = commit(&b).unwrap();
assert_eq!(ca, cb);
}
#[test]
fn deterministic_commit() {
let mut coeffs = vec![0u8; 8 * COEFF_LEN];
for i in 0..8 {
coeffs[i * COEFF_LEN + 31] = (i as u8) + 1;
}
assert_eq!(commit(&coeffs).unwrap(), commit(&coeffs).unwrap());
}
#[test]
fn distinct_coefficients_distinct_commit() {
let mut a = vec![0u8; 4 * COEFF_LEN];
a[31] = 7;
let mut b = vec![0u8; 4 * COEFF_LEN];
b[31] = 11;
assert_ne!(commit(&a).unwrap(), commit(&b).unwrap());
}
#[test]
fn over_srs_rejected() {
let too_many = vec![0u8; (MAX_SRS_LEN + 1) * COEFF_LEN];
assert_eq!(commit(&too_many).unwrap_err(), Error::LengthExceeded);
}
#[test]
fn misaligned_input_rejected() {
let bad = vec![0u8; COEFF_LEN - 1];
assert_eq!(commit(&bad).unwrap_err(), Error::BadInput);
}
#[test]
fn full_srs_commit_succeeds() {
let coeffs = vec![0u8; MAX_SRS_LEN * COEFF_LEN];
commit(&coeffs).expect("full SRS commit");
}
#[test]
fn multiproof_verify_rejects_zero_queries() {
let proof = [0u8; PROOF_LEN];
assert!(multiproof_verify(&[], &[], &[], &proof).is_err());
}
#[test]
fn multiproof_verify_rejects_invalid_proof() {
let proof = [0xffu8; PROOF_LEN];
let cs = vec![0u8; 32];
let ys = vec![0u8; 32];
let zs = vec![0u8; 1];
assert!(multiproof_verify(&cs, &ys, &zs, &proof).is_err());
}
#[test]
fn multiproof_verify_rejects_mismatched_lengths() {
let proof = [0u8; PROOF_LEN];
let cs = vec![0u8; 64];
let ys = vec![0u8; 32];
let zs = vec![0u8; 1];
assert!(multiproof_verify(&cs, &ys, &zs, &proof).is_err());
}
#[test]
fn lengths_match_constants() {
assert_eq!(COMMIT_LEN, 32);
assert_eq!(COEFF_LEN, 32);
assert_eq!(PROOF_LEN, 576);
assert_eq!(MAX_SRS_LEN, 256);
}