more functions. Added a hot fix for a sepc256k1 serde impl bug
This commit is contained in:
parent
523543b8ec
commit
d77ca4957c
18
src/lib.rs
18
src/lib.rs
|
@ -658,12 +658,15 @@ pub mod bidirectional {
|
||||||
common_params: clproto::CommonParams, // common params for NIZK
|
common_params: clproto::CommonParams, // common params for NIZK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO This is broken
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct CustomerWallet {
|
pub struct CustomerWallet {
|
||||||
sk: clsigs::SecretKeyD, // the secret key for the signature scheme (Is it possible to make this a generic field?)
|
sk: clsigs::SecretKeyD, // the secret key for the signature scheme (Is it possible to make this a generic field?)
|
||||||
#[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
|
#[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
|
||||||
cid: Fr, // channel Id
|
cid: Fr, // channel Id
|
||||||
|
#[serde(deserialize_with = "serialization_wrappers::deserialize_public_key")]
|
||||||
wpk: secp256k1::PublicKey, // signature verification key
|
wpk: secp256k1::PublicKey, // signature verification key
|
||||||
|
#[serde(deserialize_with = "serialization_wrappers::deserialize_secret_key")]
|
||||||
wsk: secp256k1::SecretKey, // signature signing key
|
wsk: secp256k1::SecretKey, // signature signing key
|
||||||
#[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
|
#[serde(serialize_with = "serialization_wrappers::serialize_generic_encodable", deserialize_with = "serialization_wrappers::deserialize_fr")]
|
||||||
h_wpk: Fr,
|
h_wpk: Fr,
|
||||||
|
@ -864,6 +867,7 @@ pub mod bidirectional {
|
||||||
let w_com = commit_scheme::commit(&cm_csp, &x, r);
|
let w_com = commit_scheme::commit(&cm_csp, &x, r);
|
||||||
// construct channel token
|
// construct channel token
|
||||||
let t_c = ChannelToken { w_com: w_com, pk: keypair.pk.clone(), third_party_pay: channel.third_party };
|
let t_c = ChannelToken { w_com: w_com, pk: keypair.pk.clone(), third_party_pay: channel.third_party };
|
||||||
|
|
||||||
// construct customer wallet secret key plus other components
|
// construct customer wallet secret key plus other components
|
||||||
let csk_c = CustomerWallet { sk: keypair.sk.clone(), cid: cid, wpk: wpk, wsk: wsk, h_wpk: h_wpk,
|
let csk_c = CustomerWallet { sk: keypair.sk.clone(), cid: cid, wpk: wpk, wsk: wsk, h_wpk: h_wpk,
|
||||||
r: r, balance: b0_customer, merchant_balance: b0_merchant,
|
r: r, balance: b0_customer, merchant_balance: b0_merchant,
|
||||||
|
@ -1686,7 +1690,7 @@ pub mod ffishim {
|
||||||
let deserialized_merchant_data: bidirectional::InitMerchantData = serde_json::from_str(&name_merchant_data).unwrap();
|
let deserialized_merchant_data: bidirectional::InitMerchantData = serde_json::from_str(&name_merchant_data).unwrap();
|
||||||
|
|
||||||
let proof1 = bidirectional::establish_customer_phase1(&deserialized_pp, &deserialized_customer_data, &deserialized_merchant_data.bases);
|
let proof1 = bidirectional::establish_customer_phase1(&deserialized_pp, &deserialized_customer_data, &deserialized_merchant_data.bases);
|
||||||
let ser = ["{\'proof\':\'", serde_json::to_string(&proof1).unwrap().as_str(), "\'}"].concat();;
|
let ser = ["{\'proof\':\'", serde_json::to_string(&proof1).unwrap().as_str(), "\'}"].concat();
|
||||||
let cser = CString::new(ser).unwrap();
|
let cser = CString::new(ser).unwrap();
|
||||||
cser.into_raw()
|
cser.into_raw()
|
||||||
}
|
}
|
||||||
|
@ -1714,13 +1718,15 @@ pub mod ffishim {
|
||||||
let deserialized_proof_1: clproto::ProofCV = serde_json::from_str(&name_proof_1).unwrap();
|
let deserialized_proof_1: clproto::ProofCV = serde_json::from_str(&name_proof_1).unwrap();
|
||||||
|
|
||||||
let wallet_sig = bidirectional::establish_merchant_phase2(&deserialized_pp, &mut deserialized_channel_state, &deserialized_merchant_data, &deserialized_proof_1);
|
let wallet_sig = bidirectional::establish_merchant_phase2(&deserialized_pp, &mut deserialized_channel_state, &deserialized_merchant_data, &deserialized_proof_1);
|
||||||
let ser = serde_json::to_string(&wallet_sig).unwrap();
|
let ser = ["{\'wallet_sig\':\'", serde_json::to_string(&wallet_sig).unwrap().as_str(), "\', \'state\':\'", serde_json::to_string(&deserialized_channel_state).unwrap().as_str() ,"\'}"].concat();
|
||||||
let cser = CString::new(ser).unwrap();
|
let cser = CString::new(ser).unwrap();
|
||||||
cser.into_raw()
|
cser.into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Everythnig above is done
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn ffishim_bidirectional_establish_customer_final(serialized_pp: *mut c_char, serialized_merchant_keypair: *mut c_char, serialized_customer_data: *mut c_char, serialized_wallet_sig: *mut c_char) -> bool {
|
pub extern fn ffishim_bidirectional_establish_customer_final(serialized_pp: *mut c_char, serialized_merchant_keypair: *mut c_char, serialized_customer_data: *mut c_char, serialized_wallet_sig: *mut c_char) -> *mut c_char {
|
||||||
// Deserialize the pp
|
// Deserialize the pp
|
||||||
let bytes_pp = unsafe { CStr::from_ptr(serialized_pp).to_bytes() };
|
let bytes_pp = unsafe { CStr::from_ptr(serialized_pp).to_bytes() };
|
||||||
let name_pp: &str = str::from_utf8(bytes_pp).unwrap(); // make sure the bytes are UTF-8
|
let name_pp: &str = str::from_utf8(bytes_pp).unwrap(); // make sure the bytes are UTF-8
|
||||||
|
@ -1741,7 +1747,11 @@ pub mod ffishim {
|
||||||
let name_wallet_sig: &str = str::from_utf8(bytes_wallet_sig).unwrap(); // make sure the bytes are UTF-8
|
let name_wallet_sig: &str = str::from_utf8(bytes_wallet_sig).unwrap(); // make sure the bytes are UTF-8
|
||||||
let deserialized_wallet_sig: clsigs::SignatureD = serde_json::from_str(&name_wallet_sig).unwrap();
|
let deserialized_wallet_sig: clsigs::SignatureD = serde_json::from_str(&name_wallet_sig).unwrap();
|
||||||
|
|
||||||
bidirectional::establish_customer_final(&deserialized_pp, &deserialized_merchant_keypair.pk, &mut deserialized_customer_data.csk, deserialized_wallet_sig)
|
// TODO make this return the csk
|
||||||
|
bidirectional::establish_customer_final(&deserialized_pp, &deserialized_merchant_keypair.pk, &mut deserialized_customer_data.csk, deserialized_wallet_sig);
|
||||||
|
let ser = ["{\'customer_data\':\'", serde_json::to_string(&deserialized_customer_data).unwrap().as_str(), "\'}"].concat();
|
||||||
|
let cser = CString::new(ser).unwrap();
|
||||||
|
cser.into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
35
src/main.py
35
src/main.py
|
@ -50,7 +50,7 @@ class Libbolt(object):
|
||||||
self.lib.ffishim_bidirectional_establish_merchant_phase2.restype = c_void_p
|
self.lib.ffishim_bidirectional_establish_merchant_phase2.restype = c_void_p
|
||||||
|
|
||||||
self.lib.ffishim_bidirectional_establish_customer_final.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p)
|
self.lib.ffishim_bidirectional_establish_customer_final.argtypes = (c_void_p, c_void_p, c_void_p, c_void_p)
|
||||||
self.lib.ffishim_bidirectional_establish_customer_final.restype = c_uint8
|
self.lib.ffishim_bidirectional_establish_customer_final.restype = c_void_p
|
||||||
|
|
||||||
# For Test Structures ONLY
|
# For Test Structures ONLY
|
||||||
|
|
||||||
|
@ -104,17 +104,26 @@ class Libbolt(object):
|
||||||
return output_dictionary['commit_setup']
|
return output_dictionary['commit_setup']
|
||||||
|
|
||||||
def bidirectional_init_customer(self, pp, channel, b0_cust, b0_merch, cm_csp, cust_keys):
|
def bidirectional_init_customer(self, pp, channel, b0_cust, b0_merch, cm_csp, cust_keys):
|
||||||
|
# return self.lib.ffishim_bidirectional_init_customer(pp, channel, b0_cust, b0_merch, cm_csp, cust_keys)
|
||||||
output_string = self.lib.ffishim_bidirectional_init_customer(pp, channel, b0_cust, b0_merch, cm_csp, cust_keys)
|
output_string = self.lib.ffishim_bidirectional_init_customer(pp, channel, b0_cust, b0_merch, cm_csp, cust_keys)
|
||||||
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
||||||
# self.lib.ffishim_free_string(channel) //TODO THIS THROWS AN ERROR?!?!?!??!!
|
# self.lib.ffishim_free_string(channel) #TODO THIS THROWS AN ERROR?!?!?!??!!
|
||||||
return (output_dictionary['customer_data'], output_dictionary['state'])
|
return (output_dictionary['customer_data'], output_dictionary['state'])
|
||||||
|
|
||||||
# def bidirectional_establish_customer_phase1(self, pp, cust_data, merch_data): # TODO merch_data.bases should be parsed out.
|
def bidirectional_establish_customer_phase1(self, pp, cust_data, merch_data): # TODO merch_data.bases should be parsed out.
|
||||||
# output_string = self.lib.ffishim_bidirectional_establish_customer_phase1(pp, cust_data, merch_data)
|
output_string = self.lib.ffishim_bidirectional_establish_customer_phase1(pp, cust_data, merch_data)
|
||||||
# output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
||||||
# return output_dictionary['proof']
|
return output_dictionary['proof']
|
||||||
|
|
||||||
|
def bidirectional_establish_merchant_phase2(self, pp, channel, merch_data, proof1):
|
||||||
|
output_string = self.lib.ffishim_bidirectional_establish_merchant_phase2(pp, channel, merch_data, proof1)
|
||||||
|
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
||||||
|
return (output_dictionary['wallet_sig'], output_dictionary['state'])
|
||||||
|
|
||||||
|
def bidirectional_establish_customer_final(self, pp, merch_keys, cust_data, wallet_sig):
|
||||||
|
output_string = self.lib.ffishim_bidirectional_establish_customer_final(pp, merch_keys, cust_data, wallet_sig)
|
||||||
|
output_dictionary = ast.literal_eval(ctypes.cast(output_string, ctypes.c_char_p).value.decode('utf-8'))
|
||||||
|
return output_dictionary['customer_data']
|
||||||
|
|
||||||
# --------------------------------------------
|
# --------------------------------------------
|
||||||
|
|
||||||
|
@ -169,13 +178,13 @@ cm_csp = libbolt.bidirectional_generate_commit_setup(pp, libbolt.util_extract_pu
|
||||||
# print(" After cm_csp")
|
# print(" After cm_csp")
|
||||||
cust_data, channel_state = libbolt.bidirectional_init_customer(pp, channel_state, b0_cust, b0_merch, cm_csp, cust_keys)
|
cust_data, channel_state = libbolt.bidirectional_init_customer(pp, channel_state, b0_cust, b0_merch, cm_csp, cust_keys)
|
||||||
# print channel_state
|
# print channel_state
|
||||||
# print(" After cust_data")
|
# print(cust_data)
|
||||||
# proof1 = libbolt.bidirectional_establish_customer_phase1(pp, cust_data, merch_data)
|
proof1 = libbolt.bidirectional_establish_customer_phase1(pp, cust_data, merch_data)
|
||||||
# print(" After proof1")
|
print(" After proof1")
|
||||||
# wallet_sig = bidirectional_establish_merchant_phase2(pp, channel, merch_data, proof1)
|
wallet_sig, channel_state = libbolt.bidirectional_establish_merchant_phase2(pp, channel_state, merch_data, proof1)
|
||||||
# print(" After wallet_sig")
|
print(" After wallet_sig")
|
||||||
# setup = bidirectional_establish_customer_final(pp, merch_keys, cust_data, wallet_sig)
|
cust_data = libbolt.bidirectional_establish_customer_final(pp, merch_keys, cust_data, wallet_sig)
|
||||||
# print(" After setup")
|
print(" After final")
|
||||||
|
|
||||||
# print(setup)
|
# print(setup)
|
||||||
# print(ctypes.cast(pp, ctypes.c_char_p).value.decode('utf-8'))
|
# print(ctypes.cast(pp, ctypes.c_char_p).value.decode('utf-8'))
|
||||||
|
|
|
@ -57,7 +57,6 @@ impl<'de> Visitor<'de> for GOneVisitor {
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<u8>();
|
let tmp = seq.next_element::<u8>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
bytes.push(b)
|
bytes.push(b)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -84,7 +83,6 @@ impl<'de> Visitor<'de> for GTwoVisitor {
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<u8>();
|
let tmp = seq.next_element::<u8>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
bytes.push(b)
|
bytes.push(b)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -111,7 +109,6 @@ impl<'de> Visitor<'de> for GTargetVisitor {
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<u8>();
|
let tmp = seq.next_element::<u8>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
bytes.push(b)
|
bytes.push(b)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -138,7 +135,6 @@ impl<'de> Visitor<'de> for FieldVisitor {
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<u8>();
|
let tmp = seq.next_element::<u8>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
bytes.push(b)
|
bytes.push(b)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -165,7 +161,6 @@ impl<'de> Visitor<'de> for OptionalFieldVisitor {
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<u8>();
|
let tmp = seq.next_element::<u8>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
bytes.push(b)
|
bytes.push(b)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -293,14 +288,11 @@ impl<'de> Visitor<'de> for G1VecVisitor {
|
||||||
|
|
||||||
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
|
||||||
// println!("Hi G1VecVisitor");
|
|
||||||
|
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<Vec<u8>>();
|
let tmp = seq.next_element::<Vec<u8>>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
vec.push(decode(&b[..]).unwrap());
|
vec.push(decode(&b[..]).unwrap());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -322,14 +314,11 @@ impl<'de> Visitor<'de> for G2VecVisitor {
|
||||||
|
|
||||||
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
|
||||||
// println!("Hi G2VecVisitor");
|
|
||||||
|
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<Vec<u8>>();
|
let tmp = seq.next_element::<Vec<u8>>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
vec.push(decode(&b[..]).unwrap());
|
vec.push(decode(&b[..]).unwrap());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -351,14 +340,12 @@ impl<'de> Visitor<'de> for GTargetVecVisitor {
|
||||||
|
|
||||||
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
|
||||||
// println!("Hi G2VecVisitor");
|
|
||||||
|
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<Vec<u8>>();
|
let tmp = seq.next_element::<Vec<u8>>();
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
vec.push(decode(&b[..]).unwrap());
|
vec.push(decode(&b[..]).unwrap());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -380,16 +367,12 @@ impl<'de> Visitor<'de> for FrVecVisitor {
|
||||||
|
|
||||||
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
|
||||||
// println!("Hi FrVecVisitor");
|
|
||||||
|
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let tmp = seq.next_element::<Vec<u8>>();
|
let tmp = seq.next_element::<Vec<u8>>();
|
||||||
// println!("tmp = {:?}", tmp);
|
|
||||||
|
|
||||||
if let Ok(Some(b)) = tmp {
|
if let Ok(Some(b)) = tmp {
|
||||||
// println!("Byte = {:?}", b);
|
|
||||||
vec.push(decode(&b[..]).unwrap());
|
vec.push(decode(&b[..]).unwrap());
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -414,7 +397,6 @@ where
|
||||||
D: Deserializer<'de>
|
D: Deserializer<'de>
|
||||||
{
|
{
|
||||||
let a = deserializer.deserialize_seq(G2VecVisitor);
|
let a = deserializer.deserialize_seq(G2VecVisitor);
|
||||||
|
|
||||||
Ok(a.unwrap())
|
Ok(a.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,4 +464,79 @@ where
|
||||||
let a = deserializer.deserialize_seq(BulletProofVisitor);
|
let a = deserializer.deserialize_seq(BulletProofVisitor);
|
||||||
|
|
||||||
Ok(a.unwrap())
|
Ok(a.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------
|
||||||
|
// These are hot fixes because secp256k1's implemenetation seems to be very very broken
|
||||||
|
// TODO THIS NEED TO BE FIXED UPSTREAM !!!
|
||||||
|
|
||||||
|
struct PublicKeyVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for PublicKeyVisitor {
|
||||||
|
type Value = secp256k1::PublicKey;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("Sequence of usize for a BulletproofGens")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
loop {
|
||||||
|
let tmp = seq.next_element::<u8>();
|
||||||
|
if let Ok(Some(b)) = tmp {
|
||||||
|
bytes.push(b)
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(secp256k1::PublicKey::from_slice(bytes.as_slice()).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize_public_key<'de, D>(deserializer: D) -> Result<secp256k1::PublicKey, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
let a = deserializer.deserialize_seq(PublicKeyVisitor);
|
||||||
|
|
||||||
|
Ok(a.unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SecretKeyVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for SecretKeyVisitor {
|
||||||
|
type Value = secp256k1::SecretKey;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("Sequence of usize for a BulletproofGens")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||||
|
|
||||||
|
let mut bytes = Vec::new();
|
||||||
|
loop {
|
||||||
|
let tmp = seq.next_element::<u8>();
|
||||||
|
if let Ok(Some(b)) = tmp {
|
||||||
|
bytes.push(b)
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(secp256k1::SecretKey::from_slice(bytes.as_slice()).unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize_secret_key<'de, D>(deserializer: D) -> Result<secp256k1::SecretKey, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
let a = deserializer.deserialize_seq(SecretKeyVisitor);
|
||||||
|
|
||||||
|
Ok(a.unwrap())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue