sp1_hypercube/verifier/
hashable_key.rs1use std::borrow::Borrow;
2
3use serde::{Deserialize, Serialize};
4use slop_algebra::{AbstractField, PrimeField, PrimeField32};
5use slop_bn254::Bn254Fr;
6use slop_challenger::IopCtx;
7use sp1_primitives::{poseidon2_hash, SP1Field, SP1GlobalContext};
8
9use crate::{MachineVerifyingKey, DIGEST_SIZE};
10
11#[derive(Clone, Serialize, Deserialize)]
13pub struct SP1VerifyingKey {
14 pub vk: MachineVerifyingKey<SP1GlobalContext>,
17}
18
19#[must_use]
22pub fn koalabears_to_bn254(digest: &[SP1Field; 8]) -> Bn254Fr {
23 let mut result = Bn254Fr::zero();
24 for word in digest.iter() {
25 result *= Bn254Fr::from_canonical_u64(1 << 31);
28 result += Bn254Fr::from_canonical_u32(word.as_canonical_u32());
29 }
30 result
31}
32
33#[must_use]
35pub fn words_to_bytes_be(words: &[u32; 8]) -> [u8; 32] {
36 let mut bytes = [0u8; 32];
37 for i in 0..8 {
38 let word_bytes = words[i].to_be_bytes();
39 bytes[i * 4..(i + 1) * 4].copy_from_slice(&word_bytes);
40 }
41 bytes
42}
43
44pub trait HashableKey {
46 fn hash_koalabear(&self) -> [SP1Field; DIGEST_SIZE];
48
49 fn hash_u32(&self) -> [u32; DIGEST_SIZE];
51
52 fn hash_bn254(&self) -> Bn254Fr {
54 koalabears_to_bn254(&self.hash_koalabear())
55 }
56
57 fn bytes32(&self) -> String {
61 let vkey_digest_bn254 = self.hash_bn254();
62 format!("0x{:0>64}", vkey_digest_bn254.as_canonical_biguint().to_str_radix(16))
63 }
64
65 fn bytes32_raw(&self) -> [u8; 32] {
69 let vkey_digest_bn254 = self.hash_bn254();
70 let vkey_bytes = vkey_digest_bn254.as_canonical_biguint().to_bytes_be();
71 let mut result = [0u8; 32];
72 result[1..].copy_from_slice(&vkey_bytes);
73 result
74 }
75
76 fn hash_bytes(&self) -> [u8; DIGEST_SIZE * 4] {
78 words_to_bytes_be(&self.hash_u32())
79 }
80
81 fn hash_u64(&self) -> [u64; DIGEST_SIZE / 2] {
83 self.hash_u32()
84 .chunks_exact(2)
85 .map(|chunk| chunk[0] as u64 | ((chunk[1] as u64) << 32))
86 .collect::<Vec<_>>()
87 .try_into()
88 .unwrap()
89 }
90}
91
92impl HashableKey for SP1VerifyingKey {
93 fn hash_koalabear(&self) -> [SP1Field; DIGEST_SIZE] {
94 self.vk.hash_koalabear()
95 }
96
97 fn hash_u32(&self) -> [u32; DIGEST_SIZE] {
98 self.vk.hash_u32()
99 }
100}
101
102impl<GC: IopCtx<F = SP1Field>> HashableKey for MachineVerifyingKey<GC>
103where
104 GC::Digest: Borrow<[SP1Field; DIGEST_SIZE]>,
105{
106 fn hash_koalabear(&self) -> [SP1Field; DIGEST_SIZE] {
107 let num_inputs = DIGEST_SIZE + 3 + 14 + 1;
108 let mut inputs = Vec::with_capacity(num_inputs);
109 inputs.extend(self.preprocessed_commit.borrow());
110 inputs.extend(self.pc_start);
111 inputs.extend(self.initial_global_cumulative_sum.0.x.0);
112 inputs.extend(self.initial_global_cumulative_sum.0.y.0);
113 inputs.push(self.enable_untrusted_programs);
114
115 poseidon2_hash(inputs)
116 }
117
118 fn hash_u32(&self) -> [u32; 8] {
119 self.hash_koalabear()
120 .into_iter()
121 .map(|n| n.as_canonical_u32())
122 .collect::<Vec<_>>()
123 .try_into()
124 .unwrap()
125 }
126}