lit_utilities_wasm/
bls.rs1use std::convert::TryFrom;
2
3use blsful::{
4 Bls12381G1Impl, Bls12381G2Impl, BlsSignatureImpl, PublicKey, Signature, SignatureSchemes,
5 TimeCryptCiphertext,
6};
7use elliptic_curve::group::GroupEncoding;
8use js_sys::Uint8Array;
9use serde::Deserialize;
10use tsify::Tsify;
11use wasm_bindgen::prelude::*;
12
13use crate::abi::{from_js, from_uint8array, into_uint8array, JsResult};
14
15#[derive(Tsify, Deserialize)]
16#[tsify(from_wasm_abi)]
17pub enum BlsVariant {
18 Bls12381G1,
19 Bls12381G2,
20}
21
22struct Bls<C>(C);
23
24impl<C: BlsSignatureImpl> Bls<C>
25where
26 C::PublicKey: TryFrom<Vec<u8>>,
27 C::Signature: TryFrom<Vec<u8>>,
28 C::SignatureShare: TryFrom<Vec<u8>>,
29{
30 pub fn combine(signature_shares: Vec<Uint8Array>) -> JsResult<Uint8Array> {
31 let signature_shares = signature_shares
32 .into_iter()
33 .map(from_uint8array)
34 .collect::<JsResult<Vec<_>>>()?;
35
36 let signature = C::core_combine_signature_shares(&signature_shares)?;
37
38 into_uint8array(signature.to_bytes())
39 }
40
41 pub fn verify(
42 public_key: Uint8Array,
43 message: Uint8Array,
44 signature: Uint8Array,
45 ) -> JsResult<()> {
46 let public_key = from_uint8array(public_key)?;
47 let signature = from_uint8array(signature)?;
48 let message = from_js::<Vec<u8>>(message)?;
49
50 let signature = Signature::<C>::ProofOfPossession(signature);
51
52 signature.verify(&PublicKey(public_key), message)?;
53
54 Ok(())
55 }
56
57 pub fn encrypt(
58 encryption_key: Uint8Array,
59 message: Uint8Array,
60 identity: Uint8Array,
61 ) -> JsResult<Uint8Array> {
62 let encryption_key = from_uint8array(encryption_key)?;
63 let encryption_key = PublicKey::<C>(encryption_key);
64
65 let message = from_js::<Vec<u8>>(message)?;
66 let identity = from_js::<Vec<u8>>(identity)?;
67
68 let ciphertext = encryption_key.encrypt_time_lock(
69 SignatureSchemes::ProofOfPossession,
70 message,
71 identity,
72 )?;
73 let ciphertext = serde_bare::to_vec(&ciphertext)?;
74
75 into_uint8array(ciphertext)
76 }
77
78 pub fn decrypt(ciphertext: Uint8Array, decryption_key: Uint8Array) -> JsResult<Uint8Array> {
79 let decryption_key = from_uint8array(decryption_key)?;
80
81 let ciphertext = from_js::<Vec<u8>>(ciphertext)?;
82 let ciphertext = serde_bare::from_slice::<TimeCryptCiphertext<C>>(&ciphertext)?;
83
84 let message = ciphertext.decrypt(&Signature::ProofOfPossession(decryption_key));
85 let message =
86 Option::<Vec<u8>>::from(message).ok_or_else(|| JsError::new("decryption failed"))?;
87
88 into_uint8array(message)
89 }
90}
91
92#[wasm_bindgen(js_name = "blsCombine")]
93pub fn bls_combine(variant: BlsVariant, signature_shares: Vec<Uint8Array>) -> JsResult<Uint8Array> {
94 match variant {
95 BlsVariant::Bls12381G1 => Bls::<Bls12381G1Impl>::combine(signature_shares),
96 BlsVariant::Bls12381G2 => Bls::<Bls12381G2Impl>::combine(signature_shares),
97 }
98}
99
100#[wasm_bindgen(js_name = "blsVerify")]
101pub fn bls_verify(
102 variant: BlsVariant,
103 public_key: Uint8Array,
104 message: Uint8Array,
105 signature: Uint8Array,
106) -> JsResult<()> {
107 match variant {
108 BlsVariant::Bls12381G1 => Bls::<Bls12381G1Impl>::verify(public_key, message, signature),
109 BlsVariant::Bls12381G2 => Bls::<Bls12381G2Impl>::verify(public_key, message, signature),
110 }
111}
112
113#[wasm_bindgen(js_name = "blsEncrypt")]
114pub fn bls_encrypt(
115 variant: BlsVariant,
116 encryption_key: Uint8Array,
117 message: Uint8Array,
118 identity: Uint8Array,
119) -> JsResult<Uint8Array> {
120 match variant {
121 BlsVariant::Bls12381G1 => Bls::<Bls12381G1Impl>::encrypt(encryption_key, message, identity),
122 BlsVariant::Bls12381G2 => Bls::<Bls12381G2Impl>::encrypt(encryption_key, message, identity),
123 }
124}
125
126#[wasm_bindgen(js_name = "blsDecrypt")]
127pub fn bls_decrypt(
128 variant: BlsVariant,
129 ciphertext: Uint8Array,
130 decryption_key: Uint8Array,
131) -> JsResult<Uint8Array> {
132 match variant {
133 BlsVariant::Bls12381G1 => Bls::<Bls12381G1Impl>::decrypt(ciphertext, decryption_key),
134 BlsVariant::Bls12381G2 => Bls::<Bls12381G2Impl>::decrypt(ciphertext, decryption_key),
135 }
136}