GithubHelp home page GithubHelp logo

go-schnorrkel's Introduction

go-schnorrkel

Discord

This repo contains the Go implementation of the sr25519 signature algorithm (schnorr over ristretto25519). The existing Rust implementation is here.

This library is currently able to create sr25519 keys, import sr25519 keys, and sign and verify messages. It is interoperable with the Rust implementation.

The BIP39 implementation in this library is compatible with the rust substrate-bip39 implementation. Note that this is not a standard bip39 implementation.

This library has been audited as of August 2021 and is production-ready. Please see the audit report for the results of the audit.

dependencies

go 1.21

usage

Example: key generation, signing, and verification

package main 

import (
	"fmt"
	
	schnorrkel "github.com/ChainSafe/go-schnorrkel"
)

func main() {
	msg := []byte("hello friends")
	signingCtx := []byte("example")

	signingTranscript := schnorrkel.NewSigningContext(signingCtx, msg)
	verifyTranscript := schnorrkel.NewSigningContext(signingCtx, msg)

	priv, pub, err := schnorrkel.GenerateKeypair()
	if err != nil {
		panic(err)
	}

	sig, err := priv.Sign(signingTranscript)
	if err != nil {
		panic(err)
	}

	ok := pub.Verify(sig, verifyTranscript)
	if !ok {
		fmt.Println("failed to verify signature")
		return
	}

	fmt.Println("verified signature")
}

Please see the godocs for more usage examples.

go-schnorrkel's People

Contributors

dependabot[bot] avatar dutterbutter avatar eclesiomelojunior avatar hammadtq avatar jimjbrettj avatar noot avatar oldgreen avatar sunnya97 avatar swdee avatar vedhavyas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-schnorrkel's Issues

can not verify from polkadot-js

package main

import (
	"fmt"

	sr25519 "github.com/ChainSafe/go-schnorrkel"
)

var SigningContext = []byte("substrate")

func main() {
	pub, err := sr25519.NewPublicKeyFromHex("0x18b39373cd7c48d3c17478b4cade579ab9a6d67d795803a167b085696ea97622")
	if err != nil {
		panic(err)
	}
	sig, err := sr25519.NewSignatureFromHex("0x429140a10fc99055153fe08a6cd630d69b8f6723d16ea2e0ca4960d14f53095ec5e3a065e4b4473c927f35883ca39401fa9fe6c0beaf5f836e13076cbb47fa8a")
	if err != nil {
		panic(err)
	}
	msg := []byte("this is a message")
	ok, err := pub.Verify(sig, sr25519.NewSigningContext([]byte("substrate"), msg))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(ok)
}

Add constants

Add constants for:

  • PublicKeySize
  • SecretKeySize
  • SignatureSize
  • ScalarSize

create `Keypair` type

create a Keypair type that contains a public and private key. create *Keypair.Sign which uses the public key in the keypair instead of needing to derive it. see #40

build failed go v1.13.7

this line please double check with go v1.13.7+

github.com/ChainSafe/go-schnorrkel

../../../go/pkg/mod/github.com/!chain!safe/[email protected]/helpers.go:22:18: syntax error: unexpected b00000111 at end of statement
note: module requires Go 1.13

How can I generate polkadot key pair

priv, pub, err := schnorrkel.GenerateKeypair()

I use the priv in subkey --inspect --network polkadot priv, but the public key generated by subkey is not the same with the public key generated by code.

Merlin transcript RNG

Right now, sign and verify won't interoperate with don't fully match the implementation in rust library, since in rust schnorrkel uses the transcript RNG to generate randomness when signing. The Go merlin library we're using doesn't have that yet: see gtank/merlin#2

See:
https://github.com/w3f/schnorrkel/blob/798ab3e0813aa478b520c5cf6dc6e02fd4e07f0a/src/sign.rs#L161
https://github.com/w3f/schnorrkel/blob/798ab3e0813aa478b520c5cf6dc6e02fd4e07f0a/src/context.rs#L153
for the relevant code in schnorrkel.

Can't compile lib because of gopkg.in

We are constantly having issues with compiling this lib because of the dependency gopkg.in/yaml.v2
Can we replace it with a github link? The gopkg.in website is always having issues.

#0 12.76 go: gopkg.in/[email protected]: unrecognized import path "gopkg.in/yaml.v2" (parse https://gopkg.in/yaml.v2?go-get=1: no go-import meta tags ())

Address "nolint" issues

There are a few issues that currently have "nolint", mostly errcheck and gosec. Address these issues

The batch verification equation is incorrect

The code per comments (and manual inspection) uses -B โˆ‘ s_i + โˆ‘ P_i H(R_i || P_i || m_i) + โˆ‘ R_i = 0 as the batch verification equation.

This is wrong and should be -B โˆ‘ z_i s_i + โˆ‘ z_i P_i H(R_i || P_i || m_i) + โˆ‘ z_i R_i = 0, where z_i are uniform random 128-bit scalars.

Extremely poor performance and other annoyances

I've been sitting on these since the last time I filed bugs because they aren't security critical, but I might as well file them so the people that do happen to use this library suffer less.

Annoyances:

  • Unlike the Rust implementation, operations that work on merlin transcripts are not side-effect free. Fixing this requires finding a different merlin implementation, or getting the merlin library to implement transcript cloning.
  • The documentation for MiniSecretKey.Public should explicitly note that it uses ExpandEd25519, instead of ExpandUniform.

Performance:

  • There is a trivial memory/time tradeoff that can be made. Since PublicKey is opaque, there is no reason not to also cache the compressed (byte-encoded) form of the public key, so that further calls to Encode can be omitted (This is why the Rust implementation has a RistrettoBoth type).
  • There should be a KeyPair type that contains both the PublicKey and SecretKey. This is both generally more useful, and allows signing without having to do a scalar-basepoint multiply + point compression (The Rust implementation has SecretKey's sign method take a public key, and defines a KeyPair type).
  • Verification calculates calculates the R step-by-step using 3 discrete constant time calls (a scalar-basepoint multiply, a scalar multiply, and a subtraction). The ristretto255 library provides VarTimeDoubleScalarBaseMult, use it (Rp := r255.NewElement().VarTimeDoubleScalarBaseMult(k, r255.NewElement().Negate(p.key), s.s) // Rp = -p.key * k + B * s.s).
  • When generating random scalars for batch verification, this implementation reads 512-bits from the entropy source, and does a wide reduction for each scalar. It is sufficient to generate 128-bit scalars, reading 128-bits from the entropy source and using FromCanonicalBytes (no reduction).
  • Batch verification uses the constant-time MultiScalarMult. VarTimeMultiScalarMult is faster.

MiniSecretKey.Decode should do something useful

// NewMiniSecretKeyFromRaw derives a mini secret key from little-endian encoded raw bytes.
func NewMiniSecretKeyFromRaw(b [32]byte) (*MiniSecretKey, error) {
	s := b
	return &MiniSecretKey{key: s}, nil
}

[snip]

func (s *MiniSecretKey) Decode(in [32]byte) (e error) {
	_, err := NewMiniSecretKeyFromRaw(in)
	return err
}

Unless the intended behavior is to implement a moderately expensive way to obtain a nil error, this should probably be fixed to set the receiver to the decoded mini secret key.

cache compressed `PublicKey`

cache compressed (encoded) PublicKey within the struct so *PublicKey.Encode returns the compressed public key, if there is one.

see #40

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.