update
This commit is contained in:
parent
082adec86b
commit
7dc39dbb36
6 changed files with 117 additions and 88 deletions
64
Cargo.lock
generated
64
Cargo.lock
generated
|
|
@ -9,20 +9,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.3"
|
||||
name = "cmov"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
checksum = "de0758edba32d61d1fd9f4d69491b47604b91ee2f7e6b33de7e54ca4ebe55dc3"
|
||||
|
||||
[[package]]
|
||||
name = "cpubits"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.6.1"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96272c2ff28b807e09250b180ad1fb7889a3258f7455759b5c3c58b719467130"
|
||||
checksum = "9fde2467e74147f492aebb834985186b2c74761927b8b9b3bd303bcb2e72199d"
|
||||
dependencies = [
|
||||
"cpubits",
|
||||
"ctutils",
|
||||
"num-traits",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctutils"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4"
|
||||
dependencies = [
|
||||
"cmov",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -33,23 +49,6 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
|
|
@ -61,24 +60,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
crypto-bigint = { version = "0.6.1" }
|
||||
crypto-bigint = { version = "0.7.1" }
|
||||
zeroize = { version = "1.8.2", optional = true }
|
||||
|
||||
[features]
|
||||
rand = ["crypto-bigint/rand"]
|
||||
rand = ["crypto-bigint/rand_core"]
|
||||
edwards = []
|
||||
zeroize = ["dep:zeroize"]
|
||||
|
||||
|
|
|
|||
24
src/lib.rs
24
src/lib.rs
|
|
@ -6,13 +6,12 @@ pub mod edwards;
|
|||
pub mod montgomery;
|
||||
pub mod traits;
|
||||
|
||||
use crypto_bigint::subtle::{Choice, ConstantTimeEq};
|
||||
pub use crypto_bigint::{ConstChoice, Encoding, NonZero, U256};
|
||||
|
||||
#[cfg(feature = "rand")]
|
||||
use crypto_bigint::{rand_core::OsRng, Random};
|
||||
pub use crypto_bigint::{Encoding, NonZero, U256};
|
||||
|
||||
use crate::traits::{Curve, Point};
|
||||
use crypto_bigint::{Choice, CtEq, EncodedUint};
|
||||
#[cfg(feature = "rand")]
|
||||
use crypto_bigint::{Random, rand_core::OsRng};
|
||||
pub(crate) use montgomery::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
|
|
@ -29,13 +28,13 @@ impl From<&Secret> for Public {
|
|||
|
||||
impl From<[u8; 32]> for Public {
|
||||
fn from(bytes: [u8; 32]) -> Public {
|
||||
Public(U256::from_le_bytes(bytes))
|
||||
Public(U256::from_le_bytes(EncodedUint::from(bytes)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Public {
|
||||
pub fn as_bytes(&self) -> [u8; 32] {
|
||||
self.0.to_le_bytes()
|
||||
self.0.to_le_bytes().into()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +52,7 @@ impl Secret {
|
|||
let point = CURVE_25519.point(public.0);
|
||||
let p = point * self.0;
|
||||
|
||||
SharedSecret(p.get_x().to_le_bytes())
|
||||
SharedSecret(p.get_x().to_le_bytes().into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +71,7 @@ impl SharedSecret {
|
|||
}
|
||||
}
|
||||
|
||||
impl ConstantTimeEq for SharedSecret {
|
||||
impl CtEq for SharedSecret {
|
||||
fn ct_eq(&self, other: &Self) -> Choice {
|
||||
self.0.ct_eq(&other.0)
|
||||
}
|
||||
|
|
@ -109,7 +108,7 @@ mod tests {
|
|||
|
||||
let x_k =
|
||||
U256::from_be_hex("0933dc6ed7122bdf2a5f1b0516e218b743868769778787cfa1ac0ae2dfa89891");
|
||||
assert_eq!(x.0, x_k.to_le_bytes());
|
||||
assert_eq!(x.0, <[u8; 32]>::from(x_k.to_le_bytes()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -125,6 +124,9 @@ mod tests {
|
|||
let sa = a.diffie_hellman(&pb);
|
||||
let sb = b.diffie_hellman(&pa);
|
||||
|
||||
assert!(bool::from(sa.ct_eq(&sb)));
|
||||
assert!(
|
||||
bool::from(sa.ct_eq(&sb)),
|
||||
"Didn't compute same shared secret"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! ladder_impl {
|
||||
($point:ident, $swap_fn:ident) => {
|
||||
impl<N> $point<N>
|
||||
impl<N: BitOps> $point<N>
|
||||
where
|
||||
N: AddMod
|
||||
+ SubMod
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer
|
||||
+ Div<Output = N>,
|
||||
N: std::convert::From<u8>,
|
||||
{
|
||||
pub fn ladder(&self, rhs: &N) -> $point<N> {
|
||||
let mut x_0 = *self;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::traits::{Curve, Point};
|
||||
use crypto_bigint::{AddMod, Encoding, NonZero, SubMod, U256};
|
||||
use crypto_bigint::{Integer, InvMod, MulMod};
|
||||
use crypto_bigint::{AddMod, EncodedUint, Encoding, InvertMod, NonZero, SubMod, U256};
|
||||
use crypto_bigint::{BitOps, Uint};
|
||||
use crypto_bigint::{Integer, MulMod};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::{BitXor, Div, Mul};
|
||||
|
||||
|
|
@ -8,18 +9,23 @@ use std::ops::{BitXor, Div, Mul};
|
|||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct MontgomeryCurve<N>
|
||||
where
|
||||
N: AddMod + SubMod + MulMod + InvMod + Integer + Copy,
|
||||
N: AddMod + SubMod + MulMod + InvertMod + Integer + Copy,
|
||||
{
|
||||
pub a: N,
|
||||
pub b: N,
|
||||
pub p: N,
|
||||
pub p: NonZero<N>,
|
||||
}
|
||||
|
||||
impl<N> MontgomeryCurve<N>
|
||||
where
|
||||
N: AddMod + SubMod + MulMod + InvMod + Copy + Integer,
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer,
|
||||
{
|
||||
pub const fn new(a: N, b: N, p: N) -> MontgomeryCurve<N> {
|
||||
pub const fn new(a: N, b: N, p: NonZero<N>) -> MontgomeryCurve<N> {
|
||||
MontgomeryCurve { a, b, p }
|
||||
}
|
||||
|
||||
|
|
@ -36,7 +42,15 @@ where
|
|||
|
||||
impl<N> Curve<MontgomeryPoint<N>, N> for MontgomeryCurve<N>
|
||||
where
|
||||
N: AddMod + SubMod + MulMod + InvMod<Output = N> + Copy + Integer + Div<Output = N>,
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer
|
||||
+ Div<Output = N>
|
||||
+ std::convert::From<u8>
|
||||
+ BitOps,
|
||||
{
|
||||
/// Get the point at an x-coordinate with parameters from this curve.
|
||||
fn point(self, x: N) -> MontgomeryPoint<N> {
|
||||
|
|
@ -53,20 +67,27 @@ where
|
|||
}
|
||||
|
||||
pub fn clamp_u256(x: U256) -> U256 {
|
||||
let mut bytes: [u8; 32] = x.to_le_bytes();
|
||||
let mut bytes: [u8; 32] = x.to_le_bytes().into();
|
||||
|
||||
// clamp value
|
||||
bytes[0] &= 248;
|
||||
bytes[31] &= 127;
|
||||
bytes[31] |= 64;
|
||||
|
||||
U256::from_le_bytes(bytes)
|
||||
U256::from_le_bytes(EncodedUint::from(bytes))
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug, Clone)]
|
||||
pub struct MontgomeryPoint<N>
|
||||
where
|
||||
N: AddMod + SubMod + Div<Output = N> + MulMod<Output = N> + InvMod<Output = N> + Copy + Integer,
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ Div<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer
|
||||
+ From<u8>,
|
||||
{
|
||||
pub x: N,
|
||||
pub z: N,
|
||||
|
|
@ -76,24 +97,23 @@ where
|
|||
|
||||
impl<N> Point<N> for MontgomeryPoint<N>
|
||||
where
|
||||
N: AddMod
|
||||
+ SubMod
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ Div<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer
|
||||
+ From<u8>,
|
||||
+ From<u8>
|
||||
+ BitOps,
|
||||
{
|
||||
fn get_x(self) -> N {
|
||||
self.x.mul_mod(
|
||||
&self.z.inv_mod(&self.curve.p).unwrap(),
|
||||
&NonZero::new(self.curve.p).unwrap(),
|
||||
)
|
||||
self.x
|
||||
.mul_mod(&self.z.invert_mod(&self.curve.p).unwrap(), &self.curve.p)
|
||||
}
|
||||
|
||||
fn add(&self, rhs: &Self, neg: &Self) -> Self {
|
||||
let p = &NonZero::new(self.curve.p).unwrap();
|
||||
let p = &self.curve.p;
|
||||
|
||||
let mut v_0 = self.x.add_mod(&self.z, p); // 1: V_0 = X_P + Z_P
|
||||
let mut v_1 = rhs.x.sub_mod(&rhs.z, p); // 2: V_1 = X_Q - Z_Q
|
||||
|
|
@ -120,7 +140,7 @@ where
|
|||
}
|
||||
|
||||
fn double(&self) -> MontgomeryPoint<N> {
|
||||
let p = &NonZero::new(self.curve.p).unwrap();
|
||||
let p = &self.curve.p;
|
||||
|
||||
let mut v_1 = self.x.add_mod(&self.z, p);
|
||||
v_1 = v_1.mul_mod(&v_1, p);
|
||||
|
|
@ -162,7 +182,16 @@ ladder_impl!(MontgomeryPoint, swap_montgomery);
|
|||
|
||||
fn swap_montgomery<N>(a: &mut MontgomeryPoint<N>, b: &mut MontgomeryPoint<N>, c: u8, max: N)
|
||||
where
|
||||
N: BitXor + Copy + Mul<Output = N> + From<u8> + Div<Output = N> + Integer + InvMod<Output = N>,
|
||||
N: BitXor
|
||||
+ Copy
|
||||
+ Mul<Output = N>
|
||||
+ From<u8>
|
||||
+ Div<Output = N>
|
||||
+ Integer
|
||||
+ InvertMod<Output = N>
|
||||
+ AddMod<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ SubMod<Output = N>,
|
||||
{
|
||||
let m = max * N::from(c);
|
||||
|
||||
|
|
@ -178,14 +207,15 @@ where
|
|||
|
||||
impl<N> Display for MontgomeryPoint<N>
|
||||
where
|
||||
N: AddMod
|
||||
+ SubMod
|
||||
+ MulMod
|
||||
+ InvMod<Output = N>
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer
|
||||
+ Display
|
||||
+ std::ops::Div<Output = N>,
|
||||
+ Div<Output = N>
|
||||
+ From<u8>,
|
||||
{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!("({} : {})", self.x, self.z))
|
||||
|
|
@ -194,7 +224,15 @@ where
|
|||
|
||||
impl<N> Mul<N> for MontgomeryPoint<N>
|
||||
where
|
||||
N: AddMod + SubMod + MulMod + InvMod<Output = N> + Copy + Integer + std::ops::Div<Output = N>,
|
||||
N: AddMod<Output = N>
|
||||
+ SubMod<Output = N>
|
||||
+ MulMod<Output = N>
|
||||
+ InvertMod<Output = N>
|
||||
+ Copy
|
||||
+ Integer
|
||||
+ Div<Output = N>
|
||||
+ std::convert::From<u8>
|
||||
+ BitOps,
|
||||
{
|
||||
type Output = MontgomeryPoint<N>;
|
||||
|
||||
|
|
@ -211,7 +249,10 @@ where
|
|||
pub const CURVE_25519: MontgomeryCurve<U256> = MontgomeryCurve::new(
|
||||
U256::from_u32(486662u32),
|
||||
U256::ONE,
|
||||
U256::ONE.shl(255).sub_mod(&U256::from_u8(19), &U256::MAX),
|
||||
NonZero::<Uint<4>>::new_unwrap(U256::ONE.shl(255).sub_mod(
|
||||
&U256::from_u8(19),
|
||||
&NonZero::<Uint<4>>::new_unwrap(U256::MAX),
|
||||
)),
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use crypto_bigint::{AddMod, InvMod, MulMod, SubMod};
|
||||
use crypto_bigint::{AddMod, InvertMod, MulMod, SubMod};
|
||||
|
||||
pub trait Curve<T, N>
|
||||
where
|
||||
T: Point<N>,
|
||||
N: AddMod<Output = N> + SubMod<Output = N> + MulMod<Output = N> + InvMod<Output = N> + Copy,
|
||||
N: AddMod<Output = N> + SubMod<Output = N> + MulMod<Output = N> + InvertMod<Output = N> + Copy,
|
||||
{
|
||||
fn point(self, x: N) -> T;
|
||||
fn generator(self) -> T;
|
||||
|
|
@ -11,7 +11,7 @@ where
|
|||
|
||||
pub trait Point<N>
|
||||
where
|
||||
N: AddMod + SubMod + MulMod + InvMod + Copy,
|
||||
N: AddMod<Output = N> + SubMod<Output = N> + MulMod<Output = N> + InvertMod<Output = N> + Copy,
|
||||
{
|
||||
fn get_x(self) -> N;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue