raycrypt 0.3.1

Encrypt at the speed of light
Documentation
use crate::ecc::field::FieldElement;
use zeroize::{Zeroize, ZeroizeOnDrop};

use crate::ecc::InvalidKey;

const BASE: [u8; 32] = [
    9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];

pub fn scalarmult(n: &[u8], p: &[u8]) -> [u8; 32] {
    let mut t = [0u8; 32];

    for i in 0..32 {
        t[i] = n[i];
    }

    t[0] &= 248;
    t[31] &= 127;
    t[31] |= 64;

    let x1 = FieldElement::from_bytes(p);
    let mut x2 = FieldElement::one();
    let mut z2 = FieldElement::zero();
    let mut x3 = x1.clone();
    let mut z3 = FieldElement::one();

    let mut swap = 0;
    for pos in (0..255).rev() {
        let bit = (t[pos / 8] >> (pos & 7)) & 1;
        swap ^= bit as i32;
        x2.swap(&mut x3, swap);
        z2.swap(&mut z3, swap);
        swap = bit as i32;

        let a = &x2 + &z2;
        let b = &x2 - &z2;
        let aa = a.square();
        let bb = b.square();
        x2 = &aa * &bb;
        let e = &aa - &bb;
        let mut da = &x3 - &z3;
        da = da * a;
        let mut cb = &x3 + &z3;
        cb = cb * b;
        x3 = &da + &cb;
        x3 = x3.square();
        z3 = &da - &cb;
        z3 = z3.square();
        z3 = &z3 * &x1;
        z2 = e.mul32(121666);
        z2 = z2 + bb;
        z2 = z2 * e;
    }

    x2.swap(&mut x3, swap);
    z2.swap(&mut z3, swap);

    let output = (z2.invert() * x2).to_bytes();

    t.zeroize();

    output
}

pub fn scalarmult_base(x: &[u8]) -> [u8; 32] {
    scalarmult(x, BASE.as_ref())
}

pub type PublicKey = [u8; 32];

#[derive(Zeroize, ZeroizeOnDrop)]
pub struct PrivateKey {
    key: [u8; 32],
}

impl PrivateKey {
    pub fn new(key: &[u8]) -> Result<PrivateKey, InvalidKey> {
        if key.len() != 32 {
            return Err(InvalidKey);
        }

        let mut key: [u8; 32] = key.try_into().unwrap();

        Ok(PrivateKey { key })
    }

    pub fn public_key(&self) -> PublicKey {
        scalarmult_base(&self.key)
    }

    pub fn exchange(&self, public: PublicKey) -> [u8; 32] {
        scalarmult(&self.key, &public)
    }
}