Skip to content

Commit 69b07f0

Browse files
Add Pedersen hashes, revise tests, add decryption convenience methods on ciphertexts
1 parent 49c13a6 commit 69b07f0

File tree

25 files changed

+598
-182
lines changed

25 files changed

+598
-182
lines changed

wasm/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ default-features = false
9999
version = "2"
100100

101101
[dependencies.wasm-bindgen]
102-
version = "0.2"
102+
version = "0.2.100"
103103
features = [ "serde-serialize" ]
104104

105105
[dependencies.wasm-bindgen-futures]
@@ -120,7 +120,7 @@ features = [
120120
]
121121

122122
[dev-dependencies.wasm-bindgen-test]
123-
version = "0.3.37"
123+
version = "0.3.50"
124124

125125
[dev-dependencies.gloo-timers]
126126
version = "0.3.0"

wasm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"The Provable Team"
77
],
88
"license": "GPL-3.0",
9-
"type": "module",
9+
1010
"main": "./dist/testnet/index.js",
1111
"browser": "./dist/testnet/index.js",
1212
"types": "./dist/testnet/index.d.ts",

wasm/src/algorithms/bhp/bhp1024.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use crate::{Field, Scalar, types::native::BHP1024Native};
17+
use crate::{Field, Scalar, from_js_typed_array, types::native::BHP1024Native};
1818
use snarkvm_console::algorithms::{Commit, Hash};
1919

2020
use js_sys::Array;
@@ -32,25 +32,13 @@ impl BHP1024 {
3232

3333
/// Hash an array of booleans.
3434
pub fn hash(&self, input: Array) -> Result<Field, String> {
35-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
36-
let input = input
37-
.to_vec()
38-
.iter()
39-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
40-
.collect::<Result<Vec<bool>, String>>()?;
41-
35+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
4236
self.0.hash(&input).map(|field| Field::from(field)).map_err(|e| e.to_string())
4337
}
4438

4539
/// Commit to an array of booleans.
4640
pub fn commit(&self, input: Array, randomizer: Scalar) -> Result<Field, String> {
47-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
48-
let input = input
49-
.to_vec()
50-
.iter()
51-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
52-
.collect::<Result<Vec<bool>, String>>()?;
53-
41+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
5442
self.0.commit(&input, &randomizer).map(|field| Field::from(field)).map_err(|e| e.to_string())
5543
}
5644
}

wasm/src/algorithms/bhp/bhp256.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use crate::{Field, Scalar, types::native::BHP256Native};
17+
use crate::{Field, Scalar, from_js_typed_array, types::native::BHP256Native};
1818
use snarkvm_console::algorithms::{Commit, Hash};
1919

2020
use js_sys::Array;
@@ -32,25 +32,13 @@ impl BHP256 {
3232

3333
/// Hash an array of booleans.
3434
pub fn hash(&self, input: Array) -> Result<Field, String> {
35-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
36-
let input = input
37-
.to_vec()
38-
.iter()
39-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
40-
.collect::<Result<Vec<bool>, String>>()?;
41-
35+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
4236
self.0.hash(&input).map(|field| Field::from(field)).map_err(|e| e.to_string())
4337
}
4438

4539
/// Commit to an array of booleans.
4640
pub fn commit(&self, input: Array, randomizer: Scalar) -> Result<Field, String> {
47-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
48-
let input = input
49-
.to_vec()
50-
.iter()
51-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
52-
.collect::<Result<Vec<bool>, String>>()?;
53-
41+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
5442
self.0.commit(&input, &randomizer).map(|field| Field::from(field)).map_err(|e| e.to_string())
5543
}
5644
}

wasm/src/algorithms/bhp/bhp512.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use crate::{Field, Scalar, types::native::BHP512Native};
17+
use crate::{Field, Scalar, from_js_typed_array, types::native::BHP512Native};
1818
use snarkvm_console::algorithms::{Commit, Hash};
1919

2020
use js_sys::Array;
@@ -32,25 +32,13 @@ impl BHP512 {
3232

3333
/// Hash an array of booleans.
3434
pub fn hash(&self, input: Array) -> Result<Field, String> {
35-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
36-
let input = input
37-
.to_vec()
38-
.iter()
39-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
40-
.collect::<Result<Vec<bool>, String>>()?;
41-
35+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
4236
self.0.hash(&input).map(|field| Field::from(field)).map_err(|e| e.to_string())
4337
}
4438

4539
/// Commit to an array of booleans.
4640
pub fn commit(&self, input: Array, randomizer: Scalar) -> Result<Field, String> {
47-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
48-
let input = input
49-
.to_vec()
50-
.iter()
51-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
52-
.collect::<Result<Vec<bool>, String>>()?;
53-
41+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
5442
self.0.commit(&input, &randomizer).map(|field| Field::from(field)).map_err(|e| e.to_string())
5543
}
5644
}

wasm/src/algorithms/bhp/bhp768.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use crate::{Field, Scalar, types::native::BHP768Native};
17+
use crate::{Field, Scalar, from_js_typed_array, types::native::BHP768Native};
1818
use snarkvm_console::algorithms::{Commit, Hash};
1919

