mirror of
https://github.com/vacp2p/mdsecheck.git
synced 2026-01-09 15:08:01 -05:00
Everything except docs, comments and autotests
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
427
Cargo.lock
generated
Normal file
427
Cargo.lock
generated
Normal file
@@ -0,0 +1,427 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "ark-ff"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70"
|
||||
dependencies = [
|
||||
"ark-ff-asm",
|
||||
"ark-ff-macros",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"arrayvec",
|
||||
"digest",
|
||||
"educe",
|
||||
"itertools",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"paste",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ff-asm"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-ff-macros"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-poly"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"ark-ff",
|
||||
"ark-serialize",
|
||||
"ark-std",
|
||||
"educe",
|
||||
"fnv",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-serialize"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7"
|
||||
dependencies = [
|
||||
"ark-serialize-derive",
|
||||
"ark-std",
|
||||
"arrayvec",
|
||||
"digest",
|
||||
"num-bigint",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-serialize-derive"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ark-std"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "educe"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
|
||||
dependencies = [
|
||||
"enum-ordinalize",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "enum-ordinalize"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5"
|
||||
dependencies = [
|
||||
"enum-ordinalize-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum-ordinalize-derive"
|
||||
version = "4.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "mdsecheck"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ark-ff",
|
||||
"ark-poly",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "mdsecheck"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ark-ff = { version = "0.5.0", default-features = false, features = ["asm"] }
|
||||
ark-poly = "0.5.0"
|
||||
rand = "0.8.5"
|
||||
77
src/lib.rs
Normal file
77
src/lib.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use ark_ff::PrimeField;
|
||||
use ark_poly::{polynomial::univariate::DensePolynomial, DenseUVPolynomial, Polynomial};
|
||||
use rand::Rng;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub mod mat;
|
||||
pub mod num;
|
||||
pub mod poly;
|
||||
|
||||
pub fn random_cauchy<F: PrimeField>(n: u32, r: &mut (impl Rng + ?Sized)) -> Option<Vec<Vec<F>>> {
|
||||
if (n == 0) || (F::MODULUS < F::BigInt::from(n as u64 * 2)) {
|
||||
return None;
|
||||
}
|
||||
let n = n as usize;
|
||||
let mut d = HashSet::with_capacity(2 * n);
|
||||
for _ in 0..2 * n {
|
||||
while !d.insert(F::rand(r)) {}
|
||||
}
|
||||
let mut m = Vec::with_capacity(n);
|
||||
for y in d.iter().skip(n) {
|
||||
let mut v = Vec::with_capacity(n);
|
||||
for x in d.iter().take(n) {
|
||||
v.push((*x - y).inverse().unwrap());
|
||||
}
|
||||
m.push(v);
|
||||
}
|
||||
Some(m)
|
||||
}
|
||||
|
||||
pub fn secure_rounds<F: PrimeField>(a: &[impl AsRef<[F]>], l: usize) -> Option<usize> {
|
||||
if l == 0 {
|
||||
return None;
|
||||
}
|
||||
let n: usize = a.len();
|
||||
let mut m = Vec::<Vec<F>>::with_capacity(n);
|
||||
m.push(vec![F::ONE; n]);
|
||||
for i in 0..n - 1 {
|
||||
m.push(mat::product_vector(a, &m[i])?);
|
||||
}
|
||||
let b = mat::product_vector(a, &m[n - 1])?;
|
||||
for y in 0..n {
|
||||
for x in 0..y {
|
||||
(m[y][x], m[x][y]) = (m[x][y], m[y][x]);
|
||||
}
|
||||
}
|
||||
let mut s = mat::unique_solution(&m, &b)?;
|
||||
s.iter_mut().for_each(|e| *e = -*e);
|
||||
s.push(F::ONE);
|
||||
let c = DensePolynomial::<F>::from_coefficients_vec(s);
|
||||
let f = num::prime_divisors(n as u32)
|
||||
.into_iter()
|
||||
.map(|e| n / e as usize)
|
||||
.collect::<HashSet<usize>>();
|
||||
let mut y: Vec<DensePolynomial<F>> = Vec::<DensePolynomial<F>>::with_capacity(f.len());
|
||||
let x = poly::new(&[0u64, 1u64]);
|
||||
let mut r = x.clone();
|
||||
for d in 1..=n / 2 {
|
||||
r = poly::power_modulo(&r, F::characteristic(), &c)?;
|
||||
if poly::nonmonic_gcd(&(&r - &x), &c).degree() > 0 {
|
||||
return None;
|
||||
}
|
||||
if f.contains(&d) {
|
||||
y.push(r.clone());
|
||||
}
|
||||
}
|
||||
let (mut g, mut h) = (x.clone(), y.clone());
|
||||
for i in 2..=l {
|
||||
g = poly::reduced_modulo(&(&g * &x), &c)?;
|
||||
for (v, u) in h.iter_mut().zip(y.iter()) {
|
||||
*v = poly::reduced_modulo(&(&*v * u), &c)?;
|
||||
if *v == g {
|
||||
return Some(i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(l)
|
||||
}
|
||||
94
src/mat.rs
Normal file
94
src/mat.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use ark_ff::Field;
|
||||
|
||||
pub fn product_vector<F: Field>(a: &[impl AsRef<[F]>], b: &[F]) -> Option<Vec<F>> {
|
||||
let k = b.len();
|
||||
if (k == 0) || a.is_empty() {
|
||||
// Either the matrix or the vector is empty
|
||||
return None;
|
||||
}
|
||||
if a.iter().any(|s| s.as_ref().len() != k) {
|
||||
// The arguments are not a matrix-vector pair for which the product is defined
|
||||
return None;
|
||||
}
|
||||
let mut v = Vec::<F>::with_capacity(a.len());
|
||||
for s in a.iter() {
|
||||
let s = s.as_ref();
|
||||
v.push((0..k).map(|i| s[i] * b[i]).sum());
|
||||
}
|
||||
Some(v)
|
||||
}
|
||||
|
||||
pub fn product_matrix<F: Field>(
|
||||
a: &[impl AsRef<[F]>],
|
||||
b: &[impl AsRef<[F]>],
|
||||
) -> Option<Vec<Vec<F>>> {
|
||||
let k = b.len();
|
||||
if (k == 0) || a.is_empty() {
|
||||
// Some matrix is empty
|
||||
return None;
|
||||
}
|
||||
let c = b[0].as_ref().len();
|
||||
if a.iter().any(|s| s.as_ref().len() != k) || (0..k).any(|y| b[y].as_ref().len() != c) {
|
||||
// The arguments are not matrices for which the product is defined
|
||||
return None;
|
||||
}
|
||||
let mut m = Vec::<Vec<F>>::with_capacity(a.len());
|
||||
for s in a.iter() {
|
||||
let mut l = Vec::<F>::with_capacity(c);
|
||||
let s = s.as_ref();
|
||||
for x in 0..c {
|
||||
l.push((0..k).map(|i| s[i] * b[i].as_ref()[x]).sum());
|
||||
}
|
||||
m.push(l);
|
||||
}
|
||||
Some(m)
|
||||
}
|
||||
|
||||
pub fn unique_solution<F: Field>(a: &[impl AsRef<[F]>], b: &[F]) -> Option<Vec<F>> {
|
||||
let n = a.len();
|
||||
if n == 0 {
|
||||
// The matrix is empty
|
||||
return None;
|
||||
}
|
||||
if b.len() != n {
|
||||
// The heights of the matrix and column vector are different
|
||||
return None;
|
||||
}
|
||||
let mut m = Vec::<Vec<F>>::with_capacity(n);
|
||||
for (r, v) in a.iter().zip(b.iter()) {
|
||||
let r = r.as_ref();
|
||||
if r.len() != n {
|
||||
// The first argument is not a square matrix
|
||||
return None;
|
||||
}
|
||||
m.push([r, &[*v][..]].concat());
|
||||
}
|
||||
for r in 0..n {
|
||||
if m[r][r] == F::ZERO {
|
||||
if let Some(p) = (r + 1..n).find(|y| m[*y][r] != F::ZERO) {
|
||||
m.swap(r, p);
|
||||
} else {
|
||||
// The matrix is singular
|
||||
return None;
|
||||
}
|
||||
}
|
||||
let c = m[r][r];
|
||||
m[r][r] = F::ONE;
|
||||
for x in r + 1..=n {
|
||||
m[r][x] /= c;
|
||||
}
|
||||
for y in r + 1..n {
|
||||
let c = m[y][r];
|
||||
m[y][r] = F::ZERO;
|
||||
for x in r + 1..=n {
|
||||
m[y][x] = m[y][x] - c * m[r][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
for r in (1..n).rev() {
|
||||
for y in 0..r {
|
||||
m[y][n] = m[y][n] - m[y][r] * m[r][n];
|
||||
}
|
||||
}
|
||||
Some((0..n).map(|y| m[y][n]).collect())
|
||||
}
|
||||
45
src/num.rs
Normal file
45
src/num.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
pub fn reversed_bits(n: &[u64]) -> impl Iterator<Item = bool> + '_ {
|
||||
n.iter()
|
||||
.rev()
|
||||
.copied()
|
||||
.skip_while(|c| *c == 0)
|
||||
.map(|c| c.reverse_bits())
|
||||
.flat_map(|c| (0..64).map(move |b| c & (1 << b) != 0))
|
||||
.skip_while(|b| !b)
|
||||
}
|
||||
|
||||
pub fn prime_divisors(mut n: u32) -> Vec<u32> {
|
||||
if n < 2 {
|
||||
return vec![];
|
||||
}
|
||||
let mut p = Vec::with_capacity(n.ilog2() as usize);
|
||||
if n & 1 == 0 {
|
||||
p.push(2);
|
||||
n >>= n.trailing_zeros();
|
||||
}
|
||||
fn extract(f: u32, m: &mut u32, l: &mut Vec<u32>) {
|
||||
l.push(f);
|
||||
*m /= f;
|
||||
while *m % f == 0 {
|
||||
*m /= f;
|
||||
}
|
||||
}
|
||||
if n % 3 == 0 {
|
||||
extract(3, &mut n, &mut p);
|
||||
}
|
||||
fn sqrt(v: u32) -> u32 {
|
||||
(v as f64).sqrt().round() as u32
|
||||
}
|
||||
let (mut d, mut s, mut b) = (5u32, 2u32, sqrt(n));
|
||||
while d <= b {
|
||||
if n % d == 0 {
|
||||
extract(d, &mut n, &mut p);
|
||||
b = sqrt(n);
|
||||
}
|
||||
(d, s) = (d + s, s ^ 6);
|
||||
}
|
||||
if n > 1 {
|
||||
p.push(n)
|
||||
}
|
||||
p
|
||||
}
|
||||
59
src/poly.rs
Normal file
59
src/poly.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
use ark_ff::{PrimeField, Zero};
|
||||
use ark_poly::{
|
||||
polynomial::univariate::{DenseOrSparsePolynomial, DensePolynomial},
|
||||
DenseUVPolynomial, Polynomial,
|
||||
};
|
||||
|
||||
pub fn new<F: PrimeField>(c: &[impl Into<F> + Clone]) -> DensePolynomial<F> {
|
||||
DensePolynomial::from_coefficients_vec(c.iter().map(|e| e.clone().into()).collect())
|
||||
}
|
||||
|
||||
pub fn reduced_modulo<F: PrimeField>(
|
||||
p: &DensePolynomial<F>,
|
||||
m: &DensePolynomial<F>,
|
||||
) -> Option<DensePolynomial<F>> {
|
||||
// This check is to avoid a "divide_with_q_and_r" panic, since
|
||||
// for some reason "divide_with_q_and_r" never returns None
|
||||
if m.is_zero() {
|
||||
return None;
|
||||
}
|
||||
Some(
|
||||
DenseOrSparsePolynomial::from(p)
|
||||
.divide_with_q_and_r(&DenseOrSparsePolynomial::from(m))?
|
||||
.1,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn power_modulo<F: PrimeField>(
|
||||
p: &DensePolynomial<F>,
|
||||
e: &[u64],
|
||||
m: &DensePolynomial<F>,
|
||||
) -> Option<DensePolynomial<F>> {
|
||||
let p = reduced_modulo(p, m)?;
|
||||
let mut r = new(&[(m.degree() > 0) as u64]);
|
||||
for b in crate::num::reversed_bits(e) {
|
||||
r = reduced_modulo(&(&r * &r), m)?;
|
||||
if b {
|
||||
r = reduced_modulo(&(&r * &p), m)?;
|
||||
}
|
||||
}
|
||||
Some(r)
|
||||
}
|
||||
|
||||
pub fn nonmonic_gcd<F: PrimeField>(
|
||||
a: &DensePolynomial<F>,
|
||||
b: &DensePolynomial<F>,
|
||||
) -> DensePolynomial<F> {
|
||||
let mut a = match reduced_modulo(a, b) {
|
||||
Some(r) => r,
|
||||
None => return a.clone(),
|
||||
};
|
||||
let mut b = match reduced_modulo(b, &a) {
|
||||
Some(r) => r,
|
||||
None => return b.clone(),
|
||||
};
|
||||
while let Some(r) = reduced_modulo(&a, &b) {
|
||||
(a, b) = (b, r);
|
||||
}
|
||||
a
|
||||
}
|
||||
Reference in New Issue
Block a user