#![allow(clippy::needless_range_loop)]
#![allow(clippy::manual_memcpy)]
pub mod ed41417;
mod edwards;
mod fe;
mod mont;
mod scalar;
pub use ed41417::{Signature, SigningKey, VerifyingKey, SIGNATURE_SIZE};
pub use edwards::{
EdwardsPoint, EDWARDS_BASE_X_BYTES, EDWARDS_BASE_Y_BYTES, EDWARDS_D_BYTES, EDWARDS_L_BYTES,
};
pub use fe::FieldElem;
pub use mont::{scalar_mult, scalar_mult_base, PublicKey, SecretKey};
pub use scalar::Scalar;
pub const SCALAR_SIZE: usize = 52;
pub const BYTES_SIZE: usize = 52;
#[inline]
pub fn clamp_scalar(scalar: &mut [u8; SCALAR_SIZE]) {
scalar[0] &= 248;
scalar[51] = (scalar[51] & 63) | 32;
}
#[inline]
pub fn cswap_bytes(cond: u8, x: &mut [u8], y: &mut [u8]) {
debug_assert_eq!(x.len(), y.len());
debug_assert!(cond == 0 || cond == 1);
let mask = 0u8.wrapping_sub(cond);
for i in 0..x.len() {
let t = mask & (x[i] ^ y[i]);
x[i] ^= t;
y[i] ^= t;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_clamp_scalar() {
let mut s = [0u8; SCALAR_SIZE];
s[0] = 0xFF;
s[51] = 0xFF;
clamp_scalar(&mut s);
assert_eq!(s[0] & 7, 0);
assert_eq!(s[51] & 0xC0, 0);
assert_eq!(s[51] & 0x20, 0x20);
}
#[test]
fn test_cswap_bytes() {
let mut x = [1u8, 2, 3, 4];
let mut y = [5u8, 6, 7, 8];
cswap_bytes(0, &mut x, &mut y);
assert_eq!(x, [1, 2, 3, 4]);
assert_eq!(y, [5, 6, 7, 8]);
cswap_bytes(1, &mut x, &mut y);
assert_eq!(x, [5, 6, 7, 8]);
assert_eq!(y, [1, 2, 3, 4]);
}
}