mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Compare commits
1 Commits
dkg-exampl
...
custom-gen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ed5592d22 |
44
.github/actions/monero-wallet-rpc/action.yml
vendored
44
.github/actions/monero-wallet-rpc/action.yml
vendored
@@ -1,44 +0,0 @@
|
|||||||
name: monero-wallet-rpc
|
|
||||||
description: Spawns a Monero Wallet-RPC.
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
version:
|
|
||||||
description: "Version to download and run"
|
|
||||||
required: false
|
|
||||||
default: v0.18.1.2
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- name: Monero Wallet RPC Cache
|
|
||||||
id: cache-monero-wallet-rpc
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: monero-wallet-rpc
|
|
||||||
key: monero-wallet-rpc-${{ runner.os }}-${{ runner.arch }}-${{ inputs.version }}
|
|
||||||
|
|
||||||
- name: Download the Monero Wallet RPC
|
|
||||||
if: steps.cache-monero-wallet-rpc.outputs.cache-hit != 'true'
|
|
||||||
# Calculates OS/ARCH to demonstrate it, yet then locks to linux-x64 due
|
|
||||||
# to the contained folder not following the same naming scheme and
|
|
||||||
# requiring further expansion not worth doing right now
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
RUNNER_OS=${{ runner.os }}
|
|
||||||
RUNNER_ARCH=${{ runner.arch }}
|
|
||||||
|
|
||||||
RUNNER_OS=${RUNNER_OS,,}
|
|
||||||
RUNNER_ARCH=${RUNNER_ARCH,,}
|
|
||||||
|
|
||||||
RUNNER_OS=linux
|
|
||||||
RUNNER_ARCH=x64
|
|
||||||
|
|
||||||
FILE=monero-$RUNNER_OS-$RUNNER_ARCH-${{ inputs.version }}.tar.bz2
|
|
||||||
wget https://downloads.getmonero.org/cli/$FILE
|
|
||||||
tar -xvf $FILE
|
|
||||||
|
|
||||||
mv monero-x86_64-linux-gnu-${{ inputs.version }}/monero-wallet-rpc monero-wallet-rpc
|
|
||||||
|
|
||||||
- name: Monero Wallet RPC
|
|
||||||
shell: bash
|
|
||||||
run: ./monero-wallet-rpc --disable-rpc-login --rpc-bind-port 6061 --allow-mismatched-daemon-version --wallet-dir ./ --detach
|
|
||||||
2
.github/actions/monero/action.yml
vendored
2
.github/actions/monero/action.yml
vendored
@@ -5,7 +5,7 @@ inputs:
|
|||||||
version:
|
version:
|
||||||
description: "Version to download and run"
|
description: "Version to download and run"
|
||||||
required: false
|
required: false
|
||||||
default: v0.18.1.2
|
default: v0.18.0.0
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
|
|||||||
3
.github/actions/test-dependencies/action.yml
vendored
3
.github/actions/test-dependencies/action.yml
vendored
@@ -29,6 +29,3 @@ runs:
|
|||||||
uses: ./.github/actions/monero
|
uses: ./.github/actions/monero
|
||||||
with:
|
with:
|
||||||
version: ${{ inputs.monero-version }}
|
version: ${{ inputs.monero-version }}
|
||||||
|
|
||||||
- name: Run a Monero Wallet-RPC
|
|
||||||
uses: ./.github/actions/monero-wallet-rpc
|
|
||||||
|
|||||||
4
.github/workflows/monero-tests.yaml
vendored
4
.github/workflows/monero-tests.yaml
vendored
@@ -33,7 +33,7 @@ jobs:
|
|||||||
# Test against all supported protocol versions
|
# Test against all supported protocol versions
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: [v0.17.3.2, v0.18.1.2]
|
version: [v0.17.3.2, v0.18.0.0]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Run Integration Tests
|
- name: Run Integration Tests
|
||||||
# Don't run if the the tests workflow also will
|
# Don't run if the the tests workflow also will
|
||||||
if: ${{ matrix.version != 'v0.18.1.2' }}
|
if: ${{ matrix.version != 'v0.18.0.0' }}
|
||||||
run: |
|
run: |
|
||||||
cargo test --package monero-serai --all-features --test '*'
|
cargo test --package monero-serai --all-features --test '*'
|
||||||
cargo test --package serai-processor monero
|
cargo test --package serai-processor monero
|
||||||
|
|||||||
1793
Cargo.lock
generated
1793
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ members = [
|
|||||||
"crypto/ff-group-tests",
|
"crypto/ff-group-tests",
|
||||||
"crypto/dalek-ff-group",
|
"crypto/dalek-ff-group",
|
||||||
"crypto/ed448",
|
"crypto/ed448",
|
||||||
|
"crypto/dynamic-generator",
|
||||||
"crypto/ciphersuite",
|
"crypto/ciphersuite",
|
||||||
|
|
||||||
"crypto/multiexp",
|
"crypto/multiexp",
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ monero-generators = { path = "generators", version = "0.1" }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
monero-rpc = "0.3"
|
|
||||||
|
|
||||||
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.5", features = ["ed25519", "tests"] }
|
frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.5", features = ["ed25519", "tests"] }
|
||||||
|
|
||||||
|
|||||||
@@ -60,15 +60,13 @@ pub(crate) fn shared_key(
|
|||||||
) -> (u8, Scalar, [u8; 8]) {
|
) -> (u8, Scalar, [u8; 8]) {
|
||||||
// 8Ra
|
// 8Ra
|
||||||
let mut output_derivation = (s * P).mul_by_cofactor().compress().to_bytes().to_vec();
|
let mut output_derivation = (s * P).mul_by_cofactor().compress().to_bytes().to_vec();
|
||||||
|
|
||||||
let mut payment_id_xor = [0; 8];
|
|
||||||
payment_id_xor
|
|
||||||
.copy_from_slice(&hash(&[output_derivation.as_ref(), [0x8d].as_ref()].concat())[.. 8]);
|
|
||||||
|
|
||||||
// || o
|
// || o
|
||||||
write_varint(&o.try_into().unwrap(), &mut output_derivation).unwrap();
|
write_varint(&o.try_into().unwrap(), &mut output_derivation).unwrap();
|
||||||
|
|
||||||
let view_tag = hash(&[b"view_tag".as_ref(), &output_derivation].concat())[0];
|
let view_tag = hash(&[b"view_tag".as_ref(), &output_derivation].concat())[0];
|
||||||
|
let mut payment_id_xor = [0; 8];
|
||||||
|
payment_id_xor
|
||||||
|
.copy_from_slice(&hash(&[output_derivation.as_ref(), [0x8d].as_ref()].concat())[.. 8]);
|
||||||
|
|
||||||
// uniqueness ||
|
// uniqueness ||
|
||||||
let shared_key = if let Some(uniqueness) = uniqueness {
|
let shared_key = if let Some(uniqueness) = uniqueness {
|
||||||
@@ -108,14 +106,6 @@ impl ViewPair {
|
|||||||
ViewPair { spend, view }
|
ViewPair { spend, view }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spend(&self) -> EdwardsPoint {
|
|
||||||
self.spend
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn view(&self) -> EdwardsPoint {
|
|
||||||
self.view.deref() * &ED25519_BASEPOINT_TABLE
|
|
||||||
}
|
|
||||||
|
|
||||||
fn subaddress_derivation(&self, index: SubaddressIndex) -> Scalar {
|
fn subaddress_derivation(&self, index: SubaddressIndex) -> Scalar {
|
||||||
hash_to_scalar(&Zeroizing::new(
|
hash_to_scalar(&Zeroizing::new(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
use std::{
|
|
||||||
collections::{HashSet, HashMap},
|
|
||||||
str::FromStr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use rand_core::{RngCore, OsRng};
|
|
||||||
|
|
||||||
use monero_rpc::{
|
|
||||||
monero::{Amount, Address},
|
|
||||||
TransferOptions,
|
|
||||||
};
|
|
||||||
|
|
||||||
use monero_serai::{
|
|
||||||
wallet::address::{Network, AddressSpec, SubaddressIndex},
|
|
||||||
wallet::Scanner,
|
|
||||||
};
|
|
||||||
|
|
||||||
mod runner;
|
|
||||||
|
|
||||||
async fn test_from_wallet_rpc_to_self(spec: AddressSpec) {
|
|
||||||
let wallet_rpc =
|
|
||||||
monero_rpc::RpcClientBuilder::new().build("http://127.0.0.1:6061").unwrap().wallet();
|
|
||||||
let daemon_rpc = runner::rpc().await;
|
|
||||||
|
|
||||||
// initialize wallet rpc
|
|
||||||
let address_resp = wallet_rpc.get_address(0, None).await;
|
|
||||||
let wallet_rpc_addr = if address_resp.is_ok() {
|
|
||||||
address_resp.unwrap().address
|
|
||||||
} else {
|
|
||||||
wallet_rpc.create_wallet("test_wallet".to_string(), None, "English".to_string()).await.unwrap();
|
|
||||||
let addr = wallet_rpc.get_address(0, None).await.unwrap().address;
|
|
||||||
daemon_rpc.generate_blocks(&addr.to_string(), 70).await.unwrap();
|
|
||||||
addr
|
|
||||||
};
|
|
||||||
|
|
||||||
// make an addr
|
|
||||||
let (_, view_pair, _) = runner::random_address();
|
|
||||||
let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()[..]).unwrap();
|
|
||||||
|
|
||||||
// refresh & make a tx
|
|
||||||
wallet_rpc.refresh(None).await.unwrap();
|
|
||||||
let tx = wallet_rpc
|
|
||||||
.transfer(
|
|
||||||
HashMap::from([(addr, Amount::ONE_XMR)]),
|
|
||||||
monero_rpc::TransferPriority::Default,
|
|
||||||
TransferOptions::default(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
let tx_hash: [u8; 32] = tx.tx_hash.0.try_into().unwrap();
|
|
||||||
|
|
||||||
// unlock it
|
|
||||||
runner::mine_until_unlocked(&daemon_rpc, &wallet_rpc_addr.to_string(), tx_hash).await;
|
|
||||||
|
|
||||||
// create the scanner
|
|
||||||
let mut scanner = Scanner::from_view(view_pair, Some(HashSet::new()));
|
|
||||||
if let AddressSpec::Subaddress(index) = spec {
|
|
||||||
scanner.register_subaddress(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve it and confirm
|
|
||||||
let tx = daemon_rpc.get_transaction(tx_hash).await.unwrap();
|
|
||||||
let output = scanner.scan_transaction(&tx).not_locked().swap_remove(0);
|
|
||||||
|
|
||||||
match spec {
|
|
||||||
AddressSpec::Subaddress(index) => assert_eq!(output.metadata.subaddress, Some(index)),
|
|
||||||
AddressSpec::Integrated(payment_id) => {
|
|
||||||
assert_eq!(output.metadata.payment_id, payment_id);
|
|
||||||
assert_eq!(output.metadata.subaddress, None);
|
|
||||||
}
|
|
||||||
_ => assert_eq!(output.metadata.subaddress, None),
|
|
||||||
}
|
|
||||||
assert_eq!(output.commitment().amount, 1000000000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
async_sequential!(
|
|
||||||
async fn test_receipt_of_wallet_rpc_tx_standard() {
|
|
||||||
test_from_wallet_rpc_to_self(AddressSpec::Standard).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn test_receipt_of_wallet_rpc_tx_subaddress() {
|
|
||||||
test_from_wallet_rpc_to_self(AddressSpec::Subaddress(SubaddressIndex::new(0, 1).unwrap()))
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn test_receipt_of_wallet_rpc_tx_integrated() {
|
|
||||||
let mut payment_id = [0u8; 8];
|
|
||||||
OsRng.fill_bytes(&mut payment_id);
|
|
||||||
test_from_wallet_rpc_to_self(AddressSpec::Integrated(payment_id)).await;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -32,8 +32,6 @@ ciphersuite = { path = "../ciphersuite", version = "0.1", features = ["std"] }
|
|||||||
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "0.2" }
|
schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "0.2" }
|
||||||
dleq = { path = "../dleq", version = "0.2", features = ["serialize"] }
|
dleq = { path = "../dleq", version = "0.2", features = ["serialize"] }
|
||||||
|
|
||||||
tokio = { version = "1", features = ["full"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ciphersuite = { path = "../ciphersuite", version = "0.1", features = ["std", "ristretto"] }
|
ciphersuite = { path = "../ciphersuite", version = "0.1", features = ["std", "ristretto"] }
|
||||||
|
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use rand_core::OsRng;
|
|
||||||
|
|
||||||
use ciphersuite::{Ciphersuite, Ristretto};
|
|
||||||
|
|
||||||
use tokio::sync::mpsc::{self, UnboundedSender, UnboundedReceiver};
|
|
||||||
|
|
||||||
use dkg::{
|
|
||||||
ThresholdParams,
|
|
||||||
encryption::{EncryptionKeyMessage, EncryptedMessage},
|
|
||||||
frost::{Commitments, SecretShare, KeyGenMachine},
|
|
||||||
};
|
|
||||||
|
|
||||||
async fn dkg<C: Ciphersuite>(
|
|
||||||
i: u16,
|
|
||||||
send: UnboundedSender<Vec<u8>>,
|
|
||||||
mut recv: UnboundedReceiver<Vec<u8>>,
|
|
||||||
) {
|
|
||||||
// Calculate the other participant's i
|
|
||||||
let other_i = i ^ 0b11;
|
|
||||||
|
|
||||||
// A 2-of-2 multisig
|
|
||||||
let params = ThresholdParams::new(2, 2, i).unwrap();
|
|
||||||
|
|
||||||
// Create a key gen machine
|
|
||||||
let machine = KeyGenMachine::new(params, "DKG Example".to_string());
|
|
||||||
// Generate coefficients
|
|
||||||
let (machine, commitments) = machine.generate_coefficients(&mut OsRng);
|
|
||||||
// Send everyone our commitments
|
|
||||||
send.send(commitments.serialize()).unwrap();
|
|
||||||
|
|
||||||
// Receive everyone else's commitments
|
|
||||||
let other_commitments = EncryptionKeyMessage::<C, Commitments<C>>::read::<&[u8]>(
|
|
||||||
&mut recv.recv().await.unwrap().as_ref(),
|
|
||||||
params,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut all_commitments = HashMap::new();
|
|
||||||
all_commitments.insert(other_i, other_commitments);
|
|
||||||
|
|
||||||
// Generate secret shares
|
|
||||||
let (machine, shares) = machine.generate_secret_shares(&mut OsRng, all_commitments).unwrap();
|
|
||||||
// Send everyone else their secret shares
|
|
||||||
send.send(shares[&other_i].serialize()).unwrap();
|
|
||||||
|
|
||||||
// Receive our shares from everyone else
|
|
||||||
let share = EncryptedMessage::<C, SecretShare<C::F>>::read::<&[u8]>(
|
|
||||||
&mut recv.recv().await.unwrap().as_ref(),
|
|
||||||
params,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut all_shares = HashMap::new();
|
|
||||||
all_shares.insert(other_i, share);
|
|
||||||
|
|
||||||
// Calculate our share
|
|
||||||
let (machine, _key) = machine.calculate_share(&mut OsRng, all_shares).unwrap();
|
|
||||||
// Assume the process succeeded, though this should only be done ater everyone votes on the key
|
|
||||||
let _keys = machine.complete();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
// Create a pair of channels
|
|
||||||
let (alice_send, alice_recv) = mpsc::unbounded_channel();
|
|
||||||
let (bob_send, bob_recv) = mpsc::unbounded_channel();
|
|
||||||
|
|
||||||
// Spawn Alice
|
|
||||||
let alice = dkg::<Ristretto>(1, alice_send, bob_recv);
|
|
||||||
// Spawn Bob
|
|
||||||
let bob = dkg::<Ristretto>(2, bob_send, alice_recv);
|
|
||||||
tokio::join!(alice, bob);
|
|
||||||
}
|
|
||||||
@@ -370,7 +370,7 @@ impl<C: Ciphersuite> KeyMachine<C> {
|
|||||||
mut self,
|
mut self,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
mut shares: HashMap<u16, EncryptedMessage<C, SecretShare<C::F>>>,
|
mut shares: HashMap<u16, EncryptedMessage<C, SecretShare<C::F>>>,
|
||||||
) -> Result<(BlameMachine<C>, C::G), FrostError<C>> {
|
) -> Result<BlameMachine<C>, FrostError<C>> {
|
||||||
validate_map(&shares, &(1 ..= self.params.n()).collect::<Vec<_>>(), self.params.i())?;
|
validate_map(&shares, &(1 ..= self.params.n()).collect::<Vec<_>>(), self.params.i())?;
|
||||||
|
|
||||||
let mut batch = BatchVerifier::new(shares.len());
|
let mut batch = BatchVerifier::new(shares.len());
|
||||||
@@ -423,8 +423,7 @@ impl<C: Ciphersuite> KeyMachine<C> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let KeyMachine { commitments, encryption, params, secret } = self;
|
let KeyMachine { commitments, encryption, params, secret } = self;
|
||||||
Ok((
|
Ok(BlameMachine {
|
||||||
BlameMachine {
|
|
||||||
commitments,
|
commitments,
|
||||||
encryption,
|
encryption,
|
||||||
result: ThresholdCore {
|
result: ThresholdCore {
|
||||||
@@ -433,9 +432,7 @@ impl<C: Ciphersuite> KeyMachine<C> {
|
|||||||
group_key: stripes[0],
|
group_key: stripes[0],
|
||||||
verification_shares,
|
verification_shares,
|
||||||
},
|
},
|
||||||
},
|
})
|
||||||
stripes[0],
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ use group::{
|
|||||||
|
|
||||||
use ciphersuite::Ciphersuite;
|
use ciphersuite::Ciphersuite;
|
||||||
|
|
||||||
/// Encryption types and utilities used to secure DKG messages.
|
mod encryption;
|
||||||
pub mod encryption;
|
|
||||||
|
|
||||||
/// The distributed key generation protocol described in the
|
/// The distributed key generation protocol described in the
|
||||||
/// [FROST paper](https://eprint.iacr.org/2020/852).
|
/// [FROST paper](https://eprint.iacr.org/2020/852).
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ pub fn frost_gen<R: RngCore + CryptoRng, C: Ciphersuite>(
|
|||||||
.drain()
|
.drain()
|
||||||
.map(|(i, machine)| {
|
.map(|(i, machine)| {
|
||||||
let our_secret_shares = generate_secret_shares(&secret_shares, i);
|
let our_secret_shares = generate_secret_shares(&secret_shares, i);
|
||||||
let these_keys = machine.calculate_share(rng, our_secret_shares).unwrap().0.complete();
|
let these_keys = machine.calculate_share(rng, our_secret_shares).unwrap().complete();
|
||||||
|
|
||||||
// Verify the verification_shares are agreed upon
|
// Verify the verification_shares are agreed upon
|
||||||
if verification_shares.is_none() {
|
if verification_shares.is_none() {
|
||||||
@@ -157,7 +157,7 @@ mod literal {
|
|||||||
blame = Some(None);
|
blame = Some(None);
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(machine.unwrap().0)
|
Some(machine.unwrap())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -191,7 +191,7 @@ mod literal {
|
|||||||
});
|
});
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(machine.unwrap().0)
|
Some(machine.unwrap())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -221,7 +221,7 @@ mod literal {
|
|||||||
});
|
});
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(machine.unwrap().0)
|
Some(machine.unwrap())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -255,7 +255,7 @@ mod literal {
|
|||||||
});
|
});
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(machine.unwrap().0)
|
Some(machine.unwrap())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
@@ -288,7 +288,7 @@ mod literal {
|
|||||||
});
|
});
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(machine.unwrap().0)
|
Some(machine.unwrap())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|||||||
16
crypto/dynamic-generator/Cargo.toml
Normal file
16
crypto/dynamic-generator/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "dynamic-generator"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Provide dynamic generators for curves implementing the Group API"
|
||||||
|
license = "MIT"
|
||||||
|
repository = "https://github.com/serai-dex/serai/tree/develop/crypto/custom-generator"
|
||||||
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
|
keywords = ["ff", "group", "generator"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
all-features = true
|
||||||
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
group = "0.12"
|
||||||
21
crypto/dynamic-generator/LICENSE
Normal file
21
crypto/dynamic-generator/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 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.
|
||||||
62
crypto/dynamic-generator/src/lib.rs
Normal file
62
crypto/dynamic-generator/src/lib.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
|
|
||||||
|
use core::any::{TypeId, Any};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
thread::{self, ThreadId},
|
||||||
|
sync::RwLock,
|
||||||
|
collections::HashMap,
|
||||||
|
};
|
||||||
|
|
||||||
|
use group::Group;
|
||||||
|
|
||||||
|
type Stack = Option<HashMap<ThreadId, HashMap<TypeId, Vec<Box<dyn Any>>>>>;
|
||||||
|
static mut GENERATORS: RwLock<Stack> = RwLock::new(None);
|
||||||
|
|
||||||
|
fn stack<G: Group>(map: &mut Stack) -> &mut Vec<Box<dyn Any>> {
|
||||||
|
map
|
||||||
|
.get_or_insert_with(HashMap::new)
|
||||||
|
.entry(thread::current().id())
|
||||||
|
.or_insert(HashMap::new())
|
||||||
|
.entry(TypeId::of::<G>())
|
||||||
|
.or_insert(Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn push<G: Group>(generator: G) {
|
||||||
|
stack::<G>(&mut unsafe { GENERATORS.write() }.unwrap()).push(Box::new(generator));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn pop<G: Group>() {
|
||||||
|
stack::<G>(&mut unsafe { GENERATORS.write() }.unwrap()).pop().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn get<G: Group>() {
|
||||||
|
stack::<G>(&mut unsafe { GENERATORS.write() }.unwrap()).get(0).unwrap_or(G::generator());
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! dynamic_generator {
|
||||||
|
($Name: ident, $Base: ident, $generator: expr) => {
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
struct $Name($Base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// type G: Group<Scalar = Self::F> + GroupOps + PrimeGroup + Zeroize + ConstantTimeEq;
|
||||||
|
macro_rules! complete_dynamic_generator {
|
||||||
|
($Name: ident, $Base: ident, $generator: expr) => {
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, ConstantTimeEq, Zeroize)]
|
||||||
|
struct $Name($Base);
|
||||||
|
impl Group for DynamicGenerator {}
|
||||||
|
impl GroupEncoding for DynamicGenerator {}
|
||||||
|
impl PrimeGroup for DynamicGenerator {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct DynamicGenerator<G: Group> { _phantom: PhantomData<G> }
|
||||||
|
impl DynamicGenerator {}
|
||||||
|
*/
|
||||||
@@ -45,9 +45,11 @@ default = "deny"
|
|||||||
|
|
||||||
exceptions = [
|
exceptions = [
|
||||||
{ allow = ["AGPL-3.0"], name = "ethereum-serai" },
|
{ allow = ["AGPL-3.0"], name = "ethereum-serai" },
|
||||||
|
|
||||||
{ allow = ["AGPL-3.0"], name = "serai-processor" },
|
{ allow = ["AGPL-3.0"], name = "serai-processor" },
|
||||||
|
|
||||||
|
{ allow = ["AGPL-3.0"], name = "serai-primitives" },
|
||||||
|
|
||||||
|
{ allow = ["AGPL-3.0"], name = "validator-sets-primitives" },
|
||||||
{ allow = ["AGPL-3.0"], name = "validator-sets-pallet" },
|
{ allow = ["AGPL-3.0"], name = "validator-sets-pallet" },
|
||||||
|
|
||||||
{ allow = ["AGPL-3.0"], name = "sp-tendermint" },
|
{ allow = ["AGPL-3.0"], name = "sp-tendermint" },
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ RUN wget https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${B
|
|||||||
# Serai recognizes the builder keys for 16/17 signatures
|
# Serai recognizes the builder keys for 16/17 signatures
|
||||||
# from the 23.0 release
|
# from the 23.0 release
|
||||||
ENV KEYS 152812300785C96444D3334D17565732E08E5E41 0AD83877C1F0CD1EE9BD660AD7CC770B81FD22A8 590B7292695AFFA5B672CBB2E13FC145CD3F4304 948444FCE03B05BA5AB0591EC37B1C1D44C786EE 9EDAFF80E080659604F4A76B2EBB056FD847F8A7 E777299FC265DD04793070EB944D35F9AC3DB76A F4FC70F07310028424EFC20A8E4256593F177720 D1DBF2C4B96F2DEBF4C16654410108112E7EA81F
|
ENV KEYS 152812300785C96444D3334D17565732E08E5E41 0AD83877C1F0CD1EE9BD660AD7CC770B81FD22A8 590B7292695AFFA5B672CBB2E13FC145CD3F4304 948444FCE03B05BA5AB0591EC37B1C1D44C786EE 9EDAFF80E080659604F4A76B2EBB056FD847F8A7 E777299FC265DD04793070EB944D35F9AC3DB76A F4FC70F07310028424EFC20A8E4256593F177720 D1DBF2C4B96F2DEBF4C16654410108112E7EA81F
|
||||||
ENV KEYS2 4DAF18FE948E7A965B30F9457E296D555E7F63A7 28E72909F1717FE9607754F8A7BEB2621678D37D 74E2DEF5D77260B98BC19438099BAD163C70FBFA 71A3B16735405025D447E8F274810B012346C9A6 9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C 287AE4CA1187C68C08B49CB2D11BD4F33F1DB499 F9A8737BF4FF5C89C903DF31DD78544CF91B1514
|
ENV KEYS2 4DAF18FE948E7A965B30F9457E296D555E7F63A7 28E72909F1717FE9607754F8A7BEB2621678D37D 74E2DEF5D77260B98BC19438099BAD163C70FBFA 71A3B16735405025D447E8F274810B012346C9A6 E463A93F5F3117EEDE6C7316BD02942421F4889F 9D3CC86A72F8494342EA5FD10A41BDC3F4FAFF1C 287AE4CA1187C68C08B49CB2D11BD4F33F1DB499 F9A8737BF4FF5C89C903DF31DD78544CF91B1514
|
||||||
|
|
||||||
# Use hardcoded prints to get keys from servers. 2 Different servers used.
|
# Use hardcoded prints to get keys from servers. 2 Different servers used.
|
||||||
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ${KEYS} \
|
RUN gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ${KEYS} \
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use sc_service::{PruningMode, PartialComponents};
|
use sc_service::PartialComponents;
|
||||||
use frame_benchmarking_cli::{ExtrinsicFactory, BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE};
|
use frame_benchmarking_cli::{ExtrinsicFactory, BenchmarkCmd, SUBSTRATE_REFERENCE_HARDWARE};
|
||||||
use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli};
|
use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli};
|
||||||
|
|
||||||
@@ -135,10 +135,7 @@ pub fn run() -> sc_cli::Result<()> {
|
|||||||
cli.create_runner(cmd)?.sync_run(|config| cmd.run::<Block>(&config))
|
cli.create_runner(cmd)?.sync_run(|config| cmd.run::<Block>(&config))
|
||||||
}
|
}
|
||||||
|
|
||||||
None => cli.create_runner(&cli.run)?.run_node_until_exit(|mut config| async {
|
None => cli.create_runner(&cli.run)?.run_node_until_exit(|config| async {
|
||||||
if config.role.is_authority() {
|
|
||||||
config.state_pruning = Some(PruningMode::ArchiveAll);
|
|
||||||
}
|
|
||||||
service::new_full(config).await.map_err(sc_cli::Error::Service)
|
service::new_full(config).await.map_err(sc_cli::Error::Service)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,6 @@ impl pallet_assets::Config for Runtime {
|
|||||||
type ApprovalDeposit = ConstU64<0>;
|
type ApprovalDeposit = ConstU64<0>;
|
||||||
|
|
||||||
// Unused hooks
|
// Unused hooks
|
||||||
type CallbackHandle = ();
|
|
||||||
type Freezer = ();
|
type Freezer = ();
|
||||||
type Extra = ();
|
type Extra = ();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "serai-primitives"
|
name = "serai-primitives"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Primitives for the Serai blockchain"
|
description = "Primitives for the Serai blockchain"
|
||||||
license = "MIT"
|
license = "AGPL-3.0-only"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/serai/primitives"
|
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/serai/primitives"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use sp_runtime::{
|
|||||||
Digest,
|
Digest,
|
||||||
};
|
};
|
||||||
use sp_blockchain::HeaderBackend;
|
use sp_blockchain::HeaderBackend;
|
||||||
|
use sp_api::BlockId;
|
||||||
|
|
||||||
use sp_consensus::{Error, BlockOrigin, Proposer, Environment};
|
use sp_consensus::{Error, BlockOrigin, Proposer, Environment};
|
||||||
use sc_consensus::import_queue::IncomingBlock;
|
use sc_consensus::import_queue::IncomingBlock;
|
||||||
@@ -199,8 +200,9 @@ impl<T: TendermintValidator> TendermintAuthority<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get our first proposal
|
// Get our first proposal
|
||||||
let proposal =
|
let proposal = authority
|
||||||
authority.get_proposal(&import.client.header(last_hash).unwrap().unwrap()).await;
|
.get_proposal(&import.client.header(BlockId::Hash(last_hash)).unwrap().unwrap())
|
||||||
|
.await;
|
||||||
|
|
||||||
// Create the gossip network
|
// Create the gossip network
|
||||||
// This has to be spawning the machine, else gossip fails for some reason
|
// This has to be spawning the machine, else gossip fails for some reason
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::{marker::PhantomData, sync::Arc, collections::HashMap};
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
use sp_api::BlockId;
|
||||||
use sp_runtime::traits::{Header, Block};
|
use sp_runtime::traits::{Header, Block};
|
||||||
use sp_blockchain::{BlockStatus, HeaderBackend, Backend as BlockchainBackend};
|
use sp_blockchain::{BlockStatus, HeaderBackend, Backend as BlockchainBackend};
|
||||||
use sp_consensus::{Error, CacheKeyId, BlockOrigin, SelectChain};
|
use sp_consensus::{Error, CacheKeyId, BlockOrigin, SelectChain};
|
||||||
@@ -14,12 +15,13 @@ use crate::{TendermintValidator, tendermint::TendermintImport};
|
|||||||
|
|
||||||
impl<T: TendermintValidator> TendermintImport<T> {
|
impl<T: TendermintValidator> TendermintImport<T> {
|
||||||
fn check_already_in_chain(&self, hash: <T::Block as Block>::Hash) -> bool {
|
fn check_already_in_chain(&self, hash: <T::Block as Block>::Hash) -> bool {
|
||||||
|
let id = BlockId::Hash(hash);
|
||||||
// If it's in chain, with justifications, return it's already on chain
|
// If it's in chain, with justifications, return it's already on chain
|
||||||
// If it's in chain, without justifications, continue the block import process to import its
|
// If it's in chain, without justifications, continue the block import process to import its
|
||||||
// justifications
|
// justifications
|
||||||
// This can be triggered if the validators add a block, without justifications, yet the p2p
|
// This can be triggered if the validators add a block, without justifications, yet the p2p
|
||||||
// process then broadcasts it with its justifications
|
// process then broadcasts it with its justifications
|
||||||
(self.client.status(hash).unwrap() == BlockStatus::InChain) &&
|
(self.client.status(id).unwrap() == BlockStatus::InChain) &&
|
||||||
self.client.justifications(hash).unwrap().is_some()
|
self.client.justifications(hash).unwrap().is_some()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,7 +173,7 @@ impl<B: Block, Be: Backend<B>> SelectChain<B> for TendermintSelectChain<B, Be> {
|
|||||||
.0
|
.0
|
||||||
.blockchain()
|
.blockchain()
|
||||||
// There should always be a finalized block
|
// There should always be a finalized block
|
||||||
.header(self.0.blockchain().last_finalized().unwrap())
|
.header(BlockId::Hash(self.0.blockchain().last_finalized().unwrap()))
|
||||||
// There should not be an error in retrieving it and since it's finalized, it should exist
|
// There should not be an error in retrieving it and since it's finalized, it should exist
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "validator-sets-primitives"
|
name = "validator-sets-primitives"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Primitives for validator sets"
|
description = "Primitives for validator sets"
|
||||||
license = "MIT"
|
license = "AGPL-3.0-only"
|
||||||
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/primitives"
|
repository = "https://github.com/serai-dex/serai/tree/develop/substrate/validator-sets/primitives"
|
||||||
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
Reference in New Issue
Block a user