Skip to content

Commit

Permalink
core: Splits onchain and offchain functionality into different modules
Browse files Browse the repository at this point in the history
  • Loading branch information
pmerkleplant authored May 4, 2024
1 parent 1470b15 commit 11c6c53
Show file tree
Hide file tree
Showing 41 changed files with 1,131 additions and 1,612 deletions.
38 changes: 22 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,28 @@

```ml
src
├─ common
│ ├─ Random - "Access to cryptographically secure randomness"
│ ├─ Message - "Functionality for constructing Ethereum Signed Message Hashes"
│ └─ Nonce - "Deterministic nonce derivation"
├─ secp256k1
│ ├─ Secp256k1 - "Cryptography-related functionality for the secp256k1 elliptic curve"
│ ├─ Secp256k1Arithmetic — "Arithmetic-related functionality for the secp256k1 elliptic curve"
│ ├─ signatures
│ │ ├─ ECDSA — "ECDSA signature functionality for secp256k1"
│ │ └─ Schnorr — "Schnorr signature functionality for secp256k1"
│ └─ stealth-addresses
│ └─ ERC5564 - "ERC-5564 conforming stealth addresses for secp256k1"
└─ interfaces
├─ IERC5564Announcer - "ERC-5564 stealth address announcement interface"
└─ IERC5564Registry - "ERC-5564 stealth meta address registry interface"
├─ onchain
│ ├─ common
│ │ ├─ Message - "Functionality for constructing Ethereum Signed Message Hashes"
│ │ └─ Nonce - "Deterministic nonce derivation"
│ └─ secp256k1
│ ├─ Secp256k1 - "Cryptography-related functionality for the secp256k1 elliptic curve"
│ ├─ Secp256k1Arithmetic — "Arithmetic-related functionality for the secp256k1 elliptic curve"
│ └─ signatures
│ ├─ ECDSA — "ECDSA signature functionality for secp256k1"
│ └─ Schnorr — "Schnorr signature functionality for secp256k1"
├─ offchain
│ ├─ common
│ │ └─ RandomOffchain - "Access to cryptographically secure randomness"
│ └─ secp256k1
│ ├─ Secp256k1Offchain - "Cryptography-related functionality for the secp256k1 elliptic curve"
│ └─ signatures
│ ├─ ECDSAOffchain — "ECDSA signature functionality for secp256k1"
│ └─ SchnorrOffchain — "Schnorr signature functionality for secp256k1"
└─ unsafe
└─ secp256k1
└─ signatures
└─ ECDSAUnsafe — "Unsafe ECDSA signature functionality for secp256k1"
```

## Installation
Expand All @@ -45,7 +52,6 @@ Several examples are provided in [`examples/`](./examples), such as:
- secure key pair and Ethereum address creation
- secp256k1 point arithmetic
- Schnorr and ECDSA signature creation and verification
- private ETH transfer via stealth addresses

## Contributing

Expand Down
1 change: 0 additions & 1 deletion docs/secp256k1/signatures/Schnorr.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ Schnorr signatures provide a number of advantages compared to ECDSA signatures:
- `Pk :: Secp256k1::PublicKey` - The signer's public key, ie `[sk]G`
- `m :: bytes32` - The keccak256 hash digest to sign


## Signature Creation

1. Derive a cryptographically secure nonce from `m` and `sk`.
Expand Down
28 changes: 28 additions & 0 deletions examples/common/Random.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity ^0.8.16;

import {Script} from "forge-std/Script.sol";
import {console2 as console} from "forge-std/console2.sol";

import {RandomOffchain} from "src/offchain/common/RandomOffchain.sol";