2020
use js_sys::Array;
@@ -32,25 +32,13 @@ impl BHP768 {
3232

3333
/// Hash an array of booleans.
3434
pub fn hash(&self, input: Array) -> Result<Field, String> {
35-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
36-
let input = input
37-
.to_vec()
38-
.iter()
39-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
40-
.collect::<Result<Vec<bool>, String>>()?;
41-
35+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
4236
self.0.hash(&input).map(|field| Field::from(field)).map_err(|e| e.to_string())
4337
}
4438

4539
/// Commit to an array of booleans.
4640
pub fn commit(&self, input: Array, randomizer: Scalar) -> Result<Field, String> {
47-
// Convert an array of booleans to a vector of booleans, failing if any values aren't booleans.
48-
let input = input
49-
.to_vec()
50-
.iter()
51-
.map(|x| x.as_bool().ok_or_else(|| "Input must be a boolean array".to_string()))
52-
.collect::<Result<Vec<bool>, String>>()?;
53-
41+
let input = from_js_typed_array!(input, as_bool, "boolean")?;
5442
self.0.commit(&input, &randomizer).map(|field| Field::from(field)).map_err(|e| e.to_string())
5543
}
5644
}

wasm/src/algorithms/bhp/mod.rs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,92 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
1616

17-
pub mod bhp1024;
1817
pub mod bhp256;
18+
pub use bhp256::BHP256;
19+
1920
pub mod bhp512;
21+
pub use bhp512::BHP512;
22+
2023
pub mod bhp768;
24+
pub use bhp768::BHP768;
25+
26+
pub mod bhp1024;
27+
pub use bhp1024::BHP1024;
28+
29+
#[cfg(test)]
30+
mod tests {
31+
use super::*;
32+
use crate::{
33+
Field,
34+
Scalar,
35+
test::create_native_field_vector,
36+
types::native::{BHP256Native, BHP512Native, BHP768Native, BHP1024Native},
37+
};
38+
use snarkvm_console::algorithms::{Commit, Hash, ToBits};
39+
40+
use js_sys::Array;
41+
use wasm_bindgen::JsValue;
42+
use wasm_bindgen_test::*;
43+
44+
const SCALAR_FIELD_ELEMENT: &str =
45+
"1774157567936692047646837016039369013254365378639847034769080448564598011047scalar";
46+
47+
#[wasm_bindgen_test]
48+
fn test_wasm_bhp_hashes_equal_native_hashes() {
49+
// Create a field element and a scalar element.
50+
let scalar = Scalar::from_string(SCALAR_FIELD_ELEMENT).unwrap();
51+
52+
// Create all exported BHP hasher instances.
53+
let bhp256 = BHP256::new();
54+
let bhp512 = BHP512::new();
55+
let bhp768 = BHP768::new();
56+
let bhp1024 = BHP1024::new();
57+
58+
// Create all native BHP hasher instances.
59+
let native_bhp256 = BHP256Native::setup("AleoBHP256").unwrap();
60+
let native_bhp512 = BHP512Native::setup("AleoBHP512").unwrap();
61+
let native_bhp768 = BHP768Native::setup("AleoBHP768").unwrap();
62+
let native_bhp1024 = BHP1024Native::setup("AleoBHP1024").unwrap();
63+
64+
for count in [1, 2, 4, 8, 16] {
65+
// Create a field vector.
66+
let fields = create_native_field_vector(Some(count));
67+
68+
// Create both a boolean vector and boolean array.
69+
let bit_vector = fields.iter()
70+
.flat_map(|item| item.to_bits_le()) // Flatten all bit representations
71+
.collect::<Vec<bool>>();
72+
let bit_array = bit_vector.iter().map(|item| JsValue::from(*item)).collect::<Array>();
73+
74+
// Hash and commit to the field element using all BHP hasher instances.
75+
let hash_256 = bhp256.hash(bit_array.clone()).unwrap();
76+
let hash_512 = bhp512.hash(bit_array.clone()).unwrap();
77+
let hash_768 = bhp768.hash(bit_array.clone()).unwrap();
78+
let hash_1024 = bhp1024.hash(bit_array.clone()).unwrap();
79+
let commit_256 = bhp256.commit(bit_array.clone(), scalar.clone()).unwrap();
80+
let commit_512 = bhp512.commit(bit_array.clone(), scalar.clone()).unwrap();
81+
let commit_768 = bhp768.commit(bit_array.clone(), scalar.clone()).unwrap();
82+
let commit_1024 = bhp1024.commit(bit_array.clone(), scalar.clone()).unwrap();
83+
84+
// Hash and commit to the field element using all native BHP hasher instances.
85+
let native_hash_256 = native_bhp256.hash(&bit_vector).unwrap();
86+
let native_hash_512 = native_bhp512.hash(&bit_vector).unwrap();
87+
let native_hash_768 = native_bhp768.hash(&bit_vector).unwrap();
88+
let native_hash_1024 = native_bhp1024.hash(&bit_vector).unwrap();
89+
let native_commit_256 = native_bhp256.commit(&bit_vector, &scalar).unwrap();
90+
let native_commit_512 = native_bhp512.commit(&bit_vector, &scalar).unwrap();
91+
let native_commit_768 = native_bhp768.commit(&bit_vector, &scalar).unwrap();
92+
let native_commit_1024 = native_bhp1024.commit(&bit_vector, &scalar).unwrap();
93+
94+
// Assert native and exported results are equal.
95+
assert_eq!(hash_256, Field::from(native_hash_256));
96+
assert_eq!(hash_512, Field::from(native_hash_512));
97+
assert_eq!(hash_768, Field::from(native_hash_768));
98+
assert_eq!(hash_1024, Field::from(native_hash_1024));
99+
assert_eq!(commit_256, Field::from(native_commit_256));
100+
assert_eq!(commit_512, Field::from(native_commit_512));
101+
assert_eq!(commit_768, Field::from(native_commit_768));
102+
assert_eq!(commit_1024, Field::from(native_commit_1024));
103+
}
104+
}
105+
}

wasm/src/algorithms/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@
1717
pub mod bhp;
1818
pub use bhp::*;
1919

20+
pub mod pedersen;
21+
pub use pedersen::*;
22+
2023
pub mod poseidon;
2124
pub use poseidon::*;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Copyright (C) 2019-2025 Provable Inc.
2+
// This file is part of the Aleo SDK library.
3+
4+
// The Aleo SDK library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// The Aleo SDK library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.
16+
17+
pub mod pedersen64;
18+
pub use pedersen64::Pedersen64;
19+
20+
pub mod pedersen128;
21+
pub use pedersen128::Pedersen128;
22+
23+
#[cfg(test)]
24+
mod tests {
25+
use super::*;
26+
use crate::{
27+
Field,
28+
Scalar,
29+
test::create_native_field_vector,
30+
types::native::{Pedersen64Native, Pedersen128Native},
31+
};
32+
use snarkvm_console::algorithms::{Commit, Hash, ToBits};
33+
34+
use crate::types::native::CurrentNetwork;
35+
use js_sys::Array;
36+
use snarkvm_console::types::U32;
37+
use wasm_bindgen::JsValue;
38+
use wasm_bindgen_test::*;
39+
40+
const SCALAR_FIELD_ELEMENT: &str =
41+
"1774157567936692047646837016039369013254365378639847034769080448564598011047scalar";
42+
43+
#[wasm_bindgen_test]
44+
fn test_wasm_pedersen_hashes_equal_native_hashes() {
45+
// Create a field element and a scalar element.
46+
let scalar = Scalar::from_string(SCALAR_FIELD_ELEMENT).unwrap();
47+
48+
// Create all exported Pedersen hasher instances.
49+
let pedersen64 = Pedersen64::new();
50+
let pedersen128 = Pedersen128::new();
51+
52+
// Create all native Pedersen hasher instances.
53+
let native_pedersen64 = Pedersen64Native::setup("AleoPedersen64");
54+
let native_pedersen128 = Pedersen128Native::setup("AleoPedersen128");
55+
56+
for count in [1, 2] {
57+
let mut numbers = Vec::with_capacity(count);
58+
(0..count).into_iter().for_each(|_| numbers.extend(U32::<CurrentNetwork>::new(1).to_bits_le()));
59+
60+
// Create both a boolean vector and boolean array.
61+
let bit_vector = numbers.iter()
62+
.flat_map(|item| item.to_bits_le()) // Flatten all bit representations
63+
.collect::<Vec<bool>>();
64+
let bit_array = bit_vector.iter().map(|item| JsValue::from(*item)).collect::<Array>();
65+
66+
// Hash and commit to the field element using all Pedersen hasher instances.
67+
let hash_64 = pedersen64.hash(bit_array.clone()).unwrap();
68+
let hash_128 = pedersen128.hash(bit_array.clone()).unwrap();
69+
let commit_64 = pedersen64.commit(bit_array.clone(), scalar.clone()).unwrap();
70+
let commit_128 = pedersen128.commit(bit_array.clone(), scalar.clone()).unwrap();
71+
72+
// Hash and commit to the field element using all native Pedersen hasher instances.
73+
let native_hash_64 = native_pedersen64.hash(&bit_vector).unwrap();
74+
let native_hash_128 = native_pedersen128.hash(&bit_vector).unwrap();
75+
let native_commit_64 = native_pedersen64.commit(&bit_vector, &scalar).unwrap();
76+
let native_commit_128 = native_pedersen128.commit(&bit_vector, &scalar).unwrap();
77+
78+
// Assert native and exported results are equal.
79+
assert_eq!(hash_64, Field::from(native_hash_64));
80+
assert_eq!(hash_128, Field::from(native_hash_128));
81+
assert_eq!(commit_64, Field::from(native_commit_64));
82+
assert_eq!(commit_128, Field::from(native_commit_128));
83+
}
84+
}
85+
}

0 commit comments

Comments
 (0)