mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-16 08:57:36 +00:00
Initial work on a tables lib
Incomplete lib intended to offer tables for all cryptographic libraries expecting them. Right now, it creates the tables at runtime. While that would still offer improvements, ideally large tables are built at compile time and simply entered into memory at runtime. My best idea for that was a linked list in the binary itself, where this app (at first call), reads a table stored to a section of data, then grabs the next reference to one and continues reading. The main issue with this idea, besides not yet researching how to encode data into the binary, was the fact the same table would be saved to disk multiple times under this simplistic model. An O(n) iteration when writing to the bin could potentially solve that. Related https://github.com/serai-dex/serai/issues/41.
This commit is contained in:
parent
0b879a53fa
commit
f029471f9f
4 changed files with 97 additions and 0 deletions
|
@ -3,6 +3,7 @@ members = [
|
|||
"crypto/transcript",
|
||||
|
||||
"crypto/dalek-ff-group",
|
||||
"crypto/tables",
|
||||
"crypto/multiexp",
|
||||
|
||||
"crypto/dleq",
|
||||
|
|
16
crypto/tables/Cargo.toml
Normal file
16
crypto/tables/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
[package]
|
||||
name = "tables"
|
||||
version = "0.1.0"
|
||||
description = "Efficient multiplication tables for ff/group"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/serai-dex/serai"
|
||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||
keywords = ["ff", "group"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
ff = "0.12"
|
||||
group = "0.12"
|
||||
|
||||
[dev-dependencies]
|
||||
k256 = { version = "0.11", features = ["bits"] }
|
21
crypto/tables/LICENSE
Normal file
21
crypto/tables/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Luke Parker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
59
crypto/tables/src/lib.rs
Normal file
59
crypto/tables/src/lib.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use std::{any::TypeId, mem, sync::Once, cell::Cell, boxed::Box, collections::HashMap};
|
||||
|
||||
use group::Group;
|
||||
|
||||
struct Tables(Cell<mem::MaybeUninit<HashMap<TypeId, *const ()>>>, Once);
|
||||
static mut TABLES: Tables = Tables(Cell::new(mem::MaybeUninit::uninit()), Once::new());
|
||||
|
||||
pub struct Table<G>(Vec<G>);
|
||||
|
||||
fn acquire() -> &'static mut HashMap<TypeId, *const ()> {
|
||||
unsafe {
|
||||
TABLES.1.call_once(|| {
|
||||
TABLES.0.set(mem::MaybeUninit::new(HashMap::new()));
|
||||
});
|
||||
&mut (*(*TABLES.0.as_ptr()).as_mut_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
/// This should ONLY be called via the generate_table macro. It is solely public to make said
|
||||
/// macro work
|
||||
#[doc(hidden)]
|
||||
pub fn __unsafe_add_table<G: Group>(table: Table<G>) {
|
||||
let tables = acquire();
|
||||
if tables.contains_key(&TypeId::of::<G>()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let ptr = std::ptr::addr_of!(*Box::leak(Box::new(table)));
|
||||
unsafe {
|
||||
tables.insert(TypeId::of::<G>(), mem::transmute::<*const Table<G>, *const ()>(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! generate_table {
|
||||
($G: ident) => {
|
||||
__unsafe_add_table(Table(vec![$G::generator()]));
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns a table usable for fast multiplication. This will panic if the table was not registered
|
||||
/// via the generate_table macro
|
||||
pub fn generator_table<G: Group>() -> &'static Table<G> {
|
||||
generate_table!(G);
|
||||
unsafe {
|
||||
acquire()
|
||||
.get(&TypeId::of::<G>())
|
||||
.map(|arc| &*mem::transmute::<*const (), *const Table<G>>(*arc))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_static() {
|
||||
use k256::ProjectivePoint;
|
||||
let table: &'static Table<ProjectivePoint> = generator_table::<ProjectivePoint>();
|
||||
dbg!("Read");
|
||||
dbg!(table.0.len());
|
||||
dbg!(&table.0);
|
||||
}
|
Loading…
Reference in a new issue