/**
* @title RandomExample
*
* @dev Run via:
*
* ```bash
* $ forge script examples/common/Random.sol:RandomExample -vvvv
* ```
*/
contract RandomExample is Script {
function run() public {
// Create random uint.
uint rand = RandomOffchain.readUint();
console.log("Random uint: ", rand);

// Bound to smaller type via discarding higher-order bits.
uint8 randByte = uint8(rand);
console.log("Random byte: ", randByte);
}
}
18 changes: 12 additions & 6 deletions examples/secp256k1/Secp256k1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ pragma solidity ^0.8.16;
import {Script} from "forge-std/Script.sol";
import {console2 as console} from "forge-std/console2.sol";

import {Secp256k1, SecretKey, PublicKey} from "src/secp256k1/Secp256k1.sol";
import {Secp256k1Offchain} from "src/offchain/secp256k1/Secp256k1Offchain.sol";
import {
Secp256k1,
SecretKey,
PublicKey
} from "src/onchain/secp256k1/Secp256k1.sol";
import {
Secp256k1Arithmetic,
Point,
ProjectivePoint
} from "src/secp256k1/Secp256k1Arithmetic.sol";
} from "src/onchain/secp256k1/Secp256k1Arithmetic.sol";

/**
* @title Secp256k1Example
Expand All @@ -24,22 +29,23 @@ import {
* regarding unused variables.
*/
contract Secp256k1Example is Script {
using Secp256k1Offchain for SecretKey;
using Secp256k1Offchain for PublicKey;
using Secp256k1 for SecretKey;
using Secp256k1 for PublicKey;

using Secp256k1Arithmetic for Point;

function run() public {
// Create new cryptographically sound secret key.
SecretKey sk = Secp256k1.newSecretKey();
assert(sk.isValid());
SecretKey sk = Secp256k1Offchain.newSecretKey();
// assert(sk.isValid());
console.log("Created new secret key:");
console.log(sk.asUint());
console.log("");

// Derive public key.
PublicKey memory pk = sk.toPublicKey();
assert(pk.isValid());
// assert(pk.isValid());
console.log("Derived public key:");
console.log(pk.toString());
console.log("");
Expand Down
25 changes: 17 additions & 8 deletions examples/secp256k1/signatures/ECDSA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ pragma solidity ^0.8.16;
import {Script} from "forge-std/Script.sol";
import {console2 as console} from "forge-std/console2.sol";

import {Secp256k1, SecretKey, PublicKey} from "src/secp256k1/Secp256k1.sol";
import {Secp256k1Offchain} from "src/offchain/secp256k1/Secp256k1Offchain.sol";
import {
Secp256k1,
SecretKey,
PublicKey
} from "src/onchain/secp256k1/Secp256k1.sol";

import {ECDSA, Signature} from "src/secp256k1/signatures/ECDSA.sol";
import {ECDSAOffchain} from
"src/offchain/secp256k1/signatures/ECDSAOffchain.sol";
import {ECDSA, Signature} from "src/onchain/secp256k1/signatures/ECDSA.sol";

/**
* @title ECDSAExample
Expand All @@ -18,9 +25,13 @@ import {ECDSA, Signature} from "src/secp256k1/signatures/ECDSA.sol";
* ```
*/
contract ECDSAExample is Script {
using Secp256k1Offchain for SecretKey;
using Secp256k1Offchain for PublicKey;
using Secp256k1 for SecretKey;
using Secp256k1 for PublicKey;

using ECDSAOffchain for SecretKey;
using ECDSAOffchain for Signature;
using ECDSA for address;
using ECDSA for SecretKey;
using ECDSA for PublicKey;
Expand All @@ -30,8 +41,8 @@ contract ECDSAExample is Script {
bytes memory message = bytes("crysol <3");

// Create new cryptographically sound secret key.
SecretKey sk = Secp256k1.newSecretKey();
assert(sk.isValid());
SecretKey sk = Secp256k1Offchain.newSecretKey();
// assert(sk.isValid());

// Sign message via ECDSA.
Signature memory sig = sk.sign(message);
Expand All @@ -40,10 +51,8 @@ contract ECDSAExample is Script {
console.log("");

// Verify signature via public key or address.
PublicKey memory pk = sk.toPublicKey();
require(sk.toPublicKey().verify(message, sig), "Signature invalid");
address addr = pk.toAddress();
require(addr.verify(message, sig), "Signature invalid");
// assert(sk.toPublicKey().verify(message, sig));
// assert(sk.toPublicKey().toAddress().verify(message, sig));

// Default serialization (65 bytes).
console.log("Default encoded signature:");
Expand Down
29 changes: 21 additions & 8 deletions examples/secp256k1/signatures/Schnorr.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@ pragma solidity ^0.8.16;
import {Script} from "forge-std/Script.sol";
import {console2 as console} from "forge-std/console2.sol";

import {Secp256k1, SecretKey, PublicKey} from "src/secp256k1/Secp256k1.sol";

import {Schnorr, Signature} from "src/secp256k1/signatures/Schnorr.sol";
import {Secp256k1Offchain} from "src/offchain/secp256k1/Secp256k1Offchain.sol";
import {
Secp256k1,
SecretKey,
PublicKey
} from "src/onchain/secp256k1/Secp256k1.sol";

import {SchnorrOffchain} from
"src/offchain/secp256k1/signatures/SchnorrOffchain.sol";
import {
Schnorr, Signature
} from "src/onchain/secp256k1/signatures/Schnorr.sol";

/**
* @title SchnorrExample
Expand All @@ -18,9 +27,14 @@ import {Schnorr, Signature} from "src/secp256k1/signatures/Schnorr.sol";
* ```
*/
contract SchnorrExample is Script {
using Secp256k1Offchain for SecretKey;
using Secp256k1Offchain for PublicKey;
using Secp256k1 for SecretKey;
using Secp256k1 for PublicKey;

using SchnorrOffchain for Signature;
using SchnorrOffchain for SecretKey;
using SchnorrOffchain for PublicKey;
using Schnorr for SecretKey;
using Schnorr for PublicKey;
using Schnorr for Signature;
Expand All @@ -29,18 +43,17 @@ contract SchnorrExample is Script {
bytes memory message = bytes("crysol <3");

// Create a cryptographically secure secret key.
SecretKey sk = Secp256k1.newSecretKey();
assert(sk.isValid());
SecretKey sk = Secp256k1Offchain.newSecretKey();
// assert(sk.isValid());

// Create Schnorr signature.
Signature memory sig = sk.sign(message);
assert(!sig.isMalleable());
// assert(!sig.isMalleable());
console.log("Signed message via Schnorr, signature:");
console.log(sig.toString());
console.log("");

// Verify signature.
PublicKey memory pk = sk.toPublicKey();
require(pk.verify(message, sig), "Could not verify own signature");
// assert(sk.toPublicKey().verify(message, sig));
}
}
99 changes: 0 additions & 99 deletions examples/secp256k1/stealth-addresses/ERC5564.sol

This file was deleted.

8 changes: 1 addition & 7 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ evm_version = "shanghai"
solc_version = "0.8.24"
via_ir = false
optimizer = false
optimizer_runs = 100_000
extra_output_files = ["irOptimized"]

[fmt]
Expand All @@ -20,12 +19,6 @@ number_underscore = "preserve"
[doc]
out = "docs_generated" # Note to not overwrite own docs

# Profile to compile without --via-ir and optimizations
# Run via `FOUNDRY_PROFILE=light forge ...`
[profile.light]
via_ir = false
optimizer = false

# Profile to compile with --via-ir and optimizations
# Run via `FOUNDRY_PROFILE=release forge ...`
[profile.release]
Expand All @@ -46,5 +39,6 @@ optimizer = true
optimizer_runs = 100_000
[profile.ci.fuzz]
runs = 10_000
max_test_rejects = 4_294_967_295
[profile.ci.invariant]
runs = 10_000
Loading

0 comments on commit 11c6c53

Please sign in to comment.