ark-r1cs-std/crypto-primitives/src/prf/blake2s/mod.rs
crypto-primitives/src/prf/blake2s/mod.rsRaw
1use alloc::vec::Vec;
2use blake2::{Blake2s as B2s, VarBlake2s};
3use digest::Digest;
4
5use super::PRF;
6use crate::CryptoError;
7
8#[cfg(feature = "r1cs")]
9pub mod constraints;
10
11#[derive(Clone)]
12pub struct Blake2s;
13
14impl PRF for Blake2s {
15 type Input = [u8; 32];
16 type Output = [u8; 32];
17 type Seed = [u8; 32];
18
19 fn evaluate(seed: &Self::Seed, input: &Self::Input) -> Result<Self::Output, CryptoError> {
20 let eval_time = start_timer!(|| "Blake2s::Eval");
21 let mut h = B2s::new();
22 h.input(seed.as_ref());
23 h.input(input.as_ref());
24 let mut result = [0u8; 32];
25 result.copy_from_slice(&h.result());
26 end_timer!(eval_time);
27 Ok(result)
28 }
29}
30
31#[derive(Clone)]
32pub struct Blake2sWithParameterBlock {
33 pub digest_length: u8,
34 pub key_length: u8,
35 pub fan_out: u8,
36 pub depth: u8,
37 pub leaf_length: u32,
38 pub node_offset: u32,
39 pub xof_digest_length: u16,
40 pub node_depth: u8,
41 pub inner_length: u8,
42 pub salt: [u8; 8],
43 pub personalization: [u8; 8],
44}
45
46impl Blake2sWithParameterBlock {
47 pub fn parameters(&self) -> [u32; 8] {
48 let mut parameters = [0; 8];
49 parameters[0] = u32::from_le_bytes([
50 self.digest_length,
51 self.key_length,
52 self.fan_out,
53 self.depth,
54 ]);
55 parameters[1] = self.leaf_length;
56 parameters[2] = self.node_offset;
57 parameters[3] = u32::from_le_bytes([
58 self.xof_digest_length as u8,
59 (self.xof_digest_length >> 8) as u8,
60 self.node_depth,
61 self.inner_length,
62 ]);
63
64 let mut salt_bytes_1 = [0; 4];
65 let mut salt_bytes_2 = [0; 4];
66 let mut personalization_bytes_1 = [0; 4];
67 let mut personalization_bytes_2 = [0; 4];
68 for i in 0..4 {
69 salt_bytes_1[i] = self.salt[i];
70 salt_bytes_2[i] = self.salt[4 + i];
71 personalization_bytes_1[i] = self.personalization[i];
72 personalization_bytes_2[i] = self.personalization[4 + i];
73 }
74 parameters[4] = u32::from_le_bytes(salt_bytes_1);
75 parameters[5] = u32::from_le_bytes(salt_bytes_2);
76 parameters[6] = u32::from_le_bytes(personalization_bytes_1);
77 parameters[7] = u32::from_le_bytes(personalization_bytes_2);
78
79 parameters
80 }
81
82 pub fn evaluate(&self, input: &[u8]) -> Vec<u8> {
83 use digest::*;
84 let eval_time = start_timer!(|| "Blake2sWithParameterBlock::Eval");
85 let mut h = VarBlake2s::with_parameter_block(&self.parameters());
86 h.input(input.as_ref());
87 end_timer!(eval_time);
88 let mut buf = Vec::with_capacity(h.output_size());
89 h.variable_result(|res| buf.extend_from_slice(res));
90 buf
91 }
92}