Skip to content

Commit 03ef263

Browse files
committed
[frontend] Add Winternitz OTS verifier
1 parent c6feda2 commit 03ef263

File tree

6 files changed

+432
-1
lines changed

6 files changed

+432
-1
lines changed

crates/frontend/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ cranelift-entity = { workspace = true }
1313
hex-literal.workspace = true
1414
num-bigint = { workspace = true }
1515
num-integer = { workspace = true }
16+
rand = { workspace = true, features = ["std_rng", "thread_rng"] }
1617
serde.workspace = true
1718
serde_json.workspace = true
1819
sha3.workspace = true

crates/frontend/src/circuits/hash_based_sig/codeword.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,23 @@ pub fn codeword(
9999
coordinates
100100
}
101101

102+
/// A function to extract the coordinates from a hash according to the rules
103+
/// specified in the `codeword` circuit
104+
pub fn extract_coordinates(hash: &[u8], dimension: usize, resolution_bits: usize) -> Vec<u8> {
105+
let mut coords = Vec::new();
106+
let coords_per_byte = 8 / resolution_bits;
107+
let mask = (1u8 << resolution_bits) - 1;
108+
109+
for i in 0..dimension {
110+
let byte_idx = i / coords_per_byte;
111+
let coord_idx = i % coords_per_byte;
112+
let shift = coord_idx * resolution_bits;
113+
let coord = (hash[byte_idx] >> shift) & mask;
114+
coords.push(coord);
115+
}
116+
coords
117+
}
118+
102119
#[cfg(test)]
103120
mod tests {
104121
use binius_core::Word;

crates/frontend/src/circuits/hash_based_sig/hashing/message.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use sha3::{Digest, Keccak256};
2+
13
use super::base::circuit_tweaked_keccak;
24
use crate::{
35
circuits::{concat::Term, keccak::Keccak},
@@ -96,6 +98,25 @@ pub fn build_message_hash(
9698
message
9799
}
98100

101+
/// Compute the tweaked hash of a message from components.
102+
///
103+
/// Constructs the complete message for Keccak-256 hashing by concatenating:
104+
/// `param || 0x02 || nonce || message`
105+
///
106+
/// # Arguments
107+
///
108+
/// * `param_bytes` - The cryptographic parameter bytes
109+
/// * `nonce_bytes` - The random nonce bytes
110+
/// * `message_bytes` - The message content bytes
111+
///
112+
/// # Returns
113+
///
114+
/// The tweaked message hash
115+
pub fn hash_message(param: &[u8], nonce: &[u8], message: &[u8]) -> [u8; 32] {
116+
let tweaked_message = build_message_hash(param, nonce, message);
117+
Keccak256::digest(tweaked_message).into()
118+
}
119+
99120
#[cfg(test)]
100121
mod tests {
101122
use proptest::prelude::*;

crates/frontend/src/circuits/hash_based_sig/hashing/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ mod chain;
44
mod message;
55

66
pub use chain::{CHAIN_TWEAK, FIXED_MESSAGE_OVERHEAD, build_chain_hash, circuit_chain_hash};
7-
pub use message::{MESSAGE_TWEAK, build_message_hash, circuit_message_hash};
7+
pub use message::{MESSAGE_TWEAK, build_message_hash, circuit_message_hash, hash_message};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
pub mod chain_verification;
22
pub mod codeword;
33
pub mod hashing;
4+
pub mod winternitz_ots;

0 commit comments

Comments
 (0)