Skip to content

Commit 1ba6b15

Browse files
committed
update readme
1 parent 86327c9 commit 1ba6b15

File tree

3 files changed

+176
-27
lines changed

3 files changed

+176
-27
lines changed

README.md

Lines changed: 164 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![GoDoc](https://godoc.org/github.com/hbakhtiyor/schnorr?status.svg)](https://godoc.org/github.com/hbakhtiyor/schnorr) [![Build Status](https://travis-ci.com/hbakhtiyor/schnorr.svg?branch=master)](https://travis-ci.com/hbakhtiyor/schnorr) [![Go Report Card](https://goreportcard.com/badge/github.com/hbakhtiyor/schnorr)](https://goreportcard.com/report/github.com/hbakhtiyor/schnorr)![License](https://badges.fyi/github/license/hbakhtiyor/schnorr)![Latest tag](https://badges.fyi/github/latest-tag/hbakhtiyor/schnorr)
1+
[![GoDoc](https://godoc.org/github.com/hbakhtiyor/schnorr?status.svg)](https://godoc.org/github.com/hbakhtiyor/schnorr) [![Build Status](https://travis-ci.com/hbakhtiyor/schnorr.svg?branch=master)](https://travis-ci.com/hbakhtiyor/schnorr) [![Go Report Card](https://goreportcard.com/badge/github.com/hbakhtiyor/schnorr)](https://goreportcard.com/report/github.com/hbakhtiyor/schnorr) [![License](https://badges.fyi/github/license/hbakhtiyor/schnorr)](https://github.com/hbakhtiyor/schnorr/blob/master/LICENSE) ![Latest tag](https://badges.fyi/github/latest-tag/hbakhtiyor/schnorr)
22

33
Go implementation of the Schnorr BIP
44
=================
@@ -19,14 +19,22 @@ correctly for every edge case!**
1919

2020
* [Usage](#usage)
2121
* [API](#api)
22-
* [Sign(privateKey *big.Int, message []byte) ([]byte, error)](#signprivatekey-bigint-message-byte-byte-error)
22+
* [Sign(privateKey *big.Int, message [32]byte) ([64]byte, error)](#signprivatekey-bigint-message-byte-byte-error)
2323
* [Arguments](#arguments)
2424
* [Returns](#returns)
2525
* [Examples](#examples)
26-
* [Verify(pubKey, message, signature []byte) (bool, error)](#verifypubkey-message-signature-byte-bool-error)
26+
* [Verify(publicKey [33]byte, message [32]byte, signature [64]byte) (bool, error)](#verifypubkey-message-signature-byte-bool-error)
2727
* [Arguments](#arguments-1)
2828
* [Returns](#returns-1)
2929
* [Examples](#examples-1)
30+
* [BatchVerify(publicKeys [][33]byte, messages [][32]byte, signatures [][64]byte) (bool, error)](#verifypubkey-message-signature-byte-bool-error)
31+
* [Arguments](#arguments-2)
32+
* [Returns](#returns-2)
33+
* [Examples](#examples-2)
34+
* [AggregateSignatures(privateKeys []*big.Int, message [32]byte) ([64]byte, error)](#verifypubkey-message-signature-byte-bool-error)
35+
* [Arguments](#arguments-3)
36+
* [Returns](#returns-3)
37+
* [Examples](#examples-3)
3038
* [Benchmark](#benchmark)
3139
* [Hardware used](#hardware-used)
3240
* [Version](#version)
@@ -47,58 +55,186 @@ import "github.com/hbakhtiyor/schnorr"
4755

4856
signature, err := schnorr.Sign(privateKey, message)
4957

50-
result, err := schnorr.Verify(pubKey, message, signature)
58+
result, err := schnorr.Verify(publicKey, message, signature)
59+
60+
result, err := schnorr.BatchVerify(publicKeys, messages, signatures)
61+
62+
signature, err := schnorr.AggregateSignatures(privateKeys, message)
5163
```
5264
## API
5365

54-
Requiring the module gives an object with two methods:
66+
Requiring the module gives an object with four methods:
5567

56-
### Sign(privateKey *big.Int, message []byte) ([]byte, error)
68+
### Sign(privateKey *big.Int, message [32]byte) ([64]byte, error)
5769

58-
Sign a 32 byte message with the private key, returning a 64 byte signature. Read [more](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki#signing)
70+
Sign a 32-byte message with the private key, returning a 64-byte signature. Read [more](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki#signing)
5971

6072
##### Arguments
6173

62-
1. privateKey (*big.Int): The secret key is an integer in the range 1..n-1.
63-
2. message ([]byte): The message is a 32-byte array.
74+
1. privateKey (*big.Int): The integer secret key in the range 1..n-1.
75+
2. message ([32]byte): The 32-byte array message.
6476

6577
##### Returns
6678

67-
([]byte, error): A 64 byte array signature. An error if signing fails.
79+
([64]byte, error): A 64-byte array signature. An error if signing fails.
6880

6981
##### Examples
7082

7183
```go
72-
// signing
84+
var message [32]byte
85+
7386
privateKey, _ := new(big.Int).SetString("B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF", 16)
74-
message, _ := hex.DecodeString("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
75-
createdSignature, err := schnorr.Sign(privateKey, message)
87+
msg, _ := hex.DecodeString("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
88+
copy(message[:], msg)
89+
90+
signature, err := schnorr.Sign(privateKey, message)
7691
if err != nil {
7792
fmt.Printf("The signing is failed: %v\n", err)
7893
}
79-
fmt.Printf("The signature is: %x\n", createdSignature)
94+
fmt.Printf("The signature is: %x\n", signature)
8095
```
8196

82-
### Verify(pubKey, message, signature []byte) (bool, error)
97+
### Verify(publicKey [33]byte, message [32]byte, signature [64]byte) (bool, error)
8398

84-
Verify a 64 byte signature of a 32 byte message against the public key. Read [more](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki#verification)
99+
Verify a 64-byte signature of a 32-byte message against the public key. Read [more](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki#verification)
85100

86101
##### Arguments
87102

88-
1. pubKey ([]byte): The public key is a 33-byte array.
89-
2. message ([]byte): The message is a 32-byte array.
90-
3. signature ([]byte): The signature is a 64-byte array.
103+
1. publicKey ([33]byte): The 33-byte array public key.
104+
2. message ([32]byte): The 32-byte array message.
105+
3. signature ([64]byte): The 64-byte array signature.
91106

92107
##### Returns
108+
93109
(bool, error): True if signature is valid, An error if verification fails.
94110

95111
##### Examples
112+
113+
```go
114+
var (
115+
publicKey [33]byte
116+
message [32]byte
117+
signature [64]byte
118+
)
119+
120+
pk, _ := hex.DecodeString("02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659")
121+
copy(publicKey[:], pk)
122+
msg, _ := hex.DecodeString("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
123+
copy(message[:], msg)
124+
sig, _ := hex.DecodeString("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD")
125+
copy(signature[:], sig)
126+
127+
if result, err := schnorr.Verify(publicKey, message, signature); err != nil {
128+
fmt.Printf("The signature verification failed: %v\n", err)
129+
} else if result {
130+
fmt.Println("The signature is valid.")
131+
}
132+
```
133+
134+
### BatchVerify(publicKeys [][33]byte, messages [][32]byte, signatures [][64]byte) (bool, error)
135+
136+
Verify a list of 64-byte signatures of a 32-byte messages against the public keys. Read [more](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki#batch-verification)
137+
138+
##### Arguments
139+
140+
1. publicKeys ([][33]byte): The list of 33-byte array public keys.
141+
2. messages ([][32]byte): The list of 32-byte array messages.
142+
3. signatures ([][64]byte): The list of 64-byte array signatures.
143+
144+
##### Returns
145+
146+
(bool, error): True if all signatures are valid, An error if one verification fails.
147+
148+
##### Examples
149+
96150
```go
97-
// verifying
98-
publicKey, _ := hex.DecodeString("02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659")
99-
message, _ := hex.DecodeString("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
100-
signatureToVerify, _ := hex.DecodeString("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD")
101-
if result, err := schnorr.Verify(publicKey, message, signatureToVerify); err != nil {
151+
var (
152+
publicKey [33]byte
153+
message [32]byte
154+
signature [64]byte
155+
publicKeys [][33]byte
156+
messages [][32]byte
157+
signatures [][64]byte
158+
)
159+
160+
pk, _ := hex.DecodeString("02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659")
161+
copy(publicKey[:], pk)
162+
publicKeys = append(publicKeys, publicKey)
163+
pk, _ = hex.DecodeString("03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B")
164+
copy(publicKey[:], pk)
165+
publicKeys = append(publicKeys, publicKey)
166+
pk, _ = hex.DecodeString("026D7F1D87AB3BBC8BC01F95D9AECE1E659D6E33C880F8EFA65FACF83E698BBBF7")
167+
copy(publicKey[:], pk)
168+
publicKeys = append(publicKeys, publicKey)
169+
msg, _ := hex.DecodeString("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
170+
copy(message[:], msg)
171+
messages = append(messages, message)
172+
msg, _ = hex.DecodeString("5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C")
173+
copy(message[:], msg)
174+
messages = append(messages, message)
175+
msg, _ = hex.DecodeString("B2F0CD8ECB23C1710903F872C31B0FD37E15224AF457722A87C5E0C7F50FFFB3")
176+
copy(message[:], msg)
177+
messages = append(messages, message)
178+
sig, _ := hex.DecodeString("2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD")
179+
copy(signature[:], sig)
180+
signatures = append(signatures, signature)
181+
sig, _ = hex.DecodeString("00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380")
182+
copy(signature[:], sig)
183+
signatures = append(signatures, signature)
184+
sig, _ = hex.DecodeString("68CA1CC46F291A385E7C255562068357F964532300BEADFFB72DD93668C0C1CAC8D26132EB3200B86D66DE9C661A464C6B2293BB9A9F5B966E53CA736C7E504F")
185+
copy(signature[:], sig)
186+
signatures = append(signatures, signature)
187+
188+
if result, err := schnorr.BatchVerify(publicKeys, messages, signatures); err != nil {
189+
fmt.Printf("The signature verification failed: %v\n", err)
190+
} else if result {
191+
fmt.Println("The signature is valid.")
192+
}
193+
```
194+
195+
### AggregateSignatures(privateKeys []*big.Int, message [32]byte) ([64]byte, error)
196+
197+
Aggregate multiple signatures of different private keys over the same message into a single 64-byte signature.
198+
199+
##### Arguments
200+
201+
1. privateKeys ([]*big.Int): The list of integer secret keys in the range 1..n-1.
202+
2. message ([32]byte): The list of 32-byte array messages.
203+
204+
##### Returns
205+
206+
(bool, error): True if all signatures are valid, An error if one verification fails.
207+
([64]byte, error): A 64-byte array signature. An error if signing fails.
208+
209+
##### Examples
210+
211+
```go
212+
var (
213+
publicKey [33]byte
214+
message [32]byte
215+
)
216+
217+
privateKey1, _ := new(big.Int).SetString("B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF", 16)
218+
privateKey2, _ := new(big.Int).SetString("C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7", 16)
219+
msg, _ := hex.DecodeString("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89")
220+
copy(message[:], msg)
221+
222+
privateKeys := []*big.Int{privateKey1, privateKey2}
223+
signature, _ := schnorr.AggregateSignatures(privateKeys, message)
224+
225+
// verifying an aggregated signature
226+
pk, _ := hex.DecodeString("02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659")
227+
copy(publicKey[:], pk)
228+
P1x, P1y := schnorr.Unmarshal(Curve, publicKey[:])
229+
230+
pk, _ = hex.DecodeString("03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B")
231+
copy(publicKey[:], pk)
232+
P2x, P2y := schnorr.Unmarshal(Curve, publicKey[:])
233+
Px, Py := Curve.Add(P1x, P1y, P2x, P2y)
234+
235+
copy(publicKey[:], schnorr.Marshal(Curve, Px, Py))
236+
237+
if result, err := schnorr.Verify(publicKey, message, signature); err != nil {
102238
fmt.Printf("The signature verification failed: %v\n", err)
103239
} else if result {
104240
fmt.Println("The signature is valid.")
@@ -108,8 +244,10 @@ if result, err := schnorr.Verify(publicKey, message, signatureToVerify); err !=
108244
## Benchmarks
109245

110246
```
111-
BenchmarkSign-4 1000 1960591 ns/op 34080 B/op 602 allocs/op
112-
BenchmarkVerify-4 100 10368368 ns/op 236963 B/op 3605 allocs/op
247+
BenchmarkSign-4 2000 1015337 ns/op 45812 B/op 814 allocs/op
248+
BenchmarkVerify-4 200 8555659 ns/op 217884 B/op 3622 allocs/op
249+
BenchmarkBatchVerify-4 100 12114966 ns/op 148343 B/op 2220 allocs/op
250+
BenchmarkAggregateSignatures-4 2000 593665 ns/op 21981 B/op 400 allocs/op
113251
```
114252

115253
##### Hardware used

schnorr.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ func BatchVerify(publicKeys [][33]byte, messages [][32]byte, signatures [][64]by
166166
}
167167

168168
// AggregateSignatures aggregates multiple signatures of different private keys over
169-
// the same message into a single 64 byte signature. (Experimental)
169+
// the same message into a single 64 byte signature.
170170
func AggregateSignatures(privateKeys []*big.Int, message [32]byte) ([64]byte, error) {
171171
sig := [64]byte{}
172172
if privateKeys == nil || len(privateKeys) == 0 {

schnorr_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,17 @@ func BenchmarkBatchVerify(b *testing.B) {
310310
}
311311
}
312312

313+
func BenchmarkAggregateSignatures(b *testing.B) {
314+
for i := 0; i < b.N; i++ {
315+
privKey1 := decodePrivateKey("B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF", nil)
316+
privKey2 := decodePrivateKey("C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7", nil)
317+
m := decodeMessage("243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89", nil)
318+
319+
pks := []*big.Int{privKey1, privKey2}
320+
AggregateSignatures(pks, m)
321+
}
322+
}
323+
313324
func decodeSignature(s string, t *testing.T) (sig [64]byte) {
314325
signature, err := hex.DecodeString(s)
315326
if err != nil && t != nil {

0 commit comments

Comments
 (0)