minisign/crypto/
cryptoutil.rs

1// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use std::ptr;
12use std::{io, mem::MaybeUninit};
13
14pub fn write_u64_le(dst: &mut [u8], mut input: u64) {
15    assert!(dst.len() == 8);
16    input = input.to_le();
17    unsafe {
18        let tmp = &input as *const _ as *const u8;
19        ptr::copy_nonoverlapping(tmp, dst.get_unchecked_mut(0), 8);
20    }
21}
22
23pub fn write_u64v_le(dst: &mut [u8], input: &[u64]) {
24    assert!(dst.len() == 8 * input.len());
25    unsafe {
26        let mut x: *mut u8 = dst.get_unchecked_mut(0);
27        let mut y: *const u64 = input.get_unchecked(0);
28        for _ in 0..input.len() {
29            let tmp = (*y).to_le();
30            ptr::copy_nonoverlapping(&tmp as *const _ as *const u8, x, 8);
31            x = x.offset(8);
32            y = y.offset(1);
33        }
34    }
35}
36
37pub fn write_u32_le(dst: &mut [u8], mut input: u32) {
38    assert!(dst.len() == 4);
39    input = input.to_le();
40    unsafe {
41        let tmp = &input as *const _ as *const u8;
42        ptr::copy_nonoverlapping(tmp, dst.get_unchecked_mut(0), 4);
43    }
44}
45
46pub fn read_u64v_le(dst: &mut [u64], input: &[u8]) {
47    assert!(dst.len() * 8 == input.len());
48    unsafe {
49        let mut x: *mut u64 = dst.get_unchecked_mut(0);
50        let mut y: *const u8 = input.get_unchecked(0);
51        for _ in 0..dst.len() {
52            let mut tmp = MaybeUninit::<u64>::uninit();
53            ptr::copy_nonoverlapping(y, tmp.as_mut_ptr() as *mut u8, 8);
54            *x = u64::from_le(tmp.assume_init());
55            x = x.offset(1);
56            y = y.offset(8);
57        }
58    }
59}
60
61#[inline]
62pub fn copy_memory(src: &[u8], dst: &mut [u8]) {
63    assert!(dst.len() >= src.len());
64    unsafe {
65        let srcp = src.as_ptr();
66        let dstp = dst.as_mut_ptr();
67        ptr::copy_nonoverlapping(srcp, dstp, src.len());
68    }
69}
70
71pub trait WriteExt {
72    fn write_u8(&mut self, val: u8) -> io::Result<()>;
73    fn write_u32_le(&mut self, val: u32) -> io::Result<()>;
74    fn write_u64_le(&mut self, val: u64) -> io::Result<()>;
75}
76
77impl<T> WriteExt for T
78where
79    T: io::Write,
80{
81    fn write_u8(&mut self, val: u8) -> io::Result<()> {
82        let buff = [val];
83        self.write_all(&buff)
84    }
85
86    fn write_u32_le(&mut self, val: u32) -> io::Result<()> {
87        let mut buff = [0u8; 4];
88        write_u32_le(&mut buff, val);
89        self.write_all(&buff)
90    }
91
92    fn write_u64_le(&mut self, val: u64) -> io::Result<()> {
93        let mut buff = [0u8; 8];
94        write_u64_le(&mut buff, val);
95        self.write_all(&buff)
96    }
97}