aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Fix <brf@hoi-polloi.org>2023-07-20 07:12:52 +0200
committerBernd Fix <brf@hoi-polloi.org>2023-07-20 07:12:52 +0200
commite6d51d271ff295d4d48861a52bb00fce70629565 (patch)
tree8ef2ebdc614a0e249a0f0172c5457053045f79fa
parent920de01ad2fcdc07e33c36700cd99cd39ea5dde6 (diff)
downloadgnunet-go-master.tar.gz
gnunet-go-master.zip
EDKEY: derived private key clamping fixed.HEADv0.1.42master
-rw-r--r--src/gnunet/crypto/gns_edkey.go27
-rw-r--r--src/gnunet/crypto/gns_edkey_test.go39
-rw-r--r--src/gnunet/service/gns/rfc-data_test.go43
-rw-r--r--src/gnunet/service/gns/rfc_test.go2
-rw-r--r--src/gnunet/service/revocation/pow_test.go332
5 files changed, 279 insertions, 164 deletions
diff --git a/src/gnunet/crypto/gns_edkey.go b/src/gnunet/crypto/gns_edkey.go
index b7e88b3..930c140 100644
--- a/src/gnunet/crypto/gns_edkey.go
+++ b/src/gnunet/crypto/gns_edkey.go
@@ -1,5 +1,5 @@
1// This file is part of gnunet-go, a GNUnet-implementation in Golang. 1// This file is part of gnunet-go, a GNUnet-implementation in Golang.
2// Copyright (C) 2019-2022 Bernd Fix >Y< 2// Copyright (C) 2019-2023 Bernd Fix >Y<
3// 3//
4// gnunet-go is free software: you can redistribute it and/or modify it 4// gnunet-go is free software: you can redistribute it and/or modify it
5// under the terms of the GNU Affero General Public License as published 5// under the terms of the GNU Affero General Public License as published
@@ -53,17 +53,17 @@ func init() {
53} 53}
54 54
55//---------------------------------------------------------------------- 55//----------------------------------------------------------------------
56// Private key 56// Public key
57//---------------------------------------------------------------------- 57//----------------------------------------------------------------------
58 58
59// EDKEYPublicImpl implements the public key scheme. 59// EDKEYPublicImpl implements the EDKEY public key scheme.
60type EDKEYPublicImpl struct { 60type EDKEYPublicImpl struct {
61 ztype enums.GNSType 61 ztype enums.GNSType
62 pub *ed25519.PublicKey 62 pub *ed25519.PublicKey
63} 63}
64 64
65// Init instance from binary data. The data represents a big integer 65// Init instance from binary data. The data represents a binary
66// (in big-endian notation) for the private scalar d. 66// representation of a curve point (as defined in RFC 8032).
67func (pk *EDKEYPublicImpl) Init(data []byte) error { 67func (pk *EDKEYPublicImpl) Init(data []byte) error {
68 pk.ztype = ZONE_EDKEY 68 pk.ztype = ZONE_EDKEY
69 pk.pub = ed25519.NewPublicKeyFromBytes(data) 69 pk.pub = ed25519.NewPublicKeyFromBytes(data)
@@ -79,8 +79,8 @@ func (pk *EDKEYPublicImpl) Bytes() []byte {
79// Derive a public key from this key based on a big integer 79// Derive a public key from this key based on a big integer
80// (key blinding). Returns the derived key and the blinding value. 80// (key blinding). Returns the derived key and the blinding value.
81func (pk *EDKEYPublicImpl) Derive(h *math.Int) (dPk ZoneKeyImpl, hOut *math.Int, err error) { 81func (pk *EDKEYPublicImpl) Derive(h *math.Int) (dPk ZoneKeyImpl, hOut *math.Int, err error) {
82 // limit to allowed value range (see LSD0001 spec) 82 // limit to allowed value range (see LSD0001 spec, 5.1.2.)
83 hOut = h.SetBit(255, 0) 83 hOut = h.Mod(ed25519.GetCurve().N)
84 derived := pk.pub.Mult(hOut) 84 derived := pk.pub.Mult(hOut)
85 dPk = &EDKEYPublicImpl{ 85 dPk = &EDKEYPublicImpl{
86 pk.ztype, 86 pk.ztype,
@@ -178,8 +178,8 @@ type EDKEYPrivateImpl struct {
178 prv *ed25519.PrivateKey // private key 178 prv *ed25519.PrivateKey // private key
179} 179}
180 180
181// Init instance from binary data. The data represents a big integer 181// Init instance from binary data. The data represents the seed
182// (in big-endian notation) for the private scalar d. 182// used to generate the private scalar and nonce (see RFC 8032).
183func (pk *EDKEYPrivateImpl) Init(data []byte) error { 183func (pk *EDKEYPrivateImpl) Init(data []byte) error {
184 pk.seed = util.Clone(data) 184 pk.seed = util.Clone(data)
185 pk.prv = ed25519.NewPrivateKeyFromSeed(data) 185 pk.prv = ed25519.NewPrivateKeyFromSeed(data)
@@ -208,9 +208,14 @@ func (pk *EDKEYPrivateImpl) Public() ZoneKeyImpl {
208// (key blinding). Returns the derived key and the blinding value. 208// (key blinding). Returns the derived key and the blinding value.
209func (pk *EDKEYPrivateImpl) Derive(h *math.Int) (dPk ZonePrivateImpl, hOut *math.Int, err error) { 209func (pk *EDKEYPrivateImpl) Derive(h *math.Int) (dPk ZonePrivateImpl, hOut *math.Int, err error) {
210 // limit to allowed value range (see LSD0001 spec 5.1.2) 210 // limit to allowed value range (see LSD0001 spec 5.1.2)
211 hOut = h.SetBit(255, 0) 211 hOut = h.Mod(ed25519.GetCurve().N)
212
212 // derive private key 213 // derive private key
213 derived := pk.prv.Mult(hOut) 214 a1 := pk.prv.D.Rsh(3)
215 a2 := h.Mul(a1).Mod(ed25519.GetCurve().N)
216 dd := a2.Lsh(3)
217 derived := ed25519.NewPrivateKeyFromD(dd)
218
214 // derive nonce 219 // derive nonce
215 md := sha256.Sum256(append(pk.prv.Nonce, h.Bytes()...)) 220 md := sha256.Sum256(append(pk.prv.Nonce, h.Bytes()...))
216 derived.Nonce = md[:] 221 derived.Nonce = md[:]
diff --git a/src/gnunet/crypto/gns_edkey_test.go b/src/gnunet/crypto/gns_edkey_test.go
index b5ba700..145bfab 100644
--- a/src/gnunet/crypto/gns_edkey_test.go
+++ b/src/gnunet/crypto/gns_edkey_test.go
@@ -22,7 +22,11 @@ import (
22 "bytes" 22 "bytes"
23 "encoding/hex" 23 "encoding/hex"
24 "gnunet/enums" 24 "gnunet/enums"
25 "gnunet/util"
25 "testing" 26 "testing"
27
28 "github.com/bfix/gospel/crypto/ed25519"
29 "github.com/bfix/gospel/math"
26) 30)
27 31
28func TestEdKeyCreate(t *testing.T) { 32func TestEdKeyCreate(t *testing.T) {
@@ -58,3 +62,38 @@ func TestDeriveEDKEY(t *testing.T) {
58 t.Fatal("derive mismatch") 62 t.Fatal("derive mismatch")
59 } 63 }
60} 64}
65
66// test 'DerivedSign' from LSD0001, 5.1.2. EDKEY
67func TestDerivedSign(t *testing.T) {
68
69 for i := 0; i < 20; i++ {
70 // generate clamped private scalar and keys (EdDSA)
71 a := util.NewRndArray(32)
72 a[31] &= 248
73 a[0] &= 127
74 a[0] |= 64
75 d := math.NewIntFromBytes(a)
76 zp := ed25519.NewPrivateKeyFromD(d)
77 zk := zp.Public()
78
79 // calculate blinding factor
80 h := math.NewIntRnd(ed25519N)
81
82 // derive keys
83 dzp := zp.Mult(h)
84 dzk := zk.Mult(h)
85 if !dzk.Q.Equals(dzp.Public().Q) {
86 t.Fatal("derive")
87 }
88
89 // per draft:
90 a1 := d.Rsh(3)
91 a2 := h.Mul(a1).Mod(ed25519N)
92 dd := a2.Lsh(3)
93 dzp2 := ed25519.NewPrivateKeyFromD(dd)
94 dzk2 := dzp2.Public()
95 if !dzk.Q.Equals(dzk2.Q) {
96 t.Fatal("mismatch")
97 }
98 }
99}
diff --git a/src/gnunet/service/gns/rfc-data_test.go b/src/gnunet/service/gns/rfc-data_test.go
index 28d76dd..5bc44c1 100644
--- a/src/gnunet/service/gns/rfc-data_test.go
+++ b/src/gnunet/service/gns/rfc-data_test.go
@@ -237,8 +237,8 @@ var tests = []*TestCase{
237 Ztld: "000G051WYJWJ80S04BRDRM2R2H9VGQCKP13VCFA4DHC4BJT88HEXQ5K8HW", 237 Ztld: "000G051WYJWJ80S04BRDRM2R2H9VGQCKP13VCFA4DHC4BJT88HEXQ5K8HW",
238 Label: "testdelegation", 238 Label: "testdelegation",
239 Dzprv: []byte{ 239 Dzprv: []byte{
240 0x0b, 0x1b, 0x29, 0xd4, 0x23, 0x0b, 0x10, 0xa8, 0xec, 0x4d, 0xa3, 0xc8, 0x6e, 0xdb, 0x88, 0xea, 240 0x3b, 0x1b, 0x29, 0xd4, 0x23, 0x0b, 0x10, 0xa8, 0xec, 0x4d, 0xa3, 0xc8, 0x6e, 0xdb, 0x88, 0xea,
241 0x8e, 0xb7, 0x1a, 0xc0, 0x34, 0xf4, 0x8d, 0x74, 0xa1, 0xa0, 0x16, 0x2d, 0xb4, 0x4e, 0x47, 0xd1, 241 0xcd, 0x54, 0x08, 0x5c, 0x1d, 0xdb, 0x63, 0xf7, 0xa9, 0xd7, 0x3f, 0x7c, 0xcb, 0x2f, 0xc3, 0x98,
242 }, 242 },
243 Dzpub: []byte{ 243 Dzpub: []byte{
244 0x9b, 0xf2, 0x33, 0x19, 0x8c, 0x6d, 0x53, 0xbb, 0xdb, 0xac, 0x49, 0x5c, 0xab, 0xd9, 0x10, 0x49, 244 0x9b, 0xf2, 0x33, 0x19, 0x8c, 0x6d, 0x53, 0xbb, 0xdb, 0xac, 0x49, 0x5c, 0xab, 0xd9, 0x10, 0x49,
@@ -252,7 +252,7 @@ var tests = []*TestCase{
252 }, 252 },
253 Recs: []*Rec{ 253 Recs: []*Rec{
254 { 254 {
255 Expire: []byte{0x00, 0x08, 0xc0, 0x6f, 0xb9, 0x28, 0x15, 0x80}, 255 Expire: []byte{0x00, 0x1c, 0xee, 0x8c, 0x10, 0xe2, 0x59, 0x80},
256 Size: []byte{0x00, 0x20}, 256 Size: []byte{0x00, 0x20},
257 Type: []byte{0x00, 0x01, 0x00, 0x00}, 257 Type: []byte{0x00, 0x01, 0x00, 0x00},
258 Flags: []byte{0x00, 0x01}, 258 Flags: []byte{0x00, 0x01},
@@ -263,39 +263,38 @@ var tests = []*TestCase{
263 }, 263 },
264 }, 264 },
265 Rdata: []byte{ 265 Rdata: []byte{
266 0x00, 0x08, 0xc0, 0x6f, 0xb9, 0x28, 0x15, 0x80, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 266 0x00, 0x1c, 0xee, 0x8c, 0x10, 0xe2, 0x59, 0x80, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
267 0x21, 0xe3, 0xb3, 0x0f, 0xf9, 0x3b, 0xc6, 0xd3, 0x5a, 0xc8, 0xc6, 0xe0, 0xe1, 0x3a, 0xfd, 0xff, 267 0x21, 0xe3, 0xb3, 0x0f, 0xf9, 0x3b, 0xc6, 0xd3, 0x5a, 0xc8, 0xc6, 0xe0, 0xe1, 0x3a, 0xfd, 0xff,
268 0x79, 0x4c, 0xb7, 0xb4, 0x4b, 0xbb, 0xc7, 0x48, 0xd2, 0x59, 0xd0, 0xa0, 0x28, 0x4d, 0xbe, 0x84, 268 0x79, 0x4c, 0xb7, 0xb4, 0x4b, 0xbb, 0xc7, 0x48, 0xd2, 0x59, 0xd0, 0xa0, 0x28, 0x4d, 0xbe, 0x84,
269 }, 269 },
270 Enc: &Enc{ 270 Enc: &Enc{
271 Nonce: []byte{ 271 Nonce: []byte{
272 0x98, 0x13, 0x2e, 0xa8, 0x68, 0x59, 0xd3, 0x5c, 272 0x98, 0x13, 0x2e, 0xa8, 0x68, 0x59, 0xd3, 0x5c, 0x88, 0xbf, 0xd3, 0x17, 0xfa, 0x99, 0x1b, 0xcb,
273 0x88, 0xbf, 0xd3, 0x17, 0xfa, 0x99, 0x1b, 0xcb,
274 }, 273 },
275 Expire: []byte{0x00, 0x08, 0xc0, 0x6f, 0xb9, 0x28, 0x15, 0x80}, 274 Expire: []byte{0x00, 0x1c, 0xee, 0x8c, 0x10, 0xe2, 0x59, 0x80},
276 Key: []byte{ 275 Key: []byte{
277 0x85, 0xc4, 0x29, 0xa9, 0x56, 0x7a, 0xa6, 0x33, 0x41, 0x1a, 0x96, 0x91, 0xe9, 0x09, 0x4c, 0x45, 276 0x85, 0xc4, 0x29, 0xa9, 0x56, 0x7a, 0xa6, 0x33, 0x41, 0x1a, 0x96, 0x91, 0xe9, 0x09, 0x4c, 0x45,
278 0x28, 0x16, 0x72, 0xbe, 0x58, 0x60, 0x34, 0xaa, 0xe4, 0xa2, 0xa2, 0xcc, 0x71, 0x61, 0x59, 0xe2, 277 0x28, 0x16, 0x72, 0xbe, 0x58, 0x60, 0x34, 0xaa, 0xe4, 0xa2, 0xa2, 0xcc, 0x71, 0x61, 0x59, 0xe2,
279 }, 278 },
280 }, 279 },
281 Bdata: []byte{ 280 Bdata: []byte{
282 0x9c, 0xc4, 0x55, 0xa1, 0x29, 0x33, 0x19, 0x43, 0x59, 0x93, 0xcb, 0x3d, 0x67, 0x17, 0x9e, 0xc0, 281 0x57, 0x7c, 0xc6, 0xc9, 0x5a, 0x14, 0xe7, 0x04, 0x09, 0xf2, 0x0b, 0x01, 0x67, 0xe6, 0x36, 0xd0,
283 0x6e, 0xa8, 0xd8, 0x89, 0x4e, 0x90, 0x4a, 0x0c, 0x35, 0xe9, 0x1c, 0x5c, 0x2f, 0xf2, 0xed, 0x93, 282 0x10, 0x80, 0x7c, 0x4f, 0x00, 0x37, 0x2d, 0x69, 0x8c, 0x82, 0x6b, 0xd9, 0x2b, 0xc2, 0x2b, 0xd6,
284 0x9c, 0xc2, 0xf8, 0x30, 0x12, 0x31, 0xf4, 0x4e, 0x59, 0x2a, 0x4a, 0xc8, 0x7e, 0x49, 0x98, 0xb9, 283 0xbb, 0x45, 0xe5, 0x27, 0x7c, 0x01, 0x88, 0x1d, 0x6a, 0x43, 0x60, 0x68, 0xe4, 0xdd, 0xf1, 0xc6,
285 0x46, 0x25, 0xc6, 0x4a, 0xf5, 0x16, 0x86, 0xa2, 0xb3, 0x6a, 0x2b, 0x28, 0x92, 0xd4, 0x4f, 0x2d, 284 0xb7, 0xd1, 0x41, 0x6f, 0xaf, 0xa6, 0x69, 0x7c, 0x25, 0xed, 0xd9, 0xea, 0xe9, 0x91, 0x67, 0xc3,
286 }, 285 },
287 RRblock: []byte{ 286 RRblock: []byte{
288 0x00, 0x00, 0x00, 0xb0, 0x00, 0x01, 0x00, 0x14, 0x9b, 0xf2, 0x33, 0x19, 0x8c, 0x6d, 0x53, 0xbb, 287 0x00, 0x00, 0x00, 0xb0, 0x00, 0x01, 0x00, 0x14, 0x9b, 0xf2, 0x33, 0x19, 0x8c, 0x6d, 0x53, 0xbb,
289 0xdb, 0xac, 0x49, 0x5c, 0xab, 0xd9, 0x10, 0x49, 0xa6, 0x84, 0xaf, 0x3f, 0x40, 0x51, 0xba, 0xca, 288 0xdb, 0xac, 0x49, 0x5c, 0xab, 0xd9, 0x10, 0x49, 0xa6, 0x84, 0xaf, 0x3f, 0x40, 0x51, 0xba, 0xca,
290 0xb0, 0xdc, 0xf2, 0x1c, 0x8c, 0xf2, 0x7a, 0x1a, 0x44, 0xd2, 0x40, 0xd0, 0x79, 0x02, 0xf4, 0x90, 289 0xb0, 0xdc, 0xf2, 0x1c, 0x8c, 0xf2, 0x7a, 0x1a, 0x9f, 0x56, 0xa8, 0x86, 0xea, 0x73, 0x9d, 0x59,
291 0xb7, 0xc4, 0x3e, 0xf0, 0x07, 0x58, 0xab, 0xce, 0x88, 0x51, 0xc1, 0x8c, 0x70, 0xac, 0x6d, 0xf9, 290 0x17, 0x50, 0x8f, 0x9b, 0x75, 0x56, 0x39, 0xf3, 0xa9, 0xac, 0xfa, 0xed, 0xed, 0xca, 0x7f, 0xbf,
292 0x7a, 0x88, 0xf7, 0x92, 0x11, 0xcf, 0x87, 0x5f, 0x78, 0x48, 0x85, 0xca, 0x3e, 0x34, 0x9e, 0xc4, 291 0xa7, 0x94, 0xb1, 0x92, 0xe0, 0x8b, 0xf9, 0xed, 0x4c, 0x7e, 0xc8, 0x59, 0x4c, 0x9f, 0x7b, 0x4e,
293 0xca, 0x89, 0x2b, 0x9f, 0xf0, 0x84, 0xc5, 0x35, 0x89, 0x65, 0xb8, 0xe7, 0x4a, 0x23, 0x15, 0x95, 292 0x19, 0x77, 0x4f, 0xf8, 0x38, 0xec, 0x38, 0x7a, 0x8f, 0x34, 0x23, 0xda, 0xac, 0x44, 0x9f, 0x59,
294 0x2d, 0x4c, 0x8c, 0x06, 0x52, 0x1c, 0x2f, 0x0c, 0x00, 0x08, 0xc0, 0x6f, 0xb9, 0x28, 0x15, 0x80, 293 0xdb, 0x4e, 0x83, 0x94, 0x3f, 0x90, 0x72, 0x00, 0x00, 0x1c, 0xee, 0x8c, 0x10, 0xe2, 0x59, 0x80,
295 0x9c, 0xc4, 0x55, 0xa1, 0x29, 0x33, 0x19, 0x43, 0x59, 0x93, 0xcb, 0x3d, 0x67, 0x17, 0x9e, 0xc0, 294 0x57, 0x7c, 0xc6, 0xc9, 0x5a, 0x14, 0xe7, 0x04, 0x09, 0xf2, 0x0b, 0x01, 0x67, 0xe6, 0x36, 0xd0,
296 0x6e, 0xa8, 0xd8, 0x89, 0x4e, 0x90, 0x4a, 0x0c, 0x35, 0xe9, 0x1c, 0x5c, 0x2f, 0xf2, 0xed, 0x93, 295 0x10, 0x80, 0x7c, 0x4f, 0x00, 0x37, 0x2d, 0x69, 0x8c, 0x82, 0x6b, 0xd9, 0x2b, 0xc2, 0x2b, 0xd6,
297 0x9c, 0xc2, 0xf8, 0x30, 0x12, 0x31, 0xf4, 0x4e, 0x59, 0x2a, 0x4a, 0xc8, 0x7e, 0x49, 0x98, 0xb9, 296 0xbb, 0x45, 0xe5, 0x27, 0x7c, 0x01, 0x88, 0x1d, 0x6a, 0x43, 0x60, 0x68, 0xe4, 0xdd, 0xf1, 0xc6,
298 0x46, 0x25, 0xc6, 0x4a, 0xf5, 0x16, 0x86, 0xa2, 0xb3, 0x6a, 0x2b, 0x28, 0x92, 0xd4, 0x4f, 0x2d, 297 0xb7, 0xd1, 0x41, 0x6f, 0xaf, 0xa6, 0x69, 0x7c, 0x25, 0xed, 0xd9, 0xea, 0xe9, 0x91, 0x67, 0xc3,
299 }, 298 },
300 }, 299 },
301 // Testcase #4 300 // Testcase #4
@@ -312,8 +311,8 @@ var tests = []*TestCase{
312 Ztld: "000G051WYJWJ80S04BRDRM2R2H9VGQCKP13VCFA4DHC4BJT88HEXQ5K8HW", 311 Ztld: "000G051WYJWJ80S04BRDRM2R2H9VGQCKP13VCFA4DHC4BJT88HEXQ5K8HW",
313 Label: "天下無敵", 312 Label: "天下無敵",
314 Dzprv: []byte{ 313 Dzprv: []byte{
315 0x07, 0xc0, 0x68, 0xa6, 0xc3, 0xf7, 0x20, 0xde, 0x0e, 0x1b, 0x69, 0xff, 0x3f, 0x53, 0xe0, 0x5d, 314 0x17, 0xc0, 0x68, 0xa6, 0xc3, 0xf7, 0x20, 0xde, 0x0e, 0x1b, 0x69, 0xff, 0x3f, 0x53, 0xe0, 0x5d,
316 0x2b, 0x06, 0xcb, 0xd1, 0xae, 0x2d, 0xdd, 0xb3, 0x4e, 0x29, 0xb7, 0xb8, 0xfd, 0xce, 0x61, 0x6b, 315 0x3f, 0xe5, 0xc5, 0xb0, 0x51, 0x25, 0x7a, 0x89, 0xa6, 0x3c, 0x1a, 0xd3, 0x5a, 0xc4, 0x35, 0x58,
317 }, 316 },
318 Dzpub: []byte{ 317 Dzpub: []byte{
319 0x74, 0xf9, 0x00, 0x68, 0xf1, 0x67, 0x69, 0x53, 0x52, 0xa8, 0xa6, 0xc2, 0xeb, 0x98, 0x48, 0x98, 318 0x74, 0xf9, 0x00, 0x68, 0xf1, 0x67, 0x69, 0x53, 0x52, 0xa8, 0xa6, 0xc2, 0xeb, 0x98, 0x48, 0x98,
diff --git a/src/gnunet/service/gns/rfc_test.go b/src/gnunet/service/gns/rfc_test.go
index c18240e..9ae1f17 100644
--- a/src/gnunet/service/gns/rfc_test.go
+++ b/src/gnunet/service/gns/rfc_test.go
@@ -225,7 +225,7 @@ func TestRecordsRFC(t *testing.T) {
225 if !bytes.Equal(skey[:32], tc.Enc.Key) { 225 if !bytes.Equal(skey[:32], tc.Enc.Key) {
226 fmt.Printf("key = %s\n", hex.EncodeToString(skey[:32])) 226 fmt.Printf("key = %s\n", hex.EncodeToString(skey[:32]))
227 fmt.Printf("KEY = %s\n", hex.EncodeToString(tc.Enc.Key)) 227 fmt.Printf("KEY = %s\n", hex.EncodeToString(tc.Enc.Key))
228 t.Log("NONCE mismatch") 228 t.Log("KEY mismatch")
229 t.Fail() 229 t.Fail()
230 continue 230 continue
231 } 231 }
diff --git a/src/gnunet/service/revocation/pow_test.go b/src/gnunet/service/revocation/pow_test.go
index 1c8d3b9..837c78d 100644
--- a/src/gnunet/service/revocation/pow_test.go
+++ b/src/gnunet/service/revocation/pow_test.go
@@ -2,6 +2,7 @@ package revocation
2 2
3import ( 3import (
4 "bytes" 4 "bytes"
5 "encoding/binary"
5 "encoding/hex" 6 "encoding/hex"
6 "gnunet/crypto" 7 "gnunet/crypto"
7 "gnunet/enums" 8 "gnunet/enums"
@@ -10,146 +11,217 @@ import (
10 "github.com/bfix/gospel/data" 11 "github.com/bfix/gospel/data"
11) 12)
12 13
14// give more output in test run
15var verbose = false
16
13// Test revocation with test vector defined in the RFC draft. 17// Test revocation with test vector defined in the RFC draft.
14func TestRevocationRFC(t *testing.T) { 18func TestRevocationRFC(t *testing.T) {
15 var ( 19 type tc struct {
16 D = "6fea32c05af58bfa979553d188605fd57d8bf9cc263b78d5f7478c07b998ed70" 20 D string
17 ZKEY = "000100002ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa" 21 Zkey string
18 PROOF = "" + 22 Sdata string
23 Proof string
24 }
25 var trev = []*tc{
26 {
27 "6fea32c05af58bfa979553d188605fd57d8bf9cc263b78d5f7478c07b998ed70",
28 "000100002ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa",
29 "00000034000000030005feb46d865c1c000100002ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa",
19 "0005feb46d865c1c" + 30 "0005feb46d865c1c" +
20 "0000395d1827c000" + 31 "0000395d1827c000" +
21 "e66a570bccd4b393" + 32 "e66a570bccd4b393" +
22 "e66a570bccd4b3ea" + 33 "e66a570bccd4b3ea" +
23 "e66a570bccd4b536" + 34 "e66a570bccd4b536" +
24 "e66a570bccd4b542" + 35 "e66a570bccd4b542" +
25 "e66a570bccd4b613" + 36 "e66a570bccd4b613" +
26 "e66a570bccd4b65f" + 37 "e66a570bccd4b65f" +
27 "e66a570bccd4b672" + 38 "e66a570bccd4b672" +
28 "e66a570bccd4b70a" + 39 "e66a570bccd4b70a" +
29 "e66a570bccd4b71a" + 40 "e66a570bccd4b71a" +
30 "e66a570bccd4b723" + 41 "e66a570bccd4b723" +
31 "e66a570bccd4b747" + 42 "e66a570bccd4b747" +
32 "e66a570bccd4b777" + 43 "e66a570bccd4b777" +
33 "e66a570bccd4b785" + 44 "e66a570bccd4b785" +
34 "e66a570bccd4b789" + 45 "e66a570bccd4b789" +
35 "e66a570bccd4b7cf" + 46 "e66a570bccd4b7cf" +
36 "e66a570bccd4b7dc" + 47 "e66a570bccd4b7dc" +
37 "e66a570bccd4b93a" + 48 "e66a570bccd4b93a" +
38 "e66a570bccd4b956" + 49 "e66a570bccd4b956" +
39 "e66a570bccd4ba4a" + 50 "e66a570bccd4ba4a" +
40 "e66a570bccd4ba9d" + 51 "e66a570bccd4ba9d" +
41 "e66a570bccd4bb28" + 52 "e66a570bccd4bb28" +
42 "e66a570bccd4bb5a" + 53 "e66a570bccd4bb5a" +
43 "e66a570bccd4bb92" + 54 "e66a570bccd4bb92" +
44 "e66a570bccd4bba2" + 55 "e66a570bccd4bba2" +
45 "e66a570bccd4bbd8" + 56 "e66a570bccd4bbd8" +
46 "e66a570bccd4bbe2" + 57 "e66a570bccd4bbe2" +
47 "e66a570bccd4bc93" + 58 "e66a570bccd4bc93" +
48 "e66a570bccd4bc94" + 59 "e66a570bccd4bc94" +
49 "e66a570bccd4bd0f" + 60 "e66a570bccd4bd0f" +
50 "e66a570bccd4bdce" + 61 "e66a570bccd4bdce" +
51 "e66a570bccd4be6a" + 62 "e66a570bccd4be6a" +
52 "e66a570bccd4be73" + 63 "e66a570bccd4be73" +
53 "00010000" + 64 "000100002ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa" +
54 "2ca223e879ecc4bbdeb5da17319281d63b2e3b6955f1c3775c804a98d5f8ddaa" + 65 "044a878a158b40f0c841d9f978cb1372eaee5199a3d87e5e2bdbc72a6c8c73d0" +
55 "044a878a158b40f0c841d9f978cb1372eaee5199a3d87e5e2bdbc72a6c8c73d0" + 66 "00181dfc39c3aaa481667b165b5844e450713d8ab6a3b2ba8fef447b65076a0f",
56 "00181dfc39c3aaa481667b165b5844e450713d8ab6a3b2ba8fef447b65076a0f" 67 },
57 ) 68 {
58 69 "5af7020ee19160328832352bbc6a68a8d71a7cbe1b929969a7c66d415a0d8f65",
59 // construct private/public key pair from test data 70 "000100143cf4b924032022f0dc50581453b85d93b047b63d446c5845cb48445ddb96688f",
60 d, err := hex.DecodeString(D) 71 "00000034000000030005ff30b08e9e10000100143cf4b924032022f0dc50581453b85d93b047b63d446c5845cb48445ddb96688f",
61 if err != nil { 72 "0005ff30b08e9e10" +
62 t.Fatal(err) 73 "0000395d1827c000" +
63 } 74 "8802bc0f10057911" +
64 prv, err := crypto.NewZonePrivate(enums.GNS_TYPE_PKEY, d) 75 "8802bc0f10057e72" +
65 if err != nil { 76 "8802bc0f10057ea3" +
66 t.Fatal(err) 77 "8802bc0f10057ff9" +
78 "8802bc0f10058214" +
79 "8802bc0f10058231" +
80 "8802bc0f100582df" +
81 "8802bc0f10058328" +
82 "8802bc0f10058401" +
83 "8802bc0f1005841b" +
84 "8802bc0f10058567" +
85 "8802bc0f1005856e" +
86 "8802bc0f100585aa" +
87 "8802bc0f100585ad" +
88 "8802bc0f100585c7" +
89 "8802bc0f10058603" +
90 "8802bc0f10058612" +
91 "8802bc0f10058628" +
92 "8802bc0f10058703" +
93 "8802bc0f1005872a" +
94 "8802bc0f10058762" +
95 "8802bc0f10058787" +
96 "8802bc0f100587cb" +
97 "8802bc0f100587cd" +
98 "8802bc0f100587d3" +
99 "8802bc0f10058844" +
100 "8802bc0f100588a0" +
101 "8802bc0f100588e3" +
102 "8802bc0f100588e8" +
103 "8802bc0f10058918" +
104 "8802bc0f10058929" +
105 "8802bc0f10058946" +
106 "000100143cf4b924032022f0dc50581453b85d93b047b63d446c5845cb48445ddb96688f" +
107 "986741cf0ea6f2055571a5f38c78feede0ccf9f26b7b6e7a86d128b867512d06" +
108 "3c951229a8e3b99b49f5b38c0205d0bd706f8826ebbd4a16964e66962b720e08",
109 },
67 } 110 }
68 zk := prv.Public()
69 111
70 // check 112 for i, tc := range trev {
71 zkey, err := hex.DecodeString(ZKEY) 113 t.Logf("Testcase #%d:\n", i+1)
72 if err != nil {
73 t.Fatal(err)
74 }
75 if !bytes.Equal(zk.Bytes(), zkey) {
76 t.Logf("zkey = %s\n", hex.EncodeToString(zk.Bytes()))
77 t.Logf("ZKEY = %s\n", hex.EncodeToString(zkey))
78 t.Fatal("Private/Public key mismatch")
79 }
80 114
81 // assemble revocation data object 115 // decode zone key
82 revD, err := hex.DecodeString(PROOF) 116 zkey, err := hex.DecodeString(tc.Zkey)
83 if err != nil { 117 if err != nil {
84 t.Fatal(err) 118 t.Fatal(err)
85 } 119 }
86 revData := new(RevData) 120 // get ztype
87 if err = data.Unmarshal(revData, revD); err != nil { 121 var ztype enums.GNSType
88 t.Fatal(err) 122 if err = binary.Read(bytes.NewReader(zkey[:4]), binary.BigEndian, &ztype); err != nil {
89 } 123 t.Fatal(err)
90 if err = revData.ZoneKeySig.Init(); err != nil { 124 }
91 t.Fatal(err) 125 // construct private/public key pair from test data
92 } 126 d, err := hex.DecodeString(tc.D)
93 // check sigature 127 if err != nil {
94 if !bytes.Equal(revData.ZoneKeySig.ZoneKey.Bytes(), zkey) { 128 t.Fatal(err)
95 t.Logf("zkey = %s\n", hex.EncodeToString(revData.ZoneKeySig.Bytes())) 129 }
96 t.Logf("ZKEY = %s\n", hex.EncodeToString(zkey)) 130 prv, err := crypto.NewZonePrivate(ztype, d)
97 t.Fatal("Wrong zone key in test revocation") 131 if err != nil {
98 } 132 t.Fatal(err)
133 }
134 zk := prv.Public()
99 135
100 // show revdata content 136 // check for correct public key
101 if testing.Verbose() { 137 if !bytes.Equal(zk.Bytes(), zkey) {
102 t.Log("REVDATA:") 138 t.Logf(" zkey = %s\n", hex.EncodeToString(zk.Bytes()))
103 t.Logf(" Timestamp: %s\n", revData.Timestamp.String()) 139 t.Logf(" ZKEY = %s\n", tc.Zkey)
104 t.Logf(" TTL: %s\n", revData.TTL.String()) 140 t.Fatal("Failed: Private/Public key mismatch")
141 }
105 142
106 work := NewPoWData(0, revData.Timestamp, &revData.ZoneKeySig.ZoneKey) 143 // assemble revocation data object
107 for i, pow := range revData.PoWs { 144 revD, err := hex.DecodeString(tc.Proof)
108 t.Logf(" PoW #%d: %d\n", i, pow) 145 if err != nil {
109 work.SetPoW(pow) 146 t.Fatal(err)
110 buf := work.Blob() 147 }
111 t.Logf(" P: %s\n", hex.EncodeToString(buf)) 148 revData := new(RevData)
112 v := work.Compute() 149 if err = data.Unmarshal(revData, revD); err != nil {
113 t.Logf(" H: %s\n", hex.EncodeToString(v.Bytes())) 150 t.Fatal(err)
114 num := 512 - v.BitLen() 151 }
115 t.Logf(" --> %d leading zeros\n", num) 152 if err = revData.ZoneKeySig.Init(); err != nil {
116 } 153 t.Fatal(err)
117 t.Logf(" ZoneKey: %s\n", hex.EncodeToString(revData.ZoneKeySig.KeyData)) 154 }
118 t.Logf(" Signature: %s\n", hex.EncodeToString(revData.ZoneKeySig.Signature)) 155 // check sigature
119 } 156 if !bytes.Equal(revData.ZoneKeySig.ZoneKey.Bytes(), zkey) {
157 t.Logf(" zkey = %s\n", hex.EncodeToString(revData.ZoneKeySig.Bytes()))
158 t.Logf(" ZKEY = %s\n", tc.Zkey)
159 t.Fatal("Failed: Wrong zone key in test revocation")
160 }
161 // show revdata content
162 if verbose {
163 t.Log(" REVDATA:")
164 t.Logf(" Timestamp: %s\n", revData.Timestamp.String())
165 t.Logf(" TTL: %s\n", revData.TTL.String())
120 166
121 // assemble data for signature 167 work := NewPoWData(0, revData.Timestamp, &revData.ZoneKeySig.ZoneKey)
122 sigBlock := &SignedRevData{ 168 for i, pow := range revData.PoWs {
123 Purpose: &crypto.SignaturePurpose{ 169 t.Logf(" PoW #%d: %d\n", i, pow)
124 Size: uint32(20 + revData.ZoneKeySig.KeySize()), 170 work.SetPoW(pow)
125 Purpose: enums.SIG_REVOCATION, 171 buf := work.Blob()
126 }, 172 t.Logf(" P: %s\n", hex.EncodeToString(buf))
127 Timestamp: revData.Timestamp, 173 v := work.Compute()
128 ZoneKey: &revData.ZoneKeySig.ZoneKey, 174 t.Logf(" H: %s\n", hex.EncodeToString(v.Bytes()))
129 } 175 num := 512 - v.BitLen()
130 sigData, err := data.Marshal(sigBlock) 176 t.Logf(" --> %d leading zeros\n", num)
131 if err != nil { 177 }
132 t.Fatal(err) 178 t.Logf(" ZoneKey: %s\n", hex.EncodeToString(revData.ZoneKeySig.KeyData))
133 } 179 t.Logf(" Signature: %s\n", hex.EncodeToString(revData.ZoneKeySig.Signature))
134 if testing.Verbose() { 180 }
135 t.Logf("SigData = %s\n", hex.EncodeToString(sigData))
136 }
137 181
138 sigOut, err := prv.Sign(sigData) 182 // assemble data for signature
139 if err != nil { 183 sigBlock := &SignedRevData{
140 t.Fatal(err) 184 Purpose: &crypto.SignaturePurpose{
141 } 185 Size: uint32(20 + revData.ZoneKeySig.KeySize()),
142 if testing.Verbose() { 186 Purpose: enums.SIG_REVOCATION,
143 t.Logf("Signature = %s\n", hex.EncodeToString(sigOut.Signature)) 187 },
144 t.Logf(" ?= %s\n", hex.EncodeToString(revData.ZoneKeySig.Signature)) 188 Timestamp: revData.Timestamp,
145 } 189 ZoneKey: &revData.ZoneKeySig.ZoneKey,
190 }
191 sigData, err := data.Marshal(sigBlock)
192 if err != nil {
193 t.Fatal(err)
194 }
146 195
147 // verify revocation data object 196 // check sigdata
148 diff, rc := revData.Verify(true) 197 sdata, err := hex.DecodeString(tc.Sdata)
149 if testing.Verbose() { 198 if err != nil {
150 t.Logf("Average difficulty of PoWs = %f\n", diff) 199 t.Fatal(err)
151 } 200 }
152 if rc != 0 { 201 if !bytes.Equal(sigData, sdata) {
153 t.Fatalf("REV_Verify (pkey): %d\n", rc) 202 t.Logf(" SigData = %s\n", hex.EncodeToString(sigData))
203 t.Logf(" != %s\n", tc.Sdata)
204 t.Fatal("Failed: signed data mismatch")
205 }
206
207 // sign data
208 sigOut, err := prv.Sign(sigData)
209 if err != nil {
210 t.Fatal(err)
211 }
212 if !bytes.Equal(sigOut.Signature, revData.ZoneKeySig.Signature) {
213 t.Logf(" Signature = %s\n", hex.EncodeToString(sigOut.Signature))
214 t.Logf(" != %s\n", hex.EncodeToString(revData.ZoneKeySig.Signature))
215 t.Fatal("Failed: signature mismatch")
216 }
217
218 // verify revocation data object
219 diff, rc := revData.Verify(true)
220 if testing.Verbose() {
221 t.Logf(" Average difficulty of PoWs = %f\n", diff)
222 }
223 if rc != 0 {
224 t.Fatalf("REV_Verify (pkey): %d\n", rc)
225 }
154 } 226 }
155} 227}