diff --git a/README.md b/README.md index 0ececb5..e7c8e61 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,171 @@ -# Schnorr signature on FourQ +# go-schnorrq + +This Go module implements the generation and verification of Schnorr signatures on the FourQ elliptic curve. + +## Features + +- Simple and easy to use +- Allows for custom hash functions +- Allows for custom public key generator functions + +## Usage + +### Signature generation + +```go + +package main + +import ( + "encoding/hex" + "fmt" + "github.com/linckode/go-schnorrq/ctx" + "github.com/linckode/go-schnorrq/keypair" + "github.com/linckode/go-schnorrq/keypair/public" +) + +func _() { + + //Fill with your data + privateKey := [32]byte{} + message := [32]byte{} + + //The default context is based around the SHA-512 algorithm. + context := ctx.DefaultContext + + //The default generator uses the default FourQLib method. + pair := keypair.NewFromPrivateKey(privateKey, &public.DefaultGenerator) + + signature, err := context.Sign(pair, message[:]) + if err != nil { + fmt.Printf("Encountered error while singining: %s", err.Error()) + return + } + fmt.Printf("Signature: %s\n", hex.EncodeToString(signature[:])) +} + +``` + +### Signature verification + +```go + +package main + +import ( + "fmt" + "github.com/linckode/go-schnorrq/ctx" + "github.com/linckode/go-schnorrq/keypair" + "github.com/linckode/go-schnorrq/keypair/public" +) + +func _() { + + //Fill with your data + privateKey := [32]byte{} + message := [32]byte{} + signature := [64]byte{} + + //The default context is based around the SHA-512 algorithm. + context := ctx.DefaultContext + + //The default generator uses the default FourQLib method. + pair := keypair.NewFromPrivateKey(privateKey, &public.DefaultGenerator) + + err := context.Verify(pair, message[:], signature) + if err != nil { + fmt.Printf("Encountered error while verifying signature: %s", err.Error()) + return + } + + fmt.Printf("Signature verifies!\n") +} + +``` + +### Using custom hashing algorithms + +KangarooTwelve example + +```go + +package main + +import ( + "github.com/linckode/circl/xof/k12" + "github.com/linckode/go-schnorrq/ctx" + "github.com/linckode/go-schnorrq/keypair" + "github.com/linckode/go-schnorrq/keypair/public" + "github.com/pkg/errors" +) + + +type K12Function struct{} + +func (hash *K12Function) GetFunctionName() string { + return "KangarooTwelve" +} + +func (hash *K12Function) Hash(input []byte) ([64]byte, error) { + state := k12.NewDraft10([]byte{}) + _, err := state.Write(input) + if err != nil { + return [64]byte{}, errors.Wrap(err, "kangaroo-twelve hashing") + } + var out = [64]byte{} + _, err = state.Read(out[:]) + if err != nil { + return [64]byte{}, errors.Wrap(err, "reading kangaroo-twelve digest") + } + return out, nil +} + + +func _() { + + K12Context := ctx.SchnorrQContext{ + HashFunction: &K12Function{}, + } + + //K12Context.Sign()... + //K12Context.Verify()... + +} +``` + +### Using custom public key generator functions + +```go + +package main + +import ( + "github.com/linckode/circl/ecc/fourq" + "github.com/linckode/go-schnorrq/keypair" +) + +type TestGenerator struct{} + +func (function *TestGenerator) Generate(privateKey [32]byte) [32]byte { + + var point fourq.Point + point.ScalarBaseMult(&privateKey) + + publicKey := [32]byte{} + point.Marshal(&publicKey) + + return publicKey +} + +func _() { + + //Fill with data + privateKey := [32]byte{} + pair := keypair.NewFromPrivateKey(privateKey, &TestGenerator{}) + +} +``` + + + diff --git a/core/schnorrq.go b/core/schnorrq.go index 138f6f9..66a7ce5 100644 --- a/core/schnorrq.go +++ b/core/schnorrq.go @@ -2,8 +2,8 @@ package core import ( "github.com/linckode/circl/ecc/fourq" - "github.com/linckode/schnorrq/hash" - "github.com/linckode/schnorrq/montgomery" + "github.com/linckode/go-schnorrq/hash" + "github.com/linckode/go-schnorrq/montgomery" "github.com/pkg/errors" ) diff --git a/ctx/schnorrq_context.go b/ctx/schnorrq_context.go index 603b4ce..57f4ccb 100644 --- a/ctx/schnorrq_context.go +++ b/ctx/schnorrq_context.go @@ -2,41 +2,41 @@ package ctx import ( "fmt" - "github.com/linckode/schnorrq/core" - "github.com/linckode/schnorrq/hash" - "github.com/linckode/schnorrq/keypair" + "github.com/linckode/go-schnorrq/core" + "github.com/linckode/go-schnorrq/hash" + "github.com/linckode/go-schnorrq/keypair" "github.com/pkg/errors" ) type SchnorrQContext struct { - hashFunction hash.Function + HashFunction hash.Function } var DefaultContext = SchnorrQContext{ - hashFunction: &hash.Sha512, + HashFunction: &hash.Sha512, } func New(function hash.Function) SchnorrQContext { var context SchnorrQContext - context.hashFunction = function + context.HashFunction = function return context } func (context *SchnorrQContext) Sign(pair keypair.KeyPair, message []byte) ([64]byte, error) { - signature, err := core.Sign(pair.PrivateKey, pair.PublicKey, message, context.hashFunction) + signature, err := core.Sign(pair.PrivateKey, pair.PublicKey, message, context.HashFunction) if err != nil { - return [64]byte{}, errors.Wrap(err, fmt.Sprintf("signing using hash %s", context.hashFunction.GetFunctionName())) + return [64]byte{}, errors.Wrap(err, fmt.Sprintf("signing using hash %s", context.HashFunction.GetFunctionName())) } return signature, nil } func (context *SchnorrQContext) Verify(pair keypair.KeyPair, message []byte, signature [64]byte) error { - err := core.Verify(pair.PublicKey, message, signature, context.hashFunction) + err := core.Verify(pair.PublicKey, message, signature, context.HashFunction) if err != nil { - return errors.Wrap(err, fmt.Sprintf("verifying signature using hash %s", context.hashFunction.GetFunctionName())) + return errors.Wrap(err, fmt.Sprintf("verifying signature using hash %s", context.HashFunction.GetFunctionName())) } return nil } diff --git a/file.go b/file.go new file mode 100644 index 0000000..163f690 --- /dev/null +++ b/file.go @@ -0,0 +1 @@ +package schnorrq diff --git a/go.mod b/go.mod index e1d9566..368e27b 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/linckode/schnorrq +module github.com/linckode/go-schnorrq go 1.22 @@ -9,12 +9,12 @@ require ( github.com/linckode/circl v1.3.71 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.9.0 + golang.org/x/sys v0.19.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - golang.org/x/sys v0.10.0 gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index ec0dc43..90bbc24 100644 --- a/go.sum +++ b/go.sum @@ -420,8 +420,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/keypair/keypair.go b/keypair/keypair.go index 7314fce..2a4758a 100644 --- a/keypair/keypair.go +++ b/keypair/keypair.go @@ -3,7 +3,7 @@ package keypair import ( "encoding/hex" "fmt" - "github.com/linckode/schnorrq/keypair/public" + "github.com/linckode/go-schnorrq/keypair/public" ) type KeyPair struct { diff --git a/keypair/public/function.go b/keypair/public/function.go index 9fda7dd..4a23c62 100644 --- a/keypair/public/function.go +++ b/keypair/public/function.go @@ -2,7 +2,7 @@ package public import ( "github.com/linckode/circl/ecc/fourq" - "github.com/linckode/schnorrq/hash" + "github.com/linckode/go-schnorrq/hash" ) type Generator interface { diff --git a/main_test.go b/main_test.go index 3e41dd8..ae4f2e4 100644 --- a/main_test.go +++ b/main_test.go @@ -1,10 +1,10 @@ -package main +package schnorrq import ( "encoding/hex" - "github.com/linckode/schnorrq/ctx" - "github.com/linckode/schnorrq/keypair" - "github.com/linckode/schnorrq/keypair/public" + "github.com/linckode/go-schnorrq/ctx" + "github.com/linckode/go-schnorrq/keypair" + "github.com/linckode/go-schnorrq/keypair/public" "testing" ) @@ -30,11 +30,10 @@ func Test(t *testing.T) { signature, err := context.Sign(pair, message[:]) if err != nil { - t.Errorf("Encountered error while singining: %s", err.Error()) return } - + t.Logf("Signature: %s\n", hex.EncodeToString(signature[:])) err = context.Verify(pair, message[:], signature) diff --git a/montgomery/montgomery.go b/montgomery/montgomery.go index dc35d14..329fc1b 100644 --- a/montgomery/montgomery.go +++ b/montgomery/montgomery.go @@ -1,7 +1,7 @@ package montgomery import ( - "github.com/linckode/schnorrq/order" + "github.com/linckode/go-schnorrq/order" "github.com/pkg/errors" ) diff --git a/montgomery/util.go b/montgomery/util.go index 149a564..811dfbb 100644 --- a/montgomery/util.go +++ b/montgomery/util.go @@ -1,7 +1,7 @@ package montgomery import ( - "github.com/linckode/schnorrq/order" + "github.com/linckode/go-schnorrq/order" "math/big" )