Skip to content

Commit

Permalink
Merge pull request #5 from mitinarseny/feat/wallet-v5r1
Browse files Browse the repository at this point in the history
feat: wallet v5r1
  • Loading branch information
mitinarseny authored Aug 21, 2024
2 parents 0bce19c + d3ef2cc commit 726c697
Show file tree
Hide file tree
Showing 25 changed files with 1,123 additions and 234 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 35 additions & 2 deletions crates/bits/src/as/bits.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use bitvec::{order::Msb0, slice::BitSlice, view::AsBits};
use bitvec::{order::Msb0, slice::BitSlice, vec::BitVec, view::AsBits};

use crate::{
de::{r#as::BitUnpackAs, BitReader, BitReaderExt},
ser::{r#as::BitPackAs, BitPack, BitWriter, BitWriterExt},
};

use super::args::NoArgs;

/// **Ser**ialize value by taking a reference to [`BitSlice`] on it.
pub struct AsBitSlice;

Expand Down Expand Up @@ -40,6 +42,37 @@ where
/// **De**/**ser**ialize value from/into exactly `N` bits.
pub struct NBits<const BITS: usize>;

/// **De**/**ser**ialize bits by prefixing its length with `N`-bit integer.
pub struct VarBits<const BITS_FOR_LEN: usize>;

impl<const BITS_FOR_LEN: usize, T> BitPackAs<T> for VarBits<BITS_FOR_LEN>
where
T: AsRef<BitSlice<u8, Msb0>>,
{
#[inline]
fn pack_as<W>(source: &T, mut writer: W) -> Result<(), W::Error>
where
W: BitWriter,
{
let source = source.as_ref();
writer
.pack_as::<_, NBits<BITS_FOR_LEN>>(source.len())?
.pack(source)?;
Ok(())
}
}

impl<const BITS_FOR_LEN: usize> BitUnpackAs<BitVec<u8, Msb0>> for VarBits<BITS_FOR_LEN> {
#[inline]
fn unpack_as<R>(mut reader: R) -> Result<BitVec<u8, Msb0>, R::Error>
where
R: BitReader,
{
let num_bits = reader.unpack_as::<_, NBits<BITS_FOR_LEN>>()?;
reader.unpack_with(num_bits)
}
}

/// **De**/**ser**ialize bytes by prefixing its length with `N`-bit integer.
pub struct VarBytes<const BITS_FOR_BYTES_LEN: usize>;

Expand Down Expand Up @@ -67,6 +100,6 @@ impl<const BITS_FOR_BYTES_LEN: usize> BitUnpackAs<Vec<u8>> for VarBytes<BITS_FOR
R: BitReader,
{
let num_bytes = reader.unpack_as::<_, NBits<BITS_FOR_BYTES_LEN>>()?;
reader.read_bytes_vec(num_bytes)
reader.unpack_as_with::<_, Vec<NoArgs<_>>>((num_bytes, ()))
}
}
4 changes: 2 additions & 2 deletions crates/bits/src/as/integer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl<const BITS: usize> BitUnpackAs<BigUint> for NBits<BITS> {
where
R: BitReader,
{
let mut bits = reader.read_bitvec(BITS)?;
let mut bits: BitVec<u8, Msb0> = reader.unpack_with(BITS)?;
let total_bits = (BITS + 7) & !7;
bits.resize(total_bits, false);
bits.shift_right(total_bits - BITS);
Expand Down Expand Up @@ -81,7 +81,7 @@ impl<const BITS: usize> BitUnpackAs<BigInt> for NBits<BITS> {
where
R: BitReader,
{
let mut bits = reader.read_bitvec(BITS)?;
let mut bits: BitVec<u8, Msb0> = reader.unpack_with(BITS)?;
let total_bits = (BITS + 7) & !7;
bits.resize(total_bits, false);
bits.shift_right(total_bits - BITS);
Expand Down
7 changes: 6 additions & 1 deletion crates/bits/src/de/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,17 @@ where
}

impl BitUnpackWithArgs for BitVec<u8, Msb0> {
/// length
type Args = usize;

#[inline]
fn unpack_with<R>(mut reader: R, len: Self::Args) -> Result<Self, R::Error>
where
R: BitReader,
{
reader.read_bitvec(len)
let mut dst = BitVec::with_capacity(len);
dst.resize(len, false);
reader.read_bits_into(&mut dst)?;
Ok(dst)
}
}
19 changes: 1 addition & 18 deletions crates/bits/src/de/reader.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::iter;

use ::bitvec::{order::Msb0, slice::BitSlice, vec::BitVec, view::AsMutBits};
use ::bitvec::{order::Msb0, slice::BitSlice, view::AsMutBits};
use impl_tools::autoimpl;

use crate::{
Expand Down Expand Up @@ -46,15 +46,6 @@ pub trait BitReader {

/// Extension helper for [`BitReader`].
pub trait BitReaderExt: BitReader {
/// Reads `n` bits and returns newly created [`BitVec`]
#[inline]
fn read_bitvec(&mut self, n: usize) -> Result<BitVec<u8, Msb0>, Self::Error> {
let mut dst = BitVec::with_capacity(n);
dst.resize(n, false);
self.read_bits_into(&mut dst)?;
Ok(dst)
}

/// Reads `dst.len()` bytes into given byte slice
#[inline]
fn read_bytes_into(&mut self, mut dst: impl AsMut<[u8]>) -> Result<(), Self::Error> {
Expand All @@ -69,14 +60,6 @@ pub trait BitReaderExt: BitReader {
Ok(arr)
}

/// Read `n` bytes and return [`Vec`]
#[inline]
fn read_bytes_vec(&mut self, n: usize) -> Result<Vec<u8>, Self::Error> {
let mut v = vec![0; n];
self.read_bytes_into(&mut v)?;
Ok(v)
}

/// Unpack value using its [`BitUnpack`] implementation
#[inline]
fn unpack<T>(&mut self) -> Result<T, Self::Error>
Expand Down
1 change: 1 addition & 0 deletions crates/contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ tlb-ton.workspace = true
anyhow.workspace = true
bitvec.workspace = true
chrono.workspace = true
impl-tools.workspace = true
lazy_static.workspace = true
num-bigint.workspace = true

Expand Down
12 changes: 6 additions & 6 deletions crates/contracts/src/wallet/mnemonic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use nacl::sign::generate_keypair;
use pbkdf2::{password_hash::Output, pbkdf2_hmac};
use sha2::Sha512;

pub use nacl::sign::Keypair;
use super::KeyPair;

lazy_static! {
static ref WORDLIST_EN: HashSet<&'static str> = include_str!("./wordlist_en.txt")
Expand All @@ -21,12 +21,12 @@ lazy_static! {
///
/// ```rust
/// # use hex_literal::hex;
/// # use ton_contracts::wallet::mnemonic::{Keypair, Mnemonic};
/// # use ton_contracts::wallet::{KeyPair, mnemonic::Mnemonic};
/// let mnemonic: Mnemonic = "dose ice enrich trigger test dove century still betray gas diet dune use other base gym mad law immense village world example praise game"
/// .parse()
/// .unwrap();
/// let kp: Keypair = mnemonic.generate_keypair(None).unwrap();
/// # assert_eq!(kp.skey, hex!("119dcf2840a3d56521d260b2f125eedc0d4f3795b9e627269a4b5a6dca8257bdc04ad1885c127fe863abb00752fa844e6439bb04f264d70de7cea580b32637ab"));
/// let kp: KeyPair = mnemonic.generate_keypair(None).unwrap();
/// # assert_eq!(kp.secret_key, hex!("119dcf2840a3d56521d260b2f125eedc0d4f3795b9e627269a4b5a6dca8257bdc04ad1885c127fe863abb00752fa844e6439bb04f264d70de7cea580b32637ab"));
/// ```
#[derive(Debug, Clone)]
pub struct Mnemonic([&'static str; 24]);
Expand All @@ -35,15 +35,15 @@ impl Mnemonic {
const PBKDF_ITERATIONS: u32 = 100000;

/// Generate [`Keypair`] with optional password
pub fn generate_keypair(&self, password: impl Into<Option<String>>) -> anyhow::Result<Keypair> {
pub fn generate_keypair(&self, password: impl Into<Option<String>>) -> anyhow::Result<KeyPair> {
let entropy = self.entropy(password)?;
let seed = Self::pbkdf2_sha512(
entropy.as_slice(),
"TON default seed",
Self::PBKDF_ITERATIONS,
64,
)?;
Ok(generate_keypair(&seed[0..32]))
Ok(generate_keypair(&seed[0..32]).into())
}

fn entropy(&self, password: impl Into<Option<String>>) -> anyhow::Result<[u8; 64]> {
Expand Down
Loading

0 comments on commit 726c697

Please sign in to comment.