forked from serai-dex/serai
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rename the coins folder to networks (serai-dex#583)
* Rename the coins folder to networks Ethereum isn't a coin. It's a network. Resolves serai-dex#357. * More renames of coins -> networks in orchestration * Correct paths in tests/ * cargo fmt
- Loading branch information
0 parents
commit 1a3719e
Showing
150 changed files
with
59,912 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
[package] | ||
name = "monero-serai" | ||
version = "0.1.4-alpha" | ||
description = "A modern Monero transaction library" | ||
license = "MIT" | ||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero" | ||
authors = ["Luke Parker <[email protected]>"] | ||
edition = "2021" | ||
rust-version = "1.79" | ||
|
||
[package.metadata.docs.rs] | ||
all-features = true | ||
rustdoc-args = ["--cfg", "docsrs"] | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[dependencies] | ||
std-shims = { path = "../../common/std-shims", version = "^0.1.1", default-features = false } | ||
|
||
zeroize = { version = "^1.5", default-features = false, features = ["zeroize_derive"] } | ||
|
||
curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "zeroize"] } | ||
|
||
monero-io = { path = "io", version = "0.1", default-features = false } | ||
monero-generators = { path = "generators", version = "0.4", default-features = false } | ||
monero-primitives = { path = "primitives", version = "0.1", default-features = false } | ||
monero-mlsag = { path = "ringct/mlsag", version = "0.1", default-features = false } | ||
monero-clsag = { path = "ringct/clsag", version = "0.1", default-features = false } | ||
monero-borromean = { path = "ringct/borromean", version = "0.1", default-features = false } | ||
monero-bulletproofs = { path = "ringct/bulletproofs", version = "0.1", default-features = false } | ||
|
||
hex-literal = "0.4" | ||
|
||
[dev-dependencies] | ||
hex = { version = "0.4", default-features = false, features = ["std"] } | ||
serde = { version = "1", default-features = false, features = ["std", "derive"] } | ||
serde_json = { version = "1", default-features = false, features = ["std"] } | ||
|
||
[features] | ||
std = [ | ||
"std-shims/std", | ||
|
||
"zeroize/std", | ||
|
||
"monero-io/std", | ||
"monero-generators/std", | ||
"monero-primitives/std", | ||
"monero-mlsag/std", | ||
"monero-clsag/std", | ||
"monero-borromean/std", | ||
"monero-bulletproofs/std", | ||
] | ||
|
||
compile-time-generators = ["curve25519-dalek/precomputed-tables", "monero-bulletproofs/compile-time-generators"] | ||
multisig = ["monero-clsag/multisig", "std"] | ||
default = ["std", "compile-time-generators"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022-2024 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# monero-serai | ||
|
||
A modern Monero transaction library. It provides a modern, Rust-friendly view of | ||
the Monero protocol. | ||
|
||
This library is usable under no-std when the `std` feature (on by default) is | ||
disabled. | ||
|
||
### Wallet Functionality | ||
|
||
monero-serai originally included wallet functionality. That has been moved to | ||
monero-wallet. | ||
|
||
### Purpose and Support | ||
|
||
monero-serai was written for Serai, a decentralized exchange aiming to support | ||
Monero. Despite this, monero-serai is intended to be a widely usable library, | ||
accurate to Monero. monero-serai guarantees the functionality needed for Serai, | ||
yet does not include any functionality specific to Serai. | ||
|
||
### Cargo Features | ||
|
||
- `std` (on by default): Enables `std` (and with it, more efficient internal | ||
implementations). | ||
- `compile-time-generators` (on by default): Derives the generators at | ||
compile-time so they don't need to be derived at runtime. This is recommended | ||
if program size doesn't need to be kept minimal. | ||
- `multisig`: Enables the `multisig` feature for all dependencies. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[package] | ||
name = "monero-generators" | ||
version = "0.4.0" | ||
description = "Monero's hash to point function and generators" | ||
license = "MIT" | ||
repository = "https://github.com/serai-dex/serai/tree/develop/networks/monero/generators" | ||
authors = ["Luke Parker <[email protected]>"] | ||
edition = "2021" | ||
|
||
[package.metadata.docs.rs] | ||
all-features = true | ||
rustdoc-args = ["--cfg", "docsrs"] | ||
|
||
[lints] | ||
workspace = true | ||
|
||
[dependencies] | ||
std-shims = { path = "../../../common/std-shims", version = "^0.1.1", default-features = false } | ||
|
||
subtle = { version = "^2.4", default-features = false } | ||
|
||
sha3 = { version = "0.10", default-features = false } | ||
curve25519-dalek = { version = "4", default-features = false, features = ["alloc", "zeroize"] } | ||
|
||
group = { version = "0.13", default-features = false } | ||
dalek-ff-group = { path = "../../../crypto/dalek-ff-group", version = "0.4", default-features = false } | ||
|
||
monero-io = { path = "../io", version = "0.1", default-features = false } | ||
|
||
[dev-dependencies] | ||
hex = "0.4" | ||
|
||
[features] | ||
std = [ | ||
"std-shims/std", | ||
|
||
"subtle/std", | ||
|
||
"sha3/std", | ||
|
||
"group/alloc", | ||
"dalek-ff-group/std", | ||
|
||
"monero-io/std" | ||
] | ||
default = ["std"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022-2024 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Monero Generators | ||
|
||
Generators used by Monero in both its Pedersen commitments and Bulletproofs(+). | ||
An implementation of Monero's `hash_to_ec` is included, as needed to generate | ||
the generators. | ||
|
||
This library is usable under no-std when the `std` feature (on by default) is | ||
disabled. | ||
|
||
### Cargo Features | ||
|
||
- `std` (on by default): Enables `std` (and with it, more efficient internal | ||
implementations). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use subtle::ConditionallySelectable; | ||
|
||
use curve25519_dalek::edwards::EdwardsPoint; | ||
|
||
use group::ff::{Field, PrimeField}; | ||
use dalek_ff_group::FieldElement; | ||
|
||
use monero_io::decompress_point; | ||
|
||
use crate::keccak256; | ||
|
||
/// Monero's `hash_to_ec` function. | ||
pub fn hash_to_point(bytes: [u8; 32]) -> EdwardsPoint { | ||
#[allow(non_snake_case)] | ||
let A = FieldElement::from(486662u64); | ||
|
||
let v = FieldElement::from_square(keccak256(&bytes)).double(); | ||
let w = v + FieldElement::ONE; | ||
let x = w.square() + (-A.square() * v); | ||
|
||
// This isn't the complete X, yet its initial value | ||
// We don't calculate the full X, and instead solely calculate Y, letting dalek reconstruct X | ||
// While inefficient, it solves API boundaries and reduces the amount of work done here | ||
#[allow(non_snake_case)] | ||
let X = { | ||
let u = w; | ||
let v = x; | ||
let v3 = v * v * v; | ||
let uv3 = u * v3; | ||
let v7 = v3 * v3 * v; | ||
let uv7 = u * v7; | ||
uv3 * uv7.pow((-FieldElement::from(5u8)) * FieldElement::from(8u8).invert().unwrap()) | ||
}; | ||
let x = X.square() * x; | ||
|
||
let y = w - x; | ||
let non_zero_0 = !y.is_zero(); | ||
let y_if_non_zero_0 = w + x; | ||
let sign = non_zero_0 & (!y_if_non_zero_0.is_zero()); | ||
|
||
let mut z = -A; | ||
z *= FieldElement::conditional_select(&v, &FieldElement::from(1u8), sign); | ||
#[allow(non_snake_case)] | ||
let Z = z + w; | ||
#[allow(non_snake_case)] | ||
let mut Y = z - w; | ||
|
||
Y *= Z.invert().unwrap(); | ||
let mut bytes = Y.to_repr(); | ||
bytes[31] |= sign.unwrap_u8() << 7; | ||
|
||
decompress_point(bytes).unwrap().mul_by_cofactor() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#![cfg_attr(docsrs, feature(doc_auto_cfg))] | ||
#![doc = include_str!("../README.md")] | ||
#![deny(missing_docs)] | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
use std_shims::{sync::OnceLock, vec::Vec}; | ||
|
||
use sha3::{Digest, Keccak256}; | ||
|
||
use curve25519_dalek::{constants::ED25519_BASEPOINT_POINT, edwards::EdwardsPoint}; | ||
|
||
use monero_io::{write_varint, decompress_point}; | ||
|
||
mod hash_to_point; | ||
pub use hash_to_point::hash_to_point; | ||
|
||
#[cfg(test)] | ||
mod tests; | ||
|
||
fn keccak256(data: &[u8]) -> [u8; 32] { | ||
Keccak256::digest(data).into() | ||
} | ||
|
||
static H_CELL: OnceLock<EdwardsPoint> = OnceLock::new(); | ||
/// Monero's `H` generator. | ||
/// | ||
/// Contrary to convention (`G` for values, `H` for randomness), `H` is used by Monero for amounts | ||
/// within Pedersen commitments. | ||
#[allow(non_snake_case)] | ||
pub fn H() -> EdwardsPoint { | ||
*H_CELL.get_or_init(|| { | ||
decompress_point(keccak256(&ED25519_BASEPOINT_POINT.compress().to_bytes())) | ||
.unwrap() | ||
.mul_by_cofactor() | ||
}) | ||
} | ||
|
||
static H_POW_2_CELL: OnceLock<[EdwardsPoint; 64]> = OnceLock::new(); | ||
/// Monero's `H` generator, multiplied by 2**i for i in 1 ..= 64. | ||
/// | ||
/// This table is useful when working with amounts, which are u64s. | ||
#[allow(non_snake_case)] | ||
pub fn H_pow_2() -> &'static [EdwardsPoint; 64] { | ||
H_POW_2_CELL.get_or_init(|| { | ||
let mut res = [H(); 64]; | ||
for i in 1 .. 64 { | ||
res[i] = res[i - 1] + res[i - 1]; | ||
} | ||
res | ||
}) | ||
} | ||
|
||
/// The maximum amount of commitments provable for within a single range proof. | ||
pub const MAX_COMMITMENTS: usize = 16; | ||
/// The amount of bits a value within a commitment may use. | ||
pub const COMMITMENT_BITS: usize = 64; | ||
/// The logarithm (over 2) of the amount of bits a value within a commitment may use. | ||
pub const LOG_COMMITMENT_BITS: usize = 6; // 2 ** 6 == N | ||
|
||
/// Container struct for Bulletproofs(+) generators. | ||
#[allow(non_snake_case)] | ||
pub struct Generators { | ||
/// The G (bold) vector of generators. | ||
pub G: Vec<EdwardsPoint>, | ||
/// The H (bold) vector of generators. | ||
pub H: Vec<EdwardsPoint>, | ||
} | ||
|
||
/// Generate generators as needed for Bulletproofs(+), as Monero does. | ||
/// | ||
/// Consumers should not call this function ad-hoc, yet call it within a build script or use a | ||
/// once-initialized static. | ||
pub fn bulletproofs_generators(dst: &'static [u8]) -> Generators { | ||
// The maximum amount of bits used within a single range proof. | ||
const MAX_MN: usize = MAX_COMMITMENTS * COMMITMENT_BITS; | ||
|
||
let mut preimage = H().compress().to_bytes().to_vec(); | ||
preimage.extend(dst); | ||
|
||
let mut res = Generators { G: Vec::with_capacity(MAX_MN), H: Vec::with_capacity(MAX_MN) }; | ||
for i in 0 .. MAX_MN { | ||
// We generate a pair of generators per iteration | ||
let i = 2 * i; | ||
|
||
let mut even = preimage.clone(); | ||
write_varint(&i, &mut even).unwrap(); | ||
res.H.push(hash_to_point(keccak256(&even))); | ||
|
||
let mut odd = preimage.clone(); | ||
write_varint(&(i + 1), &mut odd).unwrap(); | ||
res.G.push(hash_to_point(keccak256(&odd))); | ||
} | ||
res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use crate::{decompress_point, hash_to_point}; | ||
|
||
#[test] | ||
fn test_vectors() { | ||
// tests.txt file copied from monero repo | ||
// https://github.com/monero-project/monero/ | ||
// blob/ac02af92867590ca80b2779a7bbeafa99ff94dcb/tests/crypto/tests.txt | ||
let reader = include_str!("./tests.txt"); | ||
|
||
for line in reader.lines() { | ||
let mut words = line.split_whitespace(); | ||
let command = words.next().unwrap(); | ||
|
||
match command { | ||
"check_key" => { | ||
let key = words.next().unwrap(); | ||
let expected = match words.next().unwrap() { | ||
"true" => true, | ||
"false" => false, | ||
_ => unreachable!("invalid result"), | ||
}; | ||
|
||
let actual = decompress_point(hex::decode(key).unwrap().try_into().unwrap()); | ||
assert_eq!(actual.is_some(), expected); | ||
} | ||
"hash_to_ec" => { | ||
let bytes = words.next().unwrap(); | ||
let expected = words.next().unwrap(); | ||
|
||
let actual = hash_to_point(hex::decode(bytes).unwrap().try_into().unwrap()); | ||
assert_eq!(hex::encode(actual.compress().to_bytes()), expected); | ||
} | ||
_ => unreachable!("unknown command"), | ||
} | ||
} | ||
} |
Oops, something went wrong.