diff options
author | Bernd Fix <brf@hoi-polloi.org> | 2020-04-01 21:53:16 +0200 |
---|---|---|
committer | Bernd Fix <brf@hoi-polloi.org> | 2020-04-01 21:53:16 +0200 |
commit | 3d0b7cab3e273dd2f3f3d8990fb868b93b6b3f95 (patch) | |
tree | 57e067073267b9c052008e79efd539abee3ad947 | |
parent | db7da66be57c6a9df87f3ea1f3cd681539ad9b51 (diff) | |
download | gnunet-go-3d0b7cab3e273dd2f3f3d8990fb868b93b6b3f95.tar.gz gnunet-go-3d0b7cab3e273dd2f3f3d8990fb868b93b6b3f95.zip |
Adjusted revocation PoW to draft specification.
-rw-r--r-- | src/cmd/pow-test/main.go | 9 | ||||
-rw-r--r-- | src/gnunet/service/context.go | 34 | ||||
-rw-r--r-- | src/gnunet/service/revocation/pow.go | 32 |
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 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
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. |
32 | type SessionContext struct { | 32 | type 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. |
40 | func NewSessionContext() *SessionContext { | 42 | func 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. |
50 | func (ctx *SessionContext) Cancel() { | 54 | func (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 | ||
21 | import ( | 21 | import ( |
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 | ||
78 | func (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. |
77 | func (r *RevData) Next() { | 83 | func (r *RevData) Next() { |
78 | var incr func(pos int) | 84 | var incr func(pos int) |
@@ -91,33 +97,27 @@ func (r *RevData) Next() { | |||
91 | func (r *RevData) Compute() (*math.Int, error) { | 97 | func (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 | ||