arnaucube
arnaucube/shockwave-plusPublic Self-hosted repository
shockwave-plus/tensor_pcs/src/utils.rs
tensor_pcs/src/utils.rsRaw
 1use tiny_keccak::{Hasher, Keccak};
 2
 3use crate::FieldExt;
 4
 5use crate::transcript::Transcript;
 6
 7pub fn rlc_rows<F: FieldExt>(x: Vec<Vec<F>>, r: &[F]) -> Vec<F> {
 8    debug_assert_eq!(x.len(), r.len());
 9    let num_cols = x[0].len();
10    let mut result = vec![F::ZERO; num_cols];
11    for (row, r_i) in x.iter().zip(r.iter()) {
12        for j in 0..num_cols {
13            result[j] += row[j] * r_i
14        }
15    }
16    result
17}
18
19pub fn dot_prod<F: FieldExt>(x: &[F], y: &[F]) -> F {
20    assert_eq!(x.len(), y.len());
21    let mut result = F::ZERO;
22    for i in 0..x.len() {
23        result += x[i] * y[i];
24    }
25    result
26}
27
28pub fn hash_two(values: &[[u8; 32]; 2]) -> [u8; 32] {
29    let mut hasher = Keccak::v256();
30    hasher.update(&values[0]);
31    hasher.update(&values[1]);
32    let mut hash = [0u8; 32];
33    hasher.finalize(&mut hash);
34    hash
35}
36
37pub fn hash_all(values: &[[u8; 32]]) -> [u8; 32] {
38    let mut hasher = Keccak::v256();
39    for value in values {
40        hasher.update(value);
41    }
42    let mut hash = [0u8; 32];
43    hasher.finalize(&mut hash);
44    hash
45}
46
47fn sample_index(random_bytes: [u8; 64], size: usize) -> usize {
48    let mut acc: u64 = 0;
49    for b in random_bytes {
50        acc = acc << 8 ^ (b as u64);
51    }
52
53    (acc % (size as u64)) as usize
54}
55
56pub fn sample_indices<F: FieldExt>(
57    num_indices: usize,
58    max_index: usize,
59    transcript: &mut Transcript<F>,
60) -> Vec<usize> {
61    assert!(
62        num_indices <= max_index,
63        "max_index {:?} num_indices {:?}",
64        max_index,
65        num_indices
66    );
67
68    let mut indices = Vec::with_capacity(num_indices);
69    let mut counter: u32 = 0;
70
71    // TODO: Don't sample at n and n + N
72    while indices.len() < num_indices {
73        let mut random_bytes = [0u8; 64];
74
75        transcript.append_bytes(&counter.to_le_bytes());
76        transcript.challenge_bytes(&mut random_bytes);
77
78        let index = sample_index(random_bytes, max_index);
79        if !indices.contains(&index)
80        // || !indices.contains(&(index + (max_index / 2)))
81        // || !indices.contains(&(index - (max_index / 2)))
82        {
83            indices.push(index);
84        }
85        counter += 1;
86    }
87
88    indices
89}