-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
renaud dubois
authored and
renaud dubois
committed
Nov 25, 2024
1 parent
58b6479
commit f2c00ec
Showing
968 changed files
with
180,098 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# SmoothCryptoLib (SCL) | ||
A Cryptographic Library for Smooth Blockchain uses. | ||
|
||
|
||
## Compilation | ||
|
||
Clone the repository, then type `forge test`. (Some troubles are solved running `foundryup` and `forge init --force`) | ||
|
||
## Deployment | ||
|
||
Run deploy.sh to deploy the code on a target chain. | ||
The values `$RPC` and `$CHAINID` shall be set to the chain ones. | ||
The toy private and public key shall be replaced and funded (current can be used for testnet). | ||
|
||
|
||
|
||
## Benchmarks | ||
|
||
|
||
### Forge results | ||
|
||
The benchmarks are performed by averaging forge results over a loop of 100 tests. Be sure to avoid the use of -via-IR and set foundry.toml correctly to reproduce correct measurements. | ||
|
||
| curve | Function | gas | Comment | File| | ||
|--------:|---------|:--:|:----|:----| | ||
| P256 | SCL_ECDSAB4.verify | 159K | ECDSA using RIP7696 (second opcode) | libSCL_ECDSAb4.sol | | ||
|| | | || | ||
|
||
|
||
|
||
### Onchain results | ||
|
||
|
||
| PR # | Create2 | Mainnets | Testnets | | ||
|--------:|---------|:--:|:----| | ||
|[N/A](https://github.com/rdubois-crypto/FreshCryptoLib/pull/46)| 0x05eFAC4C53Ec12F11f144d0a0D18Df6dfDf83409 | | [Sepolia](https://sepolia.etherscan.io/address/0x05eFAC4C53Ec12F11f144d0a0D18Df6dfDf83409#code) ,[Optimism](https://sepolia.etherscan.io/address/0x05eFAC4C53Ec12F11f144d0a0D18Df6dfDf83409#code) | | ||
|| | | | | ||
|
||
|
||
|
||
# Audits | ||
|
||
The results of the completed audits are in the doc/audit folder. | ||
|
||
|
||
| Team | branch | Target |status |Residual risks| | ||
|--------:|---------|:---------|:---------|:--:| | ||
| [CryptoExperts](https://github.com/get-smooth/crypto-lib/tree/main/doc/Audits) | CryptoExperts |P256 | Completed | 0| | ||
| [Veridise](https://github.com/get-smooth/crypto-lib/tree/main/doc/Audits) | Veridise |P256, Ed25519 | Completed | 0 | | ||
| [Formal Land](https://github.com/formal-land/coq-of-solidity/tree/guillaume-claret%40experiments-verification-mulmuladdX_fullgen_b4/coq/CoqOfSolidity/contracts/scl/mulmuladdX_fullgen_b4)| Veridise | RIP7696 | Partial Proving | 0 | | ||
|
||
CryptoExperts and Veridise audits consisted in human auditing of the code. Formal Land conducted a partial formal verification of the code. Due to its mathematical complexity, the perimeter was restricted to ecAddn2, ecDblNeg and scalar extraction. | ||
See [here](https://github.com/formal-land/coq-of-solidity/tree/guillaume-claret%40experiments-verification-mulmuladdX_fullgen_b4/coq/CoqOfSolidity/contracts/scl/mulmuladdX_fullgen_b4) for the coq proof of the library. | ||
|
||
We are also grateful to Guido (https://github.com/guidovranken) which notice by its independant (and amazing) Fuzzing work that our weak keys testing was incorrect. | ||
|
||
# Curves implementation status | ||
|
||
|
||
|
||
| curve | status | branch | Comment | File| | ||
|--------:|---------|:--:|:----|:----| | ||
| P256 | OK | main | ECDSA using RIP7696 (first opcode) | libSCL_7212.sol | | ||
| P256 | OK | main | ECDSA using RIP7696 (second opcode) | libSCL_ECDSAb4.sol | | ||
| Ed25519| OK | main | EDDSA using RIP7696 (first opcode) with isogenies | libSCL_RIP6565.sol || | ||
|
||
# Acknowledments | ||
|
||
The following work has been half-funded by the Ethereum Fundation grant number FY24-1386: | ||
* ed25519 solidity (libSCL_RIP6565.sol ) | ||
|
||
SCL is build by the same team of the previous FCL. As such all previous contributors are credited. | ||
|
||
# Our work in Production | ||
|
||
Prior to SCL implementation, our experimental library FCL is still in production in various environments: | ||
|
||
* Base Smart Wallet: fast onboarding using FCL: https://www.smart-wallet.xyz/, deployed at 0x0BA5ED0c6AA8c49038F819E587E2633c4A9F428a (Base main and Sepolia) | ||
* Cometh Connect: https://github.com/cometh-hq/p256-signer/blob/79d58bc619109a069e212d54a18744d3803731bc/contracts/P256Signer.sol | ||
* Metamask Delegation Toolkit https://github.com/MetaMask/delegation-framework/blob/635f717372f58a2b338964ba8e3de4ad285c9a47/src/libraries/P256FCLVerifierLib.sol | ||
* Safe : https://github.com/safe-global/safe-modules/tree/main/modules/passkey/contracts/vendor/FCL | ||
|
||
|
||
## License | ||
License: This software is licensed under MIT License (see LICENSE FILE at root directory of project). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
# SmoothCryptoLib (SCL) | ||
A Cryptographic Library for Smooth Blockchain uses. | ||
|
||
This repository is a private fork of the audited SCL. In addition to SCL generic ECC solidity, | ||
it contains the actual experiments around Musig2 and FROST. | ||
|
||
|
||
## Description | ||
|
||
The aim of the Smooth-LibMPC is to provide an open source implementation of | ||
- Musig2: is a MPC scriptless algorithm, specified in BIP327, it is part of Taproot and enables n out of n signature, | ||
- Atomic Swaps: use adaptator signatures to enable trustless bridges, requires Musig2, | ||
- FROST is a threshold signature scheme (k out of n), which enables governance, without requiring to deploy on chain contract, providing more privacy on the governance. | ||
|
||
|
||
The SmoothMPCLib consists in two parts: | ||
- An onchain solidity verifier, implemented in libSCL_BIP327.sol as part of SCL (Smoo.th Crypto Lib) | ||
- A javascript implementation of signer side to be integrated into any webApp leveraging the targeted protocol. | ||
|
||
|
||
### Implementation status | ||
|
||
|
||
|
||
| Protocol | status | branch | Comment | File| | ||
|--------:|---------|:--:|:----|:----| | ||
| Onchain Verifier | OK | main | | libSCL_BIP327.sol | | ||
| Musig2-secp256k1 | OK | main | | bip327.mjs | | ||
| Musig2-ed25519 | TBD | - | | | | ||
| Atomic Swaps | In progress | - | | SCL_atomic_swaps.mjs | | ||
| Frost| TBD | - | | | | ||
| | ||
|
||
|
||
|
||
## Installation | ||
|
||
|
||
### Javascript (signer) library | ||
|
||
It is necessary to install noble-curves, which the library is based on for the elliptic primitives function. | ||
|
||
`npm install @noble/curves` | ||
|
||
Test of BIP327 can be run typing `node test_bip327.mjs`. | ||
The test includes the BIP327 test vectors, enforcing compatibility of the signer with BTC, and any 4337/7702 integrating the libSCL_BIP327.sol verifier. | ||
|
||
### Compile Solidity lib | ||
Clone the repository, then type `forge test`. (Some troubles are solved running `foundryup` and `forge init --force`). | ||
|
||
|
||
# Performing a Multisignature with libMPC Musig2 | ||
|
||
|
||
A 2 of 2 session is described here. It generalizes identically with larger user set. | ||
We use BIP327 with no tweak. | ||
|
||
Prior to any use, an object of type SCL_Musig2 must be initialized with one of the supported curve. | ||
|
||
``` | ||
const curve = 'secp256k1'; | ||
const signer = new SCL_Musig2(curve); | ||
``` | ||
|
||
|
||
### Key generation and aggregation | ||
|
||
First, user1 and user2 generates their private key, or import them from seed. | ||
``` | ||
const sk1=secp256k1.utils.randomPrivateKey();//this provides a 32 bytes array | ||
const sk2=secp256k1.utils.randomPrivateKey(); | ||
``` | ||
|
||
Corresponding aggregated key is derived from public keys: | ||
``` | ||
const pubK1=signer.IndividualPubKey_array(sk1); | ||
const pubK2=signer.IndividualPubKey_array(sk2); | ||
let aggpk = signer.Key_agg(pubkeys)[0];//here aggpk is a 33 bytes compressed public key | ||
let x_aggpk=aggpk.slice(1,33);//x-only version for noncegen | ||
``` | ||
(of course in practice derivation occurs separately in each signer secure domain) | ||
|
||
|
||
### Signature session | ||
|
||
Assuming user generated their public key according to previous section, they now want to jointly sign a message `msg`. An example session is provided [here](https://github.com/rdubois-crypto/UnruggableWallet/blob/66b84ec4f807919dd443907463318fac0ac1b5f5/src/libMPC/test_bip327.mjs#L290). | ||
|
||
#### Round 1 | ||
In first round, user1 and user2 generates public and secret nonces. Public are shared, secret keep in respective secure domain. | ||
|
||
``` | ||
const nonce1=signer.Nonce_gen_internal(rand1, sk1, pubK1, x_aggpk, msg, Buffer.from("00000000", 'hex')); | ||
const nonce2=signer.Nonce_gen_internal(rand2, sk2, pubK2, x_aggpk, msg, Buffer.from("00000000", 'hex')); | ||
let aggnonce = signer.Nonce_agg([nonce1[1].toString('hex'), nonce2[1].toString('hex')]); | ||
``` | ||
|
||
#### Round 2 | ||
In second round, each user computes its partial signature, which are then aggregated and broadcast on chain: | ||
|
||
``` | ||
const tweaks=[]; | ||
const session_ctx=[aggnonce, pubkeys, [], [], msg]; | ||
let p1=signer.Psign(nonce1[0], sk1, session_ctx); | ||
let p2=signer.Psign(nonce2[0], sk2, session_ctx); | ||
let psigs=[p1,p2]; | ||
let res=signer.Partial_sig_agg(psigs, session_ctx); | ||
``` | ||
res is the final results to push onchain. One can check the correctness in front before pushing the results: | ||
|
||
``` | ||
let check=signer.Schnorr_verify(msg, x_aggpk, res); | ||
console.log("check=", check); | ||
``` | ||
|
||
# Performing an atomic swap | ||
|
||
The description doesn't include the timelock on both chains, which cancel the deposits if Alice and Bob didn't succeed in their withdrawal. | ||
Abortion of one of the participant is the only way the protocol shall fail, which is resolved by the timelock condition of withdrawal. | ||
By convention chain1 is the chain with the lowest `chainID`. | ||
|
||
|
||
The sequencing of a Musig2 based atomic swap session is as follow: | ||
- Alice and Bob owns respective key pairs $(sk_a, Q_A)$ and $(sk_b, Q_B)$ | ||
- $P$ is the multisig public key computed with `key_agg`, | ||
- A sends 1 token to AB **on chain 2**, B sends 1 token to AB **on chain 1**, both are timelocked (refund if protocol fails), | ||
- A and B agrees offchain on R1 and R2 using `nonce_gen_internal` and `nonce_agg`. First nonce R1 is used for chain1, second R2 for chain2. Corresponding Alice and Bob secnonces are denoted as rA1, rA2, rB1, rB2. | ||
- A chooses a random tweak t, and computes the tweaked partial signature with `psign` then using t as tweak adaptator: | ||
* Alice signs and broadcast off chain $T=tG$, $s'_A1=(t+ra_1)G+H(R, P, m_1)sk_A$, where $m_1$ is the transaction sending coins from AB to A using `psign_adapt`. t is kept secret by Alice. | ||
* Using the same $t, T$, alice signs and broadcast off chain $s'A2=(t+ra_2)G+H(R, P, m_2)sk_A$ where $m_2$ is the transaction sending coins from AB to B. | ||
- B checks the compliance of $T, s'_A1, s'_A2$ using `atomic_check` | ||
- B signs and broadcast off chain partial signature $s_B1=rb.G+H(P,R,m_1)P_B$ with `psign` | ||
- knowing $t, S_A1, S_B1$ A computes $S_{AB}$ the Musig2 signatures of $m_1$ using `sign_untweak`, and broadcast it **on chain** 1. | ||
- B reads the value $S_{AB}$ on chain 1, learns t, then broadcast **on chain 2** $S_{AB}(m_2)$ using `sign_untweak` on chain 2 to unlock its token. | ||
|
||
Note: the protocol requires to broadcast onchain 4 values (2 locked tokens, then two unlocking signatures). | ||
|
||
### Improving privacy | ||
|
||
- $P_A, P_B$ and $P_{AB}$ might differ on chain 1 and 2. | ||
- Using a zk-proof of Discrete Log, it is possible to use a different curve on chain1 and chain2. | ||
|
||
### Improving security | ||
|
||
The element $t$ shall be as protected as a secret key, to prevent $B$ from stealing $A$ token. In the description, Alice has more duty regarding to the protection of this secret. | ||
|
||
|
||
|
||
|
||
# Product Roadmap | ||
|
||
- Musig2 can be used to provide protection against trappoored hardware [as explained here](https://docs.google.com/presentation/d/10JmRVq9qeoIouLyzIOMcMLnfQQbZlZoSP5eTOyXYUdI/edit#slide=id.g2bf9c14683d_1_265). Using Musig2 with account abstraction, it is possible to have a companion app handling a first key, the hardware wallet a second. | ||
- Atomic swaps enables trustless bridging between non EVM chains. We are gonna use this library to provide trustless bridge with EVM, Starknet and BTC, and later with Cosmos and Solana using the Ed25519 version. | ||
- FROST can be used to make an invisible governance in a Vault application. While SCL passkey module (using 7212) makes traditional single owner invisible, using FROST, it is the Safe itself that can be concealed. | ||
|
||
|
||
|
||
|
||
|
||
# Similar work | ||
|
||
Since the publication of our roadmap, | ||
|
||
## References | ||
https://github.com/BlockstreamResearch/scriptless-scripts/blob/a8b6ff21fc7f4529eabbe639fbff49f047a3579d/md/musig2-adaptorsig.md | ||
https://github.com/BlockstreamResearch/scriptless-scripts/blob/master/md/atomic-swap.md | ||
https://eprint.iacr.org/2021/150.pdf | ||
|
||
# Relation with Prior work | ||
|
||
While ecrecover enables an efficient implementation of Schnorr signatures, there is no trivial way to implement atomic swaps with Solana and Cosmos ecosystems. RIP7696 genericity solves the need for ed25519, avoiding to use complex zk-proof to prove discrete log equivalence. | ||
|
||
|
||
## Acknowledgment | ||
|
||
|
||
|
||
## License | ||
License: This software is licensed under MIT License (see LICENSE FILE at root directory of project). |
Oops, something went wrong.