Initial commit

main
Charlotte Som 2021-11-03 07:34:48 +00:00
commit c0c595db51
8 changed files with 787 additions and 0 deletions

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = true

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

102
Cargo.lock generated Normal file
View File

@ -0,0 +1,102 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a60553f9a9e039a333b4e9b20573b9e9b9c0bb3a11e201ccc48ef4283456d673"
[[package]]
name = "ppv-lite86"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_xoshiro"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
dependencies = [
"rand_core",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wireguard-vanity-key"
version = "0.1.0"
dependencies = [
"base64",
"rand",
"rand_xoshiro",
]

11
Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "wireguard-vanity-key"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
base64 = "0.13.0"
rand = "0.8.4"
rand_xoshiro = "0.6.0"

7
README.md Normal file
View File

@ -0,0 +1,7 @@
# wireguard-vanity-key
A vanity key generator for WireGuard. Supports prefix & suffix search.
## Requirements
- OpenCL

33
src/cpu/mod.rs Normal file
View File

@ -0,0 +1,33 @@
mod x25519;
use self::x25519::x25519_shared_key;
use crate::Key;
use rand::RngCore;
#[inline]
pub fn generate_psk(rng: &mut impl RngCore) -> Key {
let mut key: Key = [0; 32];
rng.fill_bytes(&mut key);
key
}
#[inline]
pub fn generate_privkey(rng: &mut impl RngCore) -> Key {
let mut k = generate_psk(rng);
// curve25519_clamp_secret
k[0] &= 0xF8;
k[31] = (k[31] & 127) | 64;
k
}
#[inline]
pub fn get_pubkey(private_key: &Key) -> Key {
let u = [
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,
];
x25519_shared_key(&u, private_key)
}

551
src/cpu/x25519.rs Normal file
View File

@ -0,0 +1,551 @@
// Ripped from boringtun lmao
// Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
//! Elliptic-curve Diffie-Hellman exchange over Curve25519.
use crate::Key;
use std::ops::Add;
use std::ops::Mul;
use std::ops::Sub;
#[inline(always)]
fn make_array<A, T>(slice: &[T]) -> A
where
A: Sized + Default + AsMut<[T]> + std::borrow::Borrow<[T]>,
T: Copy,
{
let mut arr: A = Default::default();
let arr_len = arr.borrow().len();
<A as AsMut<[T]>>::as_mut(&mut arr).copy_from_slice(&slice[0..arr_len]);
arr
}
const MASK_63BITS: u128 = 0x7fff_ffff_ffff_ffff;
const MASK_64BITS: u128 = 0xffff_ffff_ffff_ffff;
#[derive(Clone, Copy)]
// Internal structs for fast arithmetic
struct Felem([u64; 4]);
struct Felem2([u64; 8]);
#[cfg_attr(feature = "cargo-clippy", allow(clippy::suspicious_arithmetic_impl))]
impl Add for Felem {
type Output = Felem;
#[inline(always)]
// Addition modulo 2^255 - 19
fn add(self, other: Felem) -> Felem {
let x0 = u128::from(self.0[0]);
let x1 = u128::from(self.0[1]);
let x2 = u128::from(self.0[2]);
let x3 = u128::from(self.0[3]);
let y0 = u128::from(other.0[0]);
let y1 = u128::from(other.0[1]);
let y2 = u128::from(other.0[2]);
let y3 = u128::from(other.0[3]);
let mut acc0 = x0.wrapping_add(y0);
let mut acc1 = x1.wrapping_add(y1).wrapping_add(acc0 >> 64);
let mut acc2 = x2.wrapping_add(y2).wrapping_add(acc1 >> 64);
let mut acc3 = x3.wrapping_add(y3).wrapping_add(acc2 >> 64);
let mut top = (acc3 >> 63) & 0xffff_ffff_ffff_ffff;
acc0 &= 0xffff_ffff_ffff_ffff;
acc1 &= 0xffff_ffff_ffff_ffff;
acc2 &= 0xffff_ffff_ffff_ffff;
acc3 &= 0x7fff_ffff_ffff_ffff;
top = top.wrapping_mul(19);
acc0 = acc0.wrapping_add(top);
acc1 = acc1.wrapping_add(acc0 >> 64);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc3 = acc3.wrapping_add(acc2 >> 64);
Felem([acc0 as u64, acc1 as u64, acc2 as u64, acc3 as u64])
}
}
#[cfg_attr(feature = "cargo-clippy", allow(clippy::suspicious_arithmetic_impl))]
impl Sub for Felem {
type Output = Felem;
#[inline(always)]
// Subtraction modulo 2^255 - 19
fn sub(self, other: Felem) -> Felem {
static POLY_X4: [u128; 4] = [
0x1_ffff_ffff_ffff_ffb4,
0x1_ffff_ffff_ffff_fffe,
0x1_ffff_ffff_ffff_fffe,
0x1_ffff_ffff_ffff_fffe,
];
let x0 = u128::from(self.0[0]);
let x1 = u128::from(self.0[1]);
let x2 = u128::from(self.0[2]);
let x3 = u128::from(self.0[3]);
let y0 = u128::from(other.0[0]);
let y1 = u128::from(other.0[1]);
let y2 = u128::from(other.0[2]);
let y3 = u128::from(other.0[3]);
let mut acc0 = POLY_X4[0].wrapping_sub(y0).wrapping_add(x0);
let mut acc1 = POLY_X4[1]
.wrapping_sub(y1)
.wrapping_add(x1)
.wrapping_add(acc0 >> 64);
let mut acc2 = POLY_X4[2]
.wrapping_sub(y2)
.wrapping_add(x2)
.wrapping_add(acc1 >> 64);
let mut acc3 = POLY_X4[3]
.wrapping_sub(y3)
.wrapping_add(x3)
.wrapping_add(acc2 >> 64);
let mut top = (acc3 >> 63) & 0xffff_ffff_ffff_ffff;
acc0 &= 0xffff_ffff_ffff_ffff;
acc1 &= 0xffff_ffff_ffff_ffff;
acc2 &= 0xffff_ffff_ffff_ffff;
acc3 &= 0x7fff_ffff_ffff_ffff;
top = top.wrapping_mul(19);
acc0 = acc0.wrapping_add(top);
acc1 = acc1.wrapping_add(acc0 >> 64);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc3 = acc3.wrapping_add(acc2 >> 64);
Felem([acc0 as u64, acc1 as u64, acc2 as u64, acc3 as u64])
}
}
#[cfg_attr(feature = "cargo-clippy", allow(clippy::suspicious_arithmetic_impl))]
impl Mul for Felem {
type Output = Felem;
#[inline(always)]
// Multiplication modulo 2^255 - 19
fn mul(self, other: Felem) -> Felem {
let x0 = u128::from(self.0[0]);
let x1 = u128::from(self.0[1]);
let x2 = u128::from(self.0[2]);
let x3 = u128::from(self.0[3]);
// y0
let y0 = u128::from(other.0[0]);
let mut t = x0.wrapping_mul(y0);
let acc0 = t & 0xffff_ffff_ffff_ffff;
let mut acc1 = t >> 64;
t = x1.wrapping_mul(y0);
acc1 = acc1.wrapping_add(t);
let mut acc2 = acc1 >> 64;
acc1 &= 0xffff_ffff_ffff_ffff;
t = x2.wrapping_mul(y0);
acc2 = acc2.wrapping_add(t);
let mut acc3 = acc2 >> 64;
acc2 &= 0xffff_ffff_ffff_ffff;
t = x3.wrapping_mul(y0);
acc3 = acc3.wrapping_add(t);
let mut acc4 = acc3 >> 64;
acc3 &= 0xffff_ffff_ffff_ffff;
// y1
let y1 = u128::from(other.0[1]);
t = x0.wrapping_mul(y1);
acc1 = acc1.wrapping_add(t);
let mut top = acc1 >> 64;
acc1 &= 0xffff_ffff_ffff_ffff;
t = x1.wrapping_mul(y1);
acc2 = acc2.wrapping_add(top);
acc2 = acc2.wrapping_add(t);
top = acc2 >> 64;
acc2 &= 0xffff_ffff_ffff_ffff;
t = x2.wrapping_mul(y1);
acc3 = acc3.wrapping_add(top);
acc3 = acc3.wrapping_add(t);
top = acc3 >> 64;
acc3 &= 0xffff_ffff_ffff_ffff;
t = x3.wrapping_mul(y1);
acc4 = acc4.wrapping_add(top);
acc4 = acc4.wrapping_add(t);
let mut acc5 = acc4 >> 64;
acc4 &= 0xffff_ffff_ffff_ffff;
// y2
let y2 = u128::from(other.0[2]);
t = x0.wrapping_mul(y2);
acc2 = acc2.wrapping_add(t);
top = acc2 >> 64;
acc2 &= 0xffff_ffff_ffff_ffff;
t = x1.wrapping_mul(y2);
acc3 = acc3.wrapping_add(top);
acc3 = acc3.wrapping_add(t);
top = acc3 >> 64;
acc3 &= 0xffff_ffff_ffff_ffff;
t = x2.wrapping_mul(y2);
acc4 = acc4.wrapping_add(top);
acc4 = acc4.wrapping_add(t);
top = acc4 >> 64;
acc4 &= 0xffff_ffff_ffff_ffff;
t = x3.wrapping_mul(y2);
acc5 = acc5.wrapping_add(top);
acc5 = acc5.wrapping_add(t);
let mut acc6 = acc5 >> 64;
acc5 &= 0xffff_ffff_ffff_ffff;
// y3
let y3 = u128::from(other.0[3]);
t = x0.wrapping_mul(y3);
acc3 = acc3.wrapping_add(t);
top = acc3 >> 64;
acc3 &= 0xffff_ffff_ffff_ffff;
t = x1.wrapping_mul(y3);
acc4 = acc4.wrapping_add(top);
acc4 = acc4.wrapping_add(t);
top = acc4 >> 64;
acc4 &= 0xffff_ffff_ffff_ffff;
t = x2.wrapping_mul(y3);
acc5 = acc5.wrapping_add(top);
acc5 = acc5.wrapping_add(t);
top = acc5 >> 64;
acc5 &= 0xffff_ffff_ffff_ffff;
t = x3.wrapping_mul(y3);
acc6 = acc6.wrapping_add(top);
acc6 = acc6.wrapping_add(t);
let acc7 = acc6 >> 64;
acc6 &= 0xffff_ffff_ffff_ffff;
// Modulo
mod_25519(Felem2([
acc0 as u64,
acc1 as u64,
acc2 as u64,
acc3 as u64,
acc4 as u64,
acc5 as u64,
acc6 as u64,
acc7 as u64,
]))
}
}
impl Felem {
#[inline(always)]
// Repeatedly square modulo 2^255 - 19
fn sqr(self, mut rep: u32) -> Felem {
let mut ret = self;
while rep > 0 {
ret = mod_25519(sqr_256(ret));
rep -= 1;
}
ret
}
}
#[inline(always)]
// Square modulo 2^255 - 19
fn sqr_256(x: Felem) -> Felem2 {
let x0 = u128::from(x.0[0]);
let x1 = u128::from(x.0[1]);
let x2 = u128::from(x.0[2]);
let x3 = u128::from(x.0[3]);
// y0
let mut acc1 = x1.wrapping_mul(x0);
let mut acc2 = x2.wrapping_mul(x0);
let mut acc3 = x3.wrapping_mul(x0);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc3 = acc3.wrapping_add(acc2 >> 64);
let mut acc4 = acc3 >> 64;
acc1 &= 0xffff_ffff_ffff_ffff;
acc2 &= 0xffff_ffff_ffff_ffff;
acc3 &= 0xffff_ffff_ffff_ffff;
// y1
let mut t = x2.wrapping_mul(x1);
acc3 = acc3.wrapping_add(t);
t = x3.wrapping_mul(x1);
acc4 = acc4.wrapping_add(acc3 >> 64).wrapping_add(t);
let mut acc5 = acc4 >> 64;
acc3 &= 0xffff_ffff_ffff_ffff;
acc4 &= 0xffff_ffff_ffff_ffff;
// y2
t = x3.wrapping_mul(x2);
acc5 = acc5.wrapping_add(t);
let mut acc6 = acc5 >> 64;
acc5 &= 0xffff_ffff_ffff_ffff;
acc6 = acc6 << 1 | acc5 >> 63;
acc5 = acc5 << 1 | acc4 >> 63;
acc4 = acc4 << 1 | acc3 >> 63;
acc3 = acc3 << 1 | acc2 >> 63;
acc2 = acc2 << 1 | acc1 >> 63;
acc1 <<= 1;
let mut acc7 = acc6 >> 64;
acc1 &= 0xffff_ffff_ffff_ffff;
acc2 &= 0xffff_ffff_ffff_ffff;
acc3 &= 0xffff_ffff_ffff_ffff;
acc4 &= 0xffff_ffff_ffff_ffff;
acc5 &= 0xffff_ffff_ffff_ffff;
acc6 &= 0xffff_ffff_ffff_ffff;
let acc0 = x0.wrapping_mul(x0);
acc1 = acc1.wrapping_add(acc0 >> 64);
t = x1.wrapping_mul(x1);
acc2 = acc2.wrapping_add(acc1 >> 64).wrapping_add(t);
acc3 = acc3.wrapping_add(acc2 >> 64);
t = x2.wrapping_mul(x2);
acc4 = acc4.wrapping_add(acc3 >> 64).wrapping_add(t);
acc5 = acc5.wrapping_add(acc4 >> 64);
t = x3.wrapping_mul(x3);
acc6 = acc6.wrapping_add(acc5 >> 64).wrapping_add(t);
acc7 = acc7.wrapping_add(acc6 >> 64);
Felem2([
acc0 as u64,
acc1 as u64,
acc2 as u64,
acc3 as u64,
acc4 as u64,
acc5 as u64,
acc6 as u64,
acc7 as u64,
])
// Modulo
}
#[inline(always)]
fn mod_25519(x: Felem2) -> Felem {
let c38 = 38_u128;
let mut acc0 = u128::from(x.0[0]);
let mut acc1 = u128::from(x.0[1]);
let mut acc2 = u128::from(x.0[2]);
let mut acc3 = u128::from(x.0[3]);
let mut acc4 = u128::from(x.0[4]);
let mut acc5 = u128::from(x.0[5]);
let mut acc6 = u128::from(x.0[6]);
let mut acc7 = u128::from(x.0[7]);
acc4 = acc4.wrapping_mul(c38);
acc5 = acc5.wrapping_mul(c38);
acc6 = acc6.wrapping_mul(c38);
acc7 = acc7.wrapping_mul(c38);
acc0 = acc0.wrapping_add(acc4);
acc1 = acc1.wrapping_add(acc0 >> 64);
acc1 = acc1.wrapping_add(acc5);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc2 = acc2.wrapping_add(acc6);
acc3 = acc3.wrapping_add(acc2 >> 64);
acc3 = acc3.wrapping_add(acc7);
let mut top = (acc3 >> 63) & 0xffff_ffff_ffff_ffff;
acc0 &= 0xffff_ffff_ffff_ffff;
acc1 &= 0xffff_ffff_ffff_ffff;
acc2 &= 0xffff_ffff_ffff_ffff;
acc3 &= 0x7fff_ffff_ffff_ffff;
top = top.wrapping_mul(19);
acc0 = acc0.wrapping_add(top);
acc1 = acc1.wrapping_add(acc0 >> 64);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc3 = acc3.wrapping_add(acc2 >> 64);
Felem([acc0 as u64, acc1 as u64, acc2 as u64, acc3 as u64])
}
fn mod_final_25519(x: Felem) -> Felem {
let mut acc0 = u128::from(x.0[0]);
let mut acc1 = u128::from(x.0[1]);
let mut acc2 = u128::from(x.0[2]);
let mut acc3 = u128::from(x.0[3]);
let mut top = acc3 >> 63;
acc3 &= MASK_63BITS;
top = top.wrapping_mul(19);
acc0 = acc0.wrapping_add(top);
acc1 = acc1.wrapping_add(acc0 >> 64);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc3 = acc3.wrapping_add(acc2 >> 64);
// Mask
acc0 &= MASK_64BITS;
acc1 &= MASK_64BITS;
acc2 &= MASK_64BITS;
acc3 &= MASK_64BITS;
// At this point, acc{0-3} is in the range between 0 and 2^255 + 18, inclusively. It's not
// under 2^255 - 19 yet. So we are doing another round of modulo operation.
top = acc0.wrapping_add(19) >> 64;
top = acc1.wrapping_add(top) >> 64;
top = acc2.wrapping_add(top) >> 64;
top = acc3.wrapping_add(top) >> 63;
top = top.wrapping_mul(19);
// top is 19 if acc{0-3} is between 2^255 - 19 and 2^255 + 18, inclusively. Otherwise, it's
// zero.
acc0 = acc0.wrapping_add(top);
acc1 = acc1.wrapping_add(acc0 >> 64);
acc2 = acc2.wrapping_add(acc1 >> 64);
acc3 = acc3.wrapping_add(acc2 >> 64);
acc3 &= MASK_63BITS;
// Now acc{0-3} is between 0 and 2^255 - 20, inclusively.
Felem([acc0 as u64, acc1 as u64, acc2 as u64, acc3 as u64])
}
// Modular inverse
fn mod_inv_25519(x: Felem) -> Felem {
let m1 = x;
let m10 = x.sqr(1);
let m1001 = m10.sqr(2) * m1;
let m1011 = m1001 * m10;
let x5 = m1011.sqr(1) * m1001;
let x10 = x5.sqr(5) * x5;
let x20 = x10.sqr(10) * x10;
let x40 = x20.sqr(20) * x20;
let x50 = x40.sqr(10) * x10;
let x100 = x50.sqr(50) * x50;
let t = x100.sqr(100) * x100;
let t2 = t.sqr(50) * x50;
t2.sqr(5) * m1011
}
#[inline(always)]
// Swap two values a and b in constant time iff swap == 1
fn constant_time_swap(a: Felem, b: Felem, swap: u64) -> (Felem, Felem) {
let mask = 0_u64.wrapping_sub(swap);
let mut v = [0_u64; 4];
let mut a_out = [0_u64; 4];
let mut b_out = [0_u64; 4];
v[0] = mask & (a.0[0] ^ b.0[0]);
v[1] = mask & (a.0[1] ^ b.0[1]);
v[2] = mask & (a.0[2] ^ b.0[2]);
v[3] = mask & (a.0[3] ^ b.0[3]);
a_out[0] = v[0] ^ a.0[0];
a_out[1] = v[1] ^ a.0[1];
a_out[2] = v[2] ^ a.0[2];
a_out[3] = v[3] ^ a.0[3];
b_out[0] = v[0] ^ b.0[0];
b_out[1] = v[1] ^ b.0[1];
b_out[2] = v[2] ^ b.0[2];
b_out[3] = v[3] ^ b.0[3];
(Felem(a_out), Felem(b_out))
}
#[inline]
pub fn x25519_shared_key(peer_key: &[u8], secret_key: &[u8]) -> Key {
if peer_key.len() != 32 || secret_key.len() != 32 {
panic!("Illegal values for x25519");
}
let mut scalar = [0_u8; 32];
let mut shared_key = [0_u8; 32];
scalar[..].copy_from_slice(secret_key);
assert!(peer_key.len() == 32);
let u = Felem([
u64::from_le_bytes(make_array(&peer_key[0..])),
u64::from_le_bytes(make_array(&peer_key[8..])),
u64::from_le_bytes(make_array(&peer_key[16..])),
u64::from_le_bytes(make_array(&peer_key[24..])),
]);
scalar[0] &= 248;
scalar[31] &= 127;
scalar[31] |= 64;
let x_1 = u;
let mut x_2 = Felem([1, 0, 0, 0]);
let mut z_2 = Felem([0, 0, 0, 0]);
let mut x_3 = u;
let mut z_3 = Felem([1, 0, 0, 0]);
let a24 = Felem([121_666, 0, 0, 0]);
let mut swap = 0;
for pos in (0..=254).rev() {
let bit_val = u64::from((scalar[pos / 8] >> (pos & 7)) & 1);
swap ^= bit_val;
let (mut x2, mut x3) = constant_time_swap(x_2, x_3, swap);
let (mut z2, mut z3) = constant_time_swap(z_2, z_3, swap);
swap = bit_val;
let mut tmp0 = x3 - z3;
let mut tmp1 = x2 - z2;
x2 = x2 + z2;
z2 = x3 + z3;
z3 = x2 * tmp0;
z2 = z2 * tmp1;
tmp0 = tmp1.sqr(1);
tmp1 = x2.sqr(1);
x3 = z3 + z2;
z2 = z3 - z2;
x_2 = tmp1 * tmp0;
tmp1 = tmp1 - tmp0;
z2 = z2.sqr(1);
z3 = a24 * tmp1;
x_3 = x3.sqr(1);
tmp0 = tmp0 + z3;
z_3 = x_1 * z2;
z_2 = tmp1 * tmp0;
}
let (x2, _) = constant_time_swap(x_2, x_3, swap);
let (z2, _) = constant_time_swap(z_2, z_3, swap);
let key = mod_final_25519(x2 * mod_inv_25519(z2));
shared_key[0..8].copy_from_slice(&key.0[0].to_le_bytes());
shared_key[8..16].copy_from_slice(&key.0[1].to_le_bytes());
shared_key[16..24].copy_from_slice(&key.0[2].to_le_bytes());
shared_key[24..32].copy_from_slice(&key.0[3].to_le_bytes());
shared_key
}

73
src/main.rs Normal file
View File

@ -0,0 +1,73 @@
use std::{
pin::Pin,
thread::{spawn, JoinHandle},
time::Duration,
};
mod cpu;
pub type Key = [u8; 32];
struct ProgressCounter(pub *mut u64);
unsafe impl Send for ProgressCounter {}
unsafe impl Sync for ProgressCounter {}
impl ProgressCounter {
fn incr(&mut self) {
unsafe {
*self.0 += 1;
}
}
}
fn work(mut progress: ProgressCounter) -> JoinHandle<()> {
spawn(move || {
let mut rng = {
use rand::SeedableRng;
rand_xoshiro::Xoshiro256StarStar::from_rng(rand::thread_rng()).unwrap()
};
loop {
let key = cpu::generate_privkey(&mut rng);
let pub_key = cpu::get_pubkey(&key);
progress.incr();
// b64(pub_key).starts_with("char/")
if pub_key[0] == 0x72 && pub_key[1] == 0x16 && pub_key[2] == 0xab && pub_key[3] >= 0xfc
{
let key_str = base64::encode(key);
let pub_key_str = base64::encode(pub_key);
println!("{} -> {}", key_str, pub_key_str);
}
}
})
}
const NUM_THREADS: usize = 32;
struct Progress([u64; NUM_THREADS]);
impl Progress {
fn new() -> Self {
Progress([0; NUM_THREADS])
}
}
fn main() {
let mut progress = Box::pin(Progress::new());
let _handles: Vec<_> = (0..NUM_THREADS)
.map(|id| {
let ptr = unsafe { progress.0.as_mut_ptr().add(id) };
let progress = ProgressCounter(ptr);
work(progress)
})
.collect();
let mut last_total_progress = 0;
loop {
let total_progress = progress.0.iter().sum();
let delta = total_progress - last_total_progress;
last_total_progress = total_progress;
println!("Guess/sec ≈ {}", delta);
std::thread::sleep(Duration::from_millis(1000));
}
}