diff --git a/Cargo.toml b/Cargo.toml index 3fc63c9..c78b610 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ serde_bytes = "0.11.2" time = "*" secp256k1 = { version = "0.16.0", features = ["rand", "serde"] } sha2 = { version = "0.8", default-features = false } +hex = "0.4.0" [lib] crate-type = ["lib", "cdylib", "staticlib"] diff --git a/Makefile b/Makefile index a50649f..d2920d6 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ bench: test: # runs the unit test suite - cargo +nightly test --release #-- --nocapture + cargo +nightly test --release -- --nocapture update: cargo +nightly update diff --git a/src/cl.rs b/src/cl.rs index 4c7e3da..59054c3 100644 --- a/src/cl.rs +++ b/src/cl.rs @@ -9,6 +9,7 @@ use serde::{Serialize, Deserialize}; use util; #[derive(Clone, Serialize, Deserialize, Debug)] +#[serde(bound(deserialize = "::G1: serde::Deserialize<'de>, ::G2: serde::Deserialize<'de>"))] pub struct PublicParams { pub g1: E::G1, pub g2: E::G2, @@ -20,6 +21,17 @@ impl PartialEq for PublicParams { } } +impl PublicParams { + pub fn from_slice<'de>(ser_g1: &'de [u8], ser_g2: &'de [u8]) -> Self + where ::G1: serde::Deserialize<'de>, + ::G2: serde::Deserialize<'de> + { + let g1: E::G1 = serde_json::from_slice(ser_g1).unwrap(); + let g2: E::G2 = serde_json::from_slice(ser_g2).unwrap(); + + return PublicParams { g1, g2 }; + } +} #[derive(Clone, Serialize, Deserialize, Debug)] pub struct SecretKey { @@ -48,6 +60,7 @@ impl PartialEq for SecretKey { #[derive(Clone, Serialize, Deserialize, Debug)] +#[serde(bound(deserialize = "::G2: serde::Deserialize<'de>"))] pub struct PublicKey { pub X: E::G2, pub Y: Vec, @@ -72,6 +85,23 @@ impl PartialEq for PublicKey { } } +impl PublicKey { + pub fn from_slice<'de>(ser_x: &'de [u8], ser_y: &'de [u8], y_len: usize, num_elems: usize) -> Self + where ::G2: serde::Deserialize<'de> + { + let X: E::G2 = serde_json::from_slice(ser_x).unwrap(); + let mut Y: Vec = Vec::new(); + let mut start_pos = 0; + let mut end_pos = y_len; + for _ in 0 .. num_elems { + let y = serde_json::from_slice(&ser_y[start_pos .. end_pos]).unwrap(); + start_pos = end_pos; + end_pos += y_len; + Y.push(y); + } + return PublicKey { X, Y }; + } +} #[derive(Clone, Serialize, Deserialize, Debug)] pub struct BlindPublicKey { @@ -679,10 +709,10 @@ mod tests { let blindkeypair = BlindKeyPair::::generate(&mut rng, &mpk, l); let serialized = serde_json::to_vec(&mpk).unwrap(); - //println!("serialized = {:?}", serialized.len()); + println!("mpk serialized len = {:?}", serialized.len()); let _mpk_des: PublicParams = serde_json::from_slice(&serialized).unwrap(); - //println!("{}", mpk_des); + //println!("{}", _mpk_des); //println!("SK => {}", &keypair.secret); let sk_serialized = serde_json::to_vec(&keypair.secret).unwrap(); @@ -694,7 +724,7 @@ mod tests { //println!("PK => {}", &keypair.public); let pk_serialized = serde_json::to_vec(&keypair.public).unwrap(); - //println!("pk_serialized = {:?}", pk_serialized.len()); + println!("cl pk_serialized len = {:?}", pk_serialized.len()); let _pk_des: PublicKey = serde_json::from_slice(&pk_serialized).unwrap(); //assert_eq!(pk_des, keypair.public); @@ -716,5 +746,58 @@ mod tests { assert_eq!(upk_des, unblind_pk); assert_ne!(upk_des, keypair.public); } + + #[test] + fn test_compact_public_params_deserialize() { + let bin_g1= vec![132, 83, 99, 124, 75, 72, 15, 109, 12, 94, 84, 103, 1, 58, 160, 232, 190, 23, 119, 195, 112, 161, 152, 141, 178, 29, 141, 61, 227, 246, 215, 157, 140, 190, 100, 18, 248, 141, 57, 222, 12, 209, 191, 158, 143, 155, 87, 255]; + let bin_g2 = vec![147, 63, 33, 190, 248, 155, 91, 211, 249, 169, 1, 147, 101, 104, 219, 88, 204, 131, 38, 167, 25, 191, 86, 67, 139, 188, 171, 101, 154, 32, 234, 92, 3, 66, 235, 159, 7, 47, 16, 83, 3, 201, 13, 227, 179, 184, 101, 102, 21, 88, 153, 208, 93, 0, 57, 108, 250, 231, 74, 192, 82, 111, 13, 211, 12, 51, 224, 198, 121, 15, 63, 129, 25, 218, 193, 47, 182, 248, 112, 185, 163, 23, 175, 169, 76, 214, 36, 184, 142, 222, 48, 212, 157, 35, 115, 181]; + + let ser_g1 = util::encode_as_hexstring(&bin_g1); + let ser_g2 = util::encode_as_hexstring(&bin_g2); + + let str_g1 = ser_g1.as_bytes(); + let str_g2 = ser_g2.as_bytes(); + + let rec_mpk = PublicParams::::from_slice(&str_g1, &str_g2); + + println!("g1: {}", rec_mpk.g1); + println!("g2: {}", rec_mpk.g2); + + let rec_g1_str = serde_json::to_string(&rec_mpk.g1).unwrap(); + assert_eq!(rec_g1_str, "\"8453637c4b480f6d0c5e5467013aa0e8be1777c370a1988db21d8d3de3f6d79d8cbe6412f88d39de0cd1bf9e8f9b57ff\""); + + let rec_g2_str = serde_json::to_string(&rec_mpk.g2).unwrap(); + assert_eq!(rec_g2_str, "\"933f21bef89b5bd3f9a901936568db58cc8326a719bf56438bbcab659a20ea5c0342eb9f072f105303c90de3b3b86566155899d05d00396cfae74ac0526f0dd30c33e0c6790f3f8119dac12fb6f870b9a317afa94cd624b88ede30d49d2373b5\""); + } + + #[test] + fn test_compact_cl_public_key_deserialize() { + let bin_g2_x = vec![147, 63, 33, 190, 248, 155, 91, 211, 249, 169, 1, 147, 101, 104, 219, 88, 204, 131, 38, 167, 25, 191, 86, 67, 139, 188, 171, 101, 154, 32, 234, 92, 3, 66, 235, 159, 7, 47, 16, 83, 3, 201, 13, 227, 179, 184, 101, 102, 21, 88, 153, 208, 93, 0, 57, 108, 250, 231, 74, 192, 82, 111, 13, 211, 12, 51, 224, 198, 121, 15, 63, 129, 25, 218, 193, 47, 182, 248, 112, 185, 163, 23, 175, 169, 76, 214, 36, 184, 142, 222, 48, 212, 157, 35, 115, 181]; + let bin_g2_y1 = vec![143, 76, 112, 7, 35, 99, 254, 7, 255, 225, 69, 13, 99, 32, 92, 186, 234, 175, 230, 0, 202, 144, 1, 216, 187, 248, 152, 76, 229, 74, 156, 94, 4, 16, 132, 119, 157, 172, 231, 164, 207, 88, 41, 6, 234, 78, 73, 58, 19, 104, 236, 127, 5, 231, 248, 150, 53, 197, 85, 194, 110, 93, 1, 73, 24, 96, 149, 133, 109, 194, 16, 190, 244, 184, 254, 192, 52, 21, 205, 109, 18, 83, 189, 175, 208, 147, 74, 32, 181, 126, 224, 136, 250, 126, 224, 186]; + let bin_g2_y2 = vec![150, 132, 45, 236, 146, 135, 127, 242, 61, 55, 73, 100, 151, 12, 51, 134, 151, 42, 138, 227, 105, 54, 121, 7, 0, 27, 205, 139, 186, 69, 139, 143, 41, 132, 35, 33, 168, 35, 31, 52, 65, 5, 73, 153, 203, 25, 178, 196, 4, 9, 218, 130, 22, 64, 98, 152, 225, 212, 27, 202, 245, 234, 138, 34, 82, 102, 40, 72, 211, 248, 16, 221, 54, 154, 186, 95, 246, 132, 54, 0, 128, 170, 111, 94, 155, 166, 27, 225, 51, 31, 107, 223, 139, 0, 209, 236]; + + let ser_g2_x = util::encode_as_hexstring(&bin_g2_x); + let ser_g2_y1 = util::encode_as_hexstring(&bin_g2_y1); + let ser_g2_y2 = util::encode_as_hexstring(&bin_g2_y2); + + let str_g2_x = ser_g2_x.as_bytes(); + let str_g2_y1 = ser_g2_y1.as_bytes(); + let str_g2_y2 = ser_g2_y2.as_bytes(); + + let mut vec = Vec::new(); + vec.extend(str_g2_y1); + vec.extend(str_g2_y2); + + let rec_cl_pk = PublicKey::::from_slice(&str_g2_x, &vec.as_slice(), ser_g2_y1.len(), 2); + + let rec_x_str = serde_json::to_string(&rec_cl_pk.X).unwrap(); + assert_eq!(rec_x_str, "\"933f21bef89b5bd3f9a901936568db58cc8326a719bf56438bbcab659a20ea5c0342eb9f072f105303c90de3b3b86566155899d05d00396cfae74ac0526f0dd30c33e0c6790f3f8119dac12fb6f870b9a317afa94cd624b88ede30d49d2373b5\""); + + let rec_y1_str = serde_json::to_string(&rec_cl_pk.Y[0]).unwrap(); + assert_eq!(rec_y1_str, "\"8f4c70072363fe07ffe1450d63205cbaeaafe600ca9001d8bbf8984ce54a9c5e041084779dace7a4cf582906ea4e493a1368ec7f05e7f89635c555c26e5d0149186095856dc210bef4b8fec03415cd6d1253bdafd0934a20b57ee088fa7ee0ba\""); + + let rec_y2_str = serde_json::to_string(&rec_cl_pk.Y[1]).unwrap(); + assert_eq!(rec_y2_str, "\"96842dec92877ff23d374964970c3386972a8ae369367907001bcd8bba458b8f29842321a8231f3441054999cb19b2c40409da8216406298e1d41bcaf5ea8a2252662848d3f810dd369aba5ff684360080aa6f5e9ba61be1331f6bdf8b00d1ec\""); + } } diff --git a/src/lib.rs b/src/lib.rs index d9d7438..f40dea3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,9 +31,11 @@ extern crate serde; extern crate serde_with; extern crate libc; +extern crate hex; #[cfg(test)] extern crate core; +extern crate serde_json; pub mod cl; pub mod ccs08; @@ -503,6 +505,102 @@ pub mod bidirectional { } } +pub mod wtp_utils { + // Useful routines that simplify the Bolt WTP implementation for Zcash + use pairing::bls12_381::Bls12; + use ::{util, BoltResult}; + use cl::{PublicKey, PublicParams}; + use ped92::CSMultiParams; + pub use channels::ChannelToken; + pub use wallet::Wallet; + + const BLS12_381_CHANNEL_TOKEN_LEN: usize = 1074; + const BLS12_381_G1_LEN: usize = 48; + const BLS12_381_G2_LEN: usize = 96; + const SECP256K1_PK_LEN: usize = 33; + + pub fn reconstruct_secp_public_key(pk_bytes: &[u8; SECP256K1_PK_LEN]) -> secp256k1::PublicKey { + return secp256k1::PublicKey::from_slice(pk_bytes).unwrap(); + } + + pub fn reconstruct_wallet_bls12(channel_token: &ChannelToken, wpk: &secp256k1::PublicKey, cust_bal: u32, merch_bal: u32) -> Wallet { + let channelId = channel_token.compute_channel_id(); + let wpk_h = util::hash_pubkey_to_fr::(&wpk); + + return Wallet { + channelId, wpk: wpk_h, bc: cust_bal as i64, bm: merch_bal as i64, close: None + } + } + + pub fn reconstruct_channel_token_bls12(channel_token: &Vec) -> BoltResult> + { + // parse pkc, pkm, pkM, mpk and comParams + if channel_token.len() != BLS12_381_CHANNEL_TOKEN_LEN { + return Err(String::from("could not reconstruct the channel token!")); + } + + let num_y_elems = 5; + let num_com_params= 6; + + let mut cur_index = 0; + let mut end_index = SECP256K1_PK_LEN; + let pkc = secp256k1::PublicKey::from_slice(&channel_token[cur_index .. end_index]).unwrap(); + + cur_index = end_index; + end_index += SECP256K1_PK_LEN; + let pkm = secp256k1::PublicKey::from_slice(&channel_token[cur_index .. end_index]).unwrap(); + + cur_index = end_index; + end_index += BLS12_381_G2_LEN; // pk_M => (X, Y) + let ser_cl_x = channel_token[cur_index .. end_index].to_vec(); + let str_cl_x = util::encode_as_hexstring(&ser_cl_x); + let X = str_cl_x.as_bytes(); + + let mut Y = Vec::new(); + for _ in 0 .. num_y_elems { + cur_index = end_index; + end_index += BLS12_381_G2_LEN; + let cl_y = channel_token[cur_index .. end_index].to_vec(); + let ser_cl_y = util::encode_as_hexstring(&cl_y); + let str_cl_y = ser_cl_y.as_bytes(); + Y.extend(str_cl_y); + } + let cl_pk= PublicKey::::from_slice(&X, &Y.as_slice(), str_cl_x.len(), num_y_elems); + + cur_index = end_index; + end_index += BLS12_381_G1_LEN; + let g1 = channel_token[cur_index .. end_index].to_vec(); + let ser_mpk_g1 = util::encode_as_hexstring(&g1); + + cur_index = end_index; + end_index += BLS12_381_G2_LEN; + let g2 = channel_token[cur_index .. end_index].to_vec(); + let ser_mpk_g2 = util::encode_as_hexstring(&g2); + + let ser_g1 = ser_mpk_g1.as_bytes(); + let ser_g2 = ser_mpk_g2.as_bytes(); + + let mpk = PublicParams::::from_slice(&ser_g1, &ser_g2); + + let mut comparams = Vec::new(); + for _ in 0 .. num_com_params { + cur_index = end_index; + end_index += BLS12_381_G1_LEN; + let com = channel_token[cur_index .. end_index].to_vec(); + let ser_com = util::encode_as_hexstring(&com); + let str_com = ser_com.as_bytes(); + comparams.extend(str_com); + } + + let com_params = CSMultiParams::::from_slice(&comparams.as_slice(), ser_mpk_g1.len(), num_com_params); + + Ok(Some(ChannelToken { + pk_c: Some(pkc), pk_m: pkm, cl_pk_m: cl_pk, mpk: mpk, comParams: com_params + })) + } + +} + #[cfg(all(test, feature = "unstable"))] mod benches { use rand::{Rng, thread_rng}; @@ -895,4 +993,44 @@ mod tests { let _des_cw: bidirectional::CustomerState = serde_json::from_str(&serialized_cw).unwrap(); } + + #[test] + fn test_reconstruct_channel_token() { + let _ser_channel_token = "024c252c7e36d0c30ae7c67dabea2168f41b36b85c14d3e180b423fa1a5df0e7ac027df0457901953b9b776f4999d5a1e78\ + 049c0afa4f741d0d3bb7d9711a0f8c0038f4c70072363fe07ffe1450d63205cbaeaafe600ca9001d8bbf8984ce54a9c5e041084779dace7a4cf582906ea4e\ + 493a1368ec7f05e7f89635c555c26e5d0149186095856dc210bef4b8fec03415cd6d1253bdafd0934a20b57ee088fa7ee0bab0668b1aa84c30e856dd685ce\ + e2a95844cb68504e82fd9dd874cbf6f7ee58155245e97c52625b53f4ca969f48b33c59f0009adc70d1472a303a35ace0d96149c8cdb96f29b6f476b8f4a10\ + bd430c4658d4e0b5873fcb946a76aa861c6c4c601ab8fb0b9c88d2e8861de2f0dae2bb2a8492db2978ce8f2e509328efbf12384ae2db5c17021d222724a3b\ + c4b621bf4f32601d555ff2cfc2171adeb2f1bd42c484c1c0a1e5d7d2853c102080680cefc925808b6e3d71b29a93f7e8f5c2eeeeef944b3740feddb24ec2c\ + 17e3db22ee6a7af77e32a9d186bdcc150dd59b0cd92b92b6656cb588dec9d1d07be5e2a319bf37f1120b7c656f78dc6c4064f8d63f590f70cdc0c1746fde6\ + 035eeb9aa90b69ea666ad71b27078ab61573aec60bab80a4e6a8e4d8ce02204f5b7e0131bf24d5df1428e9e571891c6feb1c0a52ba789136b244f13f510c4\ + f1f0eb4b0a7e675f105f8102c672461da340ebcae1eddd49a009bcf3b199eb2006fab6cf0ccf102b5c6dd45722dc0c27d4b9697f627f1bcbe44f6d96842de\ + c92877ff23d374964970c3386972a8ae369367907001bcd8bba458b8f29842321a8231f3441054999cb19b2c40409da8216406298e1d41bcaf5ea8a225266\ + 2848d3f810dd369aba5ff684360080aa6f5e9ba61be1331f6bdf8b00d1ec8453637c4b480f6d0c5e5467013aa0e8be1777c370a1988db21d8d3de3f6d79d8\ + cbe6412f88d39de0cd1bf9e8f9b57ff933f21bef89b5bd3f9a901936568db58cc8326a719bf56438bbcab659a20ea5c0342eb9f072f105303c90de3b3b865\ + 66155899d05d00396cfae74ac0526f0dd30c33e0c6790f3f8119dac12fb6f870b9a317afa94cd624b88ede30d49d2373b58453637c4b480f6d0c5e5467013\ + aa0e8be1777c370a1988db21d8d3de3f6d79d8cbe6412f88d39de0cd1bf9e8f9b57ffa397625c859a63e2c6e42486c4f76f306d484cce151f8614f87506e9\ + 9c871521dd244bfeb380481aed8df823a507c7a3ad367c1797fc6efa089f929729e7d48bfa9c60860fbb212918bb91d8c6aa523046bdf208c95fa5a0fb86a\ + 1e46f92e0e5893e136b74d38e106fa990590598932a4e2458034cea22337c6f365bcb5cab59ceea03d7a9f7821ea432e262877ef0128cb73d8733c3961762\ + 26acb6b3de132c803be39a4e803cbc5a4670cb6169583fa899146fab0227dc2ae167393f96f3b8b31e015af1c305de3a07f52408e9c52495c2458ea05c7a3\ + 71dc14f3b1d6a646ed7cc0ca9417d8bde6efc1ac300d8e28f"; + let ser_channel_token = hex::decode(_ser_channel_token).unwrap(); + + let option_ct = wtp_utils::reconstruct_channel_token_bls12(&ser_channel_token); + let channel_token = match option_ct { + Ok(n) => n.unwrap(), + Err(e) => panic!("Error reconstructing compact rep of channel token: {}", e) + }; + + let channelId = channel_token.compute_channel_id(); + + let original_channelId = "[\"7523dfcf61afce756b79e44c09c5537a8384a43e059d72e3539ffcdda9566c3f\"]"; + let computed_channelId = serde_json::to_string(&channelId).unwrap(); + + println!("channel ID: {}", channelId); + println!("pkc: {:?}", channel_token.pk_c.unwrap()); + println!("pkm: {:?}", channel_token.pk_m); + + assert_eq!(original_channelId, computed_channelId); + } } diff --git a/src/ped92.rs b/src/ped92.rs index 53d59bc..35223e4 100644 --- a/src/ped92.rs +++ b/src/ped92.rs @@ -1,5 +1,5 @@ // ped92.rs -use rand::Rng; +use rand::{Rng, AsByteSliceMut}; use pairing::{Engine, CurveProjective}; use ff::{Rand, Field, PrimeField}; use std::fmt; @@ -40,6 +40,24 @@ impl PartialEq for CSMultiParams { } } +impl CSMultiParams { + pub fn from_slice<'de>(ser_gs: &'de [u8], g_len: usize, num_elems: usize) -> Self + where ::G1: serde::Deserialize<'de> + { + let mut pub_bases: Vec = Vec::new(); + let mut start_pos = 0; + let mut end_pos = g_len; + for _ in 0 .. num_elems { + let g: E::G1 = serde_json::from_slice(&ser_gs[start_pos .. end_pos]).unwrap(); + start_pos = end_pos; + end_pos += g_len; + pub_bases.push(g); + } + + return CSMultiParams { pub_bases}; + } +} + impl fmt::Display for CSMultiParams { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -369,5 +387,39 @@ mod tests { assert_eq!(proof.verify_proof(&comParams, &com.c, &challenge, None), true); } - // add tests for extend/remove commits dynamically + #[test] + fn test_cs_multiparam_serialization() { + + let mut vec: Vec = Vec::new(); + let bin_g1= vec![132, 83, 99, 124, 75, 72, 15, 109, 12, 94, 84, 103, 1, 58, 160, 232, 190, 23, 119, 195, 112, 161, 152, 141, 178, 29, 141, 61, 227, 246, 215, 157, 140, 190, 100, 18, 248, 141, 57, 222, 12, 209, 191, 158, 143, 155, 87, 255]; + let bin_g2 = vec![140, 16, 244, 244, 135, 28, 18, 94, 46, 64, 233, 195, 218, 147, 238, 170, 46, 164, 50, 92, 234, 117, 61, 158, 64, 226, 153, 38, 127, 168, 49, 125, 177, 183, 74, 164, 138, 128, 168, 84, 137, 67, 21, 179, 124, 88, 194, 239]; + let bin_g3 = vec![147, 174, 242, 238, 231, 127, 9, 120, 16, 9, 191, 238, 60, 57, 106, 34, 198, 62, 28, 183, 77, 170, 27, 116, 36, 75, 242, 26, 242, 23, 213, 31, 186, 21, 141, 219, 59, 104, 247, 118, 56, 95, 183, 124, 103, 83, 93, 154]; + + let ser_g1 = util::encode_as_hexstring(&bin_g1); + let ser_g2 = util::encode_as_hexstring(&bin_g2); + let ser_g3 = util::encode_as_hexstring(&bin_g3); + + let str_g1 = ser_g1.as_bytes(); + let str_g2 = ser_g2.as_bytes(); + let str_g3 = ser_g3.as_bytes(); + + vec.extend(str_g1); + vec.extend(str_g2); + vec.extend(str_g3); + + let rec_csparams = CSMultiParams::::from_slice(&vec.as_slice(), str_g1.len(), 3); + println!("CS params: {:?}", rec_csparams.pub_bases); + + let ser_cs = serde_json::to_string(&rec_csparams).unwrap(); + + println!("Serialized: {:}", ser_cs); + let rec_g1_str = serde_json::to_string(&rec_csparams.pub_bases[0]).unwrap(); + assert_eq!(rec_g1_str, "\"8453637c4b480f6d0c5e5467013aa0e8be1777c370a1988db21d8d3de3f6d79d8cbe6412f88d39de0cd1bf9e8f9b57ff\""); + + let rec_g2_str = serde_json::to_string(&rec_csparams.pub_bases[1]).unwrap(); + assert_eq!(rec_g2_str, "\"8c10f4f4871c125e2e40e9c3da93eeaa2ea4325cea753d9e40e299267fa8317db1b74aa48a80a854894315b37c58c2ef\""); + + let rec_g3_str = serde_json::to_string(&rec_csparams.pub_bases[2]).unwrap(); + assert_eq!(rec_g3_str, "\"93aef2eee77f09781009bfee3c396a22c63e1cb74daa1b74244bf21af217d51fba158ddb3b68f776385fb77c67535d9a\""); + } } diff --git a/src/util.rs b/src/util.rs index c15cfa1..0d904c6 100644 --- a/src/util.rs +++ b/src/util.rs @@ -24,6 +24,12 @@ pub fn is_vec_g2_equal(a: &Vec, b: &Vec) -> bool { .all(|(a, b)| a == b) } +pub fn encode_as_hexstring(bytes: &Vec) -> String { + let mut ser_hex = hex::encode(bytes); + ser_hex.insert(0, '"'); + ser_hex.push('"'); + return ser_hex; +} pub fn hash_g1_to_fr(x: &Vec) -> E::Fr { let mut x_vec: Vec = Vec::new();