Skip to content

Commit

Permalink
Simplify to only support secp256k1 but with extended type security
Browse files Browse the repository at this point in the history
  • Loading branch information
pmerkleplant authored Oct 15, 2024
1 parent f7d6034 commit 6b36e08
Show file tree
Hide file tree
Showing 57 changed files with 2,412 additions and 4,295 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/solc-version-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ jobs:
- name: Run forge tests against lowest and highest supported solc version
run: >
forge test --use 0.8.16 &&
forge test --use 0.8.27
forge test --use 0.8.28
22 changes: 7 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,9 @@ test-summary: ## Print summary of test suite
@forge test --summary --show-progress

.PHONY: coverage
coverage: ## Update coverage report and open lcov web interface
@rm -rf coverage
coverage: ## Update coverage report and print summary
@forge coverage --report lcov
@genhtml --branch-coverage --output "coverage" lcov.info
@open coverage/index.html
@forge coverage --report summary

# Note that ripgrep instead of grep is used.
# See https://github.com/BurntSushi/ripgrep.
Expand All @@ -49,31 +47,25 @@ examples: ## Run examples
@echo "## Random"
@echo "##"
@echo "########################################"
@forge script examples/common/Random.sol:RandomExample -v
@forge script examples/Random.sol:RandomExample -v
@echo "########################################"
@echo "##"
@echo "## Secp256k1"
@echo "##"
@echo "########################################"
@forge script examples/secp256k1/Secp256k1.sol:Secp256k1Example -v
@forge script examples/Secp256k1.sol:Secp256k1Example -v
@echo "########################################"
@echo "##"
@echo "## Secp256r1"
@echo "## ECDSA"
@echo "##"
@echo "########################################"
@forge script examples/secp256r1/Secp256r1.sol:Secp256r1Example -v
@echo "########################################"
@echo "##"
@echo "## ECDSA on secp56k1"
@echo "##"
@echo "########################################"
@forge script examples/secp256k1/signatures/ECDSA.sol:ECDSAExample -v
@forge script examples/signatures/ECDSA.sol:ECDSAExample -v
@echo "########################################"
@echo "##"
@echo "## Schnorr (ERC-XXX)"
@echo "##"
@echo "########################################"
@forge script examples/secp256k1/signatures/Schnorr.sol:SchnorrExample -v
@forge script examples/signatures/Schnorr.sol:SchnorrExample -v

.PHONY: fmt
fmt: ## Format project
Expand Down
106 changes: 56 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,44 @@

<h1>crysol</h1>

<a href="">[![Unit Tests][tests-shield]][tests-shield-url]</a>
<a href="">[![Tests][tests-shield]][tests-shield-url]</a>
<a href="">![Apache2/MIT licensed][license-shield]</a>
<a href="">[![Solidity][solidity-shield]][solidity-shield-url]</a>

</div>

`crysol` is a collection of **pure Solidity** libraries providing **elliptic curve cryptography** for **on- and offchain operations**.
`crysol` is a $secp256k1$ elliptic curve library for EVM applications. It targets security, correctness, simplicity, readability, and reviewability as its primary goals.

Features:
- Key generation, verification and de/serialization
- ECDSA and Schnorr signature generation, verification and de/serialization
- Point arithmetic based on complete addition formulas and `ecrecover` precompile optimizations
- Prime field arithmetic
- Secure, simple and stable interfaces

For usage examples, see [`examples/`](./examples).

## Libraries

```ml
src
├─ onchain
│ ├─ common
│ │ ├─ Message - "Functionality for constructing Ethereum Signed Message Hashes"
│ │ ├─ Nonce - "Deterministic nonce derivation"
│ │ └─ ModularArithmetic - "Provides modular arithmetic functionality"
│ ├─ 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"
│ └─ secp256r1
│ ├─ Secp256r1 - "Cryptography-related functionality for the secp256r1 elliptic curve"
│ └─ Secp256r1Arithmetic — "Arithmetic-related functionality for the secp256r1 elliptic curve"
├─ 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"
├─ Secp256k1 - "Secp256k1 cryptography library"
├─ arithmetic
│ ├─ Points "Secp256k1 point arithmetic library"
│ └─ Fp — "Secp256k1 prime field arithmetic library"
└─ signatures
├─ ECDSA — "ECDSA signature library"
└─ Schnorr — "Schnorr signature library"
offchain
├─ RandomOffchain - "Access to cryptographically secure randomness"
├─ Secp256k1Offchain - "Offchain secp256k1 cryptography library"
└─ signatures
├─ ECDSAOffchain — "Offchain ECDSA signature library"
└─ SchnorrOffchain — "Offchain Schnorr signature library"
unsafe
└─ signatures
└─ ECDSAUnsafe — "Library for unsafe ECDSA signature operations"
```

## Installation
Expand All @@ -50,13 +50,6 @@ Install with [Foundry](https://getfoundry.sh/):
$ forge install verklegarden/crysol
```

## Examples

Several examples are provided in [`examples/`](./examples), such as:
- secure key pair and Ethereum address generation
- secp256k1 point arithmetic
- Schnorr and ECDSA signature creation and verification

## Contributing

The project uses the Foundry toolchain. You can find installation instructions [here](https://getfoundry.sh/).
Expand All @@ -69,18 +62,27 @@ $ cd crysol/
$ forge install
```

Run tests:
Note that the [`Makefile`](./Makefile) provides commands for common development operations:

```bash
$ forge test
$ forge test -vvvv # Run with full stack traces
$ FOUNDRY_PROFILE=intense forge test # Run in intense mode
```

Lint:

```bash
$ forge fmt [--check]
$ make help
>
> ██████ ██████  ██  ██ ███████  ██████  ██
> ██      ██   ██  ██  ██  ██      ██    ██ ██
> ██  ██████    ████   ███████ ██  ██ ██
> ██  ██   ██   ██        ██ ██  ██ ██
>  ██████ ██  ██  ██  ███████  ██████  ███████
>
> build Build project
> clean Clean build artifacts
> coverage Update coverage report and print summary
> examples Run examples
> fmt Format project
> help Print list of all commands
> test-intense Run full test suite with intense fuzzing
> test-summary Print summary of test suite
> test Run full test suite
> todos Grep TODO's in src/ and test/
```

## Safety
Expand All @@ -89,9 +91,13 @@ This is **experimental software** and is provided on an "as is" and "as availabl

We **do not give any warranties** and **will not be liable** for any loss incurred through any use of this codebase.

## License

Licensed under either of <a href="LICENSE-APACHE">Apache License, Version 2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

<!--- Shields -->
[tests-shield]: https://github.com/verklegarden/crysol/actions/workflows/unit-tests.yml/badge.svg
[tests-shield-url]: https://github.com/verklegarden/crysol/actions/workflows/unit-tests.yml
[tests-shield]: https://github.com/verklegarden/crysol/actions/workflows/ci.yml/badge.svg
[tests-shield-url]: https://github.com/verklegarden/crysol/actions/workflows/ci.yml
[license-shield]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[solidity-shield]: https://img.shields.io/badge/solidity-%3E=0.8.16%20%3C=0.8.26-aa6746
[solidity-shield-url]: https://github.com/verklegarden/crysol/actions/workflows/solc-version-tests.yml
45 changes: 45 additions & 0 deletions SIMPLIFY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
**`crysol` is a _simple_ and _secure_ secp256k1 crypto library for EVM applications**

## Types

High-Level:
SecretKey uint \in [1, Q)
PublicKey Point

Arithmetic:
Field:
Felt uint \in [0, P)

Point:
Point (Felt, Felt)
ProjectivePoint (Felt, Felt, Felt)

While types increase costs, it provides more security.

If _not_ using .wrap(), _MUST NOT_ be able to construct invalid object.

tryXXX functions' return value is undefined if !ok.
unsafeXXX functions' behaviour undefined if !ok.

NEVER construct types yourself:
- DON't .wrap
- DON't PublicKey(x, y), Point(x, y), etc

Audit Greps:
- grep -rn "unsafe" src/
- grep -rn "wrap" src/
- grep -rn "PublicKey(" src/
- grep -rn "Point(" src/
- grep -rn "ProjectivePoint(" src/
- grep -rn "Signature(" src/ TODO: ???

## Signatures

ECDSA and Schnorr are supported


TODO: general parsing functions:
tryPublicKeyFromBlob(bytes);
publicKeyFromBlob(bytes);
tryPointFromBlob(bytes);
pointFromBlob(bytes);
6 changes: 3 additions & 3 deletions examples/common/Random.sol → examples/Random.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ 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";
import {RandomOffchain} from "offchain/RandomOffchain.sol";

/**
* @title RandomExample
*
* @dev Run via:
*
* ```bash
* $ forge script examples/common/Random.sol:RandomExample -vvvv
* $ forge script examples/Random.sol:RandomExample -vvvv
* ```
*/
contract RandomExample is Script {
function run() public {
// Create random uint.
// Read uint from CSPRNG.
uint rand = RandomOffchain.readUint();
console.log("Cryptographically secure random uint256: ", rand);
console.log("");
Expand Down
18 changes: 5 additions & 13 deletions examples/secp256k1/Secp256k1.sol → examples/Secp256k1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,17 @@ pragma solidity ^0.8.16;
import {Script} from "forge-std/Script.sol";
import {console2 as console} from "forge-std/console2.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/onchain/secp256k1/Secp256k1Arithmetic.sol";
import {Secp256k1Offchain} from "offchain/Secp256k1Offchain.sol";
import {Secp256k1, SecretKey, PublicKey} from "src/Secp256k1.sol";
import {Points, Point, ProjectivePoint} from "src/arithmetic/Points.sol";

/**
* @title Secp256k1Example
*
* @dev Run via:
*
* ```bash
* $ forge script examples/secp256k1/Secp256k1.sol:Secp256k1Example -vvvv
* $ forge script examples/Secp256k1.sol:Secp256k1Example -vvvv
* ```
*
* @dev Note that some code is commented out to reduce compiler warnings
Expand All @@ -33,7 +25,7 @@ contract Secp256k1Example is Script {
using Secp256k1Offchain for PublicKey;
using Secp256k1 for SecretKey;
using Secp256k1 for PublicKey;
using Secp256k1Arithmetic for Point;
using Points for Point;

function run() public {
// Create new cryptographically sound secret key.
Expand Down
79 changes: 0 additions & 79 deletions examples/secp256r1/Secp256r1.sol

This file was deleted.

Loading

0 comments on commit 6b36e08

Please # to comment.