From 39f978bb4f21d995d8f68d4d5ac45a302eb88dbc Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 1 Aug 2018 09:56:20 +0100 Subject: [PATCH] ExtendedSpendingKey::read() and ExtendedFullViewingKey::read() --- src/lib.rs | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a233436..2bc48d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,14 +9,16 @@ extern crate sapling_crypto; use aes::Aes256; use blake2_rfc::blake2b::{Blake2b, Blake2bResult}; -use byteorder::{ByteOrder, LittleEndian, WriteBytesExt}; +use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt}; use fpe::ff1::{BinaryNumeralString, FF1}; use pairing::{bls12_381::Bls12, Field, PrimeField, PrimeFieldRepr}; use sapling_crypto::{ - jubjub::{FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, ToUniform}, + jubjub::{ + edwards, FixedGenerators, JubjubBls12, JubjubEngine, JubjubParams, ToUniform, Unknown, + }, primitives::{Diversifier, PaymentAddress, ViewingKey}, }; -use std::io::{self, Write}; +use std::io::{self, Read, Write}; lazy_static! { static ref JUBJUB: JubjubBls12 = { JubjubBls12::new() }; @@ -87,6 +89,27 @@ impl ExpandedSpendingKey { ExpandedSpendingKey { ask, nsk, ovk } } + pub fn read(mut reader: R) -> io::Result { + let mut ask_repr = ::Repr::default(); + ask_repr.read_le(&mut reader)?; + let ask = + E::Fs::from_repr(ask_repr).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let mut nsk_repr = ::Repr::default(); + nsk_repr.read_le(&mut reader)?; + let nsk = + E::Fs::from_repr(nsk_repr).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let mut ovk = [0; 32]; + reader.read_exact(&mut ovk)?; + + Ok(ExpandedSpendingKey { + ask, + nsk, + ovk: OutgoingViewingKey(ovk), + }) + } + fn to_bytes(&self) -> [u8; 96] { let mut result = [0u8; 96]; self.ask @@ -135,6 +158,38 @@ impl FullViewingKey { } } + pub fn read(mut reader: R, params: &E::Params) -> io::Result { + let ak = edwards::Point::::read(&mut reader, params)?; + let ak = match ak.as_prime_order(params) { + Some(p) => p, + None => { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "ak not of prime order", + )) + } + }; + + let nk = edwards::Point::::read(&mut reader, params)?; + let nk = match nk.as_prime_order(params) { + Some(p) => p, + None => { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "nk not of prime order", + )) + } + }; + + let mut ovk = [0; 32]; + reader.read_exact(&mut ovk)?; + + Ok(FullViewingKey { + vk: ViewingKey { ak, nk }, + ovk: OutgoingViewingKey(ovk), + }) + } + fn to_bytes(&self) -> [u8; 96] { let mut result = [0u8; 96]; self.vk @@ -373,6 +428,27 @@ impl ExtendedSpendingKey { } } + pub fn read(mut reader: R) -> io::Result { + let depth = reader.read_u8()?; + let mut tag = [0; 4]; + reader.read_exact(&mut tag)?; + let i = reader.read_u32::()?; + let mut c = [0; 32]; + reader.read_exact(&mut c)?; + let xsk = ExpandedSpendingKey::read(&mut reader)?; + let mut dk = [0; 32]; + reader.read_exact(&mut dk)?; + + Ok(ExtendedSpendingKey { + depth, + parent_fvk_tag: FVKTag(tag), + child_index: ChildIndex::from_index(i), + chain_code: ChainCode(c), + xsk, + dk: DiversifierKey(dk), + }) + } + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_u8(self.depth)?; writer.write_all(&self.parent_fvk_tag.0)?; @@ -446,6 +522,27 @@ impl<'a> From<&'a ExtendedSpendingKey> for ExtendedFullViewingKey { } impl ExtendedFullViewingKey { + pub fn read(mut reader: R) -> io::Result { + let depth = reader.read_u8()?; + let mut tag = [0; 4]; + reader.read_exact(&mut tag)?; + let i = reader.read_u32::()?; + let mut c = [0; 32]; + reader.read_exact(&mut c)?; + let fvk = FullViewingKey::read(&mut reader, &*JUBJUB)?; + let mut dk = [0; 32]; + reader.read_exact(&mut dk)?; + + Ok(ExtendedFullViewingKey { + depth, + parent_fvk_tag: FVKTag(tag), + child_index: ChildIndex::from_index(i), + chain_code: ChainCode(c), + fvk, + dk: DiversifierKey(dk), + }) + } + pub fn write(&self, mut writer: W) -> io::Result<()> { writer.write_u8(self.depth)?; writer.write_all(&self.parent_fvk_tag.0)?; @@ -609,6 +706,23 @@ mod tests { ); } + #[test] + fn read_write() { + let seed = [0; 32]; + let xsk = ExtendedSpendingKey::master(&seed); + let fvk = ExtendedFullViewingKey::from(&xsk); + + let mut ser = vec![]; + xsk.write(&mut ser).unwrap(); + let xsk2 = ExtendedSpendingKey::read(&ser[..]).unwrap(); + assert_eq!(xsk2, xsk); + + let mut ser = vec![]; + fvk.write(&mut ser).unwrap(); + let fvk2 = ExtendedFullViewingKey::read(&ser[..]).unwrap(); + assert_eq!(fvk2, fvk); + } + #[test] fn test_vectors() { struct TestVector {