* add polyseed support
* fix pr comments
* fix tests
* Embed the mempool into the Blockchain
* Plan scheduled payments whenever outputs are received
The scheduler prior waited for the next series of payments to be added.
* Replace Tendermint step with sync_block
Step moved a step forward after an externally synced/added block. This created
a race condition to add the block between the sync process and the Tendermint
machine. Now that the block routes through Tendermint, there is no such race
condition.
* Finish binding Tendermint into Tributary and define a Tributary master object
* Add correction the last commit missed
* Add DoS limits to tributary and require provided transactions be ordered
* Fix the scheduler from dropping UTXOs when there weren't any payments
* Documentation and cargo update
* Add a dedicated db crate with a basic DB trait
It's needed by the processor and tributary (coordinator).
* Add a DB to Tributary
Adds support for reloading most of the blockchain.
* Reloaded provided transactions from the disk
Also resolves a race condition by asserting provided transactions must be
unique, allowing them to be safely provided multiple times.
* must_use annotations on DbTxn
* Support reloading the mempool from disk
* Add a NewSet event to validator-sets
Updates to the latest serai-dex/substrate due to depending on
10ccaca0eb498a2316bbf627d419b29b1a75933a.
* Add basic getters to tributary
* cargo update
* Update to the latest subxt
Writes a custom unsigned extrinic creator due to subxt having an internal error
with the scale metadata. While the code in our scope increased, it's much more
ergonomic to our usage. We may end up rewriting most of subxt, eventually.
* Make unsigned private due to unsafe calling potential
* Start defining the coordinator
* Merge AckBlock with Burns
Offers greater efficiency while reducing concerns re: atomicity.
* Correct processor flow to have the coordinator decide signing set/re-attempts
The signing set should be the first group to submit preprocesses to Tributary.
Re-attempts shouldn't be once every 30s, yet n blocks since the last relevant
message.
Removes the use of an async task/channel in the signer (and Substrate signer).
Also removes the need to be able to get the time from a coin's block, which was
a fragile system marked with a TODO already.
* cargo +nightly fmt
* cargo update
Since p256 now pulls in an extra crate with this update, the {k,p}256 imports
disable default-features to prevent growing the tree.
* Support extracting timestamps from blocks
* Make progres on handling NewSet events
Further bones out the coordinator.
* Resolve#245
* Have InInstructions track the latest block for a network in storage
* Fill out code for the rest of the Substrate events
* Clean up the Substrate block processing code
* Rename transaction file to tributary, add function for genesis
* Add a processor API to the coordinator
* Add extensive commentary on mutable to the processor's main file
Clearly establishes why consistency is guaranteed from a Rust borrow-checker
mindset. While there are plenty of... 'violations', they're clearly explained.
Hopefully, this method of thinking helps promote/ensure consistency in the
future.
* Move ConfirmKeyPair from key_gen to substrate
Clarifies the emitter and accordingly why its mutations are justified.
* Remove BatchSigned
SubstrateBlock's provision of the most recently acknowledged block has
equivalent information with the same latency. Accordingly, there's no need for
it.
* Add note to processor_messages
* Use a single txn for an entire coordinator message
Removes direct DB accesses whre possible. Documents the safety of the rest.
Does uncover one case of unsafety not previously noted.
* cargo update to remove usage of yanked crate
* Clarify safety of Scanner::block_number and KeyGen::keys
* Tweak ConfirmKeyPair to alleviate database requirements of coordinator
* Use an enum for Coin/NetworkId
It originally wasn't an enum so software which had yet to update before an
integration wouldn't error (as now enums are strictly typed). The strict typing
is preferable though.
* Code a method to determine the activation block before any block has consensus
[0; 32] is a magic for no block has been set yet due to this being the first
key pair. If [0; 32] is the latest finalized block, the processor determines
an activation block based on timestamps.
This doesn't use an Option for ergonomic reasons.
* automate whitespace & trimming test cases
* Save keys by their tweaked group_key
Keys are referred to by their tweaked versions. If a tweak was needed, keys
would fail to confirm.
* Use crypto-bigint's reduction in ed448
Achieves feasible performance in the ed448 which makes it potentially viable
for real world usage.
Accordingly prepares a new release, updating the README.
* Move the entirety of ed448 to Residue, offering a further 2-4x speedup
* Resolve#68
Notably speeds up monero-serai's build and CLSAG performance.
* Make MainDB into SubstrateDB
* Initial Tributary handling
* Add additional checks to key_gen/sign
There is the ability to cause state bloat by flooding Tributary.
KeyGen/Sign specifically shouldn't allow bloat since we check the
commitments/preprocesses/shares for validity. Accordingly, any invalid data
(such as bloat) should be detected.
It was posssible to place bloat after the valid data. Doing so would be
considered a valid KeyGen/Sign message, yet could add up to 50k kB per sign.
* Apply DKG TX handling code to all sign TXs
The existing code was almost entirely applicable. It just needed to be scoped
with an ID. While the handle function is now a bit convoluted, I don't see a
better option.
* Split FinalizedBlock into ExternalBlock and SeraiBlock
Also re-arranges their orders.
* Add support for multiple orderings in Provided
Necessary as our Tributary chains needed to agree when a Serai block has
occurred, and when a Monero block has occurred. Since those could happen at the
same time, some validators may put SeraiBlock before ExternalBlock and vice
versa, causing a chain halt. Now they can have distinct ordering queues.
* Slash on unrecognized ID
* ExternalBlock handler
* Add a SubstrateBlockAck message to the processor
When a Substrate block occurs, the coordinator is expected to emit
SubstrateBlock. This causes the processor to begin a variety of plans. The
processor now emits SubstrateBlockAck, explicitly listing all plan IDs, before
starting signing.
This lets the coordinator provide a SubstrateBlock transaction, and with it,
recognize all plan IDs as valid.
Prior, we would've had to have a spotty algorithm based upon the upcoming
Preprocess messages, or if we immediately provided the SubstrateBlock
transaction, then wait for the processor to inform us of the contained plans.
This creates an explicitly proper async flow not reliant on waiting for data
availability.
Alternatively, we could've replaced Preprocess with (Block, Vec<Preprocess>).
This would've been more efficient, yet also clunky due to the multiple usages
of the Preprocess message.
* Route the SubstrateBlock message, which is the last Tributary transaction type
* Add recent bloat checks added to signer to substrate_signer as well
* Add no_std support to transcript, dalek-ff-group, ed448, ciphersuite, multiexp, schnorr, and monero-generators
transcript, dalek-ff-group, ed449, and ciphersuite are all usable with no_std
alone. The rest additionally require alloc.
Part of #279.
* Add a test to the coordinator for running a Tributary
Impls a LocalP2p for testing.
Moves rebroadcasting into Tendermint, since it's what knows if a message is
fully valid + original.
Removes TributarySpec::validators() HashMap, as its non-determinism caused
different instances to have different round robin schedules. It was already
prior moved to a Vec for this issue, so I'm unsure why this remnant existed.
Also renames the GH no-std workflow from the prior commit.
* Add a test for Tributary
Further fleshes out the Tributary testing code.
* Test handling of DKG commitments transactions
* Add Transaction::sign.
While I don't love the introduction of empty_signed, it's practically fine.
* Tributary test wait_for_tx_inclusion function
* Additionally test DKGShares
* Handle adding new Tributaries
Removes last_block as an argument from Tendermint. It now loads from the DB as
needed. While slightly less performant, it's easiest and should be fine.
* Reload Tributaries
add_active_tributary writes the spec to disk before it returns, so even if the
VecDeque it pushes to isn't popped, the tributary will still be loaded on boot.
* Start handling P2P messages
This defines the tart of a very complex series of locks I'm really unhappy
with. At the same time, there's not immediately a better solution. This also
should work without issue.
* Clarify Arc RwLocks and sleeps in coordinator
* Send a heartbeat message when a Tributary falls behind
* cargo fmt
* cargo update
* Move json word lists to rs
Allows building the seed code without serde_json.
* Break coordinator main into multiple functions
Also moves from std::sync::RwLock to tokio::sync::RwLock to prevent wasting
cycles on spinning.
* Remove reliance on a blockchain read lock from block/commit
* Implement Tributary syncing
Also adds a forwards-lookup to the Tributary blockchain.
* Don't return from sync_block until the Tendermint machine returns if it's valid or not
We had a race condition where'd we be informed of blocks 1 .. 3, and
immediately add 1 .. 3. Because we immediately tried to add 2 after 1, it'd
fail since the tip was still the genesis, yet 2 needs the tip to be 1.
Adding a channel, while ugly, was the simplest way to accomplish this.
Also has any added block be broadcasted. Else there's a race condition where a
node which syncs up to the most recent block does so, yet fails to add the next
block when it's committed to.
* Test handle_p2p and Tributary syncing
Includes bug fixes.
* Tweak tests workflow
* Add a TributaryReader which doesn't require a borrow to operate
Reduces lock contention.
Additionally changes block_key to include the genesis. While not technically
needed, the lack of genesis introduced a side effect where any Tributary on the
the database could return the block of any other Tributary. While that wasn't a
security issue, returning it suggested it was on-chain when it wasn't. This may
have been usable to create issues.
* Document panic in FROST
* Document a pair of panics requiring 256 GB of RAM/4 GB of a context
* Add a UID function to messages
When we receive messages, we're provided with a message ID we can use to
prevent handling an item multiple times. That doesn't prevent us from *sending*
an item multiple times though. Thanks to the UID system, we can now not send if
already present.
Alternatively, we can remove the ordered message ID for just the UID, allowing
duplicates to be sent without issue, and handled on the receiving end.
* Initial code to handle messages from processors
* Document the processor/tributary/coordinator/serai flow
* Have Coordinator MainDb take a mutable borrow
* Update to substrate polkadot-v0.9.42
* Correct error message in ff-group-tests
* Update to May's nightly
Doesn't use the PR due to the needed changes.
* Support arbitrary RPC providers in monero-serai
Sets a clean path for no-std premised RPCs (buffers to an external RPC impl)/
Tor-based RPCs/client-side load balancing/...
* Correct processor's handling of the new Monero RPC code
* Correct Serai Dockerfile
* Publish ExternablBlock/SubstrateBlock, delay *Preprocess until ID acknowledged
Adds a channel for the Tributary scanner to communicate when an ID has been
acknowledged.
* Rename uid to intent
* Use U448 for Ed448 instead of U512
* Spawn a new async task for each block message
This probably should be done with n-long lived tasks, one per Tributary. While
this may not be suitably performant long-term (potential DoS vector), this at
least resolves the halting concerns.
* Move the coordinator to a n-processor design
* Ensure Tributary commits are minimal
* Properly get genesis for a Processor message
* Create a vote transaction upon GeneratedKeyPair
* Remove TODO about code de-duplication
It's infeasible to write a macro/function there. Does add a type alias which
makes things cleaner.
* Have coordinator publish batches to Substrate
* Implement MuSig key aggregation into DKG
Isn't spec compliant due to the lack of a spec to be compliant too.
Slight deviation from the paper by using a unique list instead of a multiset.
Closes#186, progresses #277.
* Correct 2/3rds definitions throughout the codebase
The prior formula failed for some values, such as 20.
20 / 3 = 6, * 2 = 12, + 1 = 13. 13 is 65%, not >= 67.
* cargo update
Resolves a yanked crate and removes some duplicated dependencies.
* Add a dedicated function to get a MuSig key
* Do the minimal amount of work for dkg to compile under no-std
The Substrate runtime requires access to the MuSig key aggregation function.
\#279 related.
* Use a MuSig signature to publish validator set key pairs to Serai
The processor/coordinator flow still has to be rewritten.
* Correct various no_std definitions
* Add a context to MuSig key aggregation
* Use proper messages for ValidatorSets/InInstructions pallet
Provides a DST, and associated metadata as beneficial.
Also utilizes MuSig's context to session-bind. Since set_keys_messages also
binds to set, this is semi-redundant, yet that's appreciated.
* Remove signed Substrate TXs from Coordinator
* Only scan v2 Monero TXs
* Fix for prior commit
* Ensure canonical points in the cross-group DLEq proof
* Fix incorrect sig_hash generation
sig_hash was used as a challenge. challenges should be of the form H(R, A, m).
These sig hashes were solely H(A, m), allowing trivial forgeries.
* cargo update
Resolves an openssl advisory and nets ~-8 crates.
* Build no-std tests with RISC-V 32 IMAC
Turns out wasm still has std, making it suboptimal to use here.
* Pin setup-protoc to v2.0.0
* Update to substrate polkadot-v0.9.43
* fix tributary sync test
* Slight terminology correction in sync test
Also correct a mistake from merging the most recent polkadot version.
* Update nightly
* Replace lazy_static with OnceLock inside monero-serai
lazy_static, if no_std environments were used, effectively required always
using spin locks. This resolves the ergonomics of that while adopting Rust std
code.
no_std does still use a spin based solution. Theoretically, we could use
atomics, yet writing our own Mutex wasn't a priority.
* no-std support for monero-serai (#311)
* Move monero-serai from std to std-shims, where possible
* no-std fixes
* Make the HttpRpc its own feature, thiserror only on std
* Drop monero-rs's epee for a homegrown one
We only need it for a single function. While I tried jeffro's, it didn't work
out of the box, had three unimplemented!s, and is no where near viable for
no_std.
Fixes#182, though should be further tested.
* no-std monero-serai
* Allow base58-monero via git
* cargo fmt
* Represent RCT amounts with None, not 0.
Fixes#282.
Does allow any v1 TXs which exist, and v2 miner-TXs, to specify Some(0). As far
as I can tell, both were/are theoreitcally possible.
* Add a message queue
This is intended to be a reliable transport between the processors and
coordinator. Since it'll be intranet only, it's written as never fail.
Primarily needs testing and a proper ID.
* cargo update
Resolves https://github.com/serai-dex/serai/security/dependabot/29
* Correct deny.toml with inclusion of message-queue
* Update nightly
* std-shims: six `Read` for &[u8]
* Use serai- prefixes on Serai-specific packages
Fixes deny.toml, also runs a minor cargo update shrinking the tree.
* Update monero-tests workflow to new name for the processor
* Correct depends for processor-messages
* Disable Rust caching
We hit the cache limit after just one or two builds, making it infeasible.
* cargo update
Resolves a yanked crate
* Move location of serai-client in Cargo.toml
* Monero: support for legacy transactions (#308)
* add mlsag
* fix last commit
* fix miner v1 txs
* fix non-miner v1 txs
* add borromean + fix mlsag
* add block hash calculations
* fix for the jokester that added unreduced scalars
to the borromean signature of
2368d846e671bf79a1f84c6d3af9f0bfe296f043f50cf17ae5e485384a53707b
* Add Borromean range proof verifying functionality
* Add MLSAG verifying functionality
* fmt & clippy :)
* update MLSAG, ss2_elements will always be 2
* Add MgSig proving
* Tidy block.rs
* Tidy Borromean, fix bugs in last commit, replace todo! with unreachable!
* Mark legacy EcdhInfo amount decryption as experimental
* Correct comments
* Write a new impl of the merkle algorithm
This one tries to be understandable.
* Only pull in things only needed for experimental when experimental
* Stop caching the Monero block hash now in processor that we have Block::hash
* Corrections for recent processor commit
* Use a clearer algorithm for the merkle
Should also be more efficient due to not shifting as often.
* Tidy Mlsag
* Remove verify_rct_* from Mlsag
Both methods were ports from Monero, overtly specific without clear
documentation. They need to be added back in, with documentation, or included
in a node which provides the necessary further context for them to be naturally
understandable.
* Move mlsag/mod.rs to mlsag.rs
This should only be a folder if it has multiple files.
* Replace EcdhInfo terminology
The ECDH encrypted the amount, yet this struct contained the encrypted amount,
not some ECDH.
Also corrects the types on the original EcdhInfo struct.
* Correct handling of commitment masks when scanning
* Route read_array through read_raw_vec
* Misc lint
* Make a proper RctType enum
No longer caches RctType in the RctSignatures as well.
* Replace Vec<Bulletproofs> with Bulletproofs
Monero uses aggregated range proofs, so there's only ever one Bulletproof. This
is enforced with a consensus rule as well, making this safe.
As for why Monero uses a vec, it's probably due to the lack of variadic typing
used. Its effectively an Option for them, yet we don't need an Option since we
do have variadic typing (enums).
* Add necessary checks to Eventuality re: supported protocols
* Fix for block 202612 and fix merkel root calculations
* MLSAG (de)serialisation fix
ss_2_elements will not always be 2 as rct type 1 transactions are not enforced to have one input
* Revert "MLSAG (de)serialisation fix"
This reverts commit 5e710e0c96.
here it checks number of MGs == number of inputs:
0a1eaf26f9/src/cryptonote_core/tx_verification_utils.cpp (L60-59)
and here it checks for RctTypeFull number of MGs == 1:
0a1eaf26f9/src/ringct/rctSigs.cpp (L1325)
so number of inputs == 1
so ss_2_elements == 2
* update `MlsagAggregate` comment
* cargo update
Resolves a yanked crate
* Move location of serai-client in Cargo.toml
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Fix the known issue with the DSA
I wrote it to only select TXs with a timelock, not only TXs which are unlocked.
This most likely explains why it so heavily selected coinbases.
Also moves an InternalError which would've never been hit on mainnet, yet
technically isn't an invariant, to only exist when cfg(test).
* Add a bin to download a chain, over RPC, reserializing and hashing every item
Parallelized. Doesn't check the deserialization is correct. Does use distinct,
persistent HTTP clients.
* Correct how Monero integration tests are run
* Support multiple RPCs in the reserialize_chain bin
* Don't call get_height every block
* Modify get_transactions to split requests as to not hit the restricted RPC limits
* Meaningful changes from aggressive-clippy
I do want to enable a few specific lints, yet aggressive-clippy as a whole
isn't worthwhile.
* Extend reserialize_chain with CLSAG/BP(+) verification
* Remove spammy println from reserialize_chain
* Update reserialize_chain for v1 and migration TXs
Also always marks 0-amount inputs as RCT due to impossibility of non-RCT
0-amount outputs.
* Only deserialize RctSignatures where's there at least one input
This is only enforced by the Monero protocol due to a single check the mixRing
isn't empty in get_pre_mlsag_hash. The value in ensuring there's a least one
input is to ensure the safety of our rct_type functions, which determines the
RctType based off structural analysis (specifically, input data if
MlsagBorromean).
rct_type was technically safe without this. A 0-input transaction would be
mis-classified as RctFull/MlsagAggregate, which would then make the
RctSignatures invalid for being RctFull (requiring exactly one input) yet not
having inputs, meaning an invalid RctSignatures would be mis-classified yet
still invalid.
This just removes the risk of mis-classification in the first place, tightening
the library's safety.
* docs/Getting Started.md: cargo build --release --all-features
* Fix the known instance of #295
* Bind RocksDB into serai-db
* Split up tests in CI to avoid node storage limits
* Corrections to prior commit
* Again
I called git commit --amend without calling git add . again :(
* Update the flow for completed signing processes
Now, an on-chain transaction exists. This resolves some ambiguities and
provides greater coordination.
* Clean Polyseed code
* Final tweaks
* Correct no-std builds for Polyseed
* Again correct no-std
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Co-authored-by: GitHub Actions <unknown>
Co-authored-by: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com>
Co-authored-by: Boog900 <108027008+Boog900@users.noreply.github.com>
Co-authored-by: Steven Chang <stevenchang5000@gmail.com>
This is only enforced by the Monero protocol due to a single check the mixRing
isn't empty in get_pre_mlsag_hash. The value in ensuring there's a least one
input is to ensure the safety of our rct_type functions, which determines the
RctType based off structural analysis (specifically, input data if
MlsagBorromean).
rct_type was technically safe without this. A 0-input transaction would be
mis-classified as RctFull/MlsagAggregate, which would then make the
RctSignatures invalid for being RctFull (requiring exactly one input) yet not
having inputs, meaning an invalid RctSignatures would be mis-classified yet
still invalid.
This just removes the risk of mis-classification in the first place, tightening
the library's safety.
I wrote it to only select TXs with a timelock, not only TXs which are unlocked.
This most likely explains why it so heavily selected coinbases.
Also moves an InternalError which would've never been hit on mainnet, yet
technically isn't an invariant, to only exist when cfg(test).
* add mlsag
* fix last commit
* fix miner v1 txs
* fix non-miner v1 txs
* add borromean + fix mlsag
* add block hash calculations
* fix for the jokester that added unreduced scalars
to the borromean signature of
2368d846e671bf79a1f84c6d3af9f0bfe296f043f50cf17ae5e485384a53707b
* Add Borromean range proof verifying functionality
* Add MLSAG verifying functionality
* fmt & clippy :)
* update MLSAG, ss2_elements will always be 2
* Add MgSig proving
* Tidy block.rs
* Tidy Borromean, fix bugs in last commit, replace todo! with unreachable!
* Mark legacy EcdhInfo amount decryption as experimental
* Correct comments
* Write a new impl of the merkle algorithm
This one tries to be understandable.
* Only pull in things only needed for experimental when experimental
* Stop caching the Monero block hash now in processor that we have Block::hash
* Corrections for recent processor commit
* Use a clearer algorithm for the merkle
Should also be more efficient due to not shifting as often.
* Tidy Mlsag
* Remove verify_rct_* from Mlsag
Both methods were ports from Monero, overtly specific without clear
documentation. They need to be added back in, with documentation, or included
in a node which provides the necessary further context for them to be naturally
understandable.
* Move mlsag/mod.rs to mlsag.rs
This should only be a folder if it has multiple files.
* Replace EcdhInfo terminology
The ECDH encrypted the amount, yet this struct contained the encrypted amount,
not some ECDH.
Also corrects the types on the original EcdhInfo struct.
* Correct handling of commitment masks when scanning
* Route read_array through read_raw_vec
* Misc lint
* Make a proper RctType enum
No longer caches RctType in the RctSignatures as well.
* Replace Vec<Bulletproofs> with Bulletproofs
Monero uses aggregated range proofs, so there's only ever one Bulletproof. This
is enforced with a consensus rule as well, making this safe.
As for why Monero uses a vec, it's probably due to the lack of variadic typing
used. Its effectively an Option for them, yet we don't need an Option since we
do have variadic typing (enums).
* Add necessary checks to Eventuality re: supported protocols
* Fix for block 202612 and fix merkel root calculations
* MLSAG (de)serialisation fix
ss_2_elements will not always be 2 as rct type 1 transactions are not enforced to have one input
* Revert "MLSAG (de)serialisation fix"
This reverts commit 5e710e0c96.
here it checks number of MGs == number of inputs:
0a1eaf26f9/src/cryptonote_core/tx_verification_utils.cpp (L60-59)
and here it checks for RctTypeFull number of MGs == 1:
0a1eaf26f9/src/ringct/rctSigs.cpp (L1325)
so number of inputs == 1
so ss_2_elements == 2
* update `MlsagAggregate` comment
* cargo update
Resolves a yanked crate
* Move location of serai-client in Cargo.toml
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Move monero-serai from std to std-shims, where possible
* no-std fixes
* Make the HttpRpc its own feature, thiserror only on std
* Drop monero-rs's epee for a homegrown one
We only need it for a single function. While I tried jeffro's, it didn't work
out of the box, had three unimplemented!s, and is no where near viable for
no_std.
Fixes#182, though should be further tested.
* no-std monero-serai
* Allow base58-monero via git
* cargo fmt
lazy_static, if no_std environments were used, effectively required always
using spin locks. This resolves the ergonomics of that while adopting Rust std
code.
no_std does still use a spin based solution. Theoretically, we could use
atomics, yet writing our own Mutex wasn't a priority.
* Partial move to ff 0.13
It turns out the newly released k256 0.12 isn't on ff 0.13, preventing further
work at this time.
* Update all crates to work on ff 0.13
The provided curves still need to be expanded to fit the new API.
* Finish adding dalek-ff-group ff 0.13 constants
* Correct FieldElement::product definition
Also stops exporting macros.
* Test most new parts of ff 0.13
* Additionally test ff-group-tests with BLS12-381 and the pasta curves
We only tested curves from RustCrypto. Now we test a curve offered by zk-crypto,
the group behind ff/group, and the pasta curves, which is by Zcash (though
Zcash developers are also behind zk-crypto).
* Finish Ed448
Fully specifies all constants, passes all tests in ff-group-tests, and finishes moving to ff-0.13.
* Add RustCrypto/elliptic-curves to allowed git repos
Needed due to k256/p256 incorrectly defining product.
* Finish writing ff 0.13 tests
* Add additional comments to dalek
* Further comments
* Update ethereum-serai to ff 0.13
* Initial work on a message box
* Finish message-box (untested)
* Expand documentation
* Embed the recipient in the signature challenge
Prevents a message from A -> B from being read as from A -> C.
* Update documentation by bifurcating sender/receiver
* Panic on receiving an invalid signature
If we've received an invalid signature in an authenticated system, a
service is malicious, critically faulty (equivalent to malicious), or
the message layer has been compromised (or is otherwise critically
faulty).
Please note a receiver who handles a message they shouldn't will trigger
this. That falls under being critically faulty.
* Documentation and helper methods
SecureMessage::new and SecureMessage::serialize.
Secure Debug for MessageBox.
* Have SecureMessage not be serialized by default
Allows passing around in-memory, if desired, and moves the error from
decrypt to new (which performs deserialization).
Decrypt no longer has an error since it panics if given an invalid
signature, due to this being intranet code.
* Explain and improve nonce handling
Includes a missing zeroize call.
* Rebase to latest develop
Updates to transcript 0.2.0.
* Add a test for the MessageBox
* Export PrivateKey and PublicKey
* Also test serialization
* Add a key_gen binary to message_box
* Have SecureMessage support Serde
* Add encrypt_to_bytes and decrypt_from_bytes
* Support String ser via base64
* Rename encrypt/decrypt to encrypt_bytes/decrypt_to_bytes
* Directly operate with values supporting Borsh
* Use bincode instead of Borsh
By staying inside of serde, we'll support many more structs. While
bincode isn't canonical, we don't need canonicity on an authenticated,
internal system.
* Turn PrivateKey, PublicKey into structs
Uses Zeroizing for the PrivateKey per #150.
* from_string functions intended for loading from an env
* Use &str for PublicKey from_string (now from_str)
The PrivateKey takes the String to take ownership of its memory and
zeroize it. That isn't needed with PublicKeys.
* Finish updating from develop
* Resolve warning
* Use ZeroizingAlloc on the key_gen binary
* Move message-box from crypto/ to common/
* Move key serialization functions to ser
* add/remove functions in MessageBox
* Implement Hash on dalek_ff_group Points
* Make MessageBox generic to its key
Exposes a &'static str variant for internal use and a RistrettoPoint
variant for external use.
* Add Private to_string as deprecated
Stub before more competent tooling is deployed.
* Private to_public
* Test both Internal and External MessageBox, only use PublicKey in the pub API
* Remove panics on invalid signatures
Leftover from when this was solely internal which is now unsafe.
* Chicken scratch a Scanner task
* Add a write function to the DKG library
Enables writing directly to a file.
Also modifies serialize to return Zeroizing<Vec<u8>> instead of just Vec<u8>.
* Make dkg::encryption pub
* Remove encryption from MessageBox
* Use a 64-bit block number in Substrate
We use a 64-bit block number in general since u32 only works for 120 years
(with a 1 second block time). As some chains even push the 1 second threshold,
especially ones based on DAG consensus, this becomes potentially as low as 60
years.
While that should still be plenty, it's not worth wondering/debating. Since
Serai uses 64-bit block numbers elsewhere, this ensures consistency.
* Misc crypto lints
* Get the scanner scratch to compile
* Initial scanner test
* First few lines of scheduler
* Further work on scheduler, solidify API
* Define Scheduler TX format
* Branch creation algorithm
* Document when the branch algorithm isn't perfect
* Only scanned confirmed blocks
* Document Coin
* Remove Canonical/ChainNumber from processor
The processor should be abstracted from canonical numbers thanks to the
coordinator, making this unnecessary.
* Add README documenting processor flow
* Use Zeroize on substrate primitives
* Define messages from/to the processor
* Correct over-specified versioning
* Correct build re: in_instructions::primitives
* Debug/some serde in crypto/
* Use a struct for ValidatorSetInstance
* Add a processor key_gen task
Redos DB handling code.
* Replace trait + impl with wrapper struct
* Add a key confirmation flow to the key gen task
* Document concerns on key_gen
* Start on a signer task
* Add Send to FROST traits
* Move processor lib.rs to main.rs
Adds a dummy main to reduce clippy dead_code warnings.
* Further flesh out main.rs
* Move the DB trait to AsRef<[u8]>
* Signer task
* Remove a panic in bitcoin when there's insufficient funds
Unchecked underflow.
* Have Monero's mine_block mine one block, not 10
It was initially a nicety to deal with the 10 block lock. C::CONFIRMATIONS
should be used for that instead.
* Test signer
* Replace channel expects with log statements
The expects weren't problematic and had nicer code. They just clutter test
output.
* Remove the old wallet file
It predates the coordinator design and shouldn't be used.
* Rename tests/scan.rs to tests/scanner.rs
* Add a wallet test
Complements the recently removed wallet file by adding a test for the scanner,
scheduler, and signer together.
* Work on a run function
Triggers a clippy ICE.
* Resolve clippy ICE
The issue was the non-fully specified lambda in signer.
* Add KeyGenEvent and KeyGenOrder
Needed so we get KeyConfirmed messages from the key gen task.
While we could've read the CoordinatorMessage to see that, routing through the
key gen tasks ensures we only handle it once it's been successfully saved to
disk.
* Expand scanner test
* Clarify processor documentation
* Have the Scanner load keys on boot/save outputs to disk
* Use Vec<u8> for Block ID
Much more flexible.
* Panic if we see the same output multiple times
* Have the Scanner DB mark itself as corrupt when doing a multi-put
This REALLY should be a TX. Since we don't have a TX API right now, this at
least offers detection.
* Have DST'd DB keys accept AsRef<[u8]>
* Restore polling all signers
Writes a custom future to do so.
Also loads signers on boot using what the scanner claims are active keys.
* Schedule OutInstructions
Adds a data field to Payment.
Also cleans some dead code.
* Panic if we create an invalid transaction
Saves the TX once it's successfully signed so if we do panic, we have a copy.
* Route coordinator messages to their respective signer
Requires adding key to the SignId.
* Send SignTransaction orders for all plans
* Add a timer to retry sign_plans when prepare_send fails
* Minor fmt'ing
* Basic Fee API
* Move the change key into Plan
* Properly route activation_number
* Remove ScannerEvent::Block
It's not used under current designs
* Nicen logs
* Add utilities to get a block's number
* Have main issue AckBlock
Also has a few misc lints.
* Parse instructions out of outputs
* Tweak TODOs and remove an unwrap
* Update Bitcoin max input/output quantity
* Only read one piece of data from Monero
Due to output randomization, it's infeasible.
* Embed plan IDs into the TXs they create
We need to stop attempting signing if we've already signed a protocol. Ideally,
any one of the participating signers should be able to provide a proof the TX
was successfully signed. We can't just run a second signing protocol though as
a single malicious signer could complete the TX signature, and publish it,
yet not complete the secondary signature.
The TX itself has to be sufficient to show that the TX matches the plan. This
is done by embedding the ID, so matching addresses/amounts plans are
distinguished, and by allowing verification a TX actually matches a set of
addresses/amounts.
For Monero, this will need augmenting with the ephemeral keys (or usage of a
static seed for them).
* Don't use OP_RETURN to encode the plan ID on Bitcoin
We can use the inputs to distinguih identical-output plans without issue.
* Update OP_RETURN data access
It's not required to be the last output.
* Add Eventualities to Monero
An Eventuality is an effective equivalent to a SignableTransaction. That is
declared not by the inputs it spends, yet the outputs it creates.
Eventualities are also bound to a 32-byte RNG seed, enabling usage of a
hash-based identifier in a SignableTransaction, allowing multiple
SignableTransactions with the same output set to have different Eventualities.
In order to prevent triggering the burning bug, the RNG seed is hashed with
the planned-to-be-used inputs' output keys. While this does bind to them, it's
only loosely bound. The TX actually created may use different inputs entirely
if a forgery is crafted (which requires no brute forcing).
Binding to the key images would provide a strong binding, yet would require
knowing the key images, which requires active communication with the spend
key.
The purpose of this is so a multisig can identify if a Transaction the entire
group planned has been executed by a subset of the group or not. Once a plan
is created, it can have an Eventuality made. The Eventuality's extra is able
to be inserted into a HashMap, so all new on-chain transactions can be
trivially checked as potential candidates. Once a potential candidate is found,
a check involving ECC ops can be performed.
While this is arguably a DoS vector, the underlying Monero blockchain would
need to be spammed with transactions to trigger it. Accordingly, it becomes
a Monero blockchain DoS vector, when this code is written on the premise
of the Monero blockchain functioning. Accordingly, it is considered handled.
If a forgery does match, it must have created the exact same outputs the
multisig would've. Accordingly, it's argued the multisig shouldn't mind.
This entire suite of code is only necessary due to the lack of outgoing
view keys, yet it's able to avoid an interactive protocol to communicate
key images on every single received output.
While this could be locked to the multisig feature, there's no practical
benefit to doing so.
* Add support for encoding Monero address to instructions
* Move Serai's Monero address encoding into serai-client
serai-client is meant to be a single library enabling using Serai. While it was
originally written as an RPC client for Serai, apps actually using Serai will
primarily be sending transactions on connected networks. Sending those
transactions require proper {In, Out}Instructions, including proper address
encoding.
Not only has address encoding been moved, yet the subxt client is now behind
a feature. coin integrations have their own features, which are on by default.
primitives are always exposed.
* Reorganize file layout a bit, add feature flags to processor
* Tidy up ETH Dockerfile
* Add Bitcoin address encoding
* Move Bitcoin::Address to serai-client's
* Comment where tweaking needs to happen
* Add an API to check if a plan was completed in a specific TX
This allows any participating signer to submit the TX ID to prevent further
signing attempts.
Also performs some API cleanup.
* Minimize FROST dependencies
* Use a seeded RNG for key gen
* Tweak keys from Key gen
* Test proper usage of Branch/Change addresses
Adds a more descriptive error to an error case in decoys, and pads Monero
payments as needed.
* Also test spending the change output
* Add queued_plans to the Scheduler
queued_plans is for payments to be issued when an amount appears, yet the
amount is currently pre-fee. One the output is actually created, the
Scheduler should be notified of the amount it was created with, moving from
queued_plans to plans under the actual amount.
Also tightens debug_asserts to asserts for invariants which may are at risk of
being exclusive to prod.
* Add missing tweak_keys call
* Correct decoy selection height handling
* Add a few log statements to the scheduler
* Simplify test's get_block_number
* Simplify, while making more robust, branch address handling in Scheduler
* Have fees deducted from payments
Corrects Monero's handling of fees when there's no change address.
Adds a DUST variable, as needed due to 1_00_000_000 not being enough to pay
its fee on Monero.
* Add comment to Monero
* Consolidate BTC/XMR prepare_send code
These aren't fully consolidated. We'd need a SignableTransaction trait for
that. This is a lot cleaner though.
* Ban integrated addresses
The reasoning why is accordingly documented.
* Tidy TODOs/dust handling
* Update README TODO
* Use a determinisitic protocol version in Monero
* Test rebuilt KeyGen machines function as expected
* Use a more robust KeyGen entropy system
* Add DB TXNs
Also load entropy from env
* Add a loop for processing messages from substrate
Allows detecting if we're behind, and if so, waiting to handle the message
* Set Monero MAX_INPUTS properly
The previous number was based on an old hard fork. With the ring size having
increased, transactions have since got larger.
* Distinguish TODOs into TODO and TODO2s
TODO2s are for after protonet
* Zeroize secret share repr in ThresholdCore write
* Work on Eventualities
Adds serialization and stops signing when an eventuality is proven.
* Use a more robust DB key schema
* Update to {k, p}256 0.12
* cargo +nightly clippy
* cargo update
* Slight message-box tweaks
* Update to recent Monero merge
* Add a Coordinator trait for communication with coordinator
* Remove KeyGenHandle for just KeyGen
While KeyGen previously accepted instructions over a channel, this breaks the
ack flow needed for coordinator communication. Now, KeyGen is the direct object
with a handle() function for messages.
Thankfully, this ended up being rather trivial for KeyGen as it has no
background tasks.
* Add a handle function to Signer
Enables determining when it's finished handling a CoordinatorMessage and
therefore creating an acknowledgement.
* Save transactions used to complete eventualities
* Use a more intelligent sleep in the signer
* Emit SignedTransaction with the first ID *we can still get from our node*
* Move Substrate message handling into the new coordinator recv loop
* Add handle function to Scanner
* Remove the plans timer
Enables ensuring the ordring on the handling of plans.
* Remove the outputs function which panicked if a precondition wasn't met
The new API only returns outputs upon satisfaction of the precondition.
* Convert SignerOrder::SignTransaction to a function
* Remove the key_gen object from sign_plans
* Refactor out get_fee/prepare_send into dedicated functions
* Save plans being signed to the DB
* Reload transactions being signed on boot
* Stop reloading TXs being signed (and report it to peers)
* Remove message-box from the processor branch
We don't use it here yet.
* cargo +nightly fmt
* Move back common/zalloc
* Update subxt to 0.27
* Zeroize ^1.5, not 1
* Update GitHub workflow
* Remove usage of SignId in completed
* add monero seed support
* fix some of the pr comments
* remove languages module and unnecessary error returns
* Clean classic seed impl
Fixes a few issues regarding Zeroize usage/API safety. Mainly a cleanup.
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This still sends a fingerprinting flare up if you send to a subaddress which
needs to be fixed. Despite that, Monero no should no longer fail to scan TXs
from monero-serai regarding additional keys.
Previously it failed becuase we supplied one key as THE key, and n-1 as
additional. Monero expects n for additional.
This does correctly select when to use THE key versus when to use the additional
key when sending. That removes the ability for recipients to fingerprint
monero-serai by receiving to a standard address yet needing to use an additional
key.
* Initial work on an In Inherents pallet
* Add an event for when a batch is executed
* Add a dummy provider for InInstructions
* Add in-instructions to the node
* Add the Serai runtime API to the processor
* Move processor tests around
* Build a subxt Client around Serai
* Successfully get Batch events from Serai
Renamed processor/substrate to processor/serai.
* Much more robust InInstruction pallet
* Implement the workaround from https://github.com/paritytech/subxt/issues/602
* Initial prototype of processor generated InInstructions
* Correct PendingCoins data flow for InInstructions
* Minor lint to in-instructions
* Remove the global Serai connection for a partial re-impl
* Correct ID handling of the processor test
* Workaround the delay in the subscription
* Make an unwrap an if let Some, remove old comments
* Lint the processor toml
* Rebase and update
* Move substrate/in-instructions to substrate/in-instructions/pallet
* Start an in-instructions primitives lib
* Properly update processor to subxt 0.24
Also corrects failures from the rebase.
* in-instructions cargo update
* Implement IsFatalError
* is_inherent -> true
* Rename in-instructions crates and misc cleanup
* Update documentation
* cargo update
* Misc update fixes
* Replace height with block_number
* Update processor src to latest subxt
* Correct pipeline for InInstructions testing
* Remove runtime::AccountId for serai_primitives::NativeAddress
* Rewrite the in-instructions pallet
Complete with respect to the currently written docs.
Drops the custom serializer for just using SCALE.
Makes slight tweaks as relevant.
* Move instructions' InherentDataProvider to a client crate
* Correct doc gen
* Add serde to in-instructions-primitives
* Add in-instructions-primitives to pallet
* Heights -> BlockNumbers
* Get batch pub test loop working
* Update in instructions pallet terminology
Removes the ambiguous Coin for Update.
Removes pending/artificial latency for furture client work.
Also moves to using serai_primitives::Coin.
* Add a BlockNumber primitive
* Belated cargo fmt
* Further document why DifferentBatch isn't fatal
* Correct processor sleeps
* Remove metadata at compile time, add test framework for Serai nodes
* Remove manual RPC client
* Simplify update test
* Improve re-exporting behavior of serai-runtime
It now re-exports all pallets underneath it.
* Add a function to get storage values to the Serai RPC
* Update substrate/ to latest substrate
* Create a dedicated crate for the Serai RPC
* Remove unused dependencies in substrate/
* Remove unused dependencies in coins/
Out of scope for this branch, just minor and path of least resistance.
* Use substrate/serai/client for the Serai RPC lib
It's a bit out of place, since these client folders are intended for the node to
access pallets and so on. This is for end-users to access Serai as a whole.
In that sense, it made more sense as a top level folder, yet that also felt
out of place.
* Move InInstructions test to serai-client for now
* Final cleanup
* Update deny.toml
* Cargo.lock update from merging develop
* Update nightly
Attempt to work around the current CI failure, which is a Rust ICE.
We previously didn't upgrade due to clippy 10134, yet that's been reverted.
* clippy
* clippy
* fmt
* NativeAddress -> SeraiAddress
* Sec fix on non-provided updates and doc fixes
* Add Serai as a Coin
Necessary in order to swap to Serai.
* Add a BlockHash type, used for batch IDs
* Remove origin from InInstruction
Makes InInstructionTarget. Adds RefundableInInstruction with origin.
* Document storage items in in-instructions
* Rename serai/client/tests/serai.rs to updates.rs
It only tested publishing updates and their successful acceptance.
* convert AddressSpec subbaddress to tuple
* add wallet-rpc tests
* fix payment id decryption bug
* run fmt
* fix CI
* use monero-rs wallet-rpc for tests
* update the subaddress index type
* fix wallet-rpc CI
* fix monero-wallet-rpc CI actions
* pull latest monero for CI
* fix pr issues
* detach monero wallet rpc
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Not only did we already have multiple booleans in it, yet it theoretically
could expand in the future. Not only is this more explicit, it actually cleans
some existing code.
commit e0a9e8825d6c22c797fb84e26ed6ef10136ca9c2
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Fri Jan 6 04:24:08 2023 -0500
Remove Scanner::address
It either needed to return an Option, panic on misconfiguration, or return a
distinct Scanner type based on burning bug immunity to offer this API properly.
Panicking wouldn't be proper, and the Option<Address> would've been... awkward.
The new register_subaddress function, maintaining the needed functionality,
also provides further clarity on the intended side effect of the previously
present Scanner::address function.
commit 7359360ab2fc8c9255c6f58250c214252ce217a4
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Fri Jan 6 01:35:02 2023 -0500
fmt/clippy from last commit
commit 80d912fc19cd268f3b019a9d9961a48b2c45e828
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Thu Jan 5 19:36:49 2023 -0500
Add Substrate "assets" pallet
While over-engineered for our purposes, it's still usable.
Also cleans the runtime a bit.
commit 2ed2944b6598d75bdc3c995aaf39b717846207de
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Wed Jan 4 23:09:58 2023 -0500
Remove the timestamp pallet
It was needed for contracts, which has since been removed. We now no longer
need it.
commit 7fc1fc2dccecebe1d94cb7b4c00f2b5cb271c87b
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Wed Jan 4 22:52:41 2023 -0500
Initial validator sets pallet (#187)
* Initial work on a Validator Sets pallet
* Update Validator Set docs per current discussions
* Update validator-sets primitives and storage handling
* Add validator set pallets to deny.toml
* Remove Curve from primitives
Since we aren't reusing keys across coins, there's no reason for it to be
on-chain (as previously planned).
* Update documentation on Validator Sets
* Use Twox64Concat instead of Identity
Ensures an even distribution of keys. While xxhash is breakable, these keys
aren't manipulatable by users.
* Add math ops on Amount and define a coin as 1e8
* Add validator-sets to the runtime and remove contracts
Also removes the randomness pallet which was only required by the contracts
runtime.
Does not remove the contracts folder yet so they can still be referred to while
validator-sets is under development. Does remove them from Cargo.toml.
* Add vote function to validator-sets
* Remove contracts folder
* Create an event for the Validator Sets pallet
* Remove old contracts crates from deny.toml
* Remove line from staking branch
* Remove staking from runtime
* Correct VS Config in runtime
* cargo update
* Resolve a few PR comments on terminology
* Create a serai-primitives crate
Move types such as Amount/Coin out of validator-sets. Will be expanded in the
future.
* Fixes for last commit
* Don't reserve set 0
* Further fixes
* Add files meant for last commit
* Remove Staking transfer
commit 3309295911d22177bd68972d138aea2f8658eb5f
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Wed Jan 4 06:17:00 2023 -0500
Reorder coins in README by market cap
commit db5d19cad33ccf067d876b7f5b7cca47c228e2fc
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Wed Jan 4 06:07:58 2023 -0500
Update README
commit 606484d744b1c6cc408382994c77f1def25d3e7d
Author: Luke Parker <lukeparker5132@gmail.com>
Date: Wed Jan 4 03:17:36 2023 -0500
cargo update
commit 3a319b229f
Author: akildemir <aeg_asd@hotmail.com>
Date: Wed Jan 4 16:26:25 2023 +0300
update address public API design
commit d9fa88fa76
Author: akildemir <aeg_asd@hotmail.com>
Date: Mon Jan 2 13:35:06 2023 +0300
fix clippy error
commit cc722e897b
Merge: cafa9b3eeca440
Author: akildemir <aeg_asd@hotmail.com>
Date: Mon Jan 2 11:39:04 2023 +0300
Merge https://github.com/serai-dex/serai into develop
commit cafa9b361e
Author: akildemir <aeg_asd@hotmail.com>
Date: Mon Jan 2 11:38:26 2023 +0300
fix build errors
commit ce5b5f2b37
Merge: f502d6749c4acf
Author: akildemir <aeg_asd@hotmail.com>
Date: Sun Jan 1 15:16:25 2023 +0300
Merge https://github.com/serai-dex/serai into develop
commit f502d67282
Author: akildemir <aeg_asd@hotmail.com>
Date: Thu Dec 22 13:13:09 2022 +0300
fix pr issues
commit 26ffb226d4
Author: akildemir <aeg_asd@hotmail.com>
Date: Thu Dec 22 13:11:43 2022 +0300
remove extraneous rpc call
commit 0e829f8531
Author: akildemir <aeg_asd@hotmail.com>
Date: Thu Dec 15 13:56:53 2022 +0300
add scan tests
commit 5123c7f121
Author: akildemir <aeg_asd@hotmail.com>
Date: Thu Dec 15 13:56:13 2022 +0300
add new address functions & comments
* Standardize the DLEq serialization function naming
They mismatched from the rest of the project.
This commit is technically incomplete as it doesn't update the dkg crate.
* Rewrite DKG encryption to enable per-message decryption without side effects
This isn't technically true as I already know a break in this which I'll
correct for shortly.
Does update documentation to explain the new scheme. Required for blame.
* Add a verifiable system for blame during the FROST DKG
Previously, if sent an invalid key share, the participant would realize that
and could accuse the sender. Without further evidence, either the accuser
or the accused could be guilty. Now, the accuser has a proof the accused is
in the wrong.
Reworks KeyMachine to return BlameMachine. This explicitly acknowledges how
locally complete keys still need group acknowledgement before the protocol
can be complete and provides a way for others to verify blame, even after a
locally successful run.
If any blame is cast, the protocol is no longer considered complete-able
(instead aborting). Further accusations of blame can still be handled however.
Updates documentation on network behavior.
Also starts to remove "OnDrop". We now use Zeroizing for anything which should
be zeroized on drop. This is a lot more piece-meal and reduces clones.
* Tweak Zeroizing and Debug impls
Expands Zeroizing to be more comprehensive.
Also updates Zeroizing<CachedPreprocess([u8; 32])> to
CachedPreprocess(Zeroizing<[u8; 32]>) so zeroizing is the first thing done
and last step before exposing the copy-able [u8; 32].
Removes private keys from Debug.
* Fix a bug where adversaries could claim to be using another user's encryption keys to learn their messages
Mentioned a few commits ago, now fixed.
This wouldn't have affected Serai, which aborts on failure, nor any DKG
currently supported. It's just about ensuring the DKG encryption is robust and
proper.
* Finish moving dleq from ser/deser to write/read
* Add tests for dkg blame
* Add a FROST test for invalid signature shares
* Batch verify encrypted messages' ephemeral keys' PoP
While the previous construction achieved n/2 average detection,
this will run in log2(n). Unfortunately, the need to keep entropy
around (or take in an RNG here) remains.
Technically, non-0-amount outputs can still appear and this considered them
as part of the global 0-amount pool. Now, only outputs which are 0-amount are
counted.
* Remove the explicit included participants from FROST
Now, whoever submits preprocesses becomes the signing set. Better separates
preprocess from sign, at the cost of slightly more annoying integrations
(Monero needs to now independently lagrange/offset its key images).
* Support caching preprocesses
Closes https://github.com/serai-dex/serai/issues/40.
I *could* have added a serialization trait to Algorithm and written a ton of
data to disk, while requiring Algorithm implementors also accept such work.
Instead, I moved preprocess to a seeded RNG (Chacha20) which should be as
secure as the regular RNG. Rebuilding from cache simply loads the previously
used Chacha seed, making the Algorithm oblivious to the fact it's being
rebuilt from a cache. This removes any requirements for it to be modified
while guaranteeing equivalency.
This builds on the last commit which delayed determining the signing set till
post-preprocess acquisition. Unfortunately, that commit did force preprocess
from ThresholdView to ThresholdKeys which had visible effects on Monero.
Serai will actually need delayed set determination for #163, and overall,
it remains better, hence it's inclusion.
* Document FROST preprocess caching
* Update ethereum to new FROST
* Fix bug in Monero offset calculation and update processor
A type alias of MoneroAddress is provided to abstract away the generic.
To keep the rest of the library sane, MoneroAddress is used everywhere.
If someone wants to use this library with another coin, they *should* be
able to parse a custom address and then recreate it as a Monero address.
While that's annoying to them, better them than any person using this
lib for Monero.
Closes#152.
* Add dkg crate
* Remove F_len and G_len
They're generally no longer used.
* Replace hash_to_vec with a provided method around associated type H: Digest
Part of trying to minimize this trait so it can be moved elsewhere. Vec,
which isn't std, may have been a blocker.
* Encrypt secret shares within the FROST library
Reduces requirements on callers in order to be correct.
* Update usage of Zeroize within FROST
* Inline functions in key_gen
There was no reason to have them separated as they were. sign probably
has the same statement available, yet that isn't the focus right now.
* Add a ciphersuite package which provides hash_to_F
* Set the Ciphersuite version to something valid
* Have ed448 export Scalar/FieldElement/Point at the top level
* Move FROST over to Ciphersuite
* Correct usage of ff in ciphersuite
* Correct documentation handling
* Move Schnorr signatures to their own crate
* Remove unused feature from schnorr
* Fix Schnorr tests
* Split DKG into a separate crate
* Add serialize to Commitments and SecretShare
Helper for buf = vec![]; .write(buf).unwrap(); buf
* Move FROST over to the new dkg crate
* Update Monero lib to latest FROST
* Correct ethereum's usage of features
* Add serialize to GeneratorProof
* Add serialize helper function to FROST
* Rename AddendumSerialize to WriteAddendum
* Update processor
* Slight fix to processor
* Create message types for FROST key gen
Taking in reader borrows absolutely wasn't feasible. Now, proper types
which can be read (and then passed directly, without a mutable borrow)
exist for key_gen. sign coming next.
* Move FROST signing to messages, not Readers/Writers/Vec<u8>
Also takes the nonce handling code and makes a dedicated file for it,
aiming to resolve complex types and make the code more legible by
replacing its previously inlined state.
* clippy
* Update FROST tests
* read_signature_share
* Update the Monero library to the new FROST packages
* Update processor to latest FROST
* Tweaks to terminology and documentation
Unbeknowst to me, height doesn't have a universal definition of the
chain length.
Bitcoin defines height as the block number, with getblockcount existing
for the chain length.
Ethereum uses the unambiguous term "block number".
Monero defines height as both the block number and the chain length.
Instead of arguing about who's right, it's agreed it referring to both
isn't productive. While we could provide our own definition, taking a
side, moving to the unambiguous block number prevents future hiccups.
height is now only a term in the Monero code, where it takes its
Monero-specific definition, as documented in the processor.
* Label the version as an alpha
* Add versions to Cargo.tomls
* Update to Zeroize 1.5
* Drop patch versions from monero-serai Cargo.toml
* Add a repository field
* Move generators to OUT_DIR
IIRC, I didn't do this originally as it constantly re-generated them.
Unfortunately, since cargo is complaining about .generators, we have to.
* Remove Timelock::fee_weight
Transaction::fee_weight's has a comment, "Assumes Timelock::None since
this library won't let you create a TX with a timelock". Accordingly,
this is dead code.
Despite being slower and only used for blinding values, its still
extremely performant. 20 is far more standard and will avoid an eye
raise from reviewers.
There is a slight note we only implement u64 varint's, while Monero does
it for arbitrary uints, yet that's not relevant at this time. It is
documented in #25.
Creates a new monero-generators crate so the monero crate can run the
code in question at build time.
Saves several seconds from running the tests.
Closes https://github.com/serai-dex/serai/issues/101.
* Apply Zeroize to nonces used in Bulletproofs
Also makes bit decomposition constant time for a given amount of
outputs.
* Fix nonce reuse for single-signer CLSAG
* Attach Zeroize to most structures in Monero, and ZOnDrop to anything with private data
* Zeroize private keys and nonces
* Merge prepare_outputs and prepare_transactions
* Ensure CLSAG is constant time
* Pass by borrow where needed, bug fixes
The past few commitments have been one in-progress chunk which I've
broken up as best read.
* Add Zeroize to FROST structs
Still needs to zeroize internally, yet next step. Not quite as
aggressive as Monero, partially due to the limitations of HashMaps,
partially due to less concern about metadata, yet does still delete a
few smaller items of metadata (group key, context string...).
* Remove Zeroize from most Monero multisig structs
These structs largely didn't have private data, just fields with private
data, yet those fields implemented ZeroizeOnDrop making them already
covered. While there is still traces of the transaction left in RAM,
fully purging that was never the intent.
* Use Zeroize within dleq
bitvec doesn't offer Zeroize, so a manual zeroing has been implemented.
* Use Zeroize for random_nonce
It isn't perfect, due to the inability to zeroize the digest, and due to
kp256 requiring a few transformations. It does the best it can though.
Does move the per-curve random_nonce to a provided one, which is allowed
as of https://github.com/cfrg/draft-irtf-cfrg-frost/pull/231.
* Use Zeroize on FROST keygen/signing
* Zeroize constant time multiexp.
* Correct when FROST keygen zeroizes
* Move the FROST keys Arc into FrostKeys
Reduces amount of instances in memory.
* Manually implement Debug for FrostCore to not leak the secret share
* Misc bug fixes
* clippy + multiexp test bug fixes
* Correct FROST key gen share summation
It leaked our own share for ourself.
* Fix cross-group DLEq tests
Considering they take 7 seconds to generate, thanks to #68, the ability
to generate them at the start instead of on first BP is greatly
appreciated.
Also performs minor cleanups regarding BPs.
* Use a struct in an enum for Bulletproofs
* verification bp working for just one proof
* add some more assert tests
* Clean BP verification
* Implement batch verification
* Add a debug assertion w_cache isn't 0
It's initially set to 0 and if not updated, this would be broken.
* Correct Monero workflow yaml
* Again try to corrent Monero workflow yaml
* Again
* Finally
* Re-apply weights as required by Bulletproofs
Removing these was insecure and my fault.
Co-authored-by: DangerousFreedom <dangfreed@tutanota.com>