aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Fix <brf@hoi-polloi.org>2020-04-01 21:53:16 +0200
committerBernd Fix <brf@hoi-polloi.org>2020-04-01 21:53:16 +0200
commit3d0b7cab3e273dd2f3f3d8990fb868b93b6b3f95 (patch)
tree57e067073267b9c052008e79efd539abee3ad947
parentdb7da66be57c6a9df87f3ea1f3cd681539ad9b51 (diff)
downloadgnunet-go-3d0b7cab3e273dd2f3f3d8990fb868b93b6b3f95.tar.gz
gnunet-go-3d0b7cab3e273dd2f3f3d8990fb868b93b6b3f95.zip
Adjusted revocation PoW to draft specification.
-rw-r--r--src/cmd/pow-test/main.go9
-rw-r--r--src/gnunet/service/context.go34
-rw-r--r--src/gnunet/service/revocation/pow.go32
3 files changed, 44 insertions, 31 deletions
diff --git a/src/cmd/pow-test/main.go b/src/cmd/pow-test/main.go
index 4b74b6e..247f442 100644
--- a/src/cmd/pow-test/main.go
+++ b/src/cmd/pow-test/main.go
@@ -1,6 +1,7 @@
1package main 1package main
2 2
3import ( 3import (
4 "encoding/hex"
4 "flag" 5 "flag"
5 "fmt" 6 "fmt"
6 "log" 7 "log"
@@ -19,7 +20,11 @@ func main() {
19 flag.IntVar(&bits, "b", 25, "Number of leading zero bits") 20 flag.IntVar(&bits, "b", 25, "Number of leading zero bits")
20 flag.BoolVar(&quiet, "q", false, "Be quiet") 21 flag.BoolVar(&quiet, "q", false, "Be quiet")
21 flag.Parse() 22 flag.Parse()
23
24 // pre-set difficulty
22 fmt.Printf("Leading zeros required: %d\n", bits) 25 fmt.Printf("Leading zeros required: %d\n", bits)
26 difficulty := math.TWO.Pow(512 - bits).Sub(math.ONE)
27 fmt.Printf("==> Difficulty: %v\n", difficulty)
23 28
24 // generate a random key pair 29 // generate a random key pair
25 pkey, _ := ed25519.NewKeypair() 30 pkey, _ := ed25519.NewKeypair()
@@ -27,9 +32,6 @@ func main() {
27 // initialize RevData structure 32 // initialize RevData structure
28 rd := revocation.NewRevData(0, pkey) 33 rd := revocation.NewRevData(0, pkey)
29 34
30 // pre-set difficulty
31 difficulty := math.TWO.Pow(512 - bits).Sub(math.ONE)
32
33 var count uint64 = 0 35 var count uint64 = 0
34 for { 36 for {
35 result, err := rd.Compute() 37 result, err := rd.Compute()
@@ -45,4 +47,5 @@ func main() {
45 } 47 }
46 fmt.Printf("PoW found after %d iterations:\n", count) 48 fmt.Printf("PoW found after %d iterations:\n", count)
47 fmt.Printf("--> Nonce=%d\n", rd.GetNonce()) 49 fmt.Printf("--> Nonce=%d\n", rd.GetNonce())
50 fmt.Printf(" REV = %s\n", hex.EncodeToString(rd.GetBlob()))
48} 51}
diff --git a/src/gnunet/service/context.go b/src/gnunet/service/context.go
index ffffafb..120d460 100644
--- a/src/gnunet/service/context.go
+++ b/src/gnunet/service/context.go
@@ -30,28 +30,38 @@ import (
30// by a service; the session is handled by the 'ServeClient' method of a 30// by a service; the session is handled by the 'ServeClient' method of a
31// service implementation. 31// service implementation.
32type SessionContext struct { 32type SessionContext struct {
33 Id int // session identifier 33 Id int // session identifier
34 wg *sync.WaitGroup // wait group for the session 34 wg *sync.WaitGroup // wait group for the session
35 sig *concurrent.Signaller // signaller for the session 35 sig *concurrent.Signaller // signaller for the session
36 pending int // number of pending go-routines 36 pending int // number of pending go-routines
37 active bool // is the context active (un-cancelled)?
38 onCancel *sync.Mutex // only run one Cancel() at a time
37} 39}
38 40
39// NewSessionContext instantiates a new session context. 41// NewSessionContext instantiates a new session context.
40func NewSessionContext() *SessionContext { 42func NewSessionContext() *SessionContext {
41 return &SessionContext{ 43 return &SessionContext{
42 Id: util.NextID(), 44 Id: util.NextID(),
43 wg: new(sync.WaitGroup), 45 wg: new(sync.WaitGroup),
44 sig: concurrent.NewSignaller(), 46 sig: concurrent.NewSignaller(),
45 pending: 0, 47 pending: 0,
48 active: true,
49 onCancel: new(sync.Mutex),
46 } 50 }
47} 51}
48 52
49// Cancel all go-routines associated with this context. 53// Cancel all go-routines associated with this context.
50func (ctx *SessionContext) Cancel() { 54func (ctx *SessionContext) Cancel() {
51 // send signal to terminate... 55 ctx.onCancel.Lock()
52 ctx.sig.Send(true) 56 if ctx.active {
53 // wait for session go-routines to finish 57 // we are going out-of-business
54 ctx.wg.Wait() 58 ctx.active = false
59 // send signal to terminate...
60 ctx.sig.Send(true)
61 // wait for session go-routines to finish
62 ctx.wg.Wait()
63 }
64 ctx.onCancel.Unlock()
55} 65}
56 66
57// Add a go-routine to the wait group. 67// Add a go-routine to the wait group.
diff --git a/src/gnunet/service/revocation/pow.go b/src/gnunet/service/revocation/pow.go
index 368b4e4..07c6241 100644
--- a/src/gnunet/service/revocation/pow.go
+++ b/src/gnunet/service/revocation/pow.go
@@ -20,12 +20,12 @@ package revocation
20 20
21import ( 21import (
22 "bytes" 22 "bytes"
23 "crypto/cipher"
23 "crypto/sha256" 24 "crypto/sha256"
24 "crypto/sha512" 25 "crypto/sha512"
25 "encoding/binary" 26 "encoding/binary"
26 "sync" 27 "sync"
27 28
28 "gnunet/crypto"
29 "gnunet/util" 29 "gnunet/util"
30 30
31 "github.com/bfix/gospel/crypto/ed25519" 31 "github.com/bfix/gospel/crypto/ed25519"
@@ -33,6 +33,7 @@ import (
33 "github.com/bfix/gospel/math" 33 "github.com/bfix/gospel/math"
34 "golang.org/x/crypto/hkdf" 34 "golang.org/x/crypto/hkdf"
35 "golang.org/x/crypto/scrypt" 35 "golang.org/x/crypto/scrypt"
36 "golang.org/x/crypto/twofish"
36) 37)
37 38
38//---------------------------------------------------------------------- 39//----------------------------------------------------------------------
@@ -73,6 +74,11 @@ func (r *RevData) GetNonce() uint64 {
73 return r.Nonce 74 return r.Nonce
74} 75}
75 76
77// GetBlob returns the binary representation of RevData
78func (r *RevData) GetBlob() []byte {
79 return r.blob
80}
81
76// Next selects the next nonce to be tested. 82// Next selects the next nonce to be tested.
77func (r *RevData) Next() { 83func (r *RevData) Next() {
78 var incr func(pos int) 84 var incr func(pos int)
@@ -91,33 +97,27 @@ func (r *RevData) Next() {
91func (r *RevData) Compute() (*math.Int, error) { 97func (r *RevData) Compute() (*math.Int, error) {
92 98
93 // generate key material 99 // generate key material
94 k, err := scrypt.Key(r.blob, []byte("gnunet-revocation-proof-of-work"), 2, 8, 2, 64) 100 k, err := scrypt.Key(r.blob, []byte("gnunet-revocation-proof-of-work"), 2, 8, 2, 32)
95 if err != nil { 101 if err != nil {
96 return nil, err 102 return nil, err
97 } 103 }
98 104
99 // generate keys
100 skey := crypto.NewSymmetricKey()
101 copy(skey.AESKey, k[:32])
102 copy(skey.TwofishKey, k[32:])
103
104 // generate initialization vector 105 // generate initialization vector
105 iv := crypto.NewSymmetricIV() 106 iv := make([]byte, 16)
106 prk := hkdf.Extract(sha512.New, k[:32], []byte("gnunet-proof-of-work-ivAES!")) 107 prk := hkdf.Extract(sha512.New, k, []byte("gnunet-proof-of-work-iv"))
107 rdr := hkdf.Expand(sha256.New, prk, []byte("gnunet-revocation-proof-of-work")) 108 rdr := hkdf.Expand(sha256.New, prk, []byte("gnunet-revocation-proof-of-work"))
108 rdr.Read(iv.AESIv) 109 rdr.Read(iv)
109 prk = hkdf.Extract(sha512.New, k[32:], []byte("gnunet-proof-of-work-ivFISH"))
110 rdr = hkdf.Expand(sha256.New, prk, []byte("gnunet-revocation-proof-of-work"))
111 rdr.Read(iv.TwofishIv)
112 110
113 // perform encryption 111 // Encrypt with Twofish CFB stream cipher
114 enc, err := crypto.SymmetricEncrypt(r.blob, skey, iv) 112 out := make([]byte, len(r.blob))
113 tf, err := twofish.NewCipher(k)
115 if err != nil { 114 if err != nil {
116 return nil, err 115 return nil, err
117 } 116 }
117 cipher.NewCFBEncrypter(tf, iv).XORKeyStream(out, r.blob)
118 118
119 // compute result 119 // compute result
120 result, err := scrypt.Key(enc, []byte("gnunet-revocation-proof-of-work"), 2, 8, 2, 64) 120 result, err := scrypt.Key(out, []byte("gnunet-revocation-proof-of-work"), 2, 8, 2, 64)
121 return math.NewIntFromBytes(result), nil 121 return math.NewIntFromBytes(result), nil
122} 122}
123 123