mirror of
https://github.com/luxfi/crypto.git
synced 2026-10-30 16:59:13 +00:00
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.
124 lines
3.3 KiB
Rust
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);
|
|
}
|