Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: wallet v5r1 #5

Merged
merged 3 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading