Skip to content

Commit

Permalink
feat: ed25519 digital signature scheme (#179)
Browse files Browse the repository at this point in the history
* init: eddsa

* fix lint&spell

* improve code comment and add doc

* fix readme dsa, downgrade anim quality

* fix latex, add bench

* improve keygen algo

* improve doc

* fix doc

* fix doc tex, add sha512

* update spell dict

* mv imgs/gifs to assets, cleanup

* add mdbook and deploy on gh-pages

* fix fmt

* use write_all instead of write

* update readme,book.toml,add desc to create_mdbook

* finalize

* update book.toml

* add sk,pk to struct, generic sha

* remove unused feature
  • Loading branch information
mrdaybird authored Jan 23, 2025
1 parent 9e8b0f9 commit 7cbbf44
Show file tree
Hide file tree
Showing 35 changed files with 2,335 additions and 252 deletions.
1 change: 1 addition & 0 deletions .codespell-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ ronkathon
crate
nd
te
SHS
61 changes: 61 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Deploy mdBook site to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
env:
MDBOOK_VERSION: 0.4.43
MDBOOK_KATEX_VERSION: 0.9.2
steps:
- uses: actions/checkout@v4
- name: Install mdBook
run: |
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf -y | sh
rustup update
cargo install --version ${MDBOOK_VERSION} mdbook
cargo install --version ${MDBOOK_KATEX_VERSION} mdbook-katex
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Build with mdBook
run: |
cargo run --bin create_mdbook
cp -r assets book/
mdbook build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./docs

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,9 @@ dump

# coverage files
lcov.info

# mdbook
create_mdbook
book
mdbook
docs
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ edition ="2021"
license ="MIT OR Apache-2.0"
name ="ronkathon"
repository ="https://github.com/pluto/ronkathon"
version = "0.1.1"
exclude =["CHANGELOG.md", "src/tree/ConstructMerkleTree.gif"]
version ="0.1.1"
exclude =["CHANGELOG.md", "assets/"]

[dependencies]
rand ="0.8"
itertools="0.14"
hex ="0.4"
rand ="0.8"
itertools ="0.14"
hex ="0.4"
crypto-bigint ="0.6.0-rc.6"
regex ="1.11.1"
num-traits ="0.2.19"

[dev-dependencies]
rstest ="0.24"
Expand All @@ -21,6 +24,7 @@ ark-ff ={ version="0.5", features=["std"] }
ark-crypto-primitives={ version="0.5", features=["sponge"] }
des ="0.8"
chacha20 ="0.9"
hex-literal ="0.4"

[[bin]]
name="hmac_sha256_bin"
Expand Down
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ to run example code.

## Primitives

- [Finite Group](src/field/group.rs)
- [Fields and Their Extensions](src/field/README.md)
- [Binary Fields](src/field/binary_towers/README.md)
- **Fundamental Algebraic Structures**
- [Group](src/algebra/group/README.md)
- [Fields and Their Extensions](src/algebra/field/README.md)
- [Binary Fields](src/field/binary_towers/README.md)
- [Curves and Their Pairings](src/curve/README.md)
- [Polynomials](src/polynomial/mod.rs)
- [KZG Commitments](src/kzg/README.md)
Expand All @@ -46,7 +47,9 @@ to run example code.

### Signatures

- [Tiny ECDSA](src/ecdsa.rs)
- [Digital Signature Algorithms](src/dsa/README.md)
- [Elliptic Curve Digital Signature Algorithm(ECDSA)](src/dsa/ecdsa.rs)
- [Edwards-Curve Digital Signature Algorithm(EdDSA)](src/dsa/eddsa/mod.rs)

### Encryption

Expand All @@ -68,10 +71,6 @@ to run example code.
- [Sha256 Hash](src/hashes/README.md)
- [Poseidon Hash](src/hashes/poseidon/README.md)

## In Progress

- [ ] Edwards curve Signatures (EdDSA)

## Resources

We have found the following resources helpful in understanding the foundational mathematics behind this implementation. After going through these, you should be able to understand the codebase
Expand Down
22 changes: 22 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
- [Introduction](README.md)
- [Algebra](src/algebra/README.md)
- [Field](src/algebra/field/README.md)
- [Binary Towers](src/algebra/field/binary_towers/README.md)
- [Group](src/algebra/group/README.md)
- [Codes](src/codes/README.md)
- [Compiler](src/compiler/README.md)
- [Curve](src/curve/README.md)
- [Digital Signature Algorithms](src/dsa/README.md)
- [Encryption]()
- [Asymmetric]()
- [RSA](src/encryption/asymmetric/rsa/README.md)
- [Symmetric Encryption](src/encryption/symmetric/README.md)
- [AES](src/encryption/symmetric/aes/README.md)
- [ChaCha](src/encryption/symmetric/chacha/README.md)
- [DES](src/encryption/symmetric/des/README.md)
- [Modes](src/encryption/symmetric/modes/README.md)
- [Hashes](src/hashes/README.md)
- [Poseidon](src/hashes/poseidon/README.md)
- [HMAC](src/hmac/README.md)
- [KZG](src/kzg/README.md)
- [Merkle Trees](src/tree/README.md)
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added assets/keygen.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/sign_and_verify.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[book]
authors = ["Contributors to Ronkathon"]
language = "en"
multilingual = false
src = "book"
title = "Ronkathon: Cryptography Educational Foundations"
description = "Cryptography Educational Foundations"

[build]
build-dir = "docs"
use-default-preprocessors = true
create-missing = true

[preprocessor.katex]
after = ["links"]

[output.html]
default-theme = "dark"
preferred-dark-theme = "coal"
git-repository-url = "https://github.com/pluto/ronkathon"
10 changes: 10 additions & 0 deletions examples/eddsa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/// Example of Ed25519 digital signature algorithm.
use ronkathon::dsa::eddsa::Ed25519;

fn main() {
let ed25519 = Ed25519::new(None);
let msg = b"Hello World";

let signature = ed25519.sign(msg);
assert!(ed25519.verify(msg, signature));
}
4 changes: 2 additions & 2 deletions src/algebra/field/binary_towers/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Binary Fields

[Binary fields](https://en.wikipedia.org/wiki/GF%282%29) denoted as $GF(2)=Z/2Z$, i.e. quotient ring of integers modulo ring of 2 integers $\{0,1\}, are a special class of Finite Fields, with modulus = $2$. Main properties exhibited by Binary fields are:
[Binary fields](https://en.wikipedia.org/wiki/GF%282%29) denoted as $GF(2)=Z/2Z$, i.e. quotient ring of integers modulo ring of 2 integers $\{0,1\}$, are a special class of Finite Fields, with modulus = $2$. Main properties exhibited by Binary fields are:
- Addition corresponds to bitwise XOR
- Multiplication corresponds to bitwise AND
- since, $x+x=0\implies x=-x$, i.e. negation of a number is itself
Expand Down Expand Up @@ -50,4 +50,4 @@ A very nice property of binary fields is defining an element using it's subfield
- Addition, Subtraction is just bitwise XOR
- Negation is the element itself
- Multiplication is done using a hybrid of Karatsuba multiplication
- Inversion is $x^{(p-2)}$, using Fermat's little theorem
- Inversion is $x^{(p-2)}$, using Fermat's little theorem
63 changes: 63 additions & 0 deletions src/bin/create_mdbook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/// Read SUMMARY.md and copy `README.md` files given in it to `book` directory.
/// Additionally, change the links to other `README.md` files to `index.md`, so that link
/// points to correct file in the mdbook.
use std::{
fs::{self, File},
io::{self, BufRead, BufReader, Write},
path::{Path, PathBuf},
};

use regex::Regex;

const DEST: &str = "book";

fn main() -> io::Result<()> {
let dest_path = Path::new(DEST);
if !dest_path.exists() {
fs::create_dir(dest_path)?;
}

let mut readmes = Vec::<PathBuf>::new();
let f = File::open("SUMMARY.md")?;
let reader = BufReader::new(f);

let re = Regex::new(r"\[.*\]\((.*)\)").unwrap();

for line in reader.lines() {
for (_, [link]) in re.captures_iter(&line?).map(|c| c.extract()) {
if !link.is_empty() {
readmes.push(PathBuf::from(link));
}
}
}

let readme_re = Regex::new(r"README.md").unwrap();

for src in &readmes {
println!("Working on: {}", src.display());

let dest = Path::new(DEST).join(src);
let dest_folder = dest.parent().unwrap();
if !dest_folder.exists() {
fs::create_dir_all(dest_folder)?;
}
let src_file = File::open(src)?;
let reader = BufReader::new(src_file);

let mut dest_file = File::create(&dest)?;

for line in reader.lines() {
let before = line.unwrap();
let after = readme_re.replace_all(&before, "index.md");
dest_file.write_all(after.as_bytes())?;
dest_file.write_all(b"\n")?;
}
}

println!("Copying SUMMARY.md to {DEST}/SUMMARY.md");
fs::copy("SUMMARY.md", "book/SUMMARY.md")?;

println!("Done!");

Ok(())
}
51 changes: 51 additions & 0 deletions src/dsa/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Digital Signature Algorithms (DSA)

### What are digital signatures?

Like its name, **Digital Signatures** are digital analogs of physical signatures. For example, when you want to write a cheque you have to "sign" it for authentication purposes. But think about how you would do the same over the internet.
Here is where **Digital Signatures** come into the picture.

**Digital Signatures** have the following properties:
1. **Authenticity**: Just like physical signatures, digital signatures provide a way to verify the identity of a signer.
2. **Integrity**: Digital signatures provide a mechanism to detect unauthorized modification to a message.
3. **Non-repudiation**: Digital signatures have a nice property that once a signer signs a message, they cannot deny having done so.

### How does a digital signature scheme look like?

Digital signature schemes consists of three algorithms $\text{Gen, Sign, Verify}$, such that:

1. The key generation algorithm, $\text{Gen}$ which takes in the security parameter $n$ and outputs public key, $\text{pk}$ and private key, $\text{sk}$.
2. The signing algorithm $\text{Sign}$ takes as input the keys and a message and outputs a signature.
3. The verification algorithm $\text{Verify}$, takes as input the public key, a message, and a signature.
It outputs bit 1 if the signature is valid for the given message and public key, otherwise 0.

### How is a digital signature scheme used?

To explain how digital signature schemes are used, let's take the example of two people, Bobby and Alex.
Bobby is the one whose signature is required, so Bobby will run the $\text{Gen(n)}$ algorithm to obtain, $\text{pk, sk}$.
Then, the public key, $\text{pk}$, is publicized as belonging to Bobby. This not only provides authentication but also ensures non-repudiation. This one of the critical parts of a secure digital signature scheme.
You can read more on this here: [Public key infrastructure](https://en.wikipedia.org/wiki/Public_key_infrastructure)

![](../../assets/keygen.gif)

Now when Alex sends a message(document, contract, etc.), $m$, for Bobby to sign, they compute the signature, $s$ as, $s\leftarrow\text{Sign(sk,m)}$ and sents $s$ to Alex or any other party who wants to take a look.
Now, any party who wants to see if Bobby signed the document or not, applies the verification algorithm using the public key as $\text{Verify(pk,m,s)}$. Thus Alex or any other party can be sure of the authenicity of
the signature as well as the integrity of the message.

![](../../assets/sign_and_verify.gif)

### When is a signature scheme said to be secure?

A digital signature scheme is said to be secure if an adversary is unable to generate a forgery, that is, a message (not previously signed) and a valid signature for a fixed public key, in any case.

### Examples of digital signature scheme

1. Elliptic Curve Digital Signature Scheme(ECDSA)
2. Edwards-Curve Digital Signature Scheme(EdDSA)

## References

1. "Introduction to Modern Cryptography" by Jonathan Katz and Yehuda Lindell
2. [Digital Signatures](https://asecuritysite.com/signatures)


7 changes: 2 additions & 5 deletions src/ecdsa.rs → src/dsa/ecdsa.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
//! ECDSA signature verification
use std::hash::{DefaultHasher, Hasher};

use algebra::field::FiniteField;
use curve::CurveGroup;

use super::*;
use crate::{algebra::field::FiniteField, curve::CurveGroup};

// PARAMETERS
// *******************************************
Expand Down Expand Up @@ -118,9 +116,8 @@ fn hash_and_extract_bits<F: Field>(m: &[u8], bit_count: usize) -> F {

#[cfg(test)]
mod tests {
use algebra::{field::prime::PlutoScalarField, group::FiniteCyclicGroup, Finite};

use super::*;
use crate::algebra::{field::prime::PlutoScalarField, group::FiniteCyclicGroup, Finite};

#[test]
fn test_sign_verify() {
Expand Down
Loading

0 comments on commit 7cbbf44

Please sign in to comment.