Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Misc] Code cleanup & docs #21

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Benchmarking

cpu.prof
mem.prof
ring-go.test

.DS_Store
59 changes: 59 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.SILENT:

#####################
### General ###
#####################

.PHONY: help
.DEFAULT_GOAL := help
help: ## Prints all the targets in all the Makefiles
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

.PHONY: list
list: ## List all make targets
@${MAKE} -pRrn : -f $(MAKEFILE_LIST) 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | sort

#####################
#### Testing ####
#####################

.PHONY: test_all
test_all: ## runs the test suite
go test -v -p 1 ./... -mod=readonly -race

##########################
#### Benchmarking ####
##########################

.PHONY: benchmark_all
benchmark_all: ## runs the benchmark suite
go test -bench=. -benchmem -cpuprofile=cpu.prof -memprofile=mem.prof

###########################
### Release Helpers ###
###########################

# List tags: git tag
# Delete tag locally: git tag -d v1.2.3
# Delete tag remotely: git push --delete origin v1.2.3

.PHONY: tag_bug_fix
tag_bug_fix: ## Tag a new bug fix release (e.g., v1.0.1 -> v1.0.2)
@$(eval LATEST_TAG=$(shell git tag --sort=-v:refname | head -n 1))
@$(eval NEW_TAG=$(shell echo $(LATEST_TAG) | awk -F. -v OFS=. '{ $$NF = sprintf("%d", $$NF + 1); print }'))
@git tag $(NEW_TAG)
@echo "New bug fix version tagged: $(NEW_TAG)"
@echo "Run the following commands to push the new tag:"
@echo " git push origin $(NEW_TAG)"
@echo "And draft a new release at https://github.com/pokt-network/smt/releases/new"


.PHONY: tag_minor_release
tag_minor_release: ## Tag a new minor release (e.g. v1.0.0 -> v1.1.0)
@$(eval LATEST_TAG=$(shell git tag --sort=-v:refname | head -n 1))
@$(eval NEW_TAG=$(shell echo $(LATEST_TAG) | awk -F. '{$$2 += 1; $$3 = 0; print $$1 "." $$2 "." $$3}'))
@git tag $(NEW_TAG)
@echo "New minor release version tagged: $(NEW_TAG)"
@echo "Run the following commands to push the new tag:"
@echo " git push origin $(NEW_TAG)"
@echo "And draft a new release at https://github.com/pokt-network/smt/releases/new"
92 changes: 51 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,72 @@
# ring-go
Implementation of linkable ring signatures using elliptic curve crypto in pure Go. It supports ring signatures over both ed25519 and secp256k1.
# ring-go <!-- omit in toc -->

### requirements
go 1.19
Implementation of linkable ring signatures using elliptic curve crypto in pure Go.
It supports ring signatures over both ed25519 and secp256k1.

### get
`go get github.com/noot/ring-go`
- [Requirements](#requirements)
- [Install](#install)
- [References](#references)
- [Usage](#usage)

## Requirements

go 1.22.2

## Install

`go get github.com/pokt-network/ring-go`

## References

### references
This implementation is based off of [Ring Confidential Transactions](https://eprint.iacr.org/2015/1098.pdf), in particular section 2, which defines MLSAG (Multilayered Linkable Spontaneous Anonymous Group signatures).

### usage
## Usage

See `examples/main.go`.

```go
package main

import (
"fmt"
"fmt"

ring "github.com/noot/ring-go"
"golang.org/x/crypto/sha3"
ring "github.com/pokt-network/ring-go"
"golang.org/x/crypto/sha3"
)

func signAndVerify(curve ring.Curve) {
privkey := curve.NewRandomScalar()
msgHash := sha3.Sum256([]byte("helloworld"))

// size of the public key ring (anonymity set)
const size = 16

// our key's secret index within the set
const idx = 7
keyring, err := ring.NewKeyRing(curve, size, privkey, idx)
if err != nil {
panic(err)
}

sig, err := keyring.Sign(msgHash, privkey)
if err != nil {
panic(err)
}

ok := sig.Verify(msgHash)
if !ok {
fmt.Println("failed to verify :(")
return
}

fmt.Println("verified signature!")
privKey := curve.NewRandomScalar()
msgHash := sha3.Sum256([]byte("helloworld"))

// size of the public key ring (anonymity set)
const size = 16

// our key's secret index within the set
const idx = 7

keyring, err := ring.NewKeyRing(curve, size, privKey, idx)
if err != nil {
panic(err)
}

sig, err := keyring.Sign(msgHash, privKey)
if err != nil {
panic(err)
}

ok := sig.Verify(msgHash)
if !ok {
fmt.Println("failed to verify :(")
return
}

fmt.Println("verified signature!")
}

func main() {
fmt.Println("using secp256k1...")
signAndVerify(ring.Secp256k1())
fmt.Println("using ed25519...")
signAndVerify(ring.Ed25519())
fmt.Println("using secp256k1...")
signAndVerify(ring.Secp256k1())
fmt.Println("using ed25519...")
signAndVerify(ring.Ed25519())
}
```
Binary file not shown.
98 changes: 49 additions & 49 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@ import (

const idx = 0

func benchmarkSign(b *testing.B, curve types.Curve, keyring *Ring, privkey types.Scalar, size, idx int) {
func benchmarkSign(b *testing.B, curve types.Curve, keyring *Ring, privKey types.Scalar, size, idx int) {
for i := 0; i < b.N; i++ {
_, err := keyring.Sign(testMsg, privkey)
_, err := keyring.Sign(testMsg, privKey)
if err != nil {
panic(err)
}
}
}

func mustKeyRing(curve types.Curve, privkey types.Scalar, size, idx int) *Ring {
keyring, err := NewKeyRing(curve, size, privkey, idx)
func mustKeyRing(curve types.Curve, privKey types.Scalar, size, idx int) *Ring {
keyring, err := NewKeyRing(curve, size, privKey, idx)
if err != nil {
panic(err)
}
Expand All @@ -28,113 +28,113 @@ func mustKeyRing(curve types.Curve, privkey types.Scalar, size, idx int) *Ring {
func BenchmarkSign2_Secp256k1(b *testing.B) {
const size = 2
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign4_Secp256k1(b *testing.B) {
const size = 4
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign8_Secp256k1(b *testing.B) {
const size = 8
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign16_Secp256k1(b *testing.B) {
const size = 16
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign32_Secp256k1(b *testing.B) {
const size = 32
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign64_Secp256k1(b *testing.B) {
const size = 64
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign128_Secp256k1(b *testing.B) {
const size = 128
curve := Secp256k1()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign2_Ed25519(b *testing.B) {
const size = 2
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign4_Ed25519(b *testing.B) {
const size = 4
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign8_Ed25519(b *testing.B) {
const size = 8
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign16_Ed25519(b *testing.B) {
const size = 16
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign32_Ed25519(b *testing.B) {
const size = 32
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign64_Ed25519(b *testing.B) {
const size = 64
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func BenchmarkSign128_Ed25519(b *testing.B) {
const size = 128
curve := Ed25519()
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
benchmarkSign(b, curve, keyring, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)
benchmarkSign(b, curve, keyring, privKey, size, idx)
}

func benchmarkVerify(b *testing.B, sig *RingSig) {
Expand All @@ -147,10 +147,10 @@ func benchmarkVerify(b *testing.B, sig *RingSig) {
}

func mustSig(curve types.Curve, size int) *RingSig {
privkey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privkey, size, idx)
privKey := curve.NewRandomScalar()
keyring := mustKeyRing(curve, privKey, size, idx)

sig, err := keyring.Sign(testMsg, privkey)
sig, err := keyring.Sign(testMsg, privKey)
if err != nil {
panic(err)
}
Expand Down
Loading