diff --git a/.github/workflows/go_lint.yml b/.github/workflows/go_lint.yml deleted file mode 100644 index d9d9d5128..000000000 --- a/.github/workflows/go_lint.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Go lint - -on: - push: - branches: [ master ] - pull_request_target: - types: [opened, synchronize, reopened] - -jobs: - - lint: - runs-on: ubuntu-latest - steps: - - name: Set up Go ^1.20 - uses: actions/setup-go@v3 - with: - go-version: ^1.20 - - - name: Check out code into the Go module directory - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Tidy - run: go mod tidy && [ -z "$(git status -s)" ] - - - name: Lint - run: make lint - - - name: Vet - run: make vet diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 000000000..a18fe8de3 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,54 @@ +name: Lint +on: + push: + branches: [ master ] + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + # pull-requests: read + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version: '1.20' + cache: false + - name: golangci-lint + uses: golangci/golangci-lint-action@v4 + with: + # Require: The version of golangci-lint to use. + # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. + # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. + version: v1.56.2 + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # + # Note: By default, the `.golangci.yml` file should be at the root of the repository. + # The location of the configuration file can be changed by using `--config=` + # args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true, then all caching functionality will be completely disabled, + # takes precedence over all other caching options. + # skip-cache: true + + # Optional: if set to true, then the action won't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true, then the action won't cache or restore ~/.cache/go-build. + # skip-build-cache: true + + # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'. + # install-mode: "goinstall" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 48a3c84bb..f06b923d6 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ exit_tunnel .DS_Store *.cov profile.tmp -Coding/ \ No newline at end of file +Coding/ +.idea/ diff --git a/.golangci.yml b/.golangci.yml index e2a66021d..7385ac54e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -8,6 +8,10 @@ run: # This file contains only configs which differ from defaults. # All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml linters-settings: + staticcheck: + checks: + - all + - '-SA1019' # Ignore deprecated for now cyclop: # The maximal code complexity to report. # Default: 10 @@ -93,6 +97,10 @@ linters-settings: - G107 # variables in URLs - G404 # use of weak random generator + gocritic: + disabled-checks: + - captLocal + linters: disable-all: true enable: @@ -109,7 +117,7 @@ linters: - asciicheck # checks that your code does not contain non-ASCII identifiers - bidichk # checks for dangerous unicode character sequences - bodyclose # checks whether HTTP response body is closed successfully - #- contextcheck # checks the function whether use a non-inherited context # TODO: enable after golangci-lint uses https://github.com/sylvia7788/contextcheck/releases/tag/v1.0.7 + - contextcheck # checks the function whether use a non-inherited context - cyclop # checks function and package cyclomatic complexity - dupl # tool for code clone detection - durationcheck # checks for two durations multiplied together @@ -163,7 +171,7 @@ linters: #- decorder # checks declaration order and count of types, constants, variables and functions #- exhaustruct # checks if all structure fields are initialized #- gci # controls golang package import order and makes it always deterministic - - godox # detects FIXME, TODO and other comment keywords + #- godox # detects FIXME, TODO and other comment keywords #- goheader # checks is file header matches to pattern - interfacebloat # checks the number of methods inside an interface #- ireturn # accept interfaces, return concrete types @@ -246,3 +254,42 @@ issues: - linters: - govet text: "shadow: declaration of \"err\" shadows declaration" + - path: 'group.go' + linters: + - interfacebloat + - path: 'group/edwards25519/scalar.go' + linters: + - ineffassign + - funlen + - path: 'group/edwards25519/const.go' + linters: + - lll + - path: 'group/edwards25519/fe.go' + linters: + - funlen + - path: "share/dkg/pedersen" + linters: + - gocognit + - funlen + - gocyclo + - cyclop + - path: "group/edwards25519/scalar.go" + linters: + - ineffassign + - path: "pairing|group" + linters: + - revive + - stylecheck + text: "var-naming: don't use an underscore in package name|ST1003: should not use underscores in package names" + - path: "pairing/(circl_bls12381|bn254)/." + linters: + - errcheck #TODO: proper error handling + text: "Error return value is not checked" + - path: "encrypt/ibe/ibe.go" + linters: + - stylecheck # Keep variable name as is + text: "var Gid should be GID|var hrGid should be hrGID|rGid should be rGID|var hGidT should be hGIDT|var GidT should be GIDT" + - path: "pairing/bls12381/circl/*|pairing/bls12381/kilic/*" + linters: + - errcheck + text: "Error return value is not checked" diff --git a/Makefile b/Makefile index 720452255..f480eb391 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ lint: tidy #golangci-lint run #staticcheck go list ./... - vet: tidy go vet ./... @@ -24,4 +23,4 @@ coverage: tidy # target to run all the possible checks; it's a good habit to run it before # pushing code check: lint vet test - echo "check done" \ No newline at end of file + echo "check done" diff --git a/encrypt/ecies/ecies.go b/encrypt/ecies/ecies.go index e36b698a4..aa7413cb3 100644 --- a/encrypt/ecies/ecies.go +++ b/encrypt/ecies/ecies.go @@ -36,13 +36,13 @@ func Encrypt(group kyber.Group, public kyber.Point, message []byte, hash func() // ephemeral key for every ECIES encryption and thus have a fresh // HKDF-derived key for AES-GCM, the nonce for AES-GCM can be an arbitrary // (even static) value. We derive it here simply via HKDF as well.) - len := 32 + 12 - buf, err := deriveKey(hash, dh, len) + keyNonceLen := 32 + 12 + buf, err := deriveKey(hash, dh, keyNonceLen) if err != nil { return nil, err } key := buf[:32] - nonce := buf[32:len] + nonce := buf[32:keyNonceLen] // Encrypt message using AES-GCM aes, err := aes.NewCipher(key) @@ -91,13 +91,13 @@ func Decrypt(group kyber.Group, private kyber.Scalar, ctx []byte, hash func() ha // Compute shared DH key and derive the symmetric key and nonce via HKDF dh := group.Point().Mul(private, R) - len := 32 + 12 - buf, err := deriveKey(hash, dh, len) + keyNonceLen := 32 + 12 + buf, err := deriveKey(hash, dh, keyNonceLen) if err != nil { return nil, err } key := buf[:32] - nonce := buf[32:len] + nonce := buf[32:keyNonceLen] // Decrypt message using AES-GCM aes, err := aes.NewCipher(key) @@ -111,18 +111,18 @@ func Decrypt(group kyber.Group, private kyber.Scalar, ctx []byte, hash func() ha return aesgcm.Open(nil, nonce, ctx[l:], nil) } -func deriveKey(hash func() hash.Hash, dh kyber.Point, len int) ([]byte, error) { +func deriveKey(hash func() hash.Hash, dh kyber.Point, l int) ([]byte, error) { dhb, err := dh.MarshalBinary() if err != nil { return nil, err } hkdf := hkdf.New(hash, dhb, nil, nil) - key := make([]byte, len, len) + key := make([]byte, l) n, err := hkdf.Read(key) if err != nil { return nil, err } - if n < len { + if n < l { return nil, errors.New("ecies: hkdf-derived key too short") } return key, nil diff --git a/encrypt/ibe/ibe.go b/encrypt/ibe/ibe.go index 592a3f726..d9c5a05d4 100644 --- a/encrypt/ibe/ibe.go +++ b/encrypt/ibe/ibe.go @@ -46,6 +46,8 @@ func H4Tag() []byte { // - msg is the actual message // - seed is the random seed to generate the random element (sigma) of the encryption // The suite must produce points which implements the `HashablePoint` interface. +// +//nolint:dupl // unavoidable func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphertext, error) { if len(msg) > s.Hash().Size() { return nil, errors.New("plaintext too long for the hash function provided") @@ -62,7 +64,7 @@ func EncryptCCAonG1(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphe // 2. Derive random sigma sigma := make([]byte, len(msg)) if _, err := rand.Read(sigma); err != nil { - return nil, fmt.Errorf("err reading rand sigma: %v", err) + return nil, fmt.Errorf("err reading rand sigma: %w", err) } // 3. Derive r from sigma and msg r, err := h3(s, sigma, msg) @@ -141,23 +143,25 @@ func DecryptCCAonG1(s pairing.Suite, private kyber.Point, c *Ciphertext) ([]byte // - msg is the actual message // - seed is the random seed to generate the random element (sigma) of the encryption // The suite must produce points which implements the `HashablePoint` interface. +// +//nolint:dupl // unavoidable func EncryptCCAonG2(s pairing.Suite, master kyber.Point, ID, msg []byte) (*Ciphertext, error) { if len(msg) > s.Hash().Size() { return nil, errors.New("plaintext too long for the hash function provided") } // 1. Compute Gid = e(Q_id, master) - hG2, ok := s.G1().Point().(kyber.HashablePoint) + hG1, ok := s.G1().Point().(kyber.HashablePoint) if !ok { return nil, errors.New("point needs to implement `kyber.HashablePoint`") } - Qid := hG2.Hash(ID) + Qid := hG1.Hash(ID) Gid := s.Pair(Qid, master) // 2. Derive random sigma sigma := make([]byte, len(msg)) if _, err := rand.Read(sigma); err != nil { - return nil, fmt.Errorf("err reading rand sigma: %v", err) + return nil, fmt.Errorf("err reading rand sigma: %w", err) } // 3. Derive r from sigma and msg r, err := h3(s, sigma, msg) @@ -231,10 +235,10 @@ func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) { h := s.Hash() if _, err := h.Write(H3Tag()); err != nil { - return nil, fmt.Errorf("err hashing h3 tag: %v", err) + return nil, fmt.Errorf("err hashing h3 tag: %w", err) } if _, err := h.Write(sigma); err != nil { - return nil, fmt.Errorf("err hashing sigma: %v", err) + return nil, fmt.Errorf("err hashing sigma: %w", err) } _, _ = h.Write(msg) // we hash it a first time: buffer = hash("IBE-H3" || sigma || msg) @@ -258,7 +262,7 @@ func h3(s pairing.Suite, sigma, msg []byte) (kyber.Scalar, error) { // but we assume that toMask is a few bits, at most 8. // For instance when using BLS12-381 toMask == 1. if hashable.ByteOrder() == kyber.BigEndian { - hashed[0] = hashed[0] >> toMask + hashed[0] >>= toMask } else { hashed[len(hashed)-1] = hashed[len(hashed)-1] >> toMask } @@ -280,10 +284,10 @@ func h4(s pairing.Suite, sigma []byte, length int) ([]byte, error) { h4 := s.Hash() if _, err := h4.Write(H4Tag()); err != nil { - return nil, fmt.Errorf("err writing h4tag: %v", err) + return nil, fmt.Errorf("err writing h4tag: %w", err) } if _, err := h4.Write(sigma); err != nil { - return nil, fmt.Errorf("err writing sigma to h4: %v", err) + return nil, fmt.Errorf("err writing sigma to h4: %w", err) } h4sigma := h4.Sum(nil)[:length] @@ -305,7 +309,7 @@ func gtToHash(s pairing.Suite, gt kyber.Point, length int) ([]byte, error) { if _, err := hashReader.Read(b); err != nil { return nil, errors.New("couldn't read from hash output") } - return b[:], nil + return b, nil } func xor(a, b []byte) []byte { diff --git a/group/edwards25519/const.go b/group/edwards25519/const.go index a9c8c5ce2..38c6824aa 100644 --- a/group/edwards25519/const.go +++ b/group/edwards25519/const.go @@ -1,7 +1,6 @@ // Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. - package edwards25519 import ( @@ -44,6 +43,7 @@ var sqrtM1 = fieldElement{ -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482, } +//nolint:unused // May be used later var paramA = fieldElement{ 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0, } @@ -55,6 +55,7 @@ var baseext = extendedGroupElement{ fieldElement{6966464, -2456167, 7033433, 6781840, 28785542, 12262365, -2659449, 13959020, -21013759, -5262166}, } +//nolint:unused // May be used later var bi = [8]preComputedGroupElement{ { fieldElement{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, diff --git a/group/edwards25519/curve.go b/group/edwards25519/curve.go index 2e0815370..88a989415 100644 --- a/group/edwards25519/curve.go +++ b/group/edwards25519/curve.go @@ -49,12 +49,12 @@ func (c *Curve) Point() kyber.Point { // requiring it to be a multiple of 8). It also returns the input and the digest used // to generate the key. func (c *Curve) NewKeyAndSeedWithInput(buffer []byte) (kyber.Scalar, []byte, []byte) { - digest := sha512.Sum512(buffer[:]) + digest := sha512.Sum512(buffer) digest[0] &= 0xf8 digest[31] &= 0x7f digest[31] |= 0x40 - secret := c.Scalar().(*scalar) + secret := c.Scalar().(*scalar) //nolint:errcheck // V4 may bring better error handling copy(secret.v[:], digest[:]) return secret, buffer, digest[32:] } diff --git a/group/edwards25519/fe.go b/group/edwards25519/fe.go index 30e6b6deb..f77286832 100644 --- a/group/edwards25519/fe.go +++ b/group/edwards25519/fe.go @@ -1,7 +1,6 @@ // Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. - package edwards25519 import ( @@ -78,7 +77,7 @@ func load4(in []byte) int64 { } func feFromBytes(dst *fieldElement, src []byte) { - h0 := load4(src[:]) + h0 := load4(src) h1 := load3(src[4:]) << 6 h2 := load3(src[7:]) << 5 h3 := load3(src[10:]) << 3 diff --git a/group/edwards25519/fe_test.go b/group/edwards25519/fe_test.go index abcd69bcd..9a3cf986a 100644 --- a/group/edwards25519/fe_test.go +++ b/group/edwards25519/fe_test.go @@ -63,7 +63,7 @@ func Test_feBnConversionRandom(t *testing.T) { b0 = b0.Mod(b0, prime) b1 := big.NewInt(0).SetBytes(p1) - b0 = b1.Mod(b1, prime) + b1 = b1.Mod(b1, prime) b2 := big.NewInt(0).SetBytes(p2) b2 = b1.Mod(b2, prime) diff --git a/group/edwards25519/ge.go b/group/edwards25519/ge.go index d5d1daba0..d18dabe20 100644 --- a/group/edwards25519/ge.go +++ b/group/edwards25519/ge.go @@ -149,10 +149,11 @@ func (p *extendedGroupElement) FromBytes(s []byte) bool { } func (p *extendedGroupElement) String() string { + sep := ",\n\t" return "extendedGroupElement{\n\t" + - p.X.String() + ",\n\t" + - p.Y.String() + ",\n\t" + - p.Z.String() + ",\n\t" + + p.X.String() + sep + + p.Y.String() + sep + + p.Z.String() + sep + p.T.String() + ",\n}" } @@ -177,6 +178,7 @@ func (p *preComputedGroupElement) Zero() { feZero(&p.xy2d) } +//nolint:dupl // Extracting common parts makes little sense func (c *completedGroupElement) Add(p *extendedGroupElement, q *cachedGroupElement) { var t0 fieldElement @@ -193,6 +195,7 @@ func (c *completedGroupElement) Add(p *extendedGroupElement, q *cachedGroupEleme feSub(&c.T, &t0, &c.T) } +//nolint:dupl // Extracting common parts makes little sense func (c *completedGroupElement) Sub(p *extendedGroupElement, q *cachedGroupElement) { var t0 fieldElement @@ -209,6 +212,7 @@ func (c *completedGroupElement) Sub(p *extendedGroupElement, q *cachedGroupEleme feAdd(&c.T, &t0, &c.T) } +//nolint:dupl // Extracting common parts makes little sense func (c *completedGroupElement) MixedAdd(p *extendedGroupElement, q *preComputedGroupElement) { var t0 fieldElement @@ -224,6 +228,7 @@ func (c *completedGroupElement) MixedAdd(p *extendedGroupElement, q *preComputed feSub(&c.T, &t0, &c.T) } +//nolint:dupl // Extracting common parts makes little sense func (c *completedGroupElement) MixedSub(p *extendedGroupElement, q *preComputedGroupElement) { var t0 fieldElement @@ -287,8 +292,9 @@ func (r *cachedGroupElement) Neg(t *cachedGroupElement) { // each multiplier is either zero or an odd number between -15 and 15. // Assumes the target array r has been preinitialized with zeros // in case the input slice a is less than 32 bytes. +// +//nolint:gocognit func slide(r *[256]int8, a *[32]byte) { - // Explode the exponent a into a little-endian array, one bit per byte for i := range a { ai := int8(a[i]) @@ -305,12 +311,14 @@ func slide(r *[256]int8, a *[32]byte) { // 1-bit encountered in a clump, and that first bit always remains 1. for i := range r { if r[i] != 0 { + innerLoop: for b := 1; b <= 6 && i+b < 256; b++ { if r[i+b] != 0 { - if r[i]+(r[i+b]<= -15 { + case r[i]-(r[i+b]<= -15: r[i] -= r[i+b] << uint(b) for k := i + b; k < 256; k++ { if r[k] == 0 { @@ -319,8 +327,8 @@ func slide(r *[256]int8, a *[32]byte) { } r[k] = 0 } - } else { - break + default: + break innerLoop } } } @@ -354,11 +362,13 @@ func selectPreComputed(t *preComputedGroupElement, pos int32, b int32) { } // geScalarMultBase computes h = a*B, where -// a = a[0]+256*a[1]+...+256^31 a[31] -// B is the Ed25519 base point (x,4/5) with x positive. +// +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. // // Preconditions: -// a[31] <= 127 +// +// a[31] <= 127 func geScalarMultBase(h *extendedGroupElement, a *[32]byte) { var e [64]int8 @@ -422,11 +432,13 @@ func selectCached(c *cachedGroupElement, Ai *[8]cachedGroupElement, b int32) { } // geScalarMult computes h = a*B, where -// a = a[0]+256*a[1]+...+256^31 a[31] -// B is the Ed25519 base point (x,4/5) with x positive. +// +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. // // Preconditions: -// a[31] <= 127 +// +// a[31] <= 127 func geScalarMult(h *extendedGroupElement, a *[32]byte, A *extendedGroupElement) { diff --git a/group/edwards25519/ge_mult_vartime.go b/group/edwards25519/ge_mult_vartime.go index 9ddd61fdf..9b97ec8a5 100644 --- a/group/edwards25519/ge_mult_vartime.go +++ b/group/edwards25519/ge_mult_vartime.go @@ -1,11 +1,13 @@ package edwards25519 // geScalarMultVartime computes h = a*B, where -// a = a[0]+256*a[1]+...+256^31 a[31] -// B is the Ed25519 base point (x,4/5) with x positive. +// +// a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. // // Preconditions: -// a[31] <= 127 +// +// a[31] <= 127 func geScalarMultVartime(h *extendedGroupElement, a *[32]byte, A *extendedGroupElement) { diff --git a/group/edwards25519/point.go b/group/edwards25519/point.go index 98cc54c5e..c117a8fc0 100644 --- a/group/edwards25519/point.go +++ b/group/edwards25519/point.go @@ -185,8 +185,8 @@ func (P *point) Data() ([]byte, error) { } func (P *point) Add(P1, P2 kyber.Point) kyber.Point { - E1 := P1.(*point) - E2 := P2.(*point) + E1 := P1.(*point) //nolint:errcheck // V4 may bring better error handling + E2 := P2.(*point) //nolint:errcheck // V4 may bring better error handling var t2 cachedGroupElement var r completedGroupElement @@ -199,8 +199,8 @@ func (P *point) Add(P1, P2 kyber.Point) kyber.Point { } func (P *point) Sub(P1, P2 kyber.Point) kyber.Point { - E1 := P1.(*point) - E2 := P2.(*point) + E1 := P1.(*point) //nolint:errcheck // V4 may bring better error handling + E2 := P2.(*point) //nolint:errcheck // V4 may bring better error handling var t2 cachedGroupElement var r completedGroupElement @@ -245,6 +245,8 @@ func (P *point) Mul(s kyber.Scalar, A kyber.Point) kyber.Point { // // This is the same code as in // https://github.com/jedisct1/libsodium/blob/4744636721d2e420f8bbe2d563f31b1f5e682229/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c#L1170 +// +//nolint:lll // Url above func (P *point) HasSmallOrder() bool { s, err := P.MarshalBinary() if err != nil { @@ -281,6 +283,8 @@ func (P *point) HasSmallOrder() bool { // // The method accepts a buffer instead of calling `MarshalBinary` on the receiver // because that always returns a value modulo `prime`. +// +//nolint:lll // Url above func (P *point) IsCanonical(s []byte) bool { if len(s) != 32 { return false @@ -479,6 +483,8 @@ func byteXor(dst, b1, b2 []byte) ([]byte, error) { // curve25519Elligator2 implements a map from fieldElement to a point on Curve25519 // as defined in section G.2.1. of [RFC9380] // [RFC9380]: https://datatracker.ietf.org/doc/html/rfc9380#ell2-opt +// +//nolint:funlen func curve25519Elligator2(u fieldElement) (xn, xd, yn, yd fieldElement) { // Some const needed var one fieldElement @@ -526,7 +532,7 @@ func curve25519Elligator2(u fieldElement) (xn, xd, yn, yd fieldElement) { feSquare(&tv2, &y11) // tv2 = y11^2 feMul(&tv2, &tv2, &gxd) // tv2 = tv2 * gxd - //y1 = y11 if e1 == 1 else y12 + // y1 = y11 if e1 == 1 else y12 if tv2 == gx1 { e1 = 1 } diff --git a/group/edwards25519/scalar.go b/group/edwards25519/scalar.go index 0783fb4ca..c295a5d5f 100644 --- a/group/edwards25519/scalar.go +++ b/group/edwards25519/scalar.go @@ -1,7 +1,6 @@ // Copyright 2013 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. - package edwards25519 import ( @@ -114,7 +113,7 @@ func (s *scalar) Div(a, b kyber.Scalar) kyber.Scalar { func (s *scalar) Inv(a kyber.Scalar) kyber.Scalar { var res scalar res.One() - ac := a.(*scalar) + ac := a.(*scalar) //nolint:errcheck // V4 may bring better error handling // Modular inversion in a multiplicative group is a^(phi(m)-1) = a^-1 mod m // Since m is prime, phi(m) = m - 1 => a^(m-2) = a^-1 mod m. // The inverse is computed using the exponentation-and-square algorithm. @@ -1932,6 +1931,8 @@ func scMul(s, a, b *[32]byte) { // // s[0]+256*s[1]+...+256^31*s[31] = s mod l // where l = 2^252 + 27742317777372353535851937790883648493. +// +//nolint:unused // May be used later func scReduce(out *[32]byte, s *[64]byte) { s0 := 2097151 & load3(s[:]) s1 := 2097151 & (load4(s[2:]) >> 5) @@ -2257,6 +2258,8 @@ func scReduce(out *[32]byte, s *[64]byte) { // for a reference. // The method accepts a buffer instead of calling `MarshalBinary` on the receiver since that // always returns values modulo `primeOrder`. +// +//nolint:lll // Url above func (s *scalar) IsCanonical(sb []byte) bool { if len(sb) != 32 { return false diff --git a/group/edwards25519/scalar_test.go b/group/edwards25519/scalar_test.go index 07d48b53c..bdd2629b7 100644 --- a/group/edwards25519/scalar_test.go +++ b/group/edwards25519/scalar_test.go @@ -70,21 +70,21 @@ func newFactoredScalar() kyber.Scalar { func (s *factoredScalar) Add(s1, s2 kyber.Scalar) kyber.Scalar { sf1 := s1.(*factoredScalar) sf2 := s2.(*factoredScalar) - scAddFact(&s.v, &sf1.v, &sf2.v) + scAddFact(&sf1.v, &sf2.v) return s } func (s *factoredScalar) Mul(s1, s2 kyber.Scalar) kyber.Scalar { sf1 := s1.(*factoredScalar) sf2 := s2.(*factoredScalar) - scMulFact(&s.v, &sf1.v, &sf2.v) + scMulFact(&sf1.v, &sf2.v) return s } func (s *factoredScalar) Sub(s1, s2 kyber.Scalar) kyber.Scalar { sf1 := s1.(*factoredScalar) sf2 := s2.(*factoredScalar) - scSubFact(&s.v, &sf1.v, &sf2.v) + scSubFact(&sf1.v, &sf2.v) return s } @@ -123,14 +123,14 @@ func TestSetBytesLE(t *testing.T) { } } -func testSimple(t *testing.T, new func() kyber.Scalar) { - s1 := new() - s2 := new() - s3 := new() +func testSimple(t *testing.T, f func() kyber.Scalar) { + s1 := f() + s2 := f() + s3 := f() s1.SetInt64(2) s2.Pick(random.New()) - s22 := new().Add(s2, s2) + s22 := f().Add(s2, s2) if !s3.Mul(s1, s2).Equal(s22) { t.Fail() @@ -138,11 +138,11 @@ func testSimple(t *testing.T, new func() kyber.Scalar) { } -func benchScalarAdd(b *testing.B, new func() kyber.Scalar) { +func benchScalarAdd(b *testing.B, f func() kyber.Scalar) { var seed = tSuite.XOF([]byte("hello world")) - s1 := new() - s2 := new() - s3 := new() + s1 := f() + s2 := f() + s3 := f() s1.Pick(seed) s2.Pick(seed) @@ -151,11 +151,11 @@ func benchScalarAdd(b *testing.B, new func() kyber.Scalar) { } } -func benchScalarMul(b *testing.B, new func() kyber.Scalar) { +func benchScalarMul(b *testing.B, f func() kyber.Scalar) { var seed = tSuite.XOF([]byte("hello world")) - s1 := new() - s2 := new() - s3 := new() + s1 := f() + s2 := f() + s3 := f() s1.Pick(seed) s2.Pick(seed) @@ -164,11 +164,11 @@ func benchScalarMul(b *testing.B, new func() kyber.Scalar) { } } -func benchScalarSub(b *testing.B, new func() kyber.Scalar) { +func benchScalarSub(b *testing.B, f func() kyber.Scalar) { var seed = tSuite.XOF([]byte("hello world")) - s1 := new() - s2 := new() - s3 := new() + s1 := f() + s2 := f() + s3 := f() s1.Pick(seed) s2.Pick(seed) @@ -226,11 +226,9 @@ func doReduction(limbs [24]int64, i int) { } func scReduceLimbs(limbs [24]int64) { - //for i in 0..23 { for i := 0; i < 23; i++ { doCarryCentered(limbs, i) } - //for i in (0..23).filter(|x| x % 2 == 1) { for i := 1; i < 23; i += 2 { doCarryCentered(limbs, i) } @@ -242,12 +240,10 @@ func scReduceLimbs(limbs [24]int64) { doReduction(limbs, 19) doReduction(limbs, 18) - //for i in (6..18).filter(|x| x % 2 == 0) { for i := 6; i < 18; i += 2 { doCarryCentered(limbs, i) } - // for i in (6..16).filter(|x| x % 2 == 1) { for i := 7; i < 16; i += 2 { doCarryCentered(limbs, i) } @@ -258,31 +254,27 @@ func scReduceLimbs(limbs [24]int64) { doReduction(limbs, 13) doReduction(limbs, 12) - //for i in (0..12).filter(|x| x % 2 == 0) { for i := 0; i < 12; i += 2 { doCarryCentered(limbs, i) } - //for i in (0..12).filter(|x| x % 2 == 1) { for i := 1; i < 12; i += 2 { doCarryCentered(limbs, i) } doReduction(limbs, 12) - //for i in 0..12 { for i := 0; i < 12; i++ { doCarryUncentered(limbs, i) } doReduction(limbs, 12) - //for i in 0..11 { for i := 0; i < 11; i++ { doCarryUncentered(limbs, i) } } -func scAddFact(s, a, c *[32]byte) { +func scAddFact(a, c *[32]byte) { a0 := 2097151 & load3(a[:]) a1 := 2097151 & (load4(a[2:]) >> 5) a2 := 2097151 & (load3(a[5:]) >> 2) @@ -337,7 +329,7 @@ func scAddFact(s, a, c *[32]byte) { scReduceLimbs(limbs) } -func scMulFact(s, a, b *[32]byte) { +func scMulFact(a, b *[32]byte) { a0 := 2097151 & load3(a[:]) a1 := 2097151 & (load4(a[2:]) >> 5) a2 := 2097151 & (load3(a[5:]) >> 2) @@ -404,7 +396,7 @@ func scMulFact(s, a, b *[32]byte) { scReduceLimbs(limbs) } -func scSubFact(s, a, c *[32]byte) { +func scSubFact(a, c *[32]byte) { a0 := 2097151 & load3(a[:]) a1 := 2097151 & (load4(a[2:]) >> 5) a2 := 2097151 & (load3(a[5:]) >> 2) diff --git a/group/edwards25519/suite.go b/group/edwards25519/suite.go index fd15f80bc..3f1f838f2 100644 --- a/group/edwards25519/suite.go +++ b/group/edwards25519/suite.go @@ -36,7 +36,7 @@ func (s *SuiteEd25519) Read(r io.Reader, objs ...interface{}) error { } func (s *SuiteEd25519) Write(w io.Writer, objs ...interface{}) error { - return fixbuf.Write(w, objs) + return fixbuf.Write(w, objs...) } // New implements the kyber.Encoding interface diff --git a/group/mod/int.go b/group/mod/int.go index c4abf59dc..741b5ca0e 100644 --- a/group/mod/int.go +++ b/group/mod/int.go @@ -14,8 +14,6 @@ import ( "go.dedis.ch/kyber/v4/util/random" ) -var one = big.NewInt(1) -var two = big.NewInt(2) var marshalScalarID = [8]byte{'m', 'o', 'd', '.', 'i', 'n', 't', ' '} // Int is a generic implementation of finite field arithmetic @@ -48,8 +46,8 @@ func NewInt(v *big.Int, m *big.Int) *Int { } // NewInt64 creates a new Int with a given int64 value and big.Int modulus. -func NewInt64(v int64, M *big.Int) *Int { - return new(Int).Init64(v, M) +func NewInt64(v int64, m *big.Int) *Int { + return new(Int).Init64(v, m) } // NewIntBytes creates a new Int with a given slice of bytes and a big.Int @@ -66,10 +64,10 @@ func NewIntString(n, d string, base int, m *big.Int) *Int { // Init a Int with a given big.Int value and modulus pointer. // Note that the value is copied; the modulus is not. -func (i *Int) Init(V *big.Int, m *big.Int) *Int { +func (i *Int) Init(v *big.Int, m *big.Int) *Int { i.M = m i.BO = kyber.BigEndian - i.V.Set(V).Mod(&i.V, m) + i.V.Set(v).Mod(&i.V, m) return i } @@ -143,7 +141,7 @@ func (i *Int) Nonzero() bool { // Since this method copies the modulus as well, // it may be used as an alternative to Init(). func (i *Int) Set(a kyber.Scalar) kyber.Scalar { - ai := a.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling i.V.Set(&ai.V) i.M = ai.M return i @@ -196,8 +194,8 @@ func (i *Int) Uint64() uint64 { // Add sets the target to a + b mod M, where M is a's modulus.. func (i *Int) Add(a, b kyber.Scalar) kyber.Scalar { - ai := a.(*Int) - bi := b.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling + bi := b.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M i.V.Add(&ai.V, &bi.V).Mod(&i.V, i.M) return i @@ -206,8 +204,8 @@ func (i *Int) Add(a, b kyber.Scalar) kyber.Scalar { // Sub sets the target to a - b mod M. // Target receives a's modulus. func (i *Int) Sub(a, b kyber.Scalar) kyber.Scalar { - ai := a.(*Int) - bi := b.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling + bi := b.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M i.V.Sub(&ai.V, &bi.V).Mod(&i.V, i.M) return i @@ -215,7 +213,7 @@ func (i *Int) Sub(a, b kyber.Scalar) kyber.Scalar { // Neg sets the target to -a mod M. func (i *Int) Neg(a kyber.Scalar) kyber.Scalar { - ai := a.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M if ai.V.Sign() > 0 { i.V.Sub(i.M, &ai.V) @@ -228,8 +226,8 @@ func (i *Int) Neg(a kyber.Scalar) kyber.Scalar { // Mul sets the target to a * b mod M. // Target receives a's modulus. func (i *Int) Mul(a, b kyber.Scalar) kyber.Scalar { - ai := a.(*Int) - bi := b.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling + bi := b.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M i.V.Mul(&ai.V, &bi.V).Mod(&i.V, i.M) return i @@ -237,8 +235,8 @@ func (i *Int) Mul(a, b kyber.Scalar) kyber.Scalar { // Div sets the target to a * b^-1 mod M, where b^-1 is the modular inverse of b. func (i *Int) Div(a, b kyber.Scalar) kyber.Scalar { - ai := a.(*Int) - bi := b.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling + bi := b.(*Int) //nolint:errcheck // V4 may bring better error handling var t big.Int i.M = ai.M i.V.Mul(&ai.V, t.ModInverse(&bi.V, i.M)) @@ -248,7 +246,7 @@ func (i *Int) Div(a, b kyber.Scalar) kyber.Scalar { // Inv sets the target to the modular inverse of a with respect to modulus M. func (i *Int) Inv(a kyber.Scalar) kyber.Scalar { - ai := a.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M i.V.ModInverse(&a.(*Int).V, i.M) return i @@ -257,7 +255,7 @@ func (i *Int) Inv(a kyber.Scalar) kyber.Scalar { // Exp sets the target to a^e mod M, // where e is an arbitrary big.Int exponent (not necessarily 0 <= e < M). func (i *Int) Exp(a kyber.Scalar, e *big.Int) kyber.Scalar { - ai := a.(*Int) + ai := a.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M // to protect against golang/go#22830 var tmp big.Int @@ -269,7 +267,7 @@ func (i *Int) Exp(a kyber.Scalar, e *big.Int) kyber.Scalar { // Jacobi computes the Jacobi symbol of (a/M), which indicates whether a is // zero (0), a positive square in M (1), or a non-square in M (-1). func (i *Int) Jacobi(as kyber.Scalar) kyber.Scalar { - ai := as.(*Int) + ai := as.(*Int) //nolint:errcheck // V4 may bring better error handling i.M = ai.M i.V.SetInt64(int64(big.Jacobi(&ai.V, i.M))) return i @@ -279,7 +277,7 @@ func (i *Int) Jacobi(as kyber.Scalar) kyber.Scalar { // Assumes the modulus M is an odd prime. // Returns true on success, false if input a is not a square. func (i *Int) Sqrt(as kyber.Scalar) bool { - ai := as.(*Int) + ai := as.(*Int) //nolint:errcheck // V4 may bring better error handling out := i.V.ModSqrt(&ai.V, ai.M) i.M = ai.M return out != nil diff --git a/group/mod/int_test.go b/group/mod/int_test.go index 6d2614ef4..143ec1afb 100644 --- a/group/mod/int_test.go +++ b/group/mod/int_test.go @@ -28,6 +28,7 @@ func TestIntEndianness(t *testing.T) { // Let's change endianness and check the result i.BO = kyber.LittleEndian buff3, err := i.MarshalBinary() + assert.Nil(t, err) assert.NotEqual(t, buff2, buff3) // let's try LittleEndian function diff --git a/group/p256/curve.go b/group/p256/curve.go index 21d53996d..f6a698b48 100644 --- a/group/p256/curve.go +++ b/group/p256/curve.go @@ -18,167 +18,164 @@ type curvePoint struct { c *curve } -func (p *curvePoint) String() string { - return "(" + p.x.String() + "," + p.y.String() + ")" +func (P *curvePoint) String() string { + return "(" + P.x.String() + "," + P.y.String() + ")" } -func (p *curvePoint) Equal(p2 kyber.Point) bool { - cp2 := p2.(*curvePoint) +func (P *curvePoint) Equal(P2 kyber.Point) bool { + cp2 := P2.(*curvePoint) //nolint:errcheck // V4 may bring better error handling // Make sure both coordinates are normalized. // Apparently Go's elliptic curve code doesn't always ensure this. - M := p.c.p.P - p.x.Mod(p.x, M) - p.y.Mod(p.y, M) + M := P.c.p.P + P.x.Mod(P.x, M) + P.y.Mod(P.y, M) cp2.x.Mod(cp2.x, M) cp2.y.Mod(cp2.y, M) - return p.x.Cmp(cp2.x) == 0 && p.y.Cmp(cp2.y) == 0 + return P.x.Cmp(cp2.x) == 0 && P.y.Cmp(cp2.y) == 0 } -func (p *curvePoint) Null() kyber.Point { - p.x = new(big.Int).SetInt64(0) - p.y = new(big.Int).SetInt64(0) - return p +func (P *curvePoint) Null() kyber.Point { + P.x = new(big.Int).SetInt64(0) + P.y = new(big.Int).SetInt64(0) + return P } -func (p *curvePoint) Base() kyber.Point { - p.x = p.c.p.Gx - p.y = p.c.p.Gy - return p +func (P *curvePoint) Base() kyber.Point { + P.x = P.c.p.Gx + P.y = P.c.p.Gy + return P } -func (p *curvePoint) Valid() bool { +func (P *curvePoint) Valid() bool { // The IsOnCurve function in Go's elliptic curve package // doesn't consider the point-at-infinity to be "on the curve" - return p.c.IsOnCurve(p.x, p.y) || - (p.x.Sign() == 0 && p.y.Sign() == 0) + return P.c.IsOnCurve(P.x, P.y) || + (P.x.Sign() == 0 && P.y.Sign() == 0) } // Try to generate a point on this curve from a chosen x-coordinate, // with a random sign. -func (p *curvePoint) genPoint(x *big.Int, rand cipher.Stream) bool { - +func (P *curvePoint) genPoint(x *big.Int, rand cipher.Stream) bool { // Compute the corresponding Y coordinate, if any y2 := new(big.Int).Mul(x, x) y2.Mul(y2, x) threeX := new(big.Int).Lsh(x, 1) threeX.Add(threeX, x) y2.Sub(y2, threeX) - y2.Add(y2, p.c.p.B) - y2.Mod(y2, p.c.p.P) - y := p.c.sqrt(y2) + y2.Add(y2, P.c.p.B) + y2.Mod(y2, P.c.p.P) + y := P.c.sqrt(y2) // Pick a random sign for the y coordinate b := make([]byte, 1) rand.XORKeyStream(b, b) if (b[0] & 0x80) != 0 { - y.Sub(p.c.p.P, y) + y.Sub(P.c.p.P, y) } // Check that it's a valid point y2t := new(big.Int).Mul(y, y) - y2t.Mod(y2t, p.c.p.P) + y2t.Mod(y2t, P.c.p.P) if y2t.Cmp(y2) != 0 { return false // Doesn't yield a valid point! } - p.x = x - p.y = y + P.x = x + P.y = y return true } -func (p *curvePoint) EmbedLen() int { +func (P *curvePoint) EmbedLen() int { // Reserve at least 8 most-significant bits for randomness, // and the least-significant 8 bits for embedded data length. // (Hopefully it's unlikely we'll need >=2048-bit curves soon.) - return (p.c.p.P.BitLen() - 8 - 8) / 8 + return (P.c.p.P.BitLen() - 8 - 8) / 8 } -func (p *curvePoint) Pick(rand cipher.Stream) kyber.Point { - return p.Embed(nil, rand) +func (P *curvePoint) Pick(rand cipher.Stream) kyber.Point { + return P.Embed(nil, rand) } -// Pick a curve point containing a variable amount of embedded data. +// Embed picks a curve point containing a variable amount of embedded data. // Remaining bits comprising the point are chosen randomly. -func (p *curvePoint) Embed(data []byte, rand cipher.Stream) kyber.Point { - - l := p.c.coordLen() - dl := p.EmbedLen() +func (P *curvePoint) Embed(data []byte, rand cipher.Stream) kyber.Point { + l := P.c.coordLen() + dl := P.EmbedLen() if dl > len(data) { dl = len(data) } for { - b := random.Bits(uint(p.c.p.P.BitLen()), false, rand) + b := random.Bits(uint(P.c.p.P.BitLen()), false, rand) if data != nil { b[l-1] = byte(dl) // Encode length in low 8 bits copy(b[l-dl-1:l-1], data) // Copy in data to embed } - if p.genPoint(new(big.Int).SetBytes(b), rand) { - return p + if P.genPoint(new(big.Int).SetBytes(b), rand) { + return P } } } -// Extract embedded data from a curve point -func (p *curvePoint) Data() ([]byte, error) { - b := p.x.Bytes() - l := p.c.coordLen() +// Data extracts embedded data from a curve point +func (P *curvePoint) Data() ([]byte, error) { + b := P.x.Bytes() + l := P.c.coordLen() if len(b) < l { // pad leading zero bytes if necessary b = append(make([]byte, l-len(b)), b...) } dl := int(b[l-1]) - if dl > p.EmbedLen() { + if dl > P.EmbedLen() { return nil, errors.New("invalid embedded data length") } return b[l-dl-1 : l-1], nil } -func (p *curvePoint) Add(a, b kyber.Point) kyber.Point { - ca := a.(*curvePoint) - cb := b.(*curvePoint) - p.x, p.y = p.c.Add(ca.x, ca.y, cb.x, cb.y) - return p +func (P *curvePoint) Add(A, B kyber.Point) kyber.Point { + ca := A.(*curvePoint) //nolint:errcheck // V4 may bring better error handling + cb := B.(*curvePoint) //nolint:errcheck // V4 may bring better error handling + P.x, P.y = P.c.Add(ca.x, ca.y, cb.x, cb.y) + return P } -func (p *curvePoint) Sub(a, b kyber.Point) kyber.Point { - ca := a.(*curvePoint) - cb := b.(*curvePoint) +func (P *curvePoint) Sub(A, B kyber.Point) kyber.Point { + ca := A.(*curvePoint) //nolint:errcheck // V4 may bring better error handling + cb := B.(*curvePoint) //nolint:errcheck // V4 may bring better error handling - cbn := p.c.Point().Neg(cb).(*curvePoint) - p.x, p.y = p.c.Add(ca.x, ca.y, cbn.x, cbn.y) - return p + cbn := P.c.Point().Neg(cb).(*curvePoint) //nolint:errcheck // V4 may bring better error handling + P.x, P.y = P.c.Add(ca.x, ca.y, cbn.x, cbn.y) + return P } -func (p *curvePoint) Neg(a kyber.Point) kyber.Point { - - s := p.c.Scalar().One() +func (P *curvePoint) Neg(A kyber.Point) kyber.Point { + s := P.c.Scalar().One() s.Neg(s) - return p.Mul(s, a).(*curvePoint) + return P.Mul(s, A).(*curvePoint) } -func (p *curvePoint) Mul(s kyber.Scalar, b kyber.Point) kyber.Point { - cs := s.(*mod.Int) - if b != nil { - cb := b.(*curvePoint) - p.x, p.y = p.c.ScalarMult(cb.x, cb.y, cs.V.Bytes()) +func (P *curvePoint) Mul(s kyber.Scalar, B kyber.Point) kyber.Point { + cs := s.(*mod.Int) //nolint:errcheck // V4 may bring better error handling + if B != nil { + cb := B.(*curvePoint) //nolint:errcheck // V4 may bring better error handling + P.x, P.y = P.c.ScalarMult(cb.x, cb.y, cs.V.Bytes()) } else { - p.x, p.y = p.c.ScalarBaseMult(cs.V.Bytes()) + P.x, P.y = P.c.ScalarBaseMult(cs.V.Bytes()) } - return p + return P } -func (p *curvePoint) MarshalSize() int { - coordlen := (p.c.Params().BitSize + 7) >> 3 +func (P *curvePoint) MarshalSize() int { + coordlen := (P.c.Params().BitSize + 7) >> 3 return 1 + 2*coordlen // uncompressed ANSI X9.62 representation } -func (p *curvePoint) MarshalBinary() ([]byte, error) { - return elliptic.Marshal(p.c, p.x, p.y), nil +func (P *curvePoint) MarshalBinary() ([]byte, error) { + return elliptic.Marshal(P.c, P.x, P.y), nil } -func (p *curvePoint) UnmarshalBinary(buf []byte) error { +func (P *curvePoint) UnmarshalBinary(buf []byte) error { // Check whether all bytes after first one are 0, so we // just return the initial point. Read everything to // prevent timing-leakage. @@ -187,24 +184,24 @@ func (p *curvePoint) UnmarshalBinary(buf []byte) error { c |= b } if c != 0 { - p.x, p.y = elliptic.Unmarshal(p.c, buf) - if p.x == nil || !p.Valid() { + P.x, P.y = elliptic.Unmarshal(P.c, buf) + if P.x == nil || !P.Valid() { return errors.New("invalid elliptic curve point") } } else { // All bytes are 0, so we initialize x and y - p.x = big.NewInt(0) - p.y = big.NewInt(0) + P.x = big.NewInt(0) + P.y = big.NewInt(0) } return nil } -func (p *curvePoint) MarshalTo(w io.Writer) (int, error) { - return marshalling.PointMarshalTo(p, w) +func (P *curvePoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(P, w) } -func (p *curvePoint) UnmarshalFrom(r io.Reader) (int, error) { - return marshalling.PointUnmarshalFrom(p, r) +func (P *curvePoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(P, r) } // interface for curve-specifc mathematical functions @@ -250,14 +247,14 @@ func (c *curve) Point() kyber.Point { return p } -func (p *curvePoint) Set(P kyber.Point) kyber.Point { - p.x = P.(*curvePoint).x - p.y = P.(*curvePoint).y - return p +func (P *curvePoint) Set(A kyber.Point) kyber.Point { + P.x = A.(*curvePoint).x + P.y = A.(*curvePoint).y + return P } -func (p *curvePoint) Clone() kyber.Point { - return &curvePoint{x: p.x, y: p.y, c: p.c} +func (P *curvePoint) Clone() kyber.Point { + return &curvePoint{x: P.x, y: P.y, c: P.c} } // Return the order of this curve: the prime N in the curve parameters. diff --git a/group/p256/qrsuite.go b/group/p256/qrsuite.go index 5e9623559..abfdcb989 100644 --- a/group/p256/qrsuite.go +++ b/group/p256/qrsuite.go @@ -37,11 +37,11 @@ func (s QrSuite) RandomStream() cipher.Stream { } func (s *QrSuite) Read(r io.Reader, objs ...interface{}) error { - return fixbuf.Read(r, s, objs) + return fixbuf.Read(r, s, objs...) } func (s *QrSuite) Write(w io.Writer, objs ...interface{}) error { - return fixbuf.Write(w, objs) + return fixbuf.Write(w, objs...) } // New implements the kyber.encoding interface @@ -56,7 +56,9 @@ func (s *QrSuite) New(t reflect.Type) interface{} { // This group size should be used only for testing and experimentation. // 512-bit DSA-style groups are no longer considered secure. func NewBlakeSHA256QR512() *QrSuite { + //nolint:lll p, _ := new(big.Int).SetString("10198267722357351868598076141027380280417188309231803909918464305012113541414604537422741096561285049775792035177041672305646773132014126091142862443826263", 10) + //nolint:lll q, _ := new(big.Int).SetString("5099133861178675934299038070513690140208594154615901954959232152506056770707302268711370548280642524887896017588520836152823386566007063045571431221913131", 10) r := new(big.Int).SetInt64(2) g := new(big.Int).SetInt64(4) diff --git a/group/p256/residue.go b/group/p256/residue.go index ab8c60373..a7eb6bbd0 100644 --- a/group/p256/residue.go +++ b/group/p256/residue.go @@ -30,140 +30,140 @@ func isPrime(i *big.Int) bool { return i.ProbablyPrime(numMRTests) } -func (p *residuePoint) String() string { return p.Int.String() } +func (P *residuePoint) String() string { return P.Int.String() } -func (p *residuePoint) Equal(p2 kyber.Point) bool { - return p.Int.Cmp(&p2.(*residuePoint).Int) == 0 +func (P *residuePoint) Equal(p2 kyber.Point) bool { + return P.Int.Cmp(&p2.(*residuePoint).Int) == 0 } -func (p *residuePoint) Null() kyber.Point { - p.Int.SetInt64(1) - return p +func (P *residuePoint) Null() kyber.Point { + P.Int.SetInt64(1) + return P } -func (p *residuePoint) Base() kyber.Point { - p.Int.Set(p.g.G) - return p +func (P *residuePoint) Base() kyber.Point { + P.Int.Set(P.g.G) + return P } -func (p *residuePoint) Set(p2 kyber.Point) kyber.Point { - p.g = p2.(*residuePoint).g - p.Int = p2.(*residuePoint).Int - return p +func (P *residuePoint) Set(P2 kyber.Point) kyber.Point { + P.g = P2.(*residuePoint).g + P.Int = P2.(*residuePoint).Int + return P } -func (p *residuePoint) Clone() kyber.Point { - return &residuePoint{g: p.g, Int: p.Int} +func (P *residuePoint) Clone() kyber.Point { + return &residuePoint{g: P.g, Int: P.Int} } -func (p *residuePoint) Valid() bool { - return p.Int.Sign() > 0 && p.Int.Cmp(p.g.P) < 0 && - new(big.Int).Exp(&p.Int, p.g.Q, p.g.P).Cmp(one) == 0 +func (P *residuePoint) Valid() bool { + return P.Int.Sign() > 0 && P.Int.Cmp(P.g.P) < 0 && + new(big.Int).Exp(&P.Int, P.g.Q, P.g.P).Cmp(one) == 0 } -func (p *residuePoint) EmbedLen() int { +func (P *residuePoint) EmbedLen() int { // Reserve at least 8 most-significant bits for randomness, // and the least-significant 16 bits for embedded data length. - return (p.g.P.BitLen() - 8 - 16) / 8 + return (P.g.P.BitLen() - 8 - 16) / 8 } -func (p *residuePoint) Pick(rand cipher.Stream) kyber.Point { - return p.Embed(nil, rand) +func (P *residuePoint) Pick(rand cipher.Stream) kyber.Point { + return P.Embed(nil, rand) } // Embed the given data with some pseudo-random bits. // This will only work efficiently for quadratic residue groups! -func (p *residuePoint) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (P *residuePoint) Embed(data []byte, rand cipher.Stream) kyber.Point { - l := p.g.PointLen() - dl := p.EmbedLen() + l := P.g.PointLen() + dl := P.EmbedLen() if dl > len(data) { dl = len(data) } for { - b := random.Bits(uint(p.g.P.BitLen()), false, rand) + b := random.Bits(uint(P.g.P.BitLen()), false, rand) if data != nil { b[l-1] = byte(dl) // Encode length in low 16 bits b[l-2] = byte(dl >> 8) copy(b[l-dl-2:l-2], data) // Copy in embedded data } - p.Int.SetBytes(b) - if p.Valid() { - return p + P.Int.SetBytes(b) + if P.Valid() { + return P } } } // Extract embedded data from a Residue group element -func (p *residuePoint) Data() ([]byte, error) { - b := p.Int.Bytes() - l := p.g.PointLen() +func (P *residuePoint) Data() ([]byte, error) { + b := P.Int.Bytes() + l := P.g.PointLen() if len(b) < l { // pad leading zero bytes if necessary b = append(make([]byte, l-len(b)), b...) } dl := int(b[l-2])<<8 + int(b[l-1]) - if dl > p.EmbedLen() { + if dl > P.EmbedLen() { return nil, errors.New("invalid embedded data length") } return b[l-dl-2 : l-2], nil } -func (p *residuePoint) Add(a, b kyber.Point) kyber.Point { - p.Int.Mul(&a.(*residuePoint).Int, &b.(*residuePoint).Int) - p.Int.Mod(&p.Int, p.g.P) - return p +func (P *residuePoint) Add(A, B kyber.Point) kyber.Point { + P.Int.Mul(&A.(*residuePoint).Int, &B.(*residuePoint).Int) + P.Int.Mod(&P.Int, P.g.P) + return P } -func (p *residuePoint) Sub(a, b kyber.Point) kyber.Point { - binv := new(big.Int).ModInverse(&b.(*residuePoint).Int, p.g.P) - p.Int.Mul(&a.(*residuePoint).Int, binv) - p.Int.Mod(&p.Int, p.g.P) - return p +func (P *residuePoint) Sub(A, B kyber.Point) kyber.Point { + binv := new(big.Int).ModInverse(&B.(*residuePoint).Int, P.g.P) + P.Int.Mul(&A.(*residuePoint).Int, binv) + P.Int.Mod(&P.Int, P.g.P) + return P } -func (p *residuePoint) Neg(a kyber.Point) kyber.Point { - p.Int.ModInverse(&a.(*residuePoint).Int, p.g.P) - return p +func (P *residuePoint) Neg(A kyber.Point) kyber.Point { + P.Int.ModInverse(&A.(*residuePoint).Int, P.g.P) + return P } -func (p *residuePoint) Mul(s kyber.Scalar, b kyber.Point) kyber.Point { - if b == nil { - return p.Base().Mul(s, p) +func (P *residuePoint) Mul(s kyber.Scalar, B kyber.Point) kyber.Point { + if B == nil { + return P.Base().Mul(s, P) } // to protect against golang/go#22830 var tmp big.Int - tmp.Exp(&b.(*residuePoint).Int, &s.(*mod.Int).V, p.g.P) - p.Int = tmp - return p + tmp.Exp(&B.(*residuePoint).Int, &s.(*mod.Int).V, P.g.P) + P.Int = tmp + return P } -func (p *residuePoint) MarshalSize() int { - return (p.g.P.BitLen() + 7) / 8 +func (P *residuePoint) MarshalSize() int { + return (P.g.P.BitLen() + 7) / 8 } -func (p *residuePoint) MarshalBinary() ([]byte, error) { - b := p.Int.Bytes() // may be shorter than len(buf) - if pre := p.MarshalSize() - len(b); pre != 0 { +func (P *residuePoint) MarshalBinary() ([]byte, error) { + b := P.Int.Bytes() // may be shorter than len(buf) + if pre := P.MarshalSize() - len(b); pre != 0 { return append(make([]byte, pre), b...), nil } return b, nil } -func (p *residuePoint) UnmarshalBinary(data []byte) error { - p.Int.SetBytes(data) - if !p.Valid() { +func (P *residuePoint) UnmarshalBinary(data []byte) error { + P.Int.SetBytes(data) + if !P.Valid() { return errors.New("invalid Residue group element") } return nil } -func (p *residuePoint) MarshalTo(w io.Writer) (int, error) { - return marshalling.PointMarshalTo(p, w) +func (P *residuePoint) MarshalTo(w io.Writer) (int, error) { + return marshalling.PointMarshalTo(P, w) } -func (p *residuePoint) UnmarshalFrom(r io.Reader) (int, error) { - return marshalling.PointUnmarshalFrom(p, r) +func (P *residuePoint) UnmarshalFrom(r io.Reader) (int, error) { + return marshalling.PointUnmarshalFrom(P, r) } /* @@ -254,11 +254,11 @@ func (g *ResidueGroup) Valid() bool { } // SetParams explicitly initializes a ResidueGroup with given parameters. -func (g *ResidueGroup) SetParams(P, Q, R, G *big.Int) { - g.P = P - g.Q = Q - g.R = R - g.G = G +func (g *ResidueGroup) SetParams(p, q, r, g1 *big.Int) { + g.P = p + g.Q = q + g.R = r + g.G = g1 if !g.Valid() { panic("SetParams: bad Residue group parameters") } @@ -271,10 +271,8 @@ func (g *ResidueGroup) QuadraticResidueGroup(bitlen uint, rand cipher.Stream) { g.R = two // pick primes p,q such that p = 2q+1 - fmt.Printf("Generating %d-bit QR group", bitlen) for i := 0; ; i++ { if i > 1000 { - print(".") i = 0 } @@ -282,23 +280,18 @@ func (g *ResidueGroup) QuadraticResidueGroup(bitlen uint, rand cipher.Stream) { b := random.Bits(bitlen-1, true, rand) b[len(b)-1] |= 1 // must be odd g.Q = new(big.Int).SetBytes(b) - //println("q?",hex.EncodeToString(g.Q.Bytes())) if !isPrime(g.Q) { continue } - // Does the corresponding P come out prime too? + // TODO:Does the corresponding P come out prime too? g.P = new(big.Int) g.P.Mul(g.Q, two) g.P.Add(g.P, one) - //println("p?",hex.EncodeToString(g.P.Bytes())) if uint(g.P.BitLen()) == bitlen && isPrime(g.P) { break } } - println() - println("p", g.P.String()) - println("q", g.Q.String()) // pick standard generator G h := new(big.Int).Set(two) @@ -310,5 +303,4 @@ func (g *ResidueGroup) QuadraticResidueGroup(bitlen uint, rand cipher.Stream) { } h.Add(h, one) } - println("g", g.G.String()) } diff --git a/group/p256/suite.go b/group/p256/suite.go index 9b25d5f68..67dead921 100644 --- a/group/p256/suite.go +++ b/group/p256/suite.go @@ -36,11 +36,11 @@ func (s *Suite128) RandomStream() cipher.Stream { } func (s *Suite128) Read(r io.Reader, objs ...interface{}) error { - return fixbuf.Read(r, s, objs) + return fixbuf.Read(r, s, objs...) } func (s *Suite128) Write(w io.Writer, objs ...interface{}) error { - return fixbuf.Write(w, objs) + return fixbuf.Write(w, objs...) } // New implements the kyber.encoding interface diff --git a/group/var_ed25519/curve.go b/group/var_ed25519/curve.go index 9c4001519..357ddd4bf 100644 --- a/group/var_ed25519/curve.go +++ b/group/var_ed25519/curve.go @@ -81,10 +81,45 @@ func (c *curve) NewKey(stream cipher.Stream) kyber.Scalar { return secret } +func (c *curve) initBasePoint(self kyber.Group, p *Param, fullGroup bool, Base point) { + var bx, by *big.Int + if fullGroup { + bx, by = &p.FBX, &p.FBY + Base.initXY(&p.FBX, &p.FBY, self) + } else { + bx, by = &p.PBX, &p.PBY + } + + if by.Sign() == 0 { + // No standard base point was defined, so pick one. + // Find the lowest-numbered y-coordinate that works. + var x, y mod.Int + for y.Init64(2, &c.P); ; y.Add(&y, &c.one) { + if !c.solveForX(&x, &y) { + continue // try another y + } + if c.coordSign(&x) != 0 { + x.Neg(&x) // try positive x first + } + Base.initXY(&x.V, &y.V, self) + if c.validPoint(Base) { + break // got one + } + x.Neg(&x) // try -bx + if c.validPoint(Base) { + break // got one + } + } + + bx, by = &x.V, &y.V + } + Base.initXY(bx, by, self) +} + // Initialize a twisted Edwards curve with given parameters. // Caller passes pointers to null and base point prototypes to be initialized. func (c *curve) init(self kyber.Group, p *Param, fullGroup bool, - null, base point) *curve { + null, Base point) *curve { c.self = self c.Param = *p c.full = fullGroup @@ -101,10 +136,10 @@ func (c *curve) init(self kyber.Group, p *Param, fullGroup bool, // Note that we do NOT initialize c.order with Init(), // as that would normalize to the modulus, resulting in zero. // Just to be sure it's never used, we leave c.order.M set to nil. - // We want it to be in a ModInt so we can pass it to P.Mul(), + // We want it to be in a ModInt, so we can pass it to P.Mul(), // but the scalar's modulus isn't needed for point multiplication. if fullGroup { - // Scalar modulus is prime-order times the ccofactor + // Scalar modulus is prime-order times the cofactor c.order.V.SetInt64(int64(p.R)).Mul(&c.order.V, &p.Q) } else { c.order.V.Set(&p.Q) // Prime-order subgroup @@ -118,46 +153,14 @@ func (c *curve) init(self kyber.Group, p *Param, fullGroup bool, null.initXY(zero, one, self) // Base point B - var bx, by *big.Int - if !fullGroup { - bx, by = &p.PBX, &p.PBY - } else { - bx, by = &p.FBX, &p.FBY - base.initXY(&p.FBX, &p.FBY, self) - } - if by.Sign() == 0 { - // No standard base point was defined, so pick one. - // Find the lowest-numbered y-coordinate that works. - //println("Picking base point:") - var x, y mod.Int - for y.Init64(2, &c.P); ; y.Add(&y, &c.one) { - if !c.solveForX(&x, &y) { - continue // try another y - } - if c.coordSign(&x) != 0 { - x.Neg(&x) // try positive x first - } - base.initXY(&x.V, &y.V, self) - if c.validPoint(base) { - break // got one - } - x.Neg(&x) // try -bx - if c.validPoint(base) { - break // got one - } - } - //println("BX: "+x.V.String()) - //println("BY: "+y.V.String()) - bx, by = &x.V, &y.V - } - base.initXY(bx, by, self) + c.initBasePoint(self, p, fullGroup, Base) // Sanity checks if !c.validPoint(null) { panic("invalid identity point " + null.String()) } - if !c.validPoint(base) { - panic("invalid base point " + base.String()) + if !c.validPoint(Base) { + panic("invalid base point " + Base.String()) } return c @@ -209,7 +212,6 @@ func (c *curve) encodePoint(x, y *mod.Int) []byte { func (c *curve) decodePoint(bb []byte, x, y *mod.Int) error { // Convert from little-endian - //fmt.Printf("decoding:\n%s\n", hex.Dump(bb)) b := make([]byte, len(bb)) reverse(b, bb) @@ -278,11 +280,8 @@ func (c *curve) validPoint(P point) bool { // Check in-subgroup by multiplying by subgroup order Q := c.self.Point() Q.Mul(&c.order, P) - if !Q.Equal(c.null) { - return false - } - return true + return Q.Equal(c.null) } // Return number of bytes that can be embedded into points on this curve. @@ -383,12 +382,11 @@ func (c *curve) data(x, y *mod.Int) ([]byte, error) { // reverse copies src into dst in byte-reversed order and returns dst, // such that src[0] goes into dst[len-1] and vice versa. // dst and src may be the same slice but otherwise must not overlap. -func reverse(dst, src []byte) []byte { +func reverse(dst, src []byte) { l := len(dst) for i, j := 0, l-1; i < (l+1)/2; { dst[i], dst[j] = src[j], src[i] i++ j-- } - return dst } diff --git a/group/var_ed25519/ext.go b/group/var_ed25519/ext.go index 11ed7f2f7..4fcf5d202 100644 --- a/group/var_ed25519/ext.go +++ b/group/var_ed25519/ext.go @@ -17,7 +17,8 @@ type extPoint struct { } func (P *extPoint) initXY(x, y *big.Int, c kyber.Group) { - P.c = c.(*ExtendedCurve) + P.c = c.(*ExtendedCurve) //nolint:errcheck // V4 may bring better error handling + P.X.Init(x, &P.c.P) P.Y.Init(y, &P.c.P) P.Z.Init64(1, &P.c.P) @@ -31,7 +32,6 @@ func (P *extPoint) getXY() (x, y *mod.Int) { func (P *extPoint) String() string { P.normalize() - //return P.c.pointString(&P.X,&P.Y) buf, _ := P.MarshalBinary() return hex.EncodeToString(buf) } @@ -69,31 +69,31 @@ func (P *extPoint) UnmarshalFrom(r io.Reader) (int, error) { // iff // (X1*Z2,Y1*Z2) == (X2*Z1,Y2*Z1) func (P *extPoint) Equal(CP2 kyber.Point) bool { - P2 := CP2.(*extPoint) + p2 := CP2.(*extPoint) //nolint:errcheck // V4 may bring better error handling var t1, t2 mod.Int - xeq := t1.Mul(&P.X, &P2.Z).Equal(t2.Mul(&P2.X, &P.Z)) - yeq := t1.Mul(&P.Y, &P2.Z).Equal(t2.Mul(&P2.Y, &P.Z)) + xeq := t1.Mul(&P.X, &p2.Z).Equal(t2.Mul(&p2.X, &P.Z)) + yeq := t1.Mul(&P.Y, &p2.Z).Equal(t2.Mul(&p2.Y, &P.Z)) return xeq && yeq } func (P *extPoint) Set(CP2 kyber.Point) kyber.Point { - P2 := CP2.(*extPoint) - P.c = P2.c - P.X.Set(&P2.X) - P.Y.Set(&P2.Y) - P.Z.Set(&P2.Z) - P.T.Set(&P2.T) + p2 := CP2.(*extPoint) //nolint:errcheck // V4 may bring better error handling + P.c = p2.c + P.X.Set(&p2.X) + P.Y.Set(&p2.Y) + P.Z.Set(&p2.Z) + P.T.Set(&p2.T) return P } func (P *extPoint) Clone() kyber.Point { - P2 := extPoint{} - P2.c = P.c - P2.X.Set(&P.X) - P2.Y.Set(&P.Y) - P2.Z.Set(&P.Z) - P2.T.Set(&P.T) - return &P2 + p2 := extPoint{} + p2.c = P.c + p2.X.Set(&P.X) + p2.Y.Set(&P.Y) + p2.Z.Set(&P.Z) + p2.T.Set(&P.T) + return &p2 } func (P *extPoint) Null() kyber.Point { @@ -120,6 +120,8 @@ func (P *extPoint) normalize() { } // Check the validity of the T coordinate +// +//nolint:unused // may be useful func (P *extPoint) checkT() { var t1, t2 mod.Int if !t1.Mul(&P.X, &P.Y).Equal(t2.Mul(&P.Z, &P.T)) { @@ -144,11 +146,13 @@ func (P *extPoint) Data() ([]byte, error) { } // Add two points using optimized extended coordinate addition formulas. +// +//nolint:dupl //Doesn't make sense to extract part of Add(), Sub(), double() func (P *extPoint) Add(CP1, CP2 kyber.Point) kyber.Point { - P1 := CP1.(*extPoint) - P2 := CP2.(*extPoint) - X1, Y1, Z1, T1 := &P1.X, &P1.Y, &P1.Z, &P1.T - X2, Y2, Z2, T2 := &P2.X, &P2.Y, &P2.Z, &P2.T + p1 := CP1.(*extPoint) //nolint:errcheck // V4 may bring better error handling + p2 := CP2.(*extPoint) //nolint:errcheck // V4 may bring better error handling + X1, Y1, Z1, T1 := &p1.X, &p1.Y, &p1.Z, &p1.T + X2, Y2, Z2, T2 := &p2.X, &p2.Y, &p2.Z, &p2.T X3, Y3, Z3, T3 := &P.X, &P.Y, &P.Z, &P.T var A, B, C, D, E, F, G, H mod.Int @@ -168,11 +172,13 @@ func (P *extPoint) Add(CP1, CP2 kyber.Point) kyber.Point { } // Subtract points. +// +//nolint:dupl //Doesn't make sense to extract part of Add(), Sub(), double() func (P *extPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { - P1 := CP1.(*extPoint) - P2 := CP2.(*extPoint) - X1, Y1, Z1, T1 := &P1.X, &P1.Y, &P1.Z, &P1.T - X2, Y2, Z2, T2 := &P2.X, &P2.Y, &P2.Z, &P2.T + p1 := CP1.(*extPoint) //nolint:errcheck // V4 may bring better error handling + p2 := CP2.(*extPoint) //nolint:errcheck // V4 may bring better error handling + X1, Y1, Z1, T1 := &p1.X, &p1.Y, &p1.Z, &p1.T + X2, Y2, Z2, T2 := &p2.X, &p2.Y, &p2.Z, &p2.T X3, Y3, Z3, T3 := &P.X, &P.Y, &P.Z, &P.T var A, B, C, D, E, F, G, H mod.Int @@ -194,7 +200,7 @@ func (P *extPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { // Find the negative of point A. // For Edwards curves, the negative of (x,y) is (-x,y). func (P *extPoint) Neg(CA kyber.Point) kyber.Point { - A := CA.(*extPoint) + A := CA.(*extPoint) //nolint:errcheck // V4 may bring better error handling P.c = A.c P.X.Neg(&A.X) P.Y.Set(&A.Y) @@ -280,7 +286,7 @@ type ExtendedCurve struct { func (c *ExtendedCurve) Point() kyber.Point { P := new(extPoint) P.c = c - //P.Set(&c.null) + return P } diff --git a/group/var_ed25519/param.go b/group/var_ed25519/param.go index 3656662cd..a5deffe24 100644 --- a/group/var_ed25519/param.go +++ b/group/var_ed25519/param.go @@ -110,6 +110,8 @@ func ParamE382() *Param { p.R = 8 p.A.SetInt64(1) p.D.SetInt64(-67254) + + //nolint:lll // Line not breakable p.PBX.SetString("3914921414754292646847594472454013487047137431784830634731377862923477302047857640522480241298429278603678181725699", 10) p.PBY.SetString("17", 10) return &p @@ -128,6 +130,8 @@ func Param41417() *Param { p.R = 8 p.A.SetInt64(1) p.D.SetInt64(3617) + + //nolint:lll // Line not breakable p.PBX.SetString("17319886477121189177719202498822615443556957307604340815256226171904769976866975908866528699294134494857887698432266169206165", 10) p.PBY.SetString("34", 10) return &p @@ -150,6 +154,8 @@ func ParamE521() *Param { p.R = 8 p.A.SetInt64(1) p.D.SetInt64(-376014) + + //nolint:lll // Line not breakable p.PBX.SetString("1571054894184995387535939749894317568645297350402905821437625181152304994381188529632591196067604100772673927915114267193389905003276673749012051148356041324", 10) p.PBY.SetString("12", 10) return &p diff --git a/group/var_ed25519/proj.go b/group/var_ed25519/proj.go index 83344a1f5..b4a54b970 100644 --- a/group/var_ed25519/proj.go +++ b/group/var_ed25519/proj.go @@ -16,7 +16,7 @@ type projPoint struct { } func (P *projPoint) initXY(x, y *big.Int, c kyber.Group) { - P.c = c.(*ProjectiveCurve) + P.c = c.(*ProjectiveCurve) //nolint:errcheck // V4 may bring better error handling P.X.Init(x, &P.c.P) P.Y.Init(y, &P.c.P) P.Z.Init64(1, &P.c.P) @@ -61,7 +61,7 @@ func (P *projPoint) UnmarshalFrom(r io.Reader) (int, error) { // iff // (X1*Z2,Y1*Z2) == (X2*Z1,Y2*Z1) func (P *projPoint) Equal(CP2 kyber.Point) bool { - P2 := CP2.(*projPoint) + P2 := CP2.(*projPoint) //nolint:errcheck // V4 may bring better error handling var t1, t2 mod.Int xeq := t1.Mul(&P.X, &P2.Z).Equal(t2.Mul(&P2.X, &P.Z)) yeq := t1.Mul(&P.Y, &P2.Z).Equal(t2.Mul(&P2.Y, &P.Z)) @@ -69,7 +69,7 @@ func (P *projPoint) Equal(CP2 kyber.Point) bool { } func (P *projPoint) Set(CP2 kyber.Point) kyber.Point { - P2 := CP2.(*projPoint) + P2 := CP2.(*projPoint) //nolint:errcheck // V4 may bring better error handling P.c = P2.c P.X.Set(&P2.X) P.Y.Set(&P2.Y) @@ -128,9 +128,11 @@ func (P *projPoint) Data() ([]byte, error) { // // http://eprint.iacr.org/2008/013.pdf // https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html +// +//nolint:dupl //Doesn't make sense to extract part of Add(), Sub() func (P *projPoint) Add(CP1, CP2 kyber.Point) kyber.Point { - P1 := CP1.(*projPoint) - P2 := CP2.(*projPoint) + P1 := CP1.(*projPoint) //nolint:errcheck // V4 may bring better error handling + P2 := CP2.(*projPoint) //nolint:errcheck // V4 may bring better error handling X1, Y1, Z1 := &P1.X, &P1.Y, &P1.Z X2, Y2, Z2 := &P2.X, &P2.Y, &P2.Z var A, B, C, D, E, F, G, X3, Y3, Z3 mod.Int @@ -155,9 +157,11 @@ func (P *projPoint) Add(CP1, CP2 kyber.Point) kyber.Point { } // Subtract points so that their scalars subtract homomorphically +// +//nolint:dupl //Doesn't make sense to extract part of Add(), Sub(), double() func (P *projPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { - P1 := CP1.(*projPoint) - P2 := CP2.(*projPoint) + P1 := CP1.(*projPoint) //nolint:errcheck // V4 may bring better error handling + P2 := CP2.(*projPoint) //nolint:errcheck // V4 may bring better error handling X1, Y1, Z1 := &P1.X, &P1.Y, &P1.Z X2, Y2, Z2 := &P2.X, &P2.Y, &P2.Z var A, B, C, D, E, F, G, X3, Y3, Z3 mod.Int @@ -184,7 +188,7 @@ func (P *projPoint) Sub(CP1, CP2 kyber.Point) kyber.Point { // Find the negative of point A. // For Edwards curves, the negative of (x,y) is (-x,y). func (P *projPoint) Neg(CA kyber.Point) kyber.Point { - A := CA.(*projPoint) + A := CA.(*projPoint) //nolint:errcheck // V4 may bring better error handling P.c = A.c P.X.Neg(&A.X) P.Y.Set(&A.Y) @@ -248,7 +252,7 @@ type ProjectiveCurve struct { func (c *ProjectiveCurve) Point() kyber.Point { P := new(projPoint) P.c = c - //P.Set(&c.null) + return P } diff --git a/group/var_ed25519/suite.go b/group/var_ed25519/suite.go index c4f7c72a1..d0e82e263 100644 --- a/group/var_ed25519/suite.go +++ b/group/var_ed25519/suite.go @@ -30,11 +30,11 @@ func (s *SuiteEd25519) XOF(seed []byte) kyber.XOF { } func (s *SuiteEd25519) Read(r io.Reader, objs ...interface{}) error { - return fixbuf.Read(r, s, objs) + return fixbuf.Read(r, s, objs...) } func (s *SuiteEd25519) Write(w io.Writer, objs ...interface{}) error { - return fixbuf.Write(w, objs) + return fixbuf.Write(w, objs...) } // New implements the kyber.encoding interface diff --git a/pairing/bls12381/bls12381_test.go b/pairing/bls12381/bls12381_test.go index 3b0c421fd..5b9e007ee 100644 --- a/pairing/bls12381/bls12381_test.go +++ b/pairing/bls12381/bls12381_test.go @@ -166,6 +166,8 @@ func TestZKCryptoVectorsG2Compressed(t *testing.T) { // Returns a log of the pseudorandom Points produced in the test, // for comparison across alternative implementations // that are supposed to be equivalent. +// +//nolint:gocyclo,cyclop // complete test func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { t.Logf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n", g.String(), g.PointLen(), g.ScalarLen()) @@ -220,13 +222,7 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { // Verify additive and multiplicative identities of the generator. // TODO: Check GT exp - /*fmt.Println("Inverse of base")*/ - //f := ptmp.Base().(*KyberGT).f - //newFp12(nil).inverse(f, f) - //fmt.Printf("\n-Inverse: %v\n", f) - //fmt.Println("Multiply by -1") ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen) - /*fmt.Printf(" \n\nChecking equality additive identity\nptmp: %v \n\n zero %v\n", ptmp, pzero)*/ if !ptmp.Equal(pzero) { t.Fatalf("generator additive identity doesn't work: (scalar -1 %v) %v (x) -1 (+) %v = %v != %v the group point identity", stmp.SetInt64(-1), ptmp.Mul(stmp.SetInt64(-1), nil), gen, ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen), pzero) @@ -256,7 +252,6 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { t.Fatalf("Diffie-Hellman didn't work: %v == %v (x) %v != %v (x) %v == %v", dh1, s2, p1, s1, p2, dh2) } points = append(points, dh1) - //t.Logf("shared secret = %v", dh1) // Test secret inverse to get from dh1 back to p1 if primeOrder { @@ -267,7 +262,6 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { } // Zero and One identity secrets - //println("dh1^0 = ",ptmp.Mul(dh1, szero).String()) if !ptmp.Mul(szero, dh1).Equal(pzero) { t.Fatalf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero) } @@ -324,11 +318,7 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { pick := func(rand cipher.Stream) (p kyber.Point) { defer func() { - /*if err := recover(); err != nil {*/ - //// TODO implement Pick for GT - //p = g.Point().Mul(g.Scalar().Pick(rand), nil) - //return - /*}*/ + // TODO implement Pick for GT }() p = g.Point().Pick(rand) return @@ -455,7 +445,7 @@ func TestKyberPairingG2(t *testing.T) { } } -func TestRacePairings(t *testing.T) { +func TestRacePairings(_ *testing.T) { suites := []pairing.Suite{ kilic.NewBLS12381Suite(), circl.NewSuiteBLS12381(), @@ -701,11 +691,12 @@ func BLSBenchmark(b *testing.B, curveOption string) { randSource := random.New(rand.Reader) var suite pairing.Suite - if curveOption == "kilic" { + switch curveOption { + case "kilic": suite = kilic.NewBLS12381Suite() - } else if curveOption == "circl" { + case "circl": suite = circl.NewSuiteBLS12381() - } else { + default: panic(fmt.Errorf("invalid curve option: %s", curveOption)) } diff --git a/pairing/bls12381/circl/g1.go b/pairing/bls12381/circl/g1.go index 72baede3a..3916bfffb 100644 --- a/pairing/bls12381/circl/g1.go +++ b/pairing/bls12381/circl/g1.go @@ -1,3 +1,4 @@ +//nolint:dupl // unavoidable duplication between g1 and g2 package circl import ( @@ -63,7 +64,7 @@ func (p *G1Elt) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (p *G1Elt) Embed(data []byte, r cipher.Stream) kyber.Point { +func (p *G1Elt) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } diff --git a/pairing/bls12381/circl/g2.go b/pairing/bls12381/circl/g2.go index 71fff4af3..eb8d3355f 100644 --- a/pairing/bls12381/circl/g2.go +++ b/pairing/bls12381/circl/g2.go @@ -1,3 +1,4 @@ +//nolint:dupl // unavoidable duplication between g1 and g2 package circl import ( @@ -63,7 +64,7 @@ func (p *G2Elt) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (p *G2Elt) Embed(data []byte, r cipher.Stream) kyber.Point { +func (p *G2Elt) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } diff --git a/pairing/bls12381/circl/gt.go b/pairing/bls12381/circl/gt.go index 431cb0b38..8ddc3fa3a 100644 --- a/pairing/bls12381/circl/gt.go +++ b/pairing/bls12381/circl/gt.go @@ -54,7 +54,7 @@ func (p *GTElt) Null() kyber.Point { p.inner.SetIdentity(); return p } func (p *GTElt) Base() kyber.Point { p.inner = *gtBase; return p } -func (p *GTElt) Pick(rand cipher.Stream) kyber.Point { +func (p *GTElt) Pick(_ cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } @@ -66,7 +66,7 @@ func (p *GTElt) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (p *GTElt) Embed(data []byte, r cipher.Stream) kyber.Point { +func (p *GTElt) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } diff --git a/pairing/bls12381/circl/suite.go b/pairing/bls12381/circl/suite.go index c84abe473..92eb21831 100644 --- a/pairing/bls12381/circl/suite.go +++ b/pairing/bls12381/circl/suite.go @@ -39,12 +39,12 @@ func (s Suite) ValidatePairing(p1, p2, p3, p4 kyber.Point) bool { return out.IsIdentity() } -func (s Suite) Read(r io.Reader, objs ...interface{}) error { - panic("Suite.Read(): deprecated in kyber") +func (s Suite) Read(_ io.Reader, _ ...interface{}) error { + panic("Suite.Read(): deprecated in drand") } -func (s Suite) Write(w io.Writer, objs ...interface{}) error { - panic("Suite.Write(): deprecated in kyber") +func (s Suite) Write(_ io.Writer, _ ...interface{}) error { + panic("Suite.Write(): deprecated in drand") } func (s Suite) Hash() hash.Hash { diff --git a/pairing/bls12381/kilic/g1.go b/pairing/bls12381/kilic/g1.go index bc907c25c..540df2a31 100644 --- a/pairing/bls12381/kilic/g1.go +++ b/pairing/bls12381/kilic/g1.go @@ -77,7 +77,7 @@ func (k *G1Elt) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (k *G1Elt) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (k *G1Elt) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } diff --git a/pairing/bls12381/kilic/g2.go b/pairing/bls12381/kilic/g2.go index 9020ebd49..69791d9bf 100644 --- a/pairing/bls12381/kilic/g2.go +++ b/pairing/bls12381/kilic/g2.go @@ -76,7 +76,7 @@ func (k *G2Elt) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (k *G2Elt) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (k *G2Elt) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } diff --git a/pairing/bls12381/kilic/gt.go b/pairing/bls12381/kilic/gt.go index 38d7a2590..351f8b86a 100644 --- a/pairing/bls12381/kilic/gt.go +++ b/pairing/bls12381/kilic/gt.go @@ -39,7 +39,7 @@ func (k *GTElt) Base() kyber.Point { panic("bls12-381.GT.Base(): unsupported operation") } -func (k *GTElt) Pick(rand cipher.Stream) kyber.Point { +func (k *GTElt) Pick(_ cipher.Stream) kyber.Point { panic("bls12-381.GT.Pick(): unsupported operation") } @@ -123,7 +123,7 @@ func (k *GTElt) EmbedLen() int { panic("bls12-381.GT.EmbedLen(): unsupported operation") } -func (k *GTElt) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (k *GTElt) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bls12-381.GT.Embed(): unsupported operation") } diff --git a/pairing/bls12381/kilic/suite.go b/pairing/bls12381/kilic/suite.go index 84551ef56..ea0232152 100644 --- a/pairing/bls12381/kilic/suite.go +++ b/pairing/bls12381/kilic/suite.go @@ -73,17 +73,17 @@ func (s *Suite) Pair(p1, p2 kyber.Point) kyber.Point { } // New implements the kyber.Encoding interface. -func (s *Suite) New(t reflect.Type) interface{} { +func (s *Suite) New(_ reflect.Type) interface{} { panic("Suite.Encoding: deprecated in kyber") } // Read is the default implementation of kyber.Encoding interface Read. -func (s *Suite) Read(r io.Reader, objs ...interface{}) error { +func (s *Suite) Read(_ io.Reader, _ ...interface{}) error { panic("Suite.Read(): deprecated in kyber") } // Write is the default implementation of kyber.Encoding interface Write. -func (s *Suite) Write(w io.Writer, objs ...interface{}) error { +func (s *Suite) Write(_ io.Writer, _ ...interface{}) error { panic("Suite.Write(): deprecated in kyber") } diff --git a/pairing/bls12381/kilic/suite_test.go b/pairing/bls12381/kilic/suite_test.go index 76c9b6e79..5b0dc0f86 100644 --- a/pairing/bls12381/kilic/suite_test.go +++ b/pairing/bls12381/kilic/suite_test.go @@ -69,7 +69,7 @@ func TestVerifySigOnG2(t *testing.T) { } } -func TestImplementInterfaces(t *testing.T) { +func TestImplementInterfaces(_ *testing.T) { var _ kyber.Point = &G1Elt{} var _ kyber.Point = &G2Elt{} var _ kyber.Point = >Elt{} diff --git a/pairing/bn254/constants.go b/pairing/bn254/constants.go index 53c5ed29f..3c8396bb0 100644 --- a/pairing/bn254/constants.go +++ b/pairing/bn254/constants.go @@ -1,3 +1,4 @@ +//nolint:lll package bn254 import ( @@ -27,6 +28,8 @@ var p2 = [4]uint64{0x3c208c16d87cfd47, 0x97816a916871ca8d, 0xb85045b68181585d, 0 var curveB = newGFp(3) // np is the negative inverse of p, mod 2^256. +// +//nolint:unused // maybe useful var np = [4]uint64{0x87d20782e4866389, 0x9ede7d651eca6ac9, 0xd8afcbd01833da80, 0xf57a22b791888c6b} // rN1 is R^-1 where R = 2^256 mod p. diff --git a/pairing/bn254/gfp.go b/pairing/bn254/gfp.go index ba95a6621..9f5b0e0fc 100644 --- a/pairing/bn254/gfp.go +++ b/pairing/bn254/gfp.go @@ -24,7 +24,7 @@ func newGFpFromBase10(x string) *gfP { bx, _ := new(big.Int).SetString(x, 10) bx = bx.Mod(bx, p) out := &gfP{} - out.Unmarshal(zeroPadBytes(bx.Bytes(), 32)) + _ = out.Unmarshal(zeroPadBytes(bx.Bytes(), 32)) montEncode(out, out) return out } diff --git a/pairing/bn254/gfp12.go b/pairing/bn254/gfp12.go index d2988f621..697c8e759 100644 --- a/pairing/bn254/gfp12.go +++ b/pairing/bn254/gfp12.go @@ -104,9 +104,9 @@ func (e *gfP12) Mul(a, b *gfP12) *gfP12 { return e } -func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { - e.x.Mul(&e.x, b) - e.y.Mul(&e.y, b) +func (e *gfP12) MulScalar(a *gfP6) *gfP12 { + e.x.Mul(&e.x, a) + e.y.Mul(&e.y, a) return e } @@ -155,7 +155,7 @@ func (e *gfP12) Invert(a *gfP12) *gfP12 { e.x.Neg(&a.x) e.y.Set(&a.y) - e.MulScalar(e, t2) + e.MulScalar(t2) return e } diff --git a/pairing/bn254/gfp_decl.go b/pairing/bn254/gfp_decl.go index 8c5429c52..21a7e21e6 100644 --- a/pairing/bn254/gfp_decl.go +++ b/pairing/bn254/gfp_decl.go @@ -10,6 +10,7 @@ import ( "golang.org/x/sys/cpu" ) +//nolint:unused // maybe useful var hasBMI2 = cpu.X86.HasBMI2 // go:noescape diff --git a/pairing/bn254/lattice.go b/pairing/bn254/lattice.go index f457cd30f..ed3efd4b0 100644 --- a/pairing/bn254/lattice.go +++ b/pairing/bn254/lattice.go @@ -18,6 +18,7 @@ var curveLattice = &lattice{ det: bigFromBase10("43776485743678550444492811490514550177096728800832068687396408373151616991234"), } +//nolint:lll,unused // maybe useful var targetLattice = &lattice{ vectors: [][]*big.Int{ {bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697761"), bigFromBase10("9931322734385697763"), bigFromBase10("9931322734385697764")}, diff --git a/pairing/bn254/optate.go b/pairing/bn254/optate.go index 6258ab475..4d6e08c5c 100644 --- a/pairing/bn254/optate.go +++ b/pairing/bn254/optate.go @@ -46,7 +46,7 @@ func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c *gfP2, b = (&gfP2{}).Neg(L1) b.MulScalar(b, &q.x).Add(b, b) - return + return a, b, c, rOut } func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twistPoint) { @@ -88,7 +88,7 @@ func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twis c = (&gfP2{}).Mul(&rOut.z, &r.t) c.Add(c, c).MulScalar(c, &q.y) - return + return a, b, c, rOut } func mulLine(ret *gfP12, a, b, c *gfP2) { diff --git a/pairing/bn254/point.go b/pairing/bn254/point.go index 07cde6470..0acd3cf0f 100644 --- a/pairing/bn254/point.go +++ b/pairing/bn254/point.go @@ -66,7 +66,7 @@ func (p *pointG1) EmbedLen() int { panic("bn254.G1: unsupported operation") } -func (p *pointG1) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (p *pointG1) Embed(_ []byte, _ cipher.Stream) kyber.Point { // XXX: An approach to implement this is: // - Encode data as the x-coordinate of a point on y²=x³+3 where len(data) // is stored in the least significant byte of x and the rest is being @@ -152,8 +152,15 @@ func (p *pointG1) UnmarshalBinary(buf []byte) error { p.g.x, p.g.y = gfP{0}, gfP{0} } - p.g.x.Unmarshal(buf) - p.g.y.Unmarshal(buf[n:]) + err := p.g.x.Unmarshal(buf) + if err != nil { + return err + } + err = p.g.y.Unmarshal(buf[n:]) + if err != nil { + return err + } + montEncode(&p.g.x, &p.g.x) montEncode(&p.g.y, &p.g.y) @@ -215,8 +222,8 @@ func hashToField(domain, m []byte) (*gfP, *gfP) { x.SetBytes(_msg[0:48]).Mod(x, p) y.SetBytes(_msg[48:96]).Mod(y, p) gx, gy := &gfP{}, &gfP{} - gx.Unmarshal(zeroPadBytes(x.Bytes(), 32)) - gy.Unmarshal(zeroPadBytes(y.Bytes(), 32)) + _ = gx.Unmarshal(zeroPadBytes(x.Bytes(), 32)) + _ = gy.Unmarshal(zeroPadBytes(y.Bytes(), 32)) montEncode(gx, gx) montEncode(gy, gy) return gx, gy @@ -254,17 +261,20 @@ func mapToPoint(domain []byte, u *gfP) kyber.Point { gfpMul(x3, c4, x3) gfpAdd(x3, newGFp(1), x3) - x, y := &gfP{}, &gfP{} - if legendre(g(x1)) == 1 { + var x *gfP + y := &gfP{} + switch { + case legendre(g(x1)) == 1: x = x1 y.Sqrt(g(x1)) - } else if legendre(g(x2)) == 1 { + case legendre(g(x2)) == 1: x = x2 y.Sqrt(g(x2)) - } else { + default: x = x3 y.Sqrt(g(x3)) } + if sgn0(u) != sgn0(y) { gfpNeg(y, y) } @@ -318,11 +328,11 @@ func expandMsgXmdKeccak256(domain, msg []byte, outLen int) []byte { _, _ = h.Write([]byte{domainLen}) // b_1 || ... || b_(ell - 1) - copy(out[(i-1)*h.Size():i*h.Size()], bi[:]) + copy(out[(i-1)*h.Size():i*h.Size()], bi) bi = h.Sum(nil) } // b_ell - copy(out[(ell-1)*h.Size():], bi[:]) + copy(out[(ell-1)*h.Size():], bi) return out[:outLen] } @@ -376,7 +386,7 @@ func (p *pointG2) EmbedLen() int { panic("bn254.G2: unsupported operation") } -func (p *pointG2) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (p *pointG2) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bn254.G2: unsupported operation") } @@ -463,10 +473,23 @@ func (p *pointG2) UnmarshalBinary(buf []byte) error { return errors.New("bn254.G2: not enough data") } - p.g.x.x.Unmarshal(buf[0*n:]) - p.g.x.y.Unmarshal(buf[1*n:]) - p.g.y.x.Unmarshal(buf[2*n:]) - p.g.y.y.Unmarshal(buf[3*n:]) + err := p.g.x.x.Unmarshal(buf[0*n:]) + if err != nil { + return err + } + err = p.g.x.y.Unmarshal(buf[1*n:]) + if err != nil { + return err + } + err = p.g.y.x.Unmarshal(buf[2*n:]) + if err != nil { + return err + } + err = p.g.y.y.Unmarshal(buf[3*n:]) + if err != nil { + return err + } + montEncode(&p.g.x.x, &p.g.x.x) montEncode(&p.g.x.y, &p.g.x.y) montEncode(&p.g.y.x, &p.g.y.x) @@ -560,7 +583,7 @@ func (p *pointGT) EmbedLen() int { panic("bn254.GT: unsupported operation") } -func (p *pointGT) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (p *pointGT) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bn254.GT: unsupported operation") } @@ -641,6 +664,7 @@ func (p *pointGT) MarshalTo(w io.Writer) (int, error) { return w.Write(buf) } +//nolint:funlen func (p *pointGT) UnmarshalBinary(buf []byte) error { n := p.ElementSize() if len(buf) < p.MarshalSize() { @@ -651,18 +675,55 @@ func (p *pointGT) UnmarshalBinary(buf []byte) error { p.g = &gfP12{} } - p.g.x.x.x.Unmarshal(buf[0*n:]) - p.g.x.x.y.Unmarshal(buf[1*n:]) - p.g.x.y.x.Unmarshal(buf[2*n:]) - p.g.x.y.y.Unmarshal(buf[3*n:]) - p.g.x.z.x.Unmarshal(buf[4*n:]) - p.g.x.z.y.Unmarshal(buf[5*n:]) - p.g.y.x.x.Unmarshal(buf[6*n:]) - p.g.y.x.y.Unmarshal(buf[7*n:]) - p.g.y.y.x.Unmarshal(buf[8*n:]) - p.g.y.y.y.Unmarshal(buf[9*n:]) - p.g.y.z.x.Unmarshal(buf[10*n:]) - p.g.y.z.y.Unmarshal(buf[11*n:]) + err := p.g.x.x.x.Unmarshal(buf[0*n:]) + if err != nil { + return err + } + err = p.g.x.x.y.Unmarshal(buf[1*n:]) + if err != nil { + return err + } + err = p.g.x.y.x.Unmarshal(buf[2*n:]) + if err != nil { + return err + } + err = p.g.x.y.y.Unmarshal(buf[3*n:]) + if err != nil { + return err + } + err = p.g.x.z.x.Unmarshal(buf[4*n:]) + if err != nil { + return err + } + err = p.g.x.z.y.Unmarshal(buf[5*n:]) + if err != nil { + return err + } + err = p.g.y.x.x.Unmarshal(buf[6*n:]) + if err != nil { + return err + } + err = p.g.y.x.y.Unmarshal(buf[7*n:]) + if err != nil { + return err + } + err = p.g.y.y.x.Unmarshal(buf[8*n:]) + if err != nil { + return err + } + err = p.g.y.y.y.Unmarshal(buf[9*n:]) + if err != nil { + return err + } + err = p.g.y.z.x.Unmarshal(buf[10*n:]) + if err != nil { + return err + } + err = p.g.y.z.y.Unmarshal(buf[11*n:]) + if err != nil { + return err + } + montEncode(&p.g.x.x.x, &p.g.x.x.x) montEncode(&p.g.x.x.y, &p.g.x.x.y) montEncode(&p.g.x.y.x, &p.g.x.y.x) @@ -677,7 +738,6 @@ func (p *pointGT) UnmarshalBinary(buf []byte) error { montEncode(&p.g.y.z.y, &p.g.y.z.y) // TODO: check if point is on curve - return nil } diff --git a/pairing/bn254/suite.go b/pairing/bn254/suite.go index f82917343..8cb3c1684 100644 --- a/pairing/bn254/suite.go +++ b/pairing/bn254/suite.go @@ -187,7 +187,7 @@ func (c *commonSuite) Read(r io.Reader, objs ...interface{}) error { // Write is the default implementation of kyber.Encoding interface Write. func (c *commonSuite) Write(w io.Writer, objs ...interface{}) error { - return fixbuf.Write(w, objs) + return fixbuf.Write(w, objs...) } // Hash returns a newly instantiated keccak256 hash function. diff --git a/pairing/bn254/suite_test.go b/pairing/bn254/suite_test.go index 113d71aec..46237f1b0 100644 --- a/pairing/bn254/suite_test.go +++ b/pairing/bn254/suite_test.go @@ -329,7 +329,6 @@ type tsrPoint struct { } func TestSuiteProtobuf(t *testing.T) { - //bn := suites.MustFind("bn254.adapter") bn1 := NewSuiteG1() bn2 := NewSuiteG2() bnT := NewSuiteGT() diff --git a/pairing/bn254/test_vectors.go b/pairing/bn254/test_vectors_test.go similarity index 100% rename from pairing/bn254/test_vectors.go rename to pairing/bn254/test_vectors_test.go diff --git a/pairing/bn256/constants.go b/pairing/bn256/constants.go index d31c5f7f6..6e4bdb5ee 100644 --- a/pairing/bn256/constants.go +++ b/pairing/bn256/constants.go @@ -20,30 +20,61 @@ var p = bigFromBase10("650005496956466037327964387423599057428253581076230035718 var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969") // xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3. -var xiToPMinus1Over6 = &gfP2{gfP{0x25af52988477cdb7, 0x3d81a455ddced86a, 0x227d012e872c2431, 0x179198d3ea65d05}, gfP{0x7407634dd9cca958, 0x36d5bd6c7afb8f26, 0xf4b1c32cebd880fa, 0x6aa7869306f455f}} +var xiToPMinus1Over6 = &gfP2{ + gfP{0x25af52988477cdb7, 0x3d81a455ddced86a, 0x227d012e872c2431, 0x179198d3ea65d05}, + gfP{0x7407634dd9cca958, 0x36d5bd6c7afb8f26, 0xf4b1c32cebd880fa, 0x6aa7869306f455f}, +} // xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+3. -var xiToPMinus1Over3 = &gfP2{gfP{0x4f59e37c01832e57, 0xae6be39ac2bbbfe4, 0xe04ea1bb697512f8, 0x3097caa8fc40e10e}, gfP{0xf8606916d3816f2c, 0x1e5c0d7926de927e, 0xbc45f3946d81185e, 0x80752a25aa738091}} +var xiToPMinus1Over3 = &gfP2{ + gfP{0x4f59e37c01832e57, 0xae6be39ac2bbbfe4, 0xe04ea1bb697512f8, 0x3097caa8fc40e10e}, + gfP{0xf8606916d3816f2c, 0x1e5c0d7926de927e, 0xbc45f3946d81185e, 0x80752a25aa738091}, +} // xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+3. -var xiToPMinus1Over2 = &gfP2{gfP{0x19da71333653ee20, 0x7eaaf34fc6ed6019, 0xc4ba3a29a60cdd1d, 0x75281311bcc9df79}, gfP{0x18dbee03fb7708fa, 0x1e7601a602c843c7, 0x5dde0688cdb231cb, 0x86db5cf2c605a524}} +var xiToPMinus1Over2 = &gfP2{ + gfP{0x19da71333653ee20, 0x7eaaf34fc6ed6019, 0xc4ba3a29a60cdd1d, 0x75281311bcc9df79}, + gfP{0x18dbee03fb7708fa, 0x1e7601a602c843c7, 0x5dde0688cdb231cb, 0x86db5cf2c605a524}, +} // xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+3. -var xiToPSquaredMinus1Over3 = &gfP{0x12d3cef5e1ada57d, 0xe2eca1463753babb, 0xca41e40ddccf750, 0x551337060397e04c} +var xiToPSquaredMinus1Over3 = &gfP{ + 0x12d3cef5e1ada57d, + 0xe2eca1463753babb, + 0xca41e40ddccf750, + 0x551337060397e04c, +} // xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+3 (a cubic root of unity, mod p). -var xiTo2PSquaredMinus2Over3 = &gfP{0x3642364f386c1db8, 0xe825f92d2acd661f, 0xf2aba7e846c19d14, 0x5a0bcea3dc52b7a0} +var xiTo2PSquaredMinus2Over3 = &gfP{ + 0x3642364f386c1db8, + 0xe825f92d2acd661f, + 0xf2aba7e846c19d14, + 0x5a0bcea3dc52b7a0, +} // xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+3 (a cubic root of -1, mod p). -var xiToPSquaredMinus1Over6 = &gfP{0xe21a761d259c78af, 0x6358fa3f5e84f7e, 0xb7c444d01ac33f0d, 0x35a9333f6e50d058} +var xiToPSquaredMinus1Over6 = &gfP{ + 0xe21a761d259c78af, + 0x6358fa3f5e84f7e, + 0xb7c444d01ac33f0d, + 0x35a9333f6e50d058, +} // xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+3. -var xiTo2PMinus2Over3 = &gfP2{gfP{0x51678e7469b3c52a, 0x4fb98f8b13319fc9, 0x29b2254db3f1df75, 0x1c044935a3d22fb2}, gfP{0x4d2ea218872f3d2c, 0x2fcb27fc4abe7b69, 0xd31d972f0e88ced9, 0x53adc04a00a73b15}} +var xiTo2PMinus2Over3 = &gfP2{ + gfP{0x51678e7469b3c52a, 0x4fb98f8b13319fc9, 0x29b2254db3f1df75, 0x1c044935a3d22fb2}, + gfP{0x4d2ea218872f3d2c, 0x2fcb27fc4abe7b69, 0xd31d972f0e88ced9, 0x53adc04a00a73b15}, +} // p2 is p, represented as little-endian 64-bit words. +// +//nolint:unused // False positive var p2 = [4]uint64{0x185cac6c5e089667, 0xee5b88d120b5b59e, 0xaa6fecb86184dc21, 0x8fb501e34aa387f9} // np is the negative inverse of p, mod 2^256. +// +//nolint:unused // False positive var np = [4]uint64{0x2387f9007f17daa9, 0x734b3343ab8513c8, 0x2524282f48054c12, 0x38997ae661c3ef3c} // rN1 is R^-1 where R = 2^256 mod p. diff --git a/pairing/bn256/gfp12.go b/pairing/bn256/gfp12.go index 8835d11ec..28e640dec 100644 --- a/pairing/bn256/gfp12.go +++ b/pairing/bn256/gfp12.go @@ -166,7 +166,7 @@ func (e *gfP12) Mul(a, b *gfP12) *gfP12 { return e } -func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { +func (e *gfP12) MulScalar(b *gfP6) *gfP12 { e.x.Mul(&e.x, b) e.y.Mul(&e.y, b) return e @@ -217,7 +217,7 @@ func (e *gfP12) Invert(a *gfP12) *gfP12 { e.x.Neg(&a.x) e.y.Set(&a.y) - e.MulScalar(e, t2) + e.MulScalar(t2) return e } diff --git a/pairing/bn256/gfp_decl.go b/pairing/bn256/gfp_decl.go index 23df6f186..e87a67325 100644 --- a/pairing/bn256/gfp_decl.go +++ b/pairing/bn256/gfp_decl.go @@ -9,6 +9,7 @@ import ( "golang.org/x/sys/cpu" ) +//nolint:unused // False positive var hasBMI2 = cpu.X86.HasBMI2 //go:noescape diff --git a/pairing/bn256/hash.go b/pairing/bn256/hash.go index 77544b00c..21c3ae72c 100644 --- a/pairing/bn256/hash.go +++ b/pairing/bn256/hash.go @@ -9,6 +9,7 @@ func HashG1(msg, dst []byte) kyber.Point { return mapToCurve(hashToBase(msg, dst)) } +//nolint:funlen func mapToCurve(t *gfP) kyber.Point { one := *newGFp(1) diff --git a/pairing/bn256/optate.go b/pairing/bn256/optate.go index a235a45be..0f5d6553b 100644 --- a/pairing/bn256/optate.go +++ b/pairing/bn256/optate.go @@ -46,7 +46,7 @@ func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c *gfP2, b = (&gfP2{}).Neg(L1) b.MulScalar(b, &q.x).Add(b, b) - return + return a, b, c, rOut } func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twistPoint) { @@ -88,7 +88,7 @@ func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twis c = (&gfP2{}).Mul(&rOut.z, &r.t) c.Add(c, c).MulScalar(c, &q.y) - return + return a, b, c, rOut } func mulLine(ret *gfP12, a, b, c *gfP2) { @@ -112,7 +112,12 @@ func mulLine(ret *gfP12, a, b, c *gfP2) { } // sixuPlus2NAF is 6u+2 in non-adjacent form. -var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, -1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 1} +var sixuPlus2NAF = []int8{ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, + 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0, -1, + 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, + 0, 1, 0, 0, 0, 1, +} // miller implements the Miller loop for calculating the Optimal Ate pairing. // See algorithm 1 from http://cryptojedi.org/papers/dclxvi-20100714.pdf diff --git a/pairing/bn256/point.go b/pairing/bn256/point.go index 48e773da6..4f9172fe5 100644 --- a/pairing/bn256/point.go +++ b/pairing/bn256/point.go @@ -16,6 +16,8 @@ var marshalPointID1 = [8]byte{'b', 'n', '2', '5', '6', '.', 'g', '1'} var marshalPointID2 = [8]byte{'b', 'n', '2', '5', '6', '.', 'g', '2'} var marshalPointIDT = [8]byte{'b', 'n', '2', '5', '6', '.', 'g', 't'} +var ErrTypeCast = errors.New("invalid type cast") + type pointG1 struct { g *curvePoint } @@ -146,7 +148,10 @@ func (p *pointG1) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { func (p *pointG1) MarshalBinary() ([]byte, error) { // Clone is required as we change the point - p = p.Clone().(*pointG1) + p, ok := p.Clone().(*pointG1) + if !ok { + return nil, ErrTypeCast + } n := p.ElementSize() // Take a copy so that p is not written to, so calls to MarshalBinary @@ -335,7 +340,7 @@ func (p *pointG2) EmbedLen() int { panic("bn256.G2: unsupported operation") } -func (p *pointG2) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (p *pointG2) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bn256.G2: unsupported operation") } @@ -373,8 +378,10 @@ func (p *pointG2) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { func (p *pointG2) MarshalBinary() ([]byte, error) { // Clone is required as we change the point during the operation - p = p.Clone().(*pointG2) - + p, ok := p.Clone().(*pointG2) + if !ok { + return nil, ErrTypeCast + } n := p.ElementSize() if p.g == nil { p.g = &twistPoint{} @@ -517,7 +524,7 @@ func (p *pointGT) EmbedLen() int { panic("bn256.GT: unsupported operation") } -func (p *pointGT) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (p *pointGT) Embed(_ []byte, _ cipher.Stream) kyber.Point { panic("bn256.GT: unsupported operation") } diff --git a/pairing/bn256/suite.go b/pairing/bn256/suite.go index 03363ad04..3ec4cee8b 100644 --- a/pairing/bn256/suite.go +++ b/pairing/bn256/suite.go @@ -151,7 +151,7 @@ func (c *commonSuite) Read(r io.Reader, objs ...interface{}) error { // Write is the default implementation of kyber.Encoding interface Write. func (c *commonSuite) Write(w io.Writer, objs ...interface{}) error { - return fixbuf.Write(w, objs) + return fixbuf.Write(w, objs...) } // Hash returns a newly instantiated sha256 hash function. diff --git a/pairing/bn256/suite_test.go b/pairing/bn256/suite_test.go index a3393bb2c..d4fc3b504 100644 --- a/pairing/bn256/suite_test.go +++ b/pairing/bn256/suite_test.go @@ -333,7 +333,7 @@ type tsrPoint struct { } func TestSuiteProtobuf(t *testing.T) { - //bn := suites.MustFind("bn256.adapter") + // bn := suites.MustFind("bn256.adapter") bn1 := NewSuiteG1() bn2 := NewSuiteG2() bnT := NewSuiteGT() diff --git a/proof/deniable.go b/proof/deniable.go index c76bb5650..3c45b5374 100644 --- a/proof/deniable.go +++ b/proof/deniable.go @@ -76,7 +76,12 @@ func (dp *deniableProver) run(suite Suite, self int, prv Prover, } // Run the prover, which will also drive the verifiers. - dp.initStep() + err := dp.initStep() + if err != nil { + dp.err[self] = err + return dp.err + } + if err := (func(ProverContext) error)(prv)(dp); err != nil { dp.err[self] = err } @@ -105,17 +110,24 @@ func (dp *deniableProver) run(suite Suite, self int, prv Prover, const keySize = 128 // Start the message buffer off in each step with a randomness commitment -func (dp *deniableProver) initStep() { +func (dp *deniableProver) initStep() error { key := make([]byte, keySize) // secret random key - _, _ = dp.prirand.Read(key) + _, err := dp.prirand.Read(key) + if err != nil { + return err + } dp.key = key msg := make([]byte, keySize) // send commitment to it xof := dp.suite.XOF(key) - xof.Read(msg) + _, err = xof.Read(msg) + if err != nil { + return err + } dp.msg = bytes.NewBuffer(msg) // The Sigma-Prover will now append its proof content to dp.msg... + return nil } func (dp *deniableProver) proofStep() (bool, error) { @@ -179,7 +191,11 @@ func (dp *deniableProver) challengeStep() error { continue // ignore participants who dropped out } chk := make([]byte, keySize) - dp.suite.XOF(key).Read(chk) + _, err := dp.suite.XOF(key).Read(chk) + if err != nil { + return err + } + if !bytes.Equal(com, chk) { return errors.New("wrong key for commit") } @@ -203,8 +219,8 @@ func (dp *deniableProver) challengeStep() error { } // Setup for the next proof step - dp.initStep() - return nil + err = dp.initStep() + return err } func (dp *deniableProver) Put(message interface{}) error { diff --git a/proof/deniable_test.go b/proof/deniable_test.go index b7533cfc4..c9b182652 100644 --- a/proof/deniable_test.go +++ b/proof/deniable_test.go @@ -105,7 +105,7 @@ func TestDeniable(t *testing.T) { msgs[i] = <-n.outbox if n.done { - t.Log(string(n.log.Bytes())) + t.Log(n.log.Bytes()) nodes[i] = nil } } diff --git a/proof/dleq/dleq.go b/proof/dleq/dleq.go index 044e616b9..ef821b03f 100644 --- a/proof/dleq/dleq.go +++ b/proof/dleq/dleq.go @@ -9,6 +9,7 @@ package dleq import ( "errors" + "fmt" "go.dedis.ch/kyber/v4" ) @@ -21,8 +22,8 @@ type Suite interface { kyber.Random } -var errorDifferentLengths = errors.New("inputs of different lengths") -var errorInvalidProof = errors.New("invalid proof") +var ErrDifferentLengths = errors.New("inputs of different lengths") +var ErrInvalidProof = errors.New("invalid proof") // Proof represents a NIZK dlog-equality proof. type Proof struct { @@ -37,7 +38,12 @@ type Proof struct { // and then computes the challenge c = H(xG,xH,vG,vH) and response r = v - cx. // Besides the proof, this function also returns the encrypted base points xG // and xH. -func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (proof *Proof, xG kyber.Point, xH kyber.Point, err error) { +func NewDLEQProof( + suite Suite, + G kyber.Point, + H kyber.Point, + x kyber.Scalar, +) (proof *Proof, xG kyber.Point, xH kyber.Point, err error) { // Encrypt base points with secret xG = suite.Point().Mul(x, G) xH = suite.Point().Mul(x, H) @@ -48,12 +54,28 @@ func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (pr vH := suite.Point().Mul(v, H) // Challenge - h := suite.Hash() - xG.MarshalTo(h) - xH.MarshalTo(h) - vG.MarshalTo(h) - vH.MarshalTo(h) - cb := h.Sum(nil) + hSuite := suite.Hash() + _, err = xG.MarshalTo(hSuite) + if err != nil { + return nil, nil, nil, err + } + + _, err = xH.MarshalTo(hSuite) + if err != nil { + return nil, nil, nil, err + } + + _, err = vG.MarshalTo(hSuite) + if err != nil { + return nil, nil, nil, err + } + + _, err = vH.MarshalTo(hSuite) + if err != nil { + return nil, nil, nil, err + } + + cb := hSuite.Sum(nil) c := suite.Scalar().Pick(suite.XOF(cb)) // Response @@ -66,9 +88,14 @@ func NewDLEQProof(suite Suite, G kyber.Point, H kyber.Point, x kyber.Scalar) (pr // NewDLEQProofBatch computes lists of NIZK dlog-equality proofs and of // encrypted base points xG and xH. Note that the challenge is computed over all // input values. -func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets []kyber.Scalar) (proof []*Proof, xG []kyber.Point, xH []kyber.Point, err error) { +func NewDLEQProofBatch( + suite Suite, + G []kyber.Point, + H []kyber.Point, + secrets []kyber.Scalar, +) (proof []*Proof, xG []kyber.Point, xH []kyber.Point, err error) { if len(G) != len(H) || len(H) != len(secrets) { - return nil, nil, nil, errorDifferentLengths + return nil, nil, nil, fmt.Errorf("invalid: %w", ErrDifferentLengths) } n := len(secrets) @@ -91,20 +118,28 @@ func NewDLEQProofBatch(suite Suite, G []kyber.Point, H []kyber.Point, secrets [] } // Collective challenge - h := suite.Hash() + hSuite := suite.Hash() for _, x := range xG { - x.MarshalTo(h) + if _, err := x.MarshalTo(hSuite); err != nil { + return nil, nil, nil, err + } } for _, x := range xH { - x.MarshalTo(h) + if _, err := x.MarshalTo(hSuite); err != nil { + return nil, nil, nil, err + } } for _, x := range vG { - x.MarshalTo(h) + if _, err := x.MarshalTo(hSuite); err != nil { + return nil, nil, nil, err + } } for _, x := range vH { - x.MarshalTo(h) + if _, err := x.MarshalTo(hSuite); err != nil { + return nil, nil, nil, err + } } - cb := h.Sum(nil) + cb := hSuite.Sum(nil) c := suite.Scalar().Pick(suite.XOF(cb)) @@ -131,7 +166,7 @@ func (p *Proof) Verify(suite Suite, G kyber.Point, H kyber.Point, xG kyber.Point a := suite.Point().Add(rG, cxG) b := suite.Point().Add(rH, cxH) if !(p.VG.Equal(a) && p.VH.Equal(b)) { - return errorInvalidProof + return fmt.Errorf("invalid. %w", ErrInvalidProof) } return nil } diff --git a/proof/dleq/dleq_test.go b/proof/dleq/dleq_test.go index a33df8cbf..0e5321cf5 100644 --- a/proof/dleq/dleq_test.go +++ b/proof/dleq/dleq_test.go @@ -57,5 +57,5 @@ func TestDLEQLengths(t *testing.T) { // Remove an element to make the test fail x = append(x[:5], x[6:]...) _, _, _, err := NewDLEQProofBatch(suite, g, h, x) - require.Equal(t, err, errorDifferentLengths) + require.ErrorIs(t, err, ErrDifferentLengths) } diff --git a/proof/hash.go b/proof/hash.go index 95790c852..c32384438 100644 --- a/proof/hash.go +++ b/proof/hash.go @@ -43,23 +43,34 @@ func (c *hashProver) Put(message interface{}) error { return c.suite.Write(&c.msg, message) } -func (c *hashProver) consumeMsg() { +func (c *hashProver) consumeMsg() error { if c.msg.Len() > 0 { - // Stir the message into the public randomness pool buf := c.msg.Bytes() c.pubrand.Reseed() - c.pubrand.Write(buf) + _, err := c.pubrand.Write(buf) + if err != nil { + return err + } // Append the current message data to the proof - c.proof.Write(buf) + _, err = c.proof.Write(buf) + if err != nil { + return err + } c.msg.Reset() } + + return nil } // Get public randomness that depends on every bit in the proof so far. func (c *hashProver) PubRand(data ...interface{}) error { - c.consumeMsg() + err := c.consumeMsg() + if err != nil { + return err + } + return c.suite.Read(c.pubrand, data...) } @@ -72,9 +83,9 @@ func (c *hashProver) PriRand(data ...interface{}) error { } // Obtain the encoded proof once the Sigma protocol is complete. -func (c *hashProver) Proof() []byte { - c.consumeMsg() - return c.proof.Bytes() +func (c *hashProver) Proof() ([]byte, error) { + err := c.consumeMsg() + return c.proof.Bytes(), err } // Noninteractive Sigma-protocol verifier context @@ -97,16 +108,21 @@ func newHashVerifier(suite Suite, protoName string, return &c, nil } -func (c *hashVerifier) consumeMsg() { +func (c *hashVerifier) consumeMsg() error { l := len(c.prbuf) - c.proof.Len() // How many bytes read? if l > 0 { // Stir consumed bytes into the public randomness pool buf := c.prbuf[:l] c.pubrand.Reseed() - c.pubrand.Write(buf) + _, err := c.pubrand.Write(buf) + if err != nil { + return err + } c.prbuf = c.proof.Bytes() // Reset to remaining bytes } + + return nil } // Read structured data from the proof @@ -116,7 +132,12 @@ func (c *hashVerifier) Get(message interface{}) error { // Get public randomness that depends on every bit in the proof so far. func (c *hashVerifier) PubRand(data ...interface{}) error { - c.consumeMsg() // Stir in newly-read data + // Stir in newly-read data + err := c.consumeMsg() + if err != nil { + return err + } + return c.suite.Read(c.pubrand, data...) } @@ -138,7 +159,7 @@ func HashProve(suite Suite, protocolName string, prover Prover) ([]byte, error) if e := (func(ProverContext) error)(prover)(ctx); e != nil { return nil, e } - return ctx.Proof(), nil + return ctx.Proof() } // HashVerify computes a hash-based noninteractive proof generated with HashProve. diff --git a/proof/proof.go b/proof/proof.go index cb4bce6b2..c0c2dd22c 100644 --- a/proof/proof.go +++ b/proof/proof.go @@ -175,7 +175,7 @@ func (rp *repPred) String() string { return rp.precString(precNone) } -func (rp *repPred) precString(prec int) string { +func (rp *repPred) precString(_ int) string { s := rp.P + "=" for i := range rp.T { if i > 0 { @@ -220,7 +220,10 @@ func (rp *repPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { // we encounter each variable if v[s] == nil { v[s] = prf.s.Scalar() - prf.pc.PriRand(v[s]) + err := prf.pc.PriRand(v[s]) + if err != nil { + return err + } } P.Mul(v[s], prf.pval[t.B]) V.Add(V, P) @@ -366,8 +369,6 @@ func (ap *andPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { // Create per-predicate prover state v := prf.makeScalars(pv) - //pp := proverPred{w,v,nil} - //prf.pp[ap] = pp // Recursively generate commitments for i := 0; i < len(sub); i++ { @@ -381,7 +382,6 @@ func (ap *andPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { func (ap *andPred) respond(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { sub := []Predicate(*ap) - //pp := prf.pp[ap] // Recursively compute responses in all sub-predicates r := prf.makeScalars(pr) @@ -484,7 +484,8 @@ func (op *orPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { prf.pp[op] = pp // Choose pre-challenges for our subs. - if w == nil { + switch { + case w == nil: // We're on a proof-obligated branch; // choose random pre-challenges for only non-obligated subs. choice, ok := prf.choice[op] @@ -495,10 +496,13 @@ func (op *orPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { for i := 0; i < len(sub); i++ { if i != choice { wi[i] = prf.s.Scalar() - prf.pc.PriRand(wi[i]) + err := prf.pc.PriRand(wi[i]) + if err != nil { + return err + } } // else wi[i] == nil for proof-obligated sub } - } else { + default: // Since w != nil, we're in a non-obligated branch, // so choose random pre-challenges for all subs // such that they add up to the master pre-challenge w. @@ -506,17 +510,25 @@ func (op *orPred) commit(prf *proof, w kyber.Scalar, pv []kyber.Scalar) error { wl := prf.s.Scalar().Set(w) for i := 0; i < last; i++ { // choose all but last wi[i] = prf.s.Scalar() - prf.pc.PriRand(wi[i]) + err := prf.pc.PriRand(wi[i]) + if err != nil { + return err + } wl.Sub(wl, wi[i]) } + wi[last] = wl } + return commitmentProducer(prf, wi, sub) +} + +func commitmentProducer(prf *proof, wi []kyber.Scalar, sub []Predicate) error { // Now recursively choose commitments within each sub for i := 0; i < len(sub); i++ { // Fresh variable-blinding secrets for each pre-commitment - if e := sub[i].commit(prf, wi[i], nil); e != nil { - return e + if err := sub[i].commit(prf, wi[i], nil); err != nil { + return err } } @@ -561,7 +573,7 @@ func (op *orPred) respond(prf *proof, c kyber.Scalar, pr []kyber.Scalar) error { } // Get from the verifier all the commitments needed for this predicate -func (op *orPred) getCommits(prf *proof, pr []kyber.Scalar) error { +func (op *orPred) getCommits(prf *proof, _ []kyber.Scalar) error { sub := []Predicate(*op) for i := range sub { if e := sub[i].getCommits(prf, nil); e != nil { diff --git a/share/dkg/pedersen/dkg.go b/share/dkg/pedersen/dkg.go index 348a8a5cf..df5623b1d 100644 --- a/share/dkg/pedersen/dkg.go +++ b/share/dkg/pedersen/dkg.go @@ -183,8 +183,6 @@ type DistKeyGenerator struct { newPresent bool // indicates whether the node is present in the old list oldPresent bool - // already processed our own deal - processed bool // public polynomial of the old group olddpub *share.PubPoly } @@ -252,19 +250,8 @@ func NewDistKeyHandler(c *Config) (*DistKeyGenerator, error) { } else if c.Reader != nil && c.UserReaderOnly { randomStream = random.New(c.Reader) } - pickErr := func() (err error) { - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("error picking secret: %v", r) - return - } - }() - secretCoeff = c.Suite.Scalar().Pick(randomStream) - return nil - }() - if pickErr != nil { - return nil, pickErr - } + secretCoeff = c.Suite.Scalar().Pick(randomStream) + // in fresh dkg case, we consider the old nodes same a new nodes c.OldNodes = c.NewNodes oidx, oldPresent = findPub(c.OldNodes, pub) @@ -283,7 +270,9 @@ func NewDistKeyHandler(c *Config) (*DistKeyGenerator, error) { if isResharing && newPresent { if c.PublicCoeffs == nil && c.Share == nil { return nil, errors.New("dkg: can't receive new shares without the public polynomial") - } else if c.PublicCoeffs != nil { + } + + if c.PublicCoeffs != nil { olddpub = share.NewPubPoly(c.Suite, c.Suite.Point().Base(), c.PublicCoeffs) } else if c.Share != nil { // take the commits of the share, no need to duplicate information @@ -386,18 +375,22 @@ func (d *DistKeyGenerator) Deals() (*DealBundle, error) { // missing deals. It returns an error if the node is not in the right state, or // if there is not enough valid shares, i.e. the dkg is failing already. func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, error) { - if d.canIssue && d.state != DealPhase { // oldnode member is not in the right state - return nil, fmt.Errorf("processdeals can only be called after producing shares - state %s", d.state.String()) + return nil, fmt.Errorf("processdeals can only be called "+ + "after producing shares - state %s", d.state.String()) } + if d.canReceive && !d.canIssue && d.state != InitPhase { // newnode member which is not in the old group is not in the riht state - return nil, fmt.Errorf("processdeals can only be called once after creating the dkg for a new member - state %s", d.state.String()) + return nil, fmt.Errorf("processdeals can only be called once "+ + "after creating the dkg for a new member - state %s", d.state.String()) } if !d.canReceive { // a node that is only in the old group should not process deals d.state = ResponsePhase // he moves on to the next phase silently + + //nolint:nilnil // protocol defined this way return nil, nil } @@ -418,7 +411,7 @@ func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, continue } - if bytes.Compare(bundle.SessionID, d.c.Nonce) != 0 { + if !bytes.Equal(bundle.SessionID, d.c.Nonce) { d.evicted = append(d.evicted, bundle.DealerIndex) d.c.Error("Deal with invalid session ID") continue @@ -486,7 +479,7 @@ func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, } } // share is valid -> store it - d.statuses.Set(bundle.DealerIndex, deal.ShareIndex, true) + d.statuses.Set(bundle.DealerIndex, deal.ShareIndex, Success) d.validShares[bundle.DealerIndex] = share d.c.Info("Valid deal processed received from dealer", bundle.DealerIndex) } @@ -500,7 +493,7 @@ func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, if !found { continue } - d.statuses.Set(dealer.Index, uint32(nidx), true) + d.statuses.Set(dealer.Index, uint32(nidx), Success) } // producing response part @@ -508,13 +501,13 @@ func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, var myshares = d.statuses.StatusesForShare(uint32(d.nidx)) for _, node := range d.c.OldNodes { // if the node is evicted, we don't even need to send a complaint or a - // response response since every honest node evicts him as well. + // response since every honest node evicts him as well. // XXX Is that always true ? Should we send a complaint still ? if contains(d.evicted, node.Index) { continue } - if myshares[node.Index] { + if myshares[node.Index] == Success { if d.c.FastSync { // we send success responses only in fast sync responses = append(responses, Response{ @@ -559,7 +552,11 @@ func (d *DistKeyGenerator) ExpectedResponsesFastSync() int { // - the justification bundle if this node must produce at least one. If nil, // this node must still wait on the justification phase. // - error if the dkg must stop now, an unrecoverable failure. -func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Result, jb *JustificationBundle, err error) { +func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) ( + res *Result, + jb *JustificationBundle, + err error) { + if !d.canReceive && d.state != DealPhase { // if we are a old node that will leave return nil, nil, fmt.Errorf("leaving node can process responses only after creating shares") @@ -577,7 +574,7 @@ func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Res // if we are not in fastsync, we expect only complaints // if there is no complaints all is good res, err = d.computeResult() - return + return res, jb, err } var validAuthors []Index @@ -587,7 +584,7 @@ func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Res continue } if d.canIssue && bundle.ShareIndex == uint32(d.nidx) { - // just in case we dont treat our own response + // just in case we don't treat our own response continue } if !isIndexIncluded(d.c.NewNodes, bundle.ShareIndex) { @@ -595,7 +592,7 @@ func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Res continue } - if bytes.Compare(bundle.SessionID, d.c.Nonce) != 0 { + if !bytes.Equal(bundle.SessionID, d.c.Nonce) { d.c.Error("Response invalid session ID") d.evictedHolders = append(d.evictedHolders, bundle.ShareIndex) continue @@ -623,6 +620,7 @@ func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Res if response.Status == Complaint { foundComplaint = true } + validAuthors = append(validAuthors, bundle.ShareIndex) } } @@ -656,10 +654,10 @@ func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Res if d.canReceive { res, err := d.computeResult() return res, nil, err - } else { - // old nodes that are not present in the new group - return nil, nil, nil } + + // old nodes that are not present in the new group + return nil, nil, nil } // check if there are some node who received at least t complaints. @@ -697,7 +695,7 @@ func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Res d.c.Info(fmt.Sprintf("Producing justifications for node %d", shareIndex)) foundJustifs = true // mark those shares as resolved in the statuses - d.statuses.Set(uint32(d.oidx), shareIndex, true) + d.statuses.Set(uint32(d.oidx), shareIndex, Success) } if !foundJustifs { // no justifications required from us ! @@ -729,10 +727,13 @@ func (d *DistKeyGenerator) ProcessJustifications(bundles []*JustificationBundle) // an old node leaving the group do not need to process justifications. // Here we simply return nil to avoid requiring higher level library to // think about which node should receive which packet + // + //nolint:nilnil // protocol defined this way return nil, nil } if d.state != JustifPhase { - return nil, fmt.Errorf("node can only process justifications after processing responses - current state %s", d.state.String()) + return nil, fmt.Errorf("node can only process justifications "+ + "after processing responses - current state %s", d.state.String()) } seen := make(map[uint32]bool) @@ -762,7 +763,7 @@ func (d *DistKeyGenerator) ProcessJustifications(bundles []*JustificationBundle) d.c.Error("Already evicted dealer - evicting dealer", bundle.DealerIndex) continue } - if bytes.Compare(bundle.SessionID, d.c.Nonce) != 0 { + if !bytes.Equal(bundle.SessionID, d.c.Nonce) { d.evicted = append(d.evicted, bundle.DealerIndex) d.c.Error("Justification bundle contains invalid session ID - evicting dealer", bundle.DealerIndex) continue @@ -810,7 +811,7 @@ func (d *DistKeyGenerator) ProcessJustifications(bundles []*JustificationBundle) d.c.Info("Old share commit and public commit valid", true) } // valid share -> mark OK - d.statuses.Set(bundle.DealerIndex, justif.ShareIndex, true) + d.statuses.Set(bundle.DealerIndex, justif.ShareIndex, Success) if justif.ShareIndex == uint32(d.nidx) { // store the share if it's for us d.c.Info("Saving our key share for", justif.ShareIndex) @@ -857,23 +858,22 @@ func (d *DistKeyGenerator) computeResult() (*Result, error) { d.state = FinishPhase // add a full complaint row on the nodes that are evicted for _, index := range d.evicted { - d.statuses.SetAll(index, false) + d.statuses.SetAll(index, Complaint) } // add all the shares and public polynomials together for the deals that are // valid ( equivalently or all justified) if d.isResharing { // instead of adding, in this case, we interpolate all shares return d.computeResharingResult() - } else { - return d.computeDKGResult() } + + return d.computeDKGResult() } func (d *DistKeyGenerator) computeResharingResult() (*Result, error) { // only old nodes sends shares shares := make([]*share.PriShare, 0, len(d.c.OldNodes)) coeffs := make(map[Index][]kyber.Point, len(d.c.OldNodes)) - var validDealers []Index for _, n := range d.c.OldNodes { if !d.statuses.AllTrue(n.Index) { // this dealer has some unjustified shares @@ -897,7 +897,6 @@ func (d *DistKeyGenerator) computeResharingResult() (*Result, error) { V: sh, I: n.Index, }) - validDealers = append(validDealers, n.Index) } // the private polynomial is generated from the old nodes, thus inheriting @@ -1131,28 +1130,32 @@ func GetNonce() []byte { } func (d *DistKeyGenerator) sign(p Packet) ([]byte, error) { - msg := p.Hash() + msg, err := p.Hash() + if err != nil { + return nil, err + } + priv := d.c.Longterm return d.c.Auth.Sign(priv, msg) } func (d *DistKeyGenerator) Info(keyvals ...interface{}) { - d.c.Info(append([]interface{}{"generator"}, keyvals...)) + d.c.Info("generator", keyvals) } func (d *DistKeyGenerator) Error(keyvals ...interface{}) { - d.c.Info(append([]interface{}{"generator"}, keyvals...)) + d.c.Info("generator", keyvals) } func (c *Config) Info(keyvals ...interface{}) { if c.Log != nil { - c.Log.Info(append([]interface{}{"dkg-log"}, keyvals...)) + c.Log.Info("dkg-log", keyvals) } } func (c *Config) Error(keyvals ...interface{}) { if c.Log != nil { - c.Log.Error(append([]interface{}{"dkg-log"}, keyvals...)) + c.Log.Error("dkg-log", keyvals) } } @@ -1166,17 +1169,17 @@ func (c *Config) CheckForDuplicates() error { for _, n := range list { if _, present := hashSet[n.Index]; present { return fmt.Errorf("index %d", n.Index) - } else { - hashSet[n.Index] = true } + hashSet[n.Index] = true } + return nil } if err := checkDuplicate(c.OldNodes); err != nil { - return fmt.Errorf("found duplicate in old nodes list: %v", err) + return fmt.Errorf("found duplicate in old nodes list: %w", err) } if err := checkDuplicate(c.NewNodes); err != nil { - return fmt.Errorf("found duplicate in new nodes list: %v", err) + return fmt.Errorf("found duplicate in new nodes list: %w", err) } return nil } diff --git a/share/dkg/pedersen/dkg_test.go b/share/dkg/pedersen/dkg_test.go index 75fc08ecd..ef0a6d1cb 100644 --- a/share/dkg/pedersen/dkg_test.go +++ b/share/dkg/pedersen/dkg_test.go @@ -458,7 +458,6 @@ func TestSelfEvictionShareHolder(t *testing.T) { } require.True(t, len(responses) > 0) - results = nil for _, node := range newTns { _, _, err := node.dkg.ProcessResponses(responses) require.True(t, contains(node.dkg.evictedHolders, newIndexToEvict)) @@ -622,7 +621,7 @@ func TestDKGThreshold(t *testing.T) { results := RunDKG(t, tns, conf, dm, rm, jm) var filtered = results[:0] for _, n := range tns { - if 0 == n.Index { + if n.Index == 0 { // node 0 is excluded by all others since he didn't even provide a // deal at the first phase,i.e. it didn't even provide a public // polynomial at the first phase. @@ -717,7 +716,7 @@ func TestDKGResharingFast(t *testing.T) { skipNew = n.Index } } - fmt.Println("skipping old index: ", list[p].Index, "public key", skipKey, "newIdx", skipNew) + t.Log("skipping old index: ", list[p].Index, "public key", skipKey, "newIdx", skipNew) newConf := &Config{ Suite: suite, @@ -1048,7 +1047,7 @@ func TestDKGTooManyComplaints(t *testing.T) { results := RunDKG(t, tns, conf, dm, nil, nil) var filtered = results[:0] for _, n := range tns { - if 0 == n.Index { + if n.Index == 0 { // node 0 is excluded by all others since he didn't even provide a // deal at the first phase,i.e. it didn't even provide a public // polynomial at the first phase. diff --git a/share/dkg/pedersen/proto_test.go b/share/dkg/pedersen/proto_test.go index 3990bdbeb..ff09e29b3 100644 --- a/share/dkg/pedersen/proto_test.go +++ b/share/dkg/pedersen/proto_test.go @@ -1,7 +1,6 @@ package dkg import ( - "fmt" "testing" "time" @@ -122,12 +121,12 @@ func (t *TestBoard) IncomingJustification() <-chan JustificationBundle { return t.newJusts } -func SetupProto(tns []*TestNode, dkgC *Config, period time.Duration, network *TestNetwork) { +func SetupProto(tns []*TestNode, period time.Duration, network *TestNetwork) { for _, n := range tns { - clock := clock.NewFakeClock() - n.clock = clock + clk := clock.NewFakeClock() + n.clock = clk n.phaser = NewTimePhaserFunc(func(Phase) { - clock.Sleep(period) + clk.Sleep(period) }) n.board = network.BoardFor(n.Index) c2 := *n.dkg.c @@ -160,7 +159,7 @@ func TestProtoFull(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) var resCh = make(chan OptionResult, 1) // start all nodes and wait until each end @@ -211,7 +210,7 @@ func TestProtoResharing(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) var resCh = make(chan OptionResult, 1) // start all nodes and wait until each end @@ -250,7 +249,7 @@ func TestProtoResharing(t *testing.T) { } testResults(t, suite, thr, n, results) - fmt.Printf("\n\n ----- RESHARING ----\n\n") + t.Log("\n\n ----- RESHARING ----\n\n") // RESHARING // we setup now the second group with one node left from old group and two // new node @@ -273,7 +272,7 @@ func TestProtoResharing(t *testing.T) { } SetupReshareNodes(newTns, newConf, tns[0].res.Key.Commits) - SetupProto(newTns, newConf, period, network) + SetupProto(newTns, period, network) resCh = make(chan OptionResult, 1) // start all nodes and wait until each end @@ -304,7 +303,7 @@ func TestProtoResharing(t *testing.T) { for optRes := range resCh { require.NoError(t, optRes.Error) results = append(results, optRes.Result) - fmt.Printf("GOT %d RESULTS\n", len(results)) + t.Logf("GOT %d RESULTS\n", len(results)) if len(results) == newN { break } @@ -330,7 +329,7 @@ func TestProtoThreshold(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) var resCh = make(chan OptionResult, 1) // start all nodes and wait until each end @@ -380,7 +379,7 @@ func TestProtoFullFast(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) var resCh = make(chan OptionResult, 1) // start all nodes and wait until each end @@ -425,7 +424,7 @@ func TestProtoResharingAbsent(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) var resCh = make(chan OptionResult, 1) // start all nodes and wait until each end @@ -464,7 +463,7 @@ func TestProtoResharingAbsent(t *testing.T) { } testResults(t, suite, thr, n, results) - fmt.Printf("\n\n ----- RESHARING ----\n\n") + t.Log("\n\n ----- RESHARING ----\n\n") // RESHARING var newTns = make([]*TestNode, newN) copy(newTns, tns[:n-1]) @@ -483,7 +482,7 @@ func TestProtoResharingAbsent(t *testing.T) { } SetupReshareNodes(newTns, newConf, tns[0].res.Key.Commits) - SetupProto(newTns, newConf, period, network) + SetupProto(newTns, period, network) /// /// We set a node as registered but offline /// @@ -517,13 +516,13 @@ func TestProtoResharingAbsent(t *testing.T) { var errNode error for optRes := range resCh { if optRes.Error != nil { - fmt.Printf("GOT ONE ERROR\n") + t.Log("GOT ONE ERROR\n") require.Nil(t, errNode, "already an error saved!?") errNode = optRes.Error continue } results = append(results, optRes.Result) - fmt.Printf("GOT %d RESULTS\n", len(results)) + t.Logf("GOT %d RESULTS\n", len(results)) if len(results) == newN-1 { break } @@ -547,7 +546,7 @@ func TestProtoThresholdFast(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) // set a node that will send a bad deal such that all deals are received // "fast", then the normal rounds are happening network.BoardFor(1).badDeal = true @@ -653,7 +652,7 @@ func TestProtoSkip(t *testing.T) { Auth: schnorr.NewScheme(suite), } SetupNodes(tns, &dkgConf) - SetupProto(tns, &dkgConf, period, network) + SetupProto(tns, period, network) for _, tn := range tns { tn.proto.skipVerif = true } @@ -677,7 +676,7 @@ func TestProtoSkip(t *testing.T) { // expect all results var results []*Result for optRes := range resCh { - //require.NoError(t, optRes.Error) + require.NoError(t, optRes.Error) results = append(results, optRes.Result) if len(results) == n { break diff --git a/share/dkg/pedersen/protocol.go b/share/dkg/pedersen/protocol.go index 364d58b00..28dac0745 100644 --- a/share/dkg/pedersen/protocol.go +++ b/share/dkg/pedersen/protocol.go @@ -3,7 +3,6 @@ package dkg import ( "bytes" "fmt" - "strings" "time" ) @@ -79,15 +78,6 @@ type Protocol struct { skipVerif bool } -// XXX TO DELETE -func printNodes(list []Node) string { - var arr []string - for _, node := range list { - arr = append(arr, fmt.Sprintf("[%d : %s]", node.Index, node.Public)) - } - return strings.Join(arr, "\n") -} - func NewProtocol(c *Config, b Board, phaser Phaser, skipVerification bool) (*Protocol, error) { dkg, err := NewDistKeyHandler(c) if err != nil { @@ -106,11 +96,11 @@ func NewProtocol(c *Config, b Board, phaser Phaser, skipVerification bool) (*Pro } func (p *Protocol) Info(keyvals ...interface{}) { - p.dkg.c.Info(append([]interface{}{"dkg-step"}, keyvals...)) + p.dkg.c.Info("dkg-step", keyvals) } func (p *Protocol) Error(keyvals ...interface{}) { - p.dkg.c.Error(append([]interface{}{"dkg-step"}, keyvals...)) + p.dkg.c.Error("dkg-step", keyvals) } func (p *Protocol) Start() { @@ -126,6 +116,7 @@ func (p *Protocol) Start() { select { case newPhase := <-p.phaser.NextPhase(): switch newPhase { + case InitPhase: case DealPhase: if !p.sendDeals() { return @@ -201,6 +192,7 @@ func (p *Protocol) startFast() { select { case newPhase := <-p.phaser.NextPhase(): switch newPhase { + case InitPhase: case DealPhase: p.Info("phaser", "msg", "moving to sending deals phase") if !p.sendDeals() { @@ -368,7 +360,7 @@ func newSet() *set { } func (s *set) Push(p Packet) { - hash := p.Hash() + hash, _ := p.Hash() idx := p.Index() if s.isBad(idx) { // already misbehaved before @@ -376,7 +368,8 @@ func (s *set) Push(p Packet) { } prev, present := s.vals[idx] if present { - if !bytes.Equal(prev.Hash(), hash) { + prevHash, _ := prev.Hash() + if !bytes.Equal(prevHash, hash) { // bad behavior - we evict delete(s.vals, idx) s.bad = append(s.bad, idx) diff --git a/share/dkg/pedersen/status.go b/share/dkg/pedersen/status.go index 5f3851ea4..4501a1dc2 100644 --- a/share/dkg/pedersen/status.go +++ b/share/dkg/pedersen/status.go @@ -6,18 +6,20 @@ import ( "strings" ) +type Status int32 + const ( - Success = true - Complaint = false + Success Status = 0 + Complaint Status = 1 ) -type BitSet map[uint32]bool +type BitSet map[uint32]Status type StatusMatrix map[uint32]BitSet -func NewStatusMatrix(dealers []Node, shareHolders []Node, status bool) *StatusMatrix { +func NewStatusMatrix(dealers []Node, shareHolders []Node, status Status) *StatusMatrix { statuses := make(map[uint32]BitSet) for _, dealer := range dealers { - bitset := make(map[uint32]bool) + bitset := make(map[uint32]Status) for _, holder := range shareHolders { bitset[holder.Index] = status } @@ -44,11 +46,11 @@ func (s *StatusMatrix) StatusesOfDealer(dealerIndex uint32) BitSet { } // can panic if indexes are not from the original list of nodes -func (s *StatusMatrix) Set(dealer, share uint32, status bool) { +func (s *StatusMatrix) Set(dealer, share uint32, status Status) { (*s)[dealer][share] = status } -func (s *StatusMatrix) SetAll(dealer uint32, status bool) { +func (s *StatusMatrix) SetAll(dealer uint32, status Status) { for share := range (*s)[dealer] { (*s)[dealer][share] = status } @@ -73,7 +75,7 @@ func (s *StatusMatrix) CompleteSuccess() bool { } // can panic if indexes are not from the original list of nodes -func (s *StatusMatrix) Get(dealer, share uint32) bool { +func (s *StatusMatrix) Get(dealer, share uint32) Status { return (*s)[dealer][share] } @@ -96,7 +98,7 @@ func (s *StatusMatrix) String() string { for _, shareIndex := range sharesIdx { status := (*s)[uint32(dealerIndex)][uint32(shareIndex)] var st string - if status { + if status == Success { st = fmt.Sprintf(" %d: ok", shareIndex) } else { st = fmt.Sprintf(" %d: no", shareIndex) @@ -108,16 +110,6 @@ func (s *StatusMatrix) String() string { return str } -func findMaxIndex(list []Node) int { - m := 0 - for _, n := range list { - if n.Index > uint32(m) { - m = int(n.Index) - } - } - return m -} - func (b BitSet) LengthComplaints() int { var count = 0 for _, status := range b { diff --git a/share/dkg/pedersen/structs.go b/share/dkg/pedersen/structs.go index 2c635d734..0966cac20 100644 --- a/share/dkg/pedersen/structs.go +++ b/share/dkg/pedersen/structs.go @@ -111,23 +111,39 @@ type DealBundle struct { } // Hash hashes the index, public coefficients and deals -func (d *DealBundle) Hash() []byte { +func (d *DealBundle) Hash() ([]byte, error) { // first order the deals in a stable order sort.SliceStable(d.Deals, func(i, j int) bool { return d.Deals[i].ShareIndex < d.Deals[j].ShareIndex }) h := sha256.New() - binary.Write(h, binary.BigEndian, d.DealerIndex) + err := binary.Write(h, binary.BigEndian, d.DealerIndex) + if err != nil { + return nil, err + } + for _, c := range d.Public { - cbuff, _ := c.MarshalBinary() - h.Write(cbuff) + cbuff, err := c.MarshalBinary() + if err != nil { + return nil, err + } + _, err = h.Write(cbuff) + if err != nil { + return nil, err + } } for _, deal := range d.Deals { - binary.Write(h, binary.BigEndian, deal.ShareIndex) - h.Write(deal.EncryptedShare) + err = binary.Write(h, binary.BigEndian, deal.ShareIndex) + if err != nil { + return nil, err + } + _, err = h.Write(deal.EncryptedShare) + if err != nil { + return nil, err + } } - h.Write(d.SessionID) - return h.Sum(nil) + _, err = h.Write(d.SessionID) + return h.Sum(nil), err } func (d *DealBundle) Index() Index { @@ -143,7 +159,7 @@ func (d *DealBundle) Sig() []byte { type Response struct { // Index of the Dealer for which this response is for DealerIndex uint32 - Status bool + Status Status } var _ Packet = (*ResponseBundle)(nil) @@ -161,23 +177,33 @@ type ResponseBundle struct { } // Hash hashes the share index and responses -func (r *ResponseBundle) Hash() []byte { +func (b *ResponseBundle) Hash() ([]byte, error) { // first order the response slice in a canonical order - sort.SliceStable(r.Responses, func(i, j int) bool { - return r.Responses[i].DealerIndex < r.Responses[j].DealerIndex + sort.SliceStable(b.Responses, func(i, j int) bool { + return b.Responses[i].DealerIndex < b.Responses[j].DealerIndex }) h := sha256.New() - binary.Write(h, binary.BigEndian, r.ShareIndex) - for _, resp := range r.Responses { - binary.Write(h, binary.BigEndian, resp.DealerIndex) - if resp.Status { - binary.Write(h, binary.BigEndian, byte(1)) + var err error + if err = binary.Write(h, binary.BigEndian, b.ShareIndex); err != nil { + return nil, err + } + + for _, resp := range b.Responses { + if err = binary.Write(h, binary.BigEndian, resp.DealerIndex); err != nil { + return nil, err + } + if resp.Status == Success { + if err = binary.Write(h, binary.BigEndian, byte(1)); err != nil { + return nil, err + } } else { - binary.Write(h, binary.BigEndian, byte(0)) + if err = binary.Write(h, binary.BigEndian, byte(0)); err != nil { + return nil, err + } } } - h.Write(r.SessionID) - return h.Sum(nil) + _, err = h.Write(b.SessionID) + return h.Sum(nil), err } func (b *ResponseBundle) Index() Index { @@ -216,20 +242,32 @@ type Justification struct { Share kyber.Scalar } -func (j *JustificationBundle) Hash() []byte { +func (j *JustificationBundle) Hash() ([]byte, error) { // sort them in a canonical order sort.SliceStable(j.Justifications, func(a, b int) bool { return j.Justifications[a].ShareIndex < j.Justifications[b].ShareIndex }) h := sha256.New() - binary.Write(h, binary.BigEndian, j.DealerIndex) + err := binary.Write(h, binary.BigEndian, j.DealerIndex) + if err != nil { + return nil, err + } for _, just := range j.Justifications { - binary.Write(h, binary.BigEndian, just.ShareIndex) - sbuff, _ := just.Share.MarshalBinary() - h.Write(sbuff) + err := binary.Write(h, binary.BigEndian, just.ShareIndex) + if err != nil { + return nil, err + } + sbuff, err := just.Share.MarshalBinary() + if err != nil { + return nil, err + } + _, err = h.Write(sbuff) + if err != nil { + return nil, err + } } - h.Write(j.SessionID) - return h.Sum(nil) + _, err = h.Write(j.SessionID) + return h.Sum(nil), err } func (j *JustificationBundle) Index() Index { @@ -244,7 +282,7 @@ func (j *JustificationBundle) Sig() []byte { // implementation uses during the different phases. This interface allows to // verify a DKG packet without knowing its specific type. type Packet interface { - Hash() []byte + Hash() ([]byte, error) Index() Index Sig() []byte } @@ -263,26 +301,37 @@ func VerifyPacketSignature(c *Config, p Packet) error { return c.OldNodes } var ok bool + var err error + var hash []byte var pub kyber.Point var sig []byte switch auth := p.(type) { case *DealBundle: - hash = auth.Hash() + hash, err = auth.Hash() + if err != nil { + return err + } pub, ok = findIndex(getDealers(), auth.DealerIndex) if !ok { return errors.New("no nodes with this public key") } sig = auth.Signature case *ResponseBundle: - hash = auth.Hash() + hash, err = auth.Hash() + if err != nil { + return err + } pub, ok = findIndex(c.NewNodes, auth.ShareIndex) if !ok { return errors.New("no nodes with this public key") } sig = auth.Signature case *JustificationBundle: - hash = auth.Hash() + hash, err = auth.Hash() + if err != nil { + return err + } pub, ok = findIndex(getDealers(), auth.DealerIndex) if !ok { return errors.New("no nodes with this public key") @@ -292,6 +341,8 @@ func VerifyPacketSignature(c *Config, p Packet) error { return errors.New("unknown packet type") } - err := c.Auth.Verify(pub, hash, sig) - return err + if err := c.Auth.Verify(pub, hash, sig); err != nil { + return fmt.Errorf("invalid signature: %w", err) + } + return nil } diff --git a/share/dkg/rabin/dkg.go b/share/dkg/rabin/dkg.go index a0acf8799..879d8b09b 100644 --- a/share/dkg/rabin/dkg.go +++ b/share/dkg/rabin/dkg.go @@ -178,7 +178,12 @@ type DistKeyGenerator struct { // the longterm secret key, the list of participants, and the // threshold t parameter. It returns an error if the secret key's // commitment can't be found in the list of participants. -func NewDistKeyGenerator(suite Suite, longterm kyber.Scalar, participants []kyber.Point, t int) (*DistKeyGenerator, error) { +func NewDistKeyGenerator( + suite Suite, + longterm kyber.Scalar, + participants []kyber.Point, + t int, +) (*DistKeyGenerator, error) { pub := suite.Point().Mul(longterm, nil) // find our index var found bool @@ -314,6 +319,7 @@ func (d *DistKeyGenerator) ProcessResponse(resp *Response) (*Justification, erro } if resp.Index != uint32(d.index) { + //nolint:nilnil // Expected behavior return nil, nil } @@ -322,6 +328,7 @@ func (d *DistKeyGenerator) ProcessResponse(resp *Response) (*Justification, erro return nil, err } if j == nil { + //nolint:nilnil // Expected behavior return nil, nil } // a justification for our own deal, are we cheating !? @@ -367,7 +374,7 @@ func (d *DistKeyGenerator) Certified() bool { // the distributed public key with SecretCommits() and ProcessSecretCommits(). func (d *DistKeyGenerator) QUAL() []int { var good []int - d.qualIter(func(i uint32, v *vss.Verifier) bool { + d.qualIter(func(i uint32, _ *vss.Verifier) bool { good = append(good, int(i)) return true }) @@ -376,7 +383,7 @@ func (d *DistKeyGenerator) QUAL() []int { func (d *DistKeyGenerator) isInQUAL(idx uint32) bool { var found bool - d.qualIter(func(i uint32, v *vss.Verifier) bool { + d.qualIter(func(i uint32, _ *vss.Verifier) bool { if i == idx { found = true return false @@ -466,6 +473,8 @@ func (d *DistKeyGenerator) ProcessSecretCommits(sc *SecretCommits) (*ComplaintCo } // commitments are fine d.commitments[sc.Index] = poly + + //nolint:nilnil // Expected behavior return nil, nil } @@ -495,7 +504,7 @@ func (d *DistKeyGenerator) ProcessComplaintCommits(cc *ComplaintCommits) (*Recon // the verification should pass for the deal, and not with the secret // commits. Verification 4) in DKG Rabin's paper. if err := v.VerifyDeal(cc.Deal, false); err != nil { - return nil, fmt.Errorf("dkg: verifying deal: %s", err) + return nil, fmt.Errorf("dkg: verifying deal: %w", err) } secretCommits, ok := d.commitments[cc.DealerIndex] @@ -593,7 +602,7 @@ func (d *DistKeyGenerator) ProcessReconstructCommits(rs *ReconstructCommits) err func (d *DistKeyGenerator) Finished() bool { var ret = true var nb = 0 - d.qualIter(func(idx uint32, v *vss.Verifier) bool { + d.qualIter(func(idx uint32, _ *vss.Verifier) bool { nb++ // ALL QUAL members should have their commitments by now either given or // reconstructed. diff --git a/share/dkg/rabin/dkg_test.go b/share/dkg/rabin/dkg_test.go index 2077f02e3..da0a5bda5 100644 --- a/share/dkg/rabin/dkg_test.go +++ b/share/dkg/rabin/dkg_test.go @@ -144,8 +144,6 @@ func TestDKGProcessResponse(t *testing.T) { require.NotNil(t, resp) assert.Equal(t, false, resp.Response.Approved) deal.RndShare.V = goodSecret - dd, _ = dkg.Deals() - encD = dd[idxRec] // no verifier tied to Response v, ok := dkg.verifiers[0] @@ -174,9 +172,8 @@ func TestDKGProcessResponse(t *testing.T) { // valid complaint from another deal from another peer dkg2 := dkgs[2] require.Nil(t, err) + // fake a wrong deal - //deal20, err := dkg2.dealer.PlaintextDeal(0) - //require.Nil(t, err) deal21, err := dkg2.dealer.PlaintextDeal(1) require.Nil(t, err) goodRnd21 := deal21.RndShare.V @@ -185,7 +182,8 @@ func TestDKGProcessResponse(t *testing.T) { require.Nil(t, err) resp12, err := rec.ProcessDeal(deals2[idxRec]) - assert.NotNil(t, resp) + assert.NotNil(t, resp12) + assert.Nil(t, err) assert.Equal(t, false, resp12.Response.Approved) deal21.RndShare.V = goodRnd21 @@ -210,7 +208,7 @@ func TestDKGProcessResponse(t *testing.T) { assert.NotNil(t, j) // hack because all is local, and resp has been modified locally by dkg2's - // dealer, the status has became "justified" + // dealer, the status has become "justified" resp12.Response.Approved = false err = dkg.ProcessJustification(j) assert.Nil(t, err) @@ -310,7 +308,6 @@ func TestDKGComplaintCommits(t *testing.T) { wrongSc.SessionID = scs[0].SessionID wrongSc.Commitments = make([]kyber.Point, len(scs[0].Commitments)) copy(wrongSc.Commitments, scs[0].Commitments) - //goodScCommit := scs[0].Commitments[0] wrongSc.Commitments[0] = suite.Point().Null() msg := wrongSc.Hash(suite) wrongSc.Signature, _ = schnorr.Sign(suite, dkgs[0].long, msg) diff --git a/share/poly.go b/share/poly.go index d0e0dd11a..b76324e6d 100644 --- a/share/poly.go +++ b/share/poly.go @@ -22,8 +22,8 @@ import ( ) // Some error definitions -var errorGroups = errors.New("non-matching groups") -var errorCoeffs = errors.New("different number of coefficients") +var errGroups = errors.New("non-matching groups") +var errCoeffs = errors.New("different number of coefficients") // PriShare represents a private share. type PriShare struct { @@ -104,10 +104,10 @@ func (p *PriPoly) Shares(n int) []*PriShare { // as a new polynomial. func (p *PriPoly) Add(q *PriPoly) (*PriPoly, error) { if p.g.String() != q.g.String() { - return nil, errorGroups + return nil, errGroups } if p.Threshold() != q.Threshold() { - return nil, errorCoeffs + return nil, errCoeffs } coeffs := make([]kyber.Scalar, p.Threshold()) for i := range coeffs { @@ -229,7 +229,7 @@ func xyScalar(g kyber.Group, shares []*PriShare, t, n int) (map[int]kyber.Scalar x := make(map[int]kyber.Scalar) y := make(map[int]kyber.Scalar) for _, s := range sorted { - if s == nil || s.V == nil || s.I < 0 { + if s == nil || s.V == nil { continue } idx := int(s.I) @@ -263,7 +263,6 @@ func RecoverPriPoly(g kyber.Group, shares []*PriShare, t, n int) (*PriPoly, erro var accPoly *PriPoly var err error - //den := g.Scalar() // Notations follow the Wikipedia article on Lagrange interpolation // https://en.wikipedia.org/wiki/Lagrange_polynomial for j := range x { @@ -363,11 +362,11 @@ func (p *PubPoly) Shares(n int) []*PubShare { // base point and thus should not be used in further computations. func (p *PubPoly) Add(q *PubPoly) (*PubPoly, error) { if p.g.String() != q.g.String() { - return nil, errorGroups + return nil, errGroups } if p.Threshold() != q.Threshold() { - return nil, errorCoeffs + return nil, errCoeffs } commits := make([]kyber.Point, p.Threshold()) @@ -430,7 +429,7 @@ func xyCommit(g kyber.Group, shares []*PubShare, t, n int) (map[int]kyber.Scalar y := make(map[int]kyber.Point) for _, s := range sorted { - if s == nil || s.V == nil || s.I < 0 { + if s == nil || s.V == nil { continue } idx := int(s.I) diff --git a/share/poly_test.go b/share/poly_test.go index 7087cc633..ee070907b 100644 --- a/share/poly_test.go +++ b/share/poly_test.go @@ -1,7 +1,6 @@ package share import ( - "fmt" "testing" "time" @@ -16,7 +15,7 @@ func TestSecretRecovery(test *testing.T) { n := 6 t := 5 poly := NewPriPoly(g, t, nil, g.RandomStream()) - fmt.Println("polynom has degree ", len(poly.coeffs)-1) + test.Log("polynom has degree ", len(poly.coeffs)-1) shares := poly.Shares(n) recovered, err := RecoverSecret(g, shares, t, n) @@ -154,16 +153,15 @@ func TestBenchy(test *testing.T) { now1 := time.Now() _, err := RecoverCommit(g, pubShares, t, n) - //now2 := time.Now() - fmt.Println("time elapsed: ", time.Since(now1)) + test.Log("time elapsed: ", time.Since(now1)) if err != nil { test.Fatal(err) } now1 = time.Now() - RecoverPubPoly(g, pubShares, t, n) + _, _ = RecoverPubPoly(g, pubShares, t, n) - fmt.Println("time elapsed public poly: ", time.Since(now1)) + test.Log("time elapsed public poly: ", time.Since(now1)) } func TestPublicRecovery(test *testing.T) { diff --git a/share/pvss/pvss.go b/share/pvss/pvss.go index 14052311b..04e9761c0 100644 --- a/share/pvss/pvss.go +++ b/share/pvss/pvss.go @@ -31,7 +31,6 @@ type Suite interface { kyber.Random } -// Some error definitions. var ErrTooFewShares = errors.New("not enough shares to recover secret") var ErrDifferentLengths = errors.New("inputs of different lengths") var ErrEncVerification = errors.New("verification of encrypted share failed") @@ -49,7 +48,13 @@ type PubVerShare struct { // the given secret and the list of public keys X using the sharing threshold // t and the base point H. The function returns the list of shares and the // public commitment polynomial. -func EncShares(suite Suite, H kyber.Point, X []kyber.Point, secret kyber.Scalar, t int) (shares []*PubVerShare, commit *share.PubPoly, err error) { +func EncShares( + suite Suite, + H kyber.Point, + X []kyber.Point, + secret kyber.Scalar, + t int, +) (shares []*PubVerShare, commit *share.PubPoly, err error) { n := len(X) encShares := make([]*PubVerShare, n) @@ -115,29 +120,25 @@ func computeGlobalChallenge(suite Suite, n int, commit *share.PubPoly, encShares h := suite.Hash() var err error for _, com := range coms { - _, err = com.MarshalTo(h) - if err != nil { + if _, err = com.MarshalTo(h); err != nil { return nil, err } } - for _, share := range encShares { - _, err = share.S.V.MarshalTo(h) - if err != nil { + for _, encShare := range encShares { + if _, err = encShare.S.V.MarshalTo(h); err != nil { return nil, err } } - for _, share := range encShares { - _, err = share.P.VG.MarshalTo(h) - if err != nil { + for _, encShare := range encShares { + if _, err = encShare.P.VG.MarshalTo(h); err != nil { return nil, err } } - for _, share := range encShares { - _, err = share.P.VH.MarshalTo(h) - if err != nil { + for _, encShare := range encShares { + if _, err = encShare.P.VH.MarshalTo(h); err != nil { return nil, err } } @@ -149,13 +150,13 @@ func computeGlobalChallenge(suite Suite, n int, commit *share.PubPoly, encShares // VerifyEncShare checks that the encrypted share sX satisfies // log_{H}(sH) == log_{X}(sX) where sH is the public commitment computed by // evaluating the public commitment polynomial at the encrypted share's index i. -func VerifyEncShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, expGlobalChallenge kyber.Scalar, encShare *PubVerShare) error { +func VerifyEncShare(suite Suite, H, X, sH kyber.Point, expGlobalChallenge kyber.Scalar, encShare *PubVerShare) error { if !encShare.P.C.Equal(expGlobalChallenge) { - return ErrGlobalChallengeVerification + return fmt.Errorf("didn't verify: %w", ErrGlobalChallengeVerification) } if err := encShare.P.Verify(suite, H, X, sH, encShare.S.V); err != nil { - return ErrEncVerification + return fmt.Errorf("didn't verify: %w", ErrEncVerification) } return nil } @@ -163,9 +164,15 @@ func VerifyEncShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, e // VerifyEncShareBatch provides the same functionality as VerifyEncShare but for // slices of encrypted shares. The function returns the valid encrypted shares // together with the corresponding public keys. -func VerifyEncShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber.Point, commit *share.PubPoly, encShares []*PubVerShare) ([]kyber.Point, []*PubVerShare, error) { +func VerifyEncShareBatch( + suite Suite, + H kyber.Point, + X, sH []kyber.Point, + commit *share.PubPoly, + encShares []*PubVerShare, +) ([]kyber.Point, []*PubVerShare, error) { if len(X) != len(sH) || len(sH) != len(encShares) { - return nil, nil, ErrDifferentLengths + return nil, nil, fmt.Errorf("didn't verify: %w", ErrDifferentLengths) } var K []kyber.Point // good public keys var E []*PubVerShare // good encrypted shares @@ -177,7 +184,6 @@ func VerifyEncShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber } for i := 0; i < len(X); i++ { - if err := VerifyEncShare(suite, H, X[i], sH[i], expGlobalChallenge, encShares[i]); err == nil { K = append(K, X[i]) E = append(E, encShares[i]) @@ -189,7 +195,12 @@ func VerifyEncShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber // DecShare first verifies the encrypted share against the encryption // consistency proof and, if valid, decrypts it and creates a decryption // consistency proof. -func DecShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, x, expGlobalChallenge kyber.Scalar, encShare *PubVerShare) (*PubVerShare, error) { +func DecShare( + suite Suite, + H, X, sH kyber.Point, + x, expGlobalChallenge kyber.Scalar, + encShare *PubVerShare, +) (*PubVerShare, error) { if err := VerifyEncShare(suite, H, X, sH, expGlobalChallenge, encShare); err != nil { return nil, err } @@ -207,9 +218,16 @@ func DecShare(suite Suite, H kyber.Point, X kyber.Point, sH kyber.Point, x, expG // DecShareBatch provides the same functionality as DecShare but for slices of // encrypted shares. The function returns the valid encrypted and decrypted // shares as well as the corresponding public keys. -func DecShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber.Point, x kyber.Scalar, expGlobalChallenges []kyber.Scalar, encShares []*PubVerShare) ([]kyber.Point, []*PubVerShare, []*PubVerShare, error) { +func DecShareBatch( + suite Suite, + H kyber.Point, + X, sH []kyber.Point, + x kyber.Scalar, + expGlobalChallenges []kyber.Scalar, + encShares []*PubVerShare, +) ([]kyber.Point, []*PubVerShare, []*PubVerShare, error) { if len(X) != len(sH) || len(sH) != len(encShares) { - return nil, nil, nil, ErrDifferentLengths + return nil, nil, nil, fmt.Errorf("didn't verify: %w", ErrDifferentLengths) } var K []kyber.Point // good public keys var E []*PubVerShare // good encrypted shares @@ -226,18 +244,28 @@ func DecShareBatch(suite Suite, H kyber.Point, X []kyber.Point, sH []kyber.Point // VerifyDecShare checks that the decrypted share sG satisfies // log_{G}(X) == log_{sG}(sX). Note that X = xG and sX = s(xG) = x(sG). -func VerifyDecShare(suite Suite, G kyber.Point, X kyber.Point, encShare *PubVerShare, decShare *PubVerShare) error { +func VerifyDecShare(suite Suite, G, X kyber.Point, encShare *PubVerShare, decShare *PubVerShare) error { // Compute challenge for the decShare h := suite.Hash() - X.MarshalTo(h) - encShare.S.V.MarshalTo(h) - decShare.P.VG.MarshalTo(h) - decShare.P.VH.MarshalTo(h) + var err error + if _, err = X.MarshalTo(h); err != nil { + return err + } + if _, err = encShare.S.V.MarshalTo(h); err != nil { + return err + } + if _, err = decShare.P.VG.MarshalTo(h); err != nil { + return err + } + if _, err = decShare.P.VH.MarshalTo(h); err != nil { + return err + } + cb := h.Sum(nil) expDecChallenge := suite.Scalar().Pick(suite.XOF(cb)) if !decShare.P.C.Equal(expDecChallenge) { - return ErrDecShareChallengeVerification + return fmt.Errorf("didn't verify: %w", ErrDecShareChallengeVerification) } if err := decShare.P.Verify(suite, G, decShare.S.V, X, encShare.S.V); err != nil { @@ -249,7 +277,13 @@ func VerifyDecShare(suite Suite, G kyber.Point, X kyber.Point, encShare *PubVerS // VerifyDecShareBatch provides the same functionality as VerifyDecShare but for // slices of decrypted shares. The function returns the the valid decrypted shares. -func VerifyDecShareBatch(suite Suite, G kyber.Point, X []kyber.Point, encShares []*PubVerShare, decShares []*PubVerShare) ([]*PubVerShare, error) { +func VerifyDecShareBatch( + suite Suite, + G kyber.Point, + X []kyber.Point, + encShares []*PubVerShare, + decShares []*PubVerShare, +) ([]*PubVerShare, error) { if len(X) != len(encShares) || len(encShares) != len(decShares) { return nil, fmt.Errorf("didn't verify: %w", ErrDifferentLengths) } @@ -265,13 +299,20 @@ func VerifyDecShareBatch(suite Suite, G kyber.Point, X []kyber.Point, encShares // RecoverSecret first verifies the given decrypted shares against their // decryption consistency proofs and then tries to recover the shared secret. -func RecoverSecret(suite Suite, G kyber.Point, X []kyber.Point, encShares []*PubVerShare, decShares []*PubVerShare, t int, n int) (kyber.Point, error) { +func RecoverSecret( + suite Suite, + G kyber.Point, + X []kyber.Point, + encShares []*PubVerShare, + decShares []*PubVerShare, + t, n int, +) (kyber.Point, error) { D, err := VerifyDecShareBatch(suite, G, X, encShares, decShares) if err != nil { return nil, err } if len(D) < t { - return nil, ErrTooFewShares + return nil, fmt.Errorf("didn't verify: %w", ErrTooFewShares) } var shares []*share.PubShare for _, s := range D { diff --git a/share/pvss/pvss_test.go b/share/pvss/pvss_test.go index 4658e9efa..dd1690568 100644 --- a/share/pvss/pvss_test.go +++ b/share/pvss/pvss_test.go @@ -201,7 +201,7 @@ func TestPVSSDeleteFail(test *testing.T) { // (3) Check decrypted shares and recover secret if possible (dealer/3rd party) _, err = RecoverSecret(suite, G, K, E, D, t, n) - require.Equal(test, err, ErrTooFewShares) // this test is supposed to fail + require.ErrorIs(test, err, ErrTooFewShares) // this test is supposed to fail } func TestPVSSBatch(test *testing.T) { diff --git a/share/vss/pedersen/vss.go b/share/vss/pedersen/vss.go index 895eb0f63..e92b1a601 100644 --- a/share/vss/pedersen/vss.go +++ b/share/vss/pedersen/vss.go @@ -6,7 +6,6 @@ package vss import ( "bytes" - "crypto/cipher" "encoding/binary" "errors" "fmt" @@ -29,8 +28,7 @@ type Suite interface { // Dealer encapsulates for creating and distributing the shares and for // replying to any Responses. type Dealer struct { - suite Suite - reader cipher.Stream + suite Suite // long is the longterm key of the Dealer long kyber.Scalar pub kyber.Point @@ -81,7 +79,7 @@ type Response struct { // Index of the verifier issuing this Response from the new set of nodes Index uint32 // false = NO APPROVAL == Complaint , true = APPROVAL - Status bool + StatusApproved bool // Signature over the whole packet Signature []byte } @@ -224,14 +222,15 @@ func (d *Dealer) EncryptedDeals() ([]*EncryptedDeal, error) { } // ProcessResponse analyzes the given Response. If it's a valid complaint, then -// it returns a Justification. This Justification must be broadcasted to every -// participants. If it's an invalid complaint, it returns an error about the +// it returns a Justification. This Justification must be broadcast to every +// participant. If it's an invalid complaint, it returns an error about the // complaint. The verifiers will also ignore an invalid Complaint. func (d *Dealer) ProcessResponse(r *Response) (*Justification, error) { if err := d.verifyResponse(r); err != nil { return nil, err } - if r.Status == StatusApproval { + if r.StatusApproved { + //nolint:nilnil // Expected behavior return nil, nil } @@ -367,12 +366,12 @@ func (v *Verifier) ProcessEncryptedDeal(e *EncryptedDeal) (*Response, error) { } r := &Response{ - SessionID: sid, - Index: uint32(v.index), - Status: StatusApproval, + SessionID: sid, + Index: uint32(v.index), + StatusApproved: StatusApproval, } if err = v.VerifyDeal(d, true); err != nil { - r.Status = StatusComplaint + r.StatusApproved = StatusComplaint } if errors.Is(err, errDealAlreadyProcessed) { @@ -501,11 +500,12 @@ func (v *Verifier) SetTimeout() { // that works on basis of approval only. func (v *Verifier) UnsafeSetResponseDKG(idx uint32, approval bool) { r := &Response{ - SessionID: v.Aggregator.sid, - Index: uint32(idx), - Status: approval, + SessionID: v.Aggregator.sid, + Index: uint32(idx), + StatusApproved: approval, } + //nolint:errcheck // Unsafe function v.Aggregator.addResponse(r) } @@ -525,7 +525,14 @@ type Aggregator struct { timeout bool } -func newAggregator(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int, sid []byte) *Aggregator { +func newAggregator( + suite Suite, + dealer kyber.Point, + verifiers, + commitments []kyber.Point, + t int, + sid []byte, +) *Aggregator { agg := &Aggregator{ suite: suite, dealer: dealer, @@ -634,7 +641,7 @@ func (a *Aggregator) verifyJustification(j *Justification) error { if !ok { return errors.New("vss: no complaints received for this justification") } - if r.Status != StatusComplaint { + if r.StatusApproved { return errors.New("vss: justification received for an approval") } @@ -643,7 +650,7 @@ func (a *Aggregator) verifyJustification(j *Justification) error { a.badDealer = true return err } - r.Status = StatusApproval + r.StatusApproved = StatusApproval return nil } @@ -686,10 +693,10 @@ func (a *Aggregator) DealCertified() bool { for i := range a.verifiers { if r, ok := a.responses[uint32(i)]; !ok { absentVerifiers++ - } else if r.Status == StatusComplaint { - isComplaint = true - } else if r.Status == StatusApproval { + } else if r.StatusApproved { approvals++ + } else { + isComplaint = true } } enoughApprovals := approvals >= a.t @@ -725,15 +732,6 @@ func validT(t int, verifiers []kyber.Point) bool { return t >= 2 && t <= len(verifiers) && int(uint32(t)) == t } -func deriveH(suite Suite, verifiers []kyber.Point) kyber.Point { - var b bytes.Buffer - for _, v := range verifiers { - _, _ = v.MarshalTo(&b) - } - base := suite.Point().Pick(suite.XOF(b.Bytes())) - return base -} - func findPub(verifiers []kyber.Point, idx uint32) (kyber.Point, bool) { iidx := int(idx) if iidx >= len(verifiers) { @@ -744,18 +742,27 @@ func findPub(verifiers []kyber.Point, idx uint32) (kyber.Point, bool) { func sessionID(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int) ([]byte, error) { h := suite.Hash() - _, _ = dealer.MarshalTo(h) + _, err := dealer.MarshalTo(h) + if err != nil { + return nil, err + } for _, v := range verifiers { - _, _ = v.MarshalTo(h) + _, err = v.MarshalTo(h) + if err != nil { + return nil, err + } } for _, c := range commitments { - _, _ = c.MarshalTo(h) + _, err = c.MarshalTo(h) + if err != nil { + return nil, err + } } - _ = binary.Write(h, binary.LittleEndian, uint32(t)) - return h.Sum(nil), nil + err = binary.Write(h, binary.LittleEndian, uint32(t)) + return h.Sum(nil), err } // Hash returns the Hash representation of the Response @@ -764,7 +771,7 @@ func (r *Response) Hash(s Suite) []byte { _, _ = h.Write([]byte("response")) _, _ = h.Write(r.SessionID) _ = binary.Write(h, binary.LittleEndian, r.Index) - _ = binary.Write(h, binary.LittleEndian, r.Status) + _ = binary.Write(h, binary.LittleEndian, r.StatusApproved) return h.Sum(nil) } diff --git a/share/vss/pedersen/vss_test.go b/share/vss/pedersen/vss_test.go index dfbd2101d..ec903bbea 100644 --- a/share/vss/pedersen/vss_test.go +++ b/share/vss/pedersen/vss_test.go @@ -144,18 +144,18 @@ func TestVSSShare(t *testing.T) { resp, err := ver.ProcessEncryptedDeal(deal) require.NotNil(t, resp) - require.Equal(t, StatusApproval, resp.Status) + require.Equal(t, StatusApproval, resp.StatusApproved) require.Nil(t, err) aggr := ver.Aggregator for i := 1; i < aggr.t-1; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusApproval} } // not enough approvals assert.Nil(t, ver.Deal()) - aggr.responses[uint32(aggr.t)] = &Response{Status: StatusApproval} + aggr.responses[uint32(aggr.t)] = &Response{StatusApproved: StatusApproval} // Timeout all other (i>t) verifiers ver.SetTimeout() @@ -174,7 +174,7 @@ func TestVSSAggregatorDealCertified(t *testing.T) { aggr := dealer.Aggregator for i := 0; i < aggr.t; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusApproval} } // Mark remaining verifiers as timed-out @@ -193,7 +193,7 @@ func TestVSSAggregatorDealCertified(t *testing.T) { // inconsistent state on purpose // too much complaints for i := 0; i < aggr.t; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusComplaint} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusComplaint} } assert.False(t, aggr.DealCertified()) } @@ -249,7 +249,7 @@ func TestVSSVerifierReceiveDeal(t *testing.T) { // correct deal resp, err := v.ProcessEncryptedDeal(encD) require.NotNil(t, resp) - assert.Equal(t, StatusApproval, resp.Status) + assert.Equal(t, StatusApproval, resp.StatusApproved) assert.Nil(t, err) assert.Equal(t, v.index, int(resp.Index)) assert.Equal(t, dealer.sid, resp.SessionID) @@ -289,7 +289,7 @@ func TestVSSVerifierReceiveDeal(t *testing.T) { v.Aggregator.deal = nil // approval already existing from same origin, should never happen right ? - v.Aggregator.responses[uint32(v.index)] = &Response{Status: StatusApproval} + v.Aggregator.responses[uint32(v.index)] = &Response{StatusApproved: StatusApproval} d.Commitments[0] = suite.Point().Pick(rng) resp, err = v.ProcessEncryptedDeal(encD) assert.Nil(t, resp) @@ -299,10 +299,9 @@ func TestVSSVerifierReceiveDeal(t *testing.T) { // valid complaint v.Aggregator.deal = nil delete(v.Aggregator.responses, uint32(v.index)) - //d.RndShare.V = suite.Scalar().SetBytes(randomBytes(32)) resp, err = v.ProcessEncryptedDeal(encD) assert.NotNil(t, resp) - assert.Equal(t, StatusComplaint, resp.Status) + assert.Equal(t, StatusComplaint, resp.StatusApproved) assert.Nil(t, err) } @@ -317,13 +316,14 @@ func TestVSSAggregatorVerifyJustification(t *testing.T) { encD, _ := dealer.EncryptedDeal(0) resp, err := v.ProcessEncryptedDeal(encD) assert.NotNil(t, resp) - assert.Equal(t, StatusComplaint, resp.Status) + assert.Equal(t, StatusComplaint, resp.StatusApproved) assert.Nil(t, err) assert.Equal(t, v.responses[uint32(v.index)], resp) // in tests, pointers point to the same underlying share.. d.SecShare.V = goodV j, err := dealer.ProcessResponse(resp) + assert.Nil(t, err) // invalid deal justified goodV = j.Deal.SecShare.V @@ -355,20 +355,18 @@ func TestVSSAggregatorVerifyResponseDuplicate(t *testing.T) { dealer, verifiers := genAll() v1 := verifiers[0] v2 := verifiers[1] - //d1 := dealer.deals[0] - //d2 := dealer.deals[1] encD1, _ := dealer.EncryptedDeal(0) encD2, _ := dealer.EncryptedDeal(1) resp1, err := v1.ProcessEncryptedDeal(encD1) assert.Nil(t, err) assert.NotNil(t, resp1) - assert.Equal(t, StatusApproval, resp1.Status) + assert.Equal(t, StatusApproval, resp1.StatusApproved) resp2, err := v2.ProcessEncryptedDeal(encD2) assert.Nil(t, err) assert.NotNil(t, resp2) - assert.Equal(t, StatusApproval, resp2.Status) + assert.Equal(t, StatusApproval, resp2.StatusApproved) err = v1.ProcessResponse(resp2) assert.Nil(t, err) @@ -380,7 +378,7 @@ func TestVSSAggregatorVerifyResponseDuplicate(t *testing.T) { assert.Error(t, err) delete(v1.Aggregator.responses, uint32(v2.index)) - v1.Aggregator.responses[uint32(v2.index)] = &Response{Status: StatusApproval} + v1.Aggregator.responses[uint32(v2.index)] = &Response{StatusApproved: StatusApproval} err = v1.ProcessResponse(resp2) assert.Error(t, err) } @@ -389,7 +387,6 @@ func TestVSSAggregatorVerifyResponse(t *testing.T) { dealer, verifiers := genAll() v := verifiers[0] deal := dealer.deals[0] - //goodSec := deal.SecShare.V wrongSec, _ := genPair() deal.SecShare.V = wrongSec encD, _ := dealer.EncryptedDeal(0) @@ -397,14 +394,14 @@ func TestVSSAggregatorVerifyResponse(t *testing.T) { resp, err := v.ProcessEncryptedDeal(encD) assert.Nil(t, err) assert.NotNil(t, resp) - assert.Equal(t, StatusComplaint, resp.Status) + assert.Equal(t, StatusComplaint, resp.StatusApproved) assert.NotNil(t, v.Aggregator) assert.Equal(t, resp.SessionID, dealer.sid) aggr := v.Aggregator r, ok := aggr.responses[uint32(v.index)] assert.True(t, ok) - assert.Equal(t, StatusComplaint, r.Status) + assert.Equal(t, StatusComplaint, r.StatusApproved) // wrong index resp.Index = uint32(len(verifiersPub)) @@ -433,12 +430,12 @@ func TestVSSAggregatorAllResponses(t *testing.T) { aggr := dealer.Aggregator for i := 0; i < aggr.t; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusApproval} } assert.False(t, aggr.DealCertified()) for i := aggr.t; i < nbVerifiers; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusApproval} } assert.True(t, aggr.DealCertified()) @@ -450,7 +447,7 @@ func TestVSSDealerTimeout(t *testing.T) { aggr := dealer.Aggregator for i := 0; i < aggr.t; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusApproval} } require.False(t, aggr.DealCertified()) @@ -479,7 +476,7 @@ func TestVSSVerifierTimeout(t *testing.T) { // Add t responses for i := 0; i < aggr.t; i++ { - aggr.responses[uint32(i)] = &Response{Status: StatusApproval} + aggr.responses[uint32(i)] = &Response{StatusApproved: StatusApproval} } assert.False(t, aggr.DealCertified()) @@ -542,8 +539,8 @@ func TestVSSAggregatorAddComplaint(t *testing.T) { var idx uint32 = 1 c := &Response{ - Index: idx, - Status: StatusComplaint, + Index: idx, + StatusApproved: StatusComplaint, } // ok assert.Nil(t, aggr.addResponse(c)) diff --git a/share/vss/rabin/dh.go b/share/vss/rabin/dh.go index 201d0f9ab..fd0d28536 100644 --- a/share/vss/rabin/dh.go +++ b/share/vss/rabin/dh.go @@ -43,14 +43,25 @@ func newAEAD(fn func() hash.Hash, preSharedKey kyber.Point, context []byte) (cip const keySize = 128 // context returns the context slice to be used when encrypting a share -func context(suite Suite, dealer kyber.Point, verifiers []kyber.Point) []byte { +func context(suite Suite, dealer kyber.Point, verifiers []kyber.Point) ([]byte, error) { h := suite.XOF([]byte("vss-dealer")) - _, _ = dealer.MarshalTo(h) - _, _ = h.Write([]byte("vss-verifiers")) + _, err := dealer.MarshalTo(h) + if err != nil { + return nil, err + } + _, err = h.Write([]byte("vss-verifiers")) + if err != nil { + return nil, err + } + for _, v := range verifiers { - _, _ = v.MarshalTo(h) + _, err = v.MarshalTo(h) + if err != nil { + return nil, err + } } + sum := make([]byte, keySize) - h.Read(sum) - return sum + _, err = h.Read(sum) + return sum, err } diff --git a/share/vss/rabin/vss.go b/share/vss/rabin/vss.go index 693afe6dc..1746867f0 100644 --- a/share/vss/rabin/vss.go +++ b/share/vss/rabin/vss.go @@ -32,7 +32,6 @@ package vss import ( "bytes" - "crypto/cipher" "encoding/binary" "errors" "fmt" @@ -55,8 +54,8 @@ type Suite interface { // Dealer encapsulates for creating and distributing the shares and for // replying to any Responses. type Dealer struct { - suite Suite - reader cipher.Stream + suite Suite + // long is the longterm key of the Dealer long kyber.Scalar pub kyber.Point @@ -181,8 +180,8 @@ func NewDealer(suite Suite, longterm, secret kyber.Scalar, verifiers []kyber.Poi T: uint32(d.t), } } - d.hkdfContext = context(suite, d.pub, verifiers) - return d, nil + d.hkdfContext, err = context(suite, d.pub, verifiers) + return d, err } // PlaintextDeal returns the plaintext version of the deal destined for peer i. @@ -259,7 +258,7 @@ func (d *Dealer) ProcessResponse(r *Response) (*Justification, error) { return nil, err } if r.Approved { - return nil, nil + return nil, nil //nolint:nilnil // Expected behavior } j := &Justification{ @@ -350,6 +349,10 @@ func NewVerifier(suite Suite, longterm kyber.Scalar, dealerKey kyber.Point, if !ok { return nil, errors.New("vss: public key not found in the list of verifiers") } + hkdfContext, err := context(suite, dealerKey, verifiers) + if err != nil { + return nil, err + } v := &Verifier{ suite: suite, longterm: longterm, @@ -357,8 +360,9 @@ func NewVerifier(suite Suite, longterm kyber.Scalar, dealerKey kyber.Point, verifiers: verifiers, pub: pub, index: index, - hkdfContext: context(suite, dealerKey, verifiers), + hkdfContext: hkdfContext, } + return v, nil } @@ -521,7 +525,14 @@ type aggregator struct { badDealer bool } -func newAggregator(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int, sid []byte) *aggregator { +func newAggregator( + suite Suite, + dealer kyber.Point, + verifiers, + commitments []kyber.Point, + t int, + sid []byte, +) *aggregator { agg := &aggregator{ suite: suite, dealer: dealer, @@ -563,7 +574,7 @@ func (a *aggregator) VerifyDeal(d *Deal, inclusion bool) error { if fi.I != gi.I { return errors.New("vss: not the same index for f and g share in Deal") } - if fi.I < 0 || fi.I >= uint32(len(a.verifiers)) { + if fi.I >= uint32(len(a.verifiers)) { return errors.New("vss: index out of bounds in Deal") } // compute fi * G + gi * H @@ -686,6 +697,7 @@ func (a *aggregator) UnsafeSetResponseDKG(idx uint32, approval bool) { Approved: approval, } + //nolint:errcheck // Unsafe function a.addResponse(r) } @@ -721,18 +733,27 @@ func findPub(verifiers []kyber.Point, idx uint32) (kyber.Point, bool) { func sessionID(suite Suite, dealer kyber.Point, verifiers, commitments []kyber.Point, t int) ([]byte, error) { h := suite.Hash() - _, _ = dealer.MarshalTo(h) + _, err := dealer.MarshalTo(h) + if err != nil { + return nil, err + } for _, v := range verifiers { - _, _ = v.MarshalTo(h) + _, err = v.MarshalTo(h) + if err != nil { + return nil, err + } } for _, c := range commitments { - _, _ = c.MarshalTo(h) + _, err = c.MarshalTo(h) + if err != nil { + return nil, err + } } - _ = binary.Write(h, binary.LittleEndian, uint32(t)) - return h.Sum(nil), nil + err = binary.Write(h, binary.LittleEndian, uint32(t)) + return h.Sum(nil), err } // Hash returns the Hash representation of the Response diff --git a/share/vss/rabin/vss_test.go b/share/vss/rabin/vss_test.go index 2de16f09a..4957657f2 100644 --- a/share/vss/rabin/vss_test.go +++ b/share/vss/rabin/vss_test.go @@ -335,8 +335,6 @@ func TestVSSAggregatorVerifyResponseDuplicate(t *testing.T) { dealer, verifiers := genAll() v1 := verifiers[0] v2 := verifiers[1] - //d1 := dealer.deals[0] - //d2 := dealer.deals[1] encD1, _ := dealer.EncryptedDeal(0) encD2, _ := dealer.EncryptedDeal(1) @@ -369,7 +367,6 @@ func TestVSSAggregatorVerifyResponse(t *testing.T) { dealer, verifiers := genAll() v := verifiers[0] deal := dealer.deals[0] - //goodSec := deal.SecShare.V wrongSec, _ := genPair() deal.SecShare.V = wrongSec encD, _ := dealer.EncryptedDeal(0) @@ -565,7 +562,8 @@ func TestVSSDHExchange(t *testing.T) { } func TestVSSContext(t *testing.T) { - c := context(suite, dealerPub, verifiersPub) + c, err := context(suite, dealerPub, verifiersPub) + assert.Nil(t, err) assert.Len(t, c, keySize) } diff --git a/shuffle/biffle.go b/shuffle/biffle.go index 035b98e4a..5d7e08d44 100644 --- a/shuffle/biffle.go +++ b/shuffle/biffle.go @@ -77,7 +77,7 @@ func Biffle(suite Suite, G, H kyber.Point, points := bifflePoints(suite, G, H, X, Y, Xbar, Ybar) choice := map[proof.Predicate]int{or: bit} prover = or.Prover(suite, secrets, points, choice) - return + return Xbar, Ybar, prover } // BiffleVerifier returns a verifier of the biffle diff --git a/shuffle/biffle_test.go b/shuffle/biffle_test.go index 7afd29012..a4f756810 100644 --- a/shuffle/biffle_test.go +++ b/shuffle/biffle_test.go @@ -9,19 +9,19 @@ import ( "go.dedis.ch/kyber/v4/xof/blake2xb" ) -func TestBiffle(t *testing.T) { +func TestBiffle(_ *testing.T) { rand := blake2xb.New(nil) s := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) biffleTest(s, N) } -func TestInvalidBiffle(t *testing.T) { +func TestInvalidBiffle(_ *testing.T) { rand := blake2xb.New(nil) s := edwards25519.NewBlakeSHA256Ed25519WithRand(rand) biffleInvalidTest(s) } -func biffleTest(suite Suite, N int) { +func biffleTest(suite Suite, n int) { rand := suite.RandomStream() h, c := setShuffleKeyPairs(rand, suite, 2) @@ -35,8 +35,8 @@ func biffleTest(suite Suite, N int) { Y[i].Add(Y[i], c[i]) // Encrypted client public key } - // Repeat only the actual shuffle portion for benchmark purposes. - for i := 0; i < N; i++ { + // Repeat only the actual shuffle portion for test purposes. + for i := 0; i < n; i++ { // Do a key-shuffle Xbar, Ybar, prover := Biffle(suite, nil, h, X, Y, rand) @@ -44,7 +44,6 @@ func biffleTest(suite Suite, N int) { if err != nil { panic("Biffle proof failed: " + err.Error()) } - //fmt.Printf("proof:\n%s\n",hex.Dump(prf)) // Check it verifier := BiffleVerifier(suite, nil, h, X, Y, Xbar, Ybar) diff --git a/shuffle/pair.go b/shuffle/pair.go index 9e904bbf0..bd267d7b6 100644 --- a/shuffle/pair.go +++ b/shuffle/pair.go @@ -68,6 +68,8 @@ type ega5 struct { } // P and V, step 5: simple k-shuffle proof +// +//nolint:unused // may be useful later type ega6 struct { SimpleShuffle } @@ -122,8 +124,10 @@ func (ps *PairShuffle) Init(grp kyber.Group, k int) *PairShuffle { } // Prove returns an error if the shuffle is not correct. +// +//nolint:funlen func (ps *PairShuffle) Prove( - pi []int, g, h kyber.Point, beta []kyber.Scalar, + pi []int, G, H kyber.Point, beta []kyber.Scalar, X, Y []kyber.Point, rand cipher.Stream, ctx proof.ProverContext) error { @@ -148,10 +152,13 @@ func (ps *PairShuffle) Prove( w := make([]kyber.Scalar, k) a := make([]kyber.Scalar, k) var tau0, nu, gamma kyber.Scalar - ctx.PriRand(u, w, a, &tau0, &nu, &gamma) + err := ctx.PriRand(u, w, a, &tau0, &nu, &gamma) + if err != nil { + return err + } // compute public commits - p1.Gamma = grp.Point().Mul(gamma, g) + p1.Gamma = grp.Point().Mul(gamma, G) wbeta := grp.Scalar() // scratch wbetasum := grp.Scalar().Set(tau0) p1.Lambda1 = grp.Point().Null() @@ -159,16 +166,16 @@ func (ps *PairShuffle) Prove( XY := grp.Point() // scratch wu := grp.Scalar() // scratch for i := 0; i < k; i++ { - p1.A[i] = grp.Point().Mul(a[i], g) - p1.C[i] = grp.Point().Mul(z.Mul(gamma, a[pi[i]]), g) - p1.U[i] = grp.Point().Mul(u[i], g) - p1.W[i] = grp.Point().Mul(z.Mul(gamma, w[i]), g) + p1.A[i] = grp.Point().Mul(a[i], G) + p1.C[i] = grp.Point().Mul(z.Mul(gamma, a[pi[i]]), G) + p1.U[i] = grp.Point().Mul(u[i], G) + p1.W[i] = grp.Point().Mul(z.Mul(gamma, w[i]), G) wbetasum.Add(wbetasum, wbeta.Mul(w[i], beta[pi[i]])) p1.Lambda1.Add(p1.Lambda1, XY.Mul(wu.Sub(w[piinv[i]], u[i]), X[i])) p1.Lambda2.Add(p1.Lambda2, XY.Mul(wu.Sub(w[piinv[i]], u[i]), Y[i])) } - p1.Lambda1.Add(p1.Lambda1, XY.Mul(wbetasum, g)) - p1.Lambda2.Add(p1.Lambda2, XY.Mul(wbetasum, h)) + p1.Lambda1.Add(p1.Lambda1, XY.Mul(wbetasum, G)) + p1.Lambda2.Add(p1.Lambda2, XY.Mul(wbetasum, H)) if err := ctx.Put(p1); err != nil { return err } @@ -180,7 +187,7 @@ func (ps *PairShuffle) Prove( } B := make([]kyber.Point, k) for i := 0; i < k; i++ { - P := grp.Point().Mul(v2.Zrho[i], g) + P := grp.Point().Mul(v2.Zrho[i], G) B[i] = P.Sub(P, p1.U[i]) } @@ -193,7 +200,7 @@ func (ps *PairShuffle) Prove( d := make([]kyber.Scalar, k) for i := 0; i < k; i++ { d[i] = grp.Scalar().Mul(gamma, b[pi[i]]) - p3.D[i] = grp.Point().Mul(d[i], g) + p3.D[i] = grp.Point().Mul(d[i], G) } if err := ctx.Put(p3); err != nil { return err @@ -225,12 +232,12 @@ func (ps *PairShuffle) Prove( } // P,V step 6: embedded simple k-shuffle proof - return ps.pv6.Prove(g, gamma, r, s, rand, ctx) + return ps.pv6.Prove(G, gamma, r, s, rand, ctx) } // Verify ElGamal Pair Shuffle proofs. func (ps *PairShuffle) Verify( - g, h kyber.Point, X, Y, Xbar, Ybar []kyber.Point, + G, H kyber.Point, X, Y, Xbar, Ybar []kyber.Point, ctx proof.VerifierContext) error { // Validate all vector lengths @@ -253,7 +260,7 @@ func (ps *PairShuffle) Verify( } B := make([]kyber.Point, k) for i := 0; i < k; i++ { - P := grp.Point().Mul(v2.Zrho[i], g) + P := grp.Point().Mul(v2.Zrho[i], G) B[i] = P.Sub(P, p1.U[i]) } @@ -276,7 +283,7 @@ func (ps *PairShuffle) Verify( } // P,V step 6: simple k-shuffle - if err := ps.pv6.Verify(g, p1.Gamma, ctx); err != nil { + if err := ps.pv6.Verify(G, p1.Gamma, ctx); err != nil { return err } @@ -290,19 +297,14 @@ func (ps *PairShuffle) Verify( Phi1 = Phi1.Sub(Phi1, P.Mul(v2.Zrho[i], X[i])) Phi2 = Phi2.Add(Phi2, P.Mul(p5.Zsigma[i], Ybar[i])) // (32) Phi2 = Phi2.Sub(Phi2, P.Mul(v2.Zrho[i], Y[i])) - // println("i",i) if !P.Mul(p5.Zsigma[i], p1.Gamma).Equal( // (33) Q.Add(p1.W[i], p3.D[i])) { return errors.New("invalid PairShuffleProof") } } - // println("last") - // println("Phi1",Phi1.String()); - // println("Phi2",Phi2.String()); - // println("1",P.Add(p1.Lambda1,Q.Mul(g,p5.Ztau)).String()); - // println("2",P.Add(p1.Lambda2,Q.Mul(h,p5.Ztau)).String()); - if !P.Add(p1.Lambda1, Q.Mul(p5.Ztau, g)).Equal(Phi1) || // (34) - !P.Add(p1.Lambda2, Q.Mul(p5.Ztau, h)).Equal(Phi2) { // (35) + + if !P.Add(p1.Lambda1, Q.Mul(p5.Ztau, G)).Equal(Phi1) || // (34) + !P.Add(p1.Lambda2, Q.Mul(p5.Ztau, H)).Equal(Phi2) { // (35) return errors.New("invalid PairShuffleProof") } @@ -313,8 +315,8 @@ func (ps *PairShuffle) Verify( // producing a correctness proof in the process. // Returns (Xbar,Ybar), the shuffled and randomized pairs. // If g or h is nil, the standard base point is used. -func Shuffle(group kyber.Group, g, h kyber.Point, X, Y []kyber.Point, - rand cipher.Stream) (XX, YY []kyber.Point, P proof.Prover) { +func Shuffle(group kyber.Group, G, H kyber.Point, X, Y []kyber.Point, + rand cipher.Stream) (xx, yy []kyber.Point, p proof.Prover) { k := len(X) if k != len(Y) { @@ -332,9 +334,7 @@ func Shuffle(group kyber.Group, g, h kyber.Point, X, Y []kyber.Point, for i := k - 1; i > 0; i-- { // Shuffle by random swaps j := int(randUint64(rand) % uint64(i+1)) if j != i { - t := pi[j] - pi[j] = pi[i] - pi[i] = t + pi[j], pi[i] = pi[i], pi[j] } } @@ -348,14 +348,14 @@ func Shuffle(group kyber.Group, g, h kyber.Point, X, Y []kyber.Point, Xbar := make([]kyber.Point, k) Ybar := make([]kyber.Point, k) for i := 0; i < k; i++ { - Xbar[i] = ps.grp.Point().Mul(beta[pi[i]], g) + Xbar[i] = ps.grp.Point().Mul(beta[pi[i]], G) Xbar[i].Add(Xbar[i], X[pi[i]]) - Ybar[i] = ps.grp.Point().Mul(beta[pi[i]], h) + Ybar[i] = ps.grp.Point().Mul(beta[pi[i]], H) Ybar[i].Add(Ybar[i], Y[pi[i]]) } prover := func(ctx proof.ProverContext) error { - return ps.Prove(pi, g, h, beta, X, Y, rand, ctx) + return ps.Prove(pi, G, H, beta, X, Y, rand, ctx) } return Xbar, Ybar, prover } @@ -367,13 +367,11 @@ func randUint64(rand cipher.Stream) uint64 { } // Verifier produces a Sigma-protocol verifier to check the correctness of a shuffle. -func Verifier(group kyber.Group, g, h kyber.Point, - X, Y, Xbar, Ybar []kyber.Point) proof.Verifier { - +func Verifier(group kyber.Group, G, H kyber.Point, X, Y, Xbar, Ybar []kyber.Point) proof.Verifier { ps := PairShuffle{} ps.Init(group, len(X)) verifier := func(ctx proof.VerifierContext) error { - return ps.Verify(g, h, X, Y, Xbar, Ybar, ctx) + return ps.Verify(G, H, X, Y, Xbar, Ybar, ctx) } return verifier } diff --git a/shuffle/sequence_test.go b/shuffle/sequence_test.go index 5f9610819..63814e625 100644 --- a/shuffle/sequence_test.go +++ b/shuffle/sequence_test.go @@ -20,37 +20,37 @@ func TestAssertXY(t *testing.T) { { x: nil, y: nil, - errStr: "X is empty", + errStr: "array X is empty", }, { x: [][]kyber.Point{{}}, y: [][]kyber.Point{{}}, - errStr: "X is empty", + errStr: "array X is empty", }, { x: [][]kyber.Point{make([]kyber.Point, 1)}, y: [][]kyber.Point{{}}, - errStr: "Y is empty", + errStr: "array Y is empty", }, { x: [][]kyber.Point{make([]kyber.Point, 1)}, y: nil, - errStr: "Y is empty", + errStr: "array Y is empty", }, { x: [][]kyber.Point{make([]kyber.Point, 1), make([]kyber.Point, 2)}, y: [][]kyber.Point{make([]kyber.Point, 1)}, - errStr: "X and Y have a different size: 2 != 1", + errStr: "arrays X and Y have a different size: 2 != 1", }, { x: [][]kyber.Point{make([]kyber.Point, 1)}, y: [][]kyber.Point{make([]kyber.Point, 2)}, - errStr: "Y[0] has unexpected size: 1 != 2", + errStr: "array Y[0] has unexpected size: 1 != 2", }, { x: [][]kyber.Point{make([]kyber.Point, 1), make([]kyber.Point, 2)}, y: [][]kyber.Point{make([]kyber.Point, 1), make([]kyber.Point, 1)}, - errStr: "X[1] has unexpected size: 1 != 2", + errStr: "array X[1] has unexpected size: 1 != 2", }, } diff --git a/shuffle/sequences.go b/shuffle/sequences.go index 35f079549..1c41c49c6 100644 --- a/shuffle/sequences.go +++ b/shuffle/sequences.go @@ -33,9 +33,11 @@ import ( // Last coordinate is (NQ-1, k-1) // // Variable names are as representative to the paper as possible. -func SequencesShuffle(group kyber.Group, g, h kyber.Point, X, Y [][]kyber.Point, - rand cipher.Stream) (Xbar, Ybar [][]kyber.Point, getProver func(e []kyber.Scalar) ( - proof.Prover, error)) { +func SequencesShuffle( + group kyber.Group, + G, H kyber.Point, + X, Y [][]kyber.Point, + rand cipher.Stream) (xBar, yBar [][]kyber.Point, getProver func(e []kyber.Scalar) (proof.Prover, error)) { err := assertXY(X, Y) if err != nil { @@ -71,25 +73,25 @@ func SequencesShuffle(group kyber.Group, g, h kyber.Point, X, Y [][]kyber.Point, } // Perform the Shuffle - Xbar = make([][]kyber.Point, NQ) - Ybar = make([][]kyber.Point, NQ) + xBar = make([][]kyber.Point, NQ) + yBar = make([][]kyber.Point, NQ) for j := 0; j < NQ; j++ { - Xbar[j] = make([]kyber.Point, k) - Ybar[j] = make([]kyber.Point, k) + xBar[j] = make([]kyber.Point, k) + yBar[j] = make([]kyber.Point, k) for i := 0; i < k; i++ { - Xbar[j][i] = group.Point().Mul(beta[j][pi[i]], g) - Xbar[j][i].Add(Xbar[j][i], X[j][pi[i]]) + xBar[j][i] = group.Point().Mul(beta[j][pi[i]], G) + xBar[j][i].Add(xBar[j][i], X[j][pi[i]]) - Ybar[j][i] = group.Point().Mul(beta[j][pi[i]], h) - Ybar[j][i].Add(Ybar[j][i], Y[j][pi[i]]) + yBar[j][i] = group.Point().Mul(beta[j][pi[i]], H) + yBar[j][i].Add(yBar[j][i], Y[j][pi[i]]) } } getProver = func(e []kyber.Scalar) (proof.Prover, error) { // EGAR 2 (Prover) - Standard ElGamal k-shuffle proof: Knowledge of - // (XUp, YUp), (XDown, YDown) and e[j] + // (xUp, yUp), (xDown, yDown) and e[j] ps := PairShuffle{} ps.Init(group, k) @@ -111,36 +113,36 @@ func SequencesShuffle(group kyber.Group, g, h kyber.Point, X, Y [][]kyber.Point, } } - XUp, YUp, _, _ := GetSequenceVerifiable(group, X, Y, Xbar, Ybar, e) + XUp, YUp, _, _ := GetSequenceVerifiable(group, X, Y, xBar, yBar, e) - return ps.Prove(pi, g, h, beta2, XUp, YUp, rand, ctx) + return ps.Prove(pi, G, H, beta2, XUp, YUp, rand, ctx) }, nil } - return Xbar, Ybar, getProver + return xBar, yBar, getProver } -// assertXY checks that X, Y have the same dimensions and at least one element +// assertXY checks that x, y have the same dimensions and at least one element func assertXY(X, Y [][]kyber.Point) error { if len(X) == 0 || len(X[0]) == 0 { - return errors.New("X is empty") + return errors.New("array X is empty") } if len(Y) == 0 || len(Y[0]) == 0 { - return errors.New("Y is empty") + return errors.New("array Y is empty") } if len(X) != len(Y) { - return fmt.Errorf("X and Y have a different size: %d != %d", len(X), len(Y)) + return fmt.Errorf("arrays X and Y have a different size: %d != %d", len(X), len(Y)) } expected := len(X[0]) for i := range X { if len(X[i]) != expected { - return fmt.Errorf("X[%d] has unexpected size: %d != %d", i, expected, len(X[i])) + return fmt.Errorf("array X[%d] has unexpected size: %d != %d", i, expected, len(X[i])) } if len(Y[i]) != expected { - return fmt.Errorf("Y[%d] has unexpected size: %d != %d", i, expected, len(Y[i])) + return fmt.Errorf("array Y[%d] has unexpected size: %d != %d", i, expected, len(Y[i])) } } @@ -150,38 +152,38 @@ func assertXY(X, Y [][]kyber.Point) error { // GetSequenceVerifiable returns the consolidated input and output of sequence // shuffling elements. Needed by the prover and verifier. func GetSequenceVerifiable(group kyber.Group, X, Y, Xbar, Ybar [][]kyber.Point, e []kyber.Scalar) ( - XUp, YUp, XDown, YDown []kyber.Point) { + xUp, yUp, xDown, yDown []kyber.Point) { // EGAR1 (Verifier) - Consolidate input and output NQ := len(X) k := len(X[0]) - XUp = make([]kyber.Point, k) - YUp = make([]kyber.Point, k) - XDown = make([]kyber.Point, k) - YDown = make([]kyber.Point, k) + xUp = make([]kyber.Point, k) + yUp = make([]kyber.Point, k) + xDown = make([]kyber.Point, k) + yDown = make([]kyber.Point, k) for i := 0; i < k; i++ { // No modification could be made for e[0] -> e[0] = 1 if one wanted - // Remark 7 in the paper - XUp[i] = group.Point().Mul(e[0], X[0][i]) - YUp[i] = group.Point().Mul(e[0], Y[0][i]) + xUp[i] = group.Point().Mul(e[0], X[0][i]) + yUp[i] = group.Point().Mul(e[0], Y[0][i]) - XDown[i] = group.Point().Mul(e[0], Xbar[0][i]) - YDown[i] = group.Point().Mul(e[0], Ybar[0][i]) + xDown[i] = group.Point().Mul(e[0], Xbar[0][i]) + yDown[i] = group.Point().Mul(e[0], Ybar[0][i]) for j := 1; j < NQ; j++ { - XUp[i] = group.Point().Add(XUp[i], + xUp[i] = group.Point().Add(xUp[i], group.Point().Mul(e[j], X[j][i])) - YUp[i] = group.Point().Add(YUp[i], + yUp[i] = group.Point().Add(yUp[i], group.Point().Mul(e[j], Y[j][i])) - XDown[i] = group.Point().Add(XDown[i], + xDown[i] = group.Point().Add(xDown[i], group.Point().Mul(e[j], Xbar[j][i])) - YDown[i] = group.Point().Add(YDown[i], + yDown[i] = group.Point().Add(yDown[i], group.Point().Mul(e[j], Ybar[j][i])) } } - return XUp, YUp, XDown, YDown + return xUp, yUp, xDown, yDown } diff --git a/shuffle/shuffle_test.go b/shuffle/shuffle_test.go index b02371779..722c9277d 100644 --- a/shuffle/shuffle_test.go +++ b/shuffle/shuffle_test.go @@ -15,7 +15,7 @@ var k = 5 var NQ = 6 var N = 1 -func TestShufflePair(t *testing.T) { +func TestShufflePair(_ *testing.T) { s := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) pairShuffleTest(s, k, N) } @@ -25,7 +25,7 @@ func TestShuffleInvalidPair(t *testing.T) { pairInvalidShuffleTest(t, s, k) } -func TestShuffleSequence(t *testing.T) { +func TestShuffleSequence(_ *testing.T) { s := edwards25519.NewBlakeSHA256Ed25519WithRand(blake2xb.New(nil)) sequenceShuffleTest(s, k, NQ, N) } @@ -151,19 +151,19 @@ func generateAndEncryptRandomSequences( return X, Y } -func sequenceShuffleTest(suite Suite, k, NQ, N int) { +func sequenceShuffleTest(suite Suite, k, nq, n int) { rand := suite.RandomStream() h, c := setShuffleKeyPairs(rand, suite, k) X, Y := generateAndEncryptRandomSequences(rand, suite, h, c, k) // Repeat only the actual shuffle portion for benchmark purposes. - for i := 0; i < N; i++ { + for i := 0; i < n; i++ { // Do a key-shuffle XX, YY, getProver := SequencesShuffle(suite, nil, h, X, Y, rand) - e := make([]kyber.Scalar, NQ) - for j := 0; j < NQ; j++ { + e := make([]kyber.Scalar, nq) + for j := 0; j < nq; j++ { e[j] = suite.Scalar().Pick(suite.RandomStream()) } @@ -189,7 +189,7 @@ func sequenceShuffleTest(suite Suite, k, NQ, N int) { } } -func sequenceInvalidShuffleTest(t *testing.T, suite Suite, k, NQ int) { +func sequenceInvalidShuffleTest(t *testing.T, suite Suite, k, nq int) { rand := suite.RandomStream() h, c := setShuffleKeyPairs(rand, suite, k) X, Y := generateAndEncryptRandomSequences(rand, suite, h, c, k) @@ -200,8 +200,8 @@ func sequenceInvalidShuffleTest(t *testing.T, suite Suite, k, NQ int) { // Corrupt original inputs X[0][0], Y[0][0] = X[0][1], Y[0][1] - e := make([]kyber.Scalar, NQ) - for j := 0; j < NQ; j++ { + e := make([]kyber.Scalar, nq) + for j := 0; j < nq; j++ { e[j] = suite.Scalar().Pick(suite.RandomStream()) } diff --git a/shuffle/simple.go b/shuffle/simple.go index b2fbe99ba..d2d5e5609 100644 --- a/shuffle/simple.go +++ b/shuffle/simple.go @@ -86,8 +86,10 @@ func (ss *SimpleShuffle) Init(grp kyber.Group, k int) *SimpleShuffle { // Neff, "Verifiable Mixing (Shuffling) of ElGamal Pairs", 2004. // The Scalar vector y must be a permutation of Scalar vector x // but with all elements multiplied by common Scalar gamma. -func (ss *SimpleShuffle) Prove(G kyber.Point, gamma kyber.Scalar, - x, y []kyber.Scalar, rand cipher.Stream, +// +//nolint:funlen // 51 statement instead of authorized 50 +func (ss *SimpleShuffle) Prove(g kyber.Point, gamma kyber.Scalar, + x, y []kyber.Scalar, _ cipher.Stream, ctx proof.ProverContext) error { grp := ss.grp @@ -100,18 +102,10 @@ func (ss *SimpleShuffle) Prove(G kyber.Point, gamma kyber.Scalar, panic("mismatched vector lengths") } - // // Dump input vectors to show their correspondences - // for i := 0; i < k; i++ { - // println("x",grp.Scalar().Mul(gamma,x[i]).String()) - // } - // for i := 0; i < k; i++ { - // println("y",y[i].String()) - // } - // Step 0: inputs for i := 0; i < k; i++ { // (4) - ss.p0.X[i] = grp.Point().Mul(x[i], G) - ss.p0.Y[i] = grp.Point().Mul(y[i], G) + ss.p0.X[i] = grp.Point().Mul(x[i], g) + ss.p0.Y[i] = grp.Point().Mul(y[i], g) } if err := ctx.Put(ss.p0); err != nil { return err @@ -133,18 +127,22 @@ func (ss *SimpleShuffle) Prove(G kyber.Point, gamma kyber.Scalar, } thlen := 2*k - 1 // (7) theta and Theta vectors theta := make([]kyber.Scalar, thlen) - ctx.PriRand(theta) + err := ctx.PriRand(theta) + if err != nil { + return err + } + Theta := make([]kyber.Point, thlen+1) - Theta[0] = thenc(grp, G, nil, nil, theta[0], yhat[0]) + Theta[0] = thenc(grp, g, nil, nil, theta[0], yhat[0]) for i := 1; i < k; i++ { - Theta[i] = thenc(grp, G, theta[i-1], xhat[i], + Theta[i] = thenc(grp, g, theta[i-1], xhat[i], theta[i], yhat[i]) } for i := k; i < thlen; i++ { - Theta[i] = thenc(grp, G, theta[i-1], gamma, + Theta[i] = thenc(grp, g, theta[i-1], gamma, theta[i], nil) } - Theta[thlen] = thenc(grp, G, theta[thlen-1], gamma, nil, nil) + Theta[thlen] = thenc(grp, g, theta[thlen-1], gamma, nil, nil) ss.p2.Theta = Theta if err := ctx.Put(ss.p2); err != nil { return err @@ -177,9 +175,9 @@ func (ss *SimpleShuffle) Prove(G kyber.Point, gamma kyber.Scalar, // Simple helper to verify Theta elements, // by checking whether A^a*B^-b = T. // P,Q,s are simply "scratch" kyber.Point/Scalars reused for efficiency. -func thver(A, B, T, P, Q kyber.Point, a, b, s kyber.Scalar) bool { - P.Mul(a, A) - Q.Mul(s.Neg(b), B) +func thver(A, B, T, P, Q kyber.Point, aS, bS, s kyber.Scalar) bool { + P.Mul(aS, A) + Q.Mul(s.Neg(bS), B) P.Add(P, Q) return P.Equal(T) } diff --git a/sign/anon/enc.go b/sign/anon/enc.go index 281898ce8..5d0ff8e4e 100644 --- a/sign/anon/enc.go +++ b/sign/anon/enc.go @@ -8,22 +8,19 @@ import ( "go.dedis.ch/kyber/v4/util/key" ) -func header(suite Suite, X kyber.Point, x kyber.Scalar, - Xb, xb []byte, anonymitySet Set) []byte { - - //fmt.Printf("Xb %s\nxb %s\n", - // hex.EncodeToString(Xb),hex.EncodeToString(xb)) +func header(suite Suite, _ kyber.Point, x kyber.Scalar, + xb1, xb2 []byte, anonymitySet Set) []byte { // Encrypt the master scalar key with each public key in the set S := suite.Point() - hdr := Xb + hdr := xb1 for i := range anonymitySet { Y := anonymitySet[i] S.Mul(x, Y) // compute DH shared secret seed, _ := S.MarshalBinary() xof := suite.XOF(seed) - xc := make([]byte, len(xb)) - xof.XORKeyStream(xc, xb) + xc := make([]byte, len(xb2)) + xof.XORKeyStream(xc, xb2) hdr = append(hdr, xc...) } return hdr @@ -44,7 +41,13 @@ func encryptKey(suite Suite, anonymitySet Set) (k, c []byte) { // Decrypt and verify a key encrypted via encryptKey. // On success, returns the key and the length of the decrypted header. -func decryptKey(suite Suite, ciphertext []byte, anonymitySet Set, mine int, privateKey kyber.Scalar) ([]byte, int, error) { +func decryptKey( + suite Suite, + ciphertext []byte, + anonymitySet Set, + mine int, + privateKey kyber.Scalar, +) ([]byte, int, error) { // Decode the (supposed) ephemeral public key from the front X := suite.Point() var Xb []byte @@ -118,7 +121,7 @@ const macSize = 16 // If the provided set contains only one public key, // this reduces to conventional single-receiver public-key encryption. func Encrypt(suite Suite, message []byte, - anonymitySet Set) []byte { + anonymitySet Set) ([]byte, error) { xb, hdr := encryptKey(suite, anonymitySet) xof := suite.XOF(xb) @@ -136,9 +139,12 @@ func Encrypt(suite Suite, message []byte, xof.XORKeyStream(ctx, message) xof = suite.XOF(ctx) - xof.Read(mac) + _, err := xof.Read(mac) + if err != nil { + return nil, err + } - return ciphertext + return ciphertext, nil } // Decrypt a message encrypted for a particular anonymity set. diff --git a/sign/anon/enc_test.go b/sign/anon/enc_test.go index e7d29c94d..f4e6f117e 100644 --- a/sign/anon/enc_test.go +++ b/sign/anon/enc_test.go @@ -24,7 +24,10 @@ func ExampleEncrypt_one() { // Encrypt a message with the public key M := []byte("Hello World!") - C := Encrypt(suite, M, Set(X)) + C, err := Encrypt(suite, M, Set(X)) + if err != nil { + panic(err.Error()) + } fmt.Printf("Encryption of '%s':\n%s", string(M), hex.Dump(C)) // Decrypt the ciphertext with the private key @@ -67,7 +70,10 @@ func ExampleEncrypt_anonSet() { // Encrypt a message with all the public keys M := []byte("Hello World!") // message to encrypt - C := Encrypt(suite, M, Set(X)) + C, err := Encrypt(suite, M, Set(X)) + if err != nil { + panic(err.Error()) + } fmt.Printf("Encryption of '%s':\n%s", string(M), hex.Dump(C)) // Decrypt the ciphertext with the known private key diff --git a/sign/anon/sig.go b/sign/anon/sig.go index 4ad911bf0..f30c18d74 100644 --- a/sign/anon/sig.go +++ b/sign/anon/sig.go @@ -163,8 +163,6 @@ func Sign(suite Suite, message []byte, PH.Add(PH.Mul(s[i], linkBase), P.Mul(c[i], linkTag)) } c[(i+1)%n] = signH1(suite, H1pre, PG, PH) - //fmt.Printf("s%d %s\n",i,s[i].String()) - //fmt.Printf("c%d %s\n",(i+1)%n,c[(i+1)%n].String()) } s[pi] = suite.Scalar() s[pi].Mul(privateKey, c[pi]).Sub(u, s[pi]) // s_pi = u - x_pi c_pi diff --git a/sign/bdn/bdn_test.go b/sign/bdn/bdn_test.go index 39dbc1851..46aa659d8 100644 --- a/sign/bdn/bdn_test.go +++ b/sign/bdn/bdn_test.go @@ -30,7 +30,7 @@ func TestBDN_HashPointToR_BN256(t *testing.T) { require.Equal(t, "933f6013eb3f654f9489d6d45ad04eaf", coefs[2].String()) require.Equal(t, 16, coefs[0].MarshalSize()) - mask, _ := sign.NewMask(suite, []kyber.Point{p1, p2, p3}, nil) + mask, _ := sign.NewMask([]kyber.Point{p1, p2, p3}, nil) mask.SetBit(0, true) mask.SetBit(1, true) mask.SetBit(2, true) @@ -54,7 +54,7 @@ func TestBDN_AggregateSignatures(t *testing.T) { sig2, err := Sign(suite, private2, msg) require.NoError(t, err) - mask, _ := sign.NewMask(suite, []kyber.Point{public1, public2}, nil) + mask, _ := sign.NewMask([]kyber.Point{public1, public2}, nil) mask.SetBit(0, true) mask.SetBit(1, true) @@ -65,6 +65,7 @@ func TestBDN_AggregateSignatures(t *testing.T) { require.NoError(t, err) aggregatedKey, err := AggregatePublicKeys(suite, mask) + require.NoError(t, err) sig, err := aggregatedSig.MarshalBinary() require.NoError(t, err) @@ -74,6 +75,7 @@ func TestBDN_AggregateSignatures(t *testing.T) { mask.SetBit(1, false) aggregatedKey, err = AggregatePublicKeys(suite, mask) + require.NoError(t, err) err = Verify(suite, aggregatedKey, msg, sig) require.Error(t, err) @@ -90,7 +92,7 @@ func TestBDN_SubsetSignature(t *testing.T) { sig2, err := Sign(suite, private2, msg) require.NoError(t, err) - mask, _ := sign.NewMask(suite, []kyber.Point{public1, public3, public2}, nil) + mask, _ := sign.NewMask([]kyber.Point{public1, public3, public2}, nil) mask.SetBit(0, true) mask.SetBit(2, true) @@ -98,6 +100,7 @@ func TestBDN_SubsetSignature(t *testing.T) { require.NoError(t, err) aggregatedKey, err := AggregatePublicKeys(suite, mask) + require.NoError(t, err) sig, err := aggregatedSig.MarshalBinary() require.NoError(t, err) @@ -128,7 +131,7 @@ func TestBDN_RogueAttack(t *testing.T) { require.NoError(t, scheme.Verify(agg, msg, sig)) // New scheme that should detect - mask, _ := sign.NewMask(suite, pubs, nil) + mask, _ := sign.NewMask(pubs, nil) mask.SetBit(0, true) mask.SetBit(1, true) agg, err = AggregatePublicKeys(suite, mask) @@ -146,7 +149,7 @@ func Benchmark_BDN_AggregateSigs(b *testing.B) { sig2, err := Sign(suite, private2, msg) require.Nil(b, err) - mask, _ := sign.NewMask(suite, []kyber.Point{public1, public2}, nil) + mask, _ := sign.NewMask([]kyber.Point{public1, public2}, nil) mask.SetBit(0, true) mask.SetBit(1, false) diff --git a/sign/bls/bls_test.go b/sign/bls/bls_test.go index 1cfdacda4..cd1edcedb 100644 --- a/sign/bls/bls_test.go +++ b/sign/bls/bls_test.go @@ -222,6 +222,7 @@ func BenchmarkBLSVerifyAggregate(b *testing.B) { sig2, err := scheme.Sign(private2, msg) require.Nil(b, err) sig, err := scheme.AggregateSignatures(sig1, sig2) + require.Nil(b, err) key := scheme.AggregatePublicKeys(public1, public2) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -242,7 +243,7 @@ func BenchmarkBLSVerifyBatchVerify(b *testing.B) { private, public := scheme.NewKeyPair(random.New()) privates[i] = private publics[i] = public - msg := make([]byte, 64, 64) + msg := make([]byte, 64) _, err := rand.Read(msg) require.Nil(b, err) msgs[i] = msg diff --git a/sign/cosi/cosi.go b/sign/cosi/cosi.go index df61d53d8..9b417bfac 100644 --- a/sign/cosi/cosi.go +++ b/sign/cosi/cosi.go @@ -63,7 +63,11 @@ func Commit(suite Suite) (v kyber.Scalar, V kyber.Point) { // AggregateCommitments returns the sum of the given commitments and the // bitwise OR of the corresponding masks. -func AggregateCommitments(suite Suite, commitments []kyber.Point, masks [][]byte) (sum kyber.Point, commits []byte, err error) { +func AggregateCommitments( + suite Suite, + commitments []kyber.Point, + masks [][]byte, +) (sum kyber.Point, commits []byte, err error) { if len(commitments) != len(masks) { return nil, nil, errors.New("mismatching lengths of commitment and mask slices") } @@ -153,7 +157,7 @@ func Sign(suite Suite, commitment kyber.Point, response kyber.Scalar, mask *Mask return nil, errors.New("marshalling of signature failed") } sig := make([]byte, lenSig+mask.Len()) - copy(sig[:], VB) + copy(sig, VB) copy(sig[lenV:lenSig], RB) copy(sig[lenSig:], mask.mask) return sig, nil @@ -198,7 +202,10 @@ func Verify(suite Suite, publics []kyber.Point, message, sig []byte, policy Poli if err != nil { return err } - mask.SetMask(sig[lenRes:]) + err = mask.SetMask(sig[lenRes:]) + if err != nil { + return err + } A := mask.AggregatePublic ABuff, err := A.MarshalBinary() if err != nil { @@ -261,7 +268,10 @@ func NewMask(suite Suite, publics []kyber.Point, myKey kyber.Point) (*Mask, erro found := false for i, key := range publics { if key.Equal(myKey) { - m.SetBit(i, true) + err := m.SetBit(i, true) + if err != nil { + return nil, err + } found = true break } @@ -276,7 +286,7 @@ func NewMask(suite Suite, publics []kyber.Point, myKey kyber.Point) (*Mask, erro // Mask returns a copy of the participation bitmask. func (m *Mask) Mask() []byte { clone := make([]byte, len(m.mask)) - copy(clone[:], m.mask) + copy(clone, m.mask) return clone } diff --git a/sign/cosi/cosi_test.go b/sign/cosi/cosi_test.go index 331d8fd01..ae8dda296 100644 --- a/sign/cosi/cosi_test.go +++ b/sign/cosi/cosi_test.go @@ -161,13 +161,9 @@ func TestMask(t *testing.T) { n := 17 // Generate key pairs - var kps []*key.Pair - var privates []kyber.Scalar var publics []kyber.Point for i := 0; i < n; i++ { kp := key.NewKeyPair(testSuite) - kps = append(kps, kp) - privates = append(privates, kp.Private) publics = append(publics, kp.Public) } diff --git a/sign/dss/dss.go b/sign/dss/dss.go index 6896d5065..f50c7e558 100644 --- a/sign/dss/dss.go +++ b/sign/dss/dss.go @@ -74,7 +74,7 @@ type PartialSig struct { // threshold. It returns an error if the public key of the secret can't be found // in the list of participants. func NewDSS(suite Suite, secret kyber.Scalar, participants []kyber.Point, - long, random DistKeyShare, msg []byte, T int) (*DSS, error) { + long, random DistKeyShare, msg []byte, t int) (*DSS, error) { public := suite.Point().Mul(secret, nil) var i int var found bool @@ -99,7 +99,7 @@ func NewDSS(suite Suite, secret kyber.Scalar, participants []kyber.Point, random: random, randomPoly: share.NewPubPoly(suite, suite.Point().Base(), random.Commitments()), msg: msg, - T: T, + T: t, partialsIdx: make(map[int]bool), sessionID: sessionID(suite, long, random), }, nil diff --git a/sign/dss/dss_test.go b/sign/dss/dss_test.go index b5c488175..b66ceed5d 100644 --- a/sign/dss/dss_test.go +++ b/sign/dss/dss_test.go @@ -24,8 +24,6 @@ var partSec []kyber.Scalar var longterms []*dkg.DistKeyShare var randoms []*dkg.DistKeyShare -var dss []*DSS - func init() { partPubs = make([]kyber.Point, nbParticipants) partSec = make([]kyber.Scalar, nbParticipants) @@ -220,6 +218,6 @@ func genPair() (kyber.Scalar, kyber.Point) { func randomBytes(n int) []byte { var buff = make([]byte, n) - _, _ = rand.Read(buff[:]) + _, _ = rand.Read(buff) return buff } diff --git a/sign/eddsa/eddsa.go b/sign/eddsa/eddsa.go index 798fbd256..e6ce52bb3 100644 --- a/sign/eddsa/eddsa.go +++ b/sign/eddsa/eddsa.go @@ -5,14 +5,26 @@ package eddsa import ( "crypto/cipher" "crypto/sha512" - "errors" "fmt" - "go.dedis.ch/kyber/v4" "go.dedis.ch/kyber/v4/group/edwards25519" ) var group = new(edwards25519.Curve) +var ErrPKMarshalling = fmt.Errorf("error unmarshalling public key") +var ErrPKInvalid = fmt.Errorf("invalid public key") +var ErrPKSmallOrder = fmt.Errorf("public key has small order") +var ErrPKNotCanonical = fmt.Errorf("public key is not canonical") + +var ErrEdDSAWrongLength = fmt.Errorf("wrong length for decoding EdDSA private") +var ErrSchnorrInvalidScalar = fmt.Errorf("schnorr: s invalid scalar") +var ErrSignatureLength = fmt.Errorf("signature length invalid") +var ErrSignatureNotCanonical = fmt.Errorf("signature is not canonical") +var ErrSignatureRecNotEqual = fmt.Errorf("reconstructed S is not equal to signature") + +var ErrPointRSmallOrder = fmt.Errorf("point R has small order") +var ErrPointRNotCanonical = fmt.Errorf("point R is not canonical") +var ErrPointRInvalid = fmt.Errorf("point R invalid") // EdDSA is a structure holding the data necessary to make a series of // EdDSA signatures. @@ -61,7 +73,7 @@ func (e *EdDSA) MarshalBinary() ([]byte, error) { // UnmarshalBinary transforms a slice of bytes into a EdDSA signature. func (e *EdDSA) UnmarshalBinary(buff []byte) error { if len(buff) != 64 { - return errors.New("wrong length for decoding EdDSA private") + return fmt.Errorf("error: %w", ErrEdDSAWrongLength) } secret, _, prefix := group.NewKeyAndSeedWithInput(buff[:32]) @@ -76,8 +88,12 @@ func (e *EdDSA) UnmarshalBinary(buff []byte) error { // Sign will return a EdDSA signature of the message msg using Ed25519. func (e *EdDSA) Sign(msg []byte) ([]byte, error) { hash := sha512.New() - _, _ = hash.Write(e.prefix) - _, _ = hash.Write(msg) + if _, err := hash.Write(e.prefix); err != nil { + return nil, err + } + if _, err := hash.Write(msg); err != nil { + return nil, err + } // deterministic random secret and its commit r := group.Scalar().SetBytes(hash.Sum(nil)) @@ -95,9 +111,15 @@ func (e *EdDSA) Sign(msg []byte) ([]byte, error) { return nil, err } - _, _ = hash.Write(Rbuff) - _, _ = hash.Write(Abuff) - _, _ = hash.Write(msg) + if _, err := hash.Write(Rbuff); err != nil { + return nil, err + } + if _, err := hash.Write(Abuff); err != nil { + return nil, err + } + if _, err := hash.Write(msg); err != nil { + return nil, err + } h := group.Scalar().SetBytes(hash.Sum(nil)) @@ -126,7 +148,7 @@ func (e *EdDSA) Sign(msg []byte) ([]byte, error) { // does not have a small order. func VerifyWithChecks(pub, msg, sig []byte) error { if len(sig) != 64 { - return fmt.Errorf("signature length invalid, expect 64 but got %v", len(sig)) + return fmt.Errorf("error: %w: expect 64 but got %v", ErrSignatureLength, len(sig)) } type scalarCanCheckCanonical interface { @@ -134,7 +156,7 @@ func VerifyWithChecks(pub, msg, sig []byte) error { } if !group.Scalar().(scalarCanCheckCanonical).IsCanonical(sig[32:]) { - return fmt.Errorf("signature is not canonical") + return fmt.Errorf("error: %w", ErrSignatureNotCanonical) } type pointCanCheckCanonicalAndSmallOrder interface { @@ -144,36 +166,42 @@ func VerifyWithChecks(pub, msg, sig []byte) error { R := group.Point() if !R.(pointCanCheckCanonicalAndSmallOrder).IsCanonical(sig[:32]) { - return fmt.Errorf("R is not canonical") + return fmt.Errorf("error: %w", ErrPointRNotCanonical) } if err := R.UnmarshalBinary(sig[:32]); err != nil { - return fmt.Errorf("got R invalid point: %s", err) + return fmt.Errorf("error: %w: %w", ErrPointRInvalid, err) } if R.(pointCanCheckCanonicalAndSmallOrder).HasSmallOrder() { - return fmt.Errorf("R has small order") + return fmt.Errorf("error: %w", ErrPointRSmallOrder) } s := group.Scalar() if err := s.UnmarshalBinary(sig[32:]); err != nil { - return fmt.Errorf("schnorr: s invalid scalar %s", err) + return fmt.Errorf("error: %w: %w", ErrSchnorrInvalidScalar, err) } public := group.Point() if !public.(pointCanCheckCanonicalAndSmallOrder).IsCanonical(pub) { - return fmt.Errorf("public key is not canonical") + return fmt.Errorf("error: %w", ErrPKNotCanonical) } if err := public.UnmarshalBinary(pub); err != nil { - return fmt.Errorf("invalid public key: %s", err) + return fmt.Errorf("error: %w: %w", ErrPKInvalid, err) } if public.(pointCanCheckCanonicalAndSmallOrder).HasSmallOrder() { - return fmt.Errorf("public key has small order") + return fmt.Errorf("error: %w", ErrPKSmallOrder) } // reconstruct h = H(R || Public || Msg) hash := sha512.New() - _, _ = hash.Write(sig[:32]) - _, _ = hash.Write(pub) - _, _ = hash.Write(msg) + if _, err := hash.Write(sig[:32]); err != nil { + return err + } + if _, err := hash.Write(pub); err != nil { + return err + } + if _, err := hash.Write(msg); err != nil { + return err + } h := group.Scalar().SetBytes(hash.Sum(nil)) // reconstruct S == k*A + R @@ -182,7 +210,7 @@ func VerifyWithChecks(pub, msg, sig []byte) error { RhA := group.Point().Add(R, hA) if !RhA.Equal(S) { - return errors.New("reconstructed S is not equal to signature") + return fmt.Errorf("error: %w", ErrSignatureRecNotEqual) } return nil } @@ -192,7 +220,7 @@ func VerifyWithChecks(pub, msg, sig []byte) error { func Verify(public kyber.Point, msg, sig []byte) error { PBuf, err := public.MarshalBinary() if err != nil { - return fmt.Errorf("error unmarshalling public key: %s", err) + return fmt.Errorf("error: %w: %w", ErrPKMarshalling, err) } return VerifyWithChecks(PBuf, msg, sig) } diff --git a/sign/eddsa/eddsa_test.go b/sign/eddsa/eddsa_test.go index eff788719..57506be4e 100644 --- a/sign/eddsa/eddsa_test.go +++ b/sign/eddsa/eddsa_test.go @@ -106,10 +106,10 @@ func TestEdDSASigning(t *testing.T) { // Test signature malleability func TestEdDSAVerifyMalleability(t *testing.T) { /* l = 2^252+27742317777372353535851937790883648493, prime order of the base point */ - var L []uint16 = []uint16{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + L := []uint16{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10} - var c uint16 = 0 + var c uint16 suite := edwards25519.NewBlakeSHA256Ed25519() randomStream := suite.RandomStream() @@ -129,7 +129,7 @@ func TestEdDSAVerifyMalleability(t *testing.T) { } err = Verify(ed.Public, msg, sig) - require.EqualError(t, err, "signature is not canonical") + require.ErrorIs(t, err, ErrSignatureNotCanonical) // Additional malleability test from golang/crypto // https://github.com/golang/crypto/blob/master/ed25519/ed25519_test.go#L167 @@ -148,12 +148,12 @@ func TestEdDSAVerifyMalleability(t *testing.T) { 0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa} err = VerifyWithChecks(publicKey, msg2, sig2) - require.EqualError(t, err, "signature is not canonical") + require.ErrorIs(t, err, ErrSignatureNotCanonical) } // Test non-canonical R func TestEdDSAVerifyNonCanonicalR(t *testing.T) { - var nonCanonicalR []byte = []byte{0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + nonCanonicalR := []byte{0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} @@ -171,12 +171,12 @@ func TestEdDSAVerifyNonCanonicalR(t *testing.T) { sig[i] = nonCanonicalR[i] } err = Verify(ed.Public, msg, sig) - require.EqualError(t, err, "R is not canonical") + require.ErrorIs(t, err, ErrPointRNotCanonical) } // Test non-canonical keys func TestEdDSAVerifyNonCanonicalPK(t *testing.T) { - var nonCanonicalPk []byte = []byte{0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + nonCanonicalPk := []byte{0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} @@ -191,12 +191,12 @@ func TestEdDSAVerifyNonCanonicalPK(t *testing.T) { require.Nil(t, Verify(ed.Public, msg, sig)) err = VerifyWithChecks(nonCanonicalPk, msg, sig) - require.EqualError(t, err, "public key is not canonical") + require.ErrorIs(t, err, ErrPKNotCanonical) } // Test for small order R func TestEdDSAVerifySmallOrderR(t *testing.T) { - var smallOrderR []byte = []byte{0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, + smallOrderR := []byte{0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a} @@ -215,12 +215,12 @@ func TestEdDSAVerifySmallOrderR(t *testing.T) { } err = Verify(ed.Public, msg, sig) - require.EqualError(t, err, "R has small order") + require.ErrorIs(t, err, ErrPointRSmallOrder) } // Test for small order public key func TestEdDSAVerifySmallOrderPK(t *testing.T) { - var smallOrderPk []byte = []byte{0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, + smallOrderPk := []byte{0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a} @@ -238,7 +238,7 @@ func TestEdDSAVerifySmallOrderPK(t *testing.T) { require.Nil(t, err) err = Verify(ed.Public, msg, sig) - require.EqualError(t, err, "public key has small order") + require.ErrorIs(t, err, ErrPKSmallOrder) } // Test the property of a EdDSA signature @@ -274,7 +274,7 @@ func ConstantStream(buff []byte) cipher.Stream { } // XORKexStream implements the cipher.Stream interface -func (cs *constantStream) XORKeyStream(dst, src []byte) { +func (cs *constantStream) XORKeyStream(dst, _ []byte) { copy(dst, cs.seed) } @@ -336,7 +336,7 @@ func TestGolden(t *testing.T) { sig2, err := ed.Sign(msg) assert.Nil(t, err) - if !bytes.Equal(sig, sig2[:]) { + if !bytes.Equal(sig, sig2) { t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2) } diff --git a/sign/mask.go b/sign/mask.go index 22bc572c4..7c68c9132 100644 --- a/sign/mask.go +++ b/sign/mask.go @@ -6,7 +6,6 @@ import ( "fmt" "go.dedis.ch/kyber/v4" - "go.dedis.ch/kyber/v4/pairing" ) // Mask is a bitmask of the participation to a collective signature. @@ -17,7 +16,7 @@ type Mask struct { // NewMask creates a new mask from a list of public keys. If a key is provided, it // will set the bit of the key to 1 or return an error if it is not found. -func NewMask(suite pairing.Suite, publics []kyber.Point, myKey kyber.Point) (*Mask, error) { +func NewMask(publics []kyber.Point, myKey kyber.Point) (*Mask, error) { m := &Mask{ publics: publics, } @@ -26,8 +25,8 @@ func NewMask(suite pairing.Suite, publics []kyber.Point, myKey kyber.Point) (*Ma if myKey != nil { for i, key := range publics { if key.Equal(myKey) { - m.SetBit(i, true) - return m, nil + err := m.SetBit(i, true) + return m, err } } @@ -40,7 +39,7 @@ func NewMask(suite pairing.Suite, publics []kyber.Point, myKey kyber.Point) (*Ma // Mask returns the bitmask as a byte array. func (m *Mask) Mask() []byte { clone := make([]byte, len(m.mask)) - copy(clone[:], m.mask) + copy(clone, m.mask) return clone } diff --git a/sign/mask_test.go b/sign/mask_test.go index 41c26d8c3..7a3eeb118 100644 --- a/sign/mask_test.go +++ b/sign/mask_test.go @@ -25,7 +25,7 @@ func init() { } func TestMask_CreateMask(t *testing.T) { - mask, err := NewMask(suite, publics, nil) + mask, err := NewMask(publics, nil) require.NoError(t, err) require.Equal(t, len(publics), len(mask.Publics())) @@ -34,19 +34,19 @@ func TestMask_CreateMask(t *testing.T) { require.Equal(t, n/8+1, mask.Len()) require.Equal(t, uint8(0), mask.Mask()[0]) - mask, err = NewMask(suite, publics, publics[2]) + mask, err = NewMask(publics, publics[2]) require.NoError(t, err) require.Equal(t, len(publics), len(mask.Publics())) require.Equal(t, 1, mask.CountEnabled()) require.Equal(t, uint8(0x4), mask.Mask()[0]) - mask, err = NewMask(suite, publics, suite.G1().Point()) + _, err = NewMask(publics, suite.G1().Point()) require.Error(t, err) } func TestMask_SetBit(t *testing.T) { - mask, err := NewMask(suite, publics, publics[2]) + mask, err := NewMask(publics, publics[2]) require.NoError(t, err) err = mask.SetBit(1, true) @@ -72,7 +72,7 @@ func TestMask_SetBit(t *testing.T) { } func TestMask_SetAndMerge(t *testing.T) { - mask, err := NewMask(suite, publics, publics[2]) + mask, err := NewMask(publics, publics[2]) require.NoError(t, err) err = mask.SetMask([]byte{}) @@ -90,7 +90,7 @@ func TestMask_SetAndMerge(t *testing.T) { } func TestMask_PositionalQueries(t *testing.T) { - mask, err := NewMask(suite, publics, publics[2]) + mask, err := NewMask(publics, publics[2]) require.NoError(t, err) for i := 0; i < 10000; i++ { diff --git a/sign/schnorr/schnorr.go b/sign/schnorr/schnorr.go index b7ff7f955..6354a3f04 100644 --- a/sign/schnorr/schnorr.go +++ b/sign/schnorr/schnorr.go @@ -28,25 +28,25 @@ type Suite interface { kyber.Random } -type SchnorrScheme struct { +type Scheme struct { s Suite } func NewScheme(s Suite) sign.Scheme { - return &SchnorrScheme{s} + return &Scheme{s} } -func (s *SchnorrScheme) NewKeyPair(random cipher.Stream) (kyber.Scalar, kyber.Point) { +func (s *Scheme) NewKeyPair(random cipher.Stream) (kyber.Scalar, kyber.Point) { priv := s.s.Scalar().Pick(random) pub := s.s.Point().Mul(priv, nil) return priv, pub } -func (s *SchnorrScheme) Sign(private kyber.Scalar, msg []byte) ([]byte, error) { +func (s *Scheme) Sign(private kyber.Scalar, msg []byte) ([]byte, error) { return Sign(s.s, private, msg) } -func (s *SchnorrScheme) Verify(public kyber.Point, msg, sig []byte) error { +func (s *Scheme) Verify(public kyber.Point, msg, sig []byte) error { return Verify(s.s, public, msg, sig) } @@ -109,10 +109,10 @@ func VerifyWithChecks(g kyber.Group, pub, msg, sig []byte) error { } if p, ok := R.(pointCanCheckCanonicalAndSmallOrder); ok { if !p.IsCanonical(sig[:pointSize]) { - return fmt.Errorf("R is not canonical") + return fmt.Errorf("point R is not canonical") } if p.HasSmallOrder() { - return fmt.Errorf("R has small order") + return fmt.Errorf("point R has small order") } } if s, ok := g.Scalar().(scalarCanCheckCanonical); ok && !s.IsCanonical(sig[pointSize:]) { @@ -163,7 +163,7 @@ func VerifyWithChecks(g kyber.Group, pub, msg, sig []byte) error { func Verify(g kyber.Group, public kyber.Point, msg, sig []byte) error { PBuf, err := public.MarshalBinary() if err != nil { - return fmt.Errorf("error unmarshalling public key: %s", err) + return fmt.Errorf("error unmarshalling public key: %w", err) } return VerifyWithChecks(g, PBuf, msg, sig) } diff --git a/sign/schnorr/schnorr_test.go b/sign/schnorr/schnorr_test.go index 32633951b..6b22679bd 100644 --- a/sign/schnorr/schnorr_test.go +++ b/sign/schnorr/schnorr_test.go @@ -72,11 +72,11 @@ type quickstream struct { rand *rand.Rand } -func (s *quickstream) XORKeyStream(dst, src []byte) { +func (s *quickstream) XORKeyStream(dst, _ []byte) { s.rand.Read(dst) } -func (s *quickstream) Generate(rand *rand.Rand, size int) reflect.Value { +func (s *quickstream) Generate(rand *rand.Rand, _ int) reflect.Value { return reflect.ValueOf(&quickstream{rand: rand}) } @@ -100,10 +100,10 @@ func TestQuickSchnorrSignature(t *testing.T) { func TestSchnorrMalleability(t *testing.T) { /* l = 2^252+27742317777372353535851937790883648493, prime order of the base point */ - var L []uint16 = []uint16{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + L := []uint16{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10} - var c uint16 = 0 + var c uint16 msg := []byte("Hello Schnorr") suite := edwards25519.NewBlakeSHA256Ed25519() diff --git a/suites/suites.go b/suites/suites.go index 72d5154b7..67e7ce417 100644 --- a/suites/suites.go +++ b/suites/suites.go @@ -37,7 +37,10 @@ var ErrUnknownSuite = errors.New("unknown suite") func Find(name string) (Suite, error) { if s, ok := suites[strings.ToLower(name)]; ok { if requireConstTime && strings.ToLower(s.String()) != "ed25519" { - return nil, errors.New("requested suite exists but is not implemented with constant time algorithms as required by suites.RequireConstantTime") + return nil, errors.New( + "requested suite exists but is not implemented " + + "with constant time algorithms as required by " + + "suites.RequireConstantTime") } return s, nil } diff --git a/util/encoding/encoding.go b/util/encoding/encoding.go index 792c088be..21da816eb 100644 --- a/util/encoding/encoding.go +++ b/util/encoding/encoding.go @@ -23,7 +23,7 @@ func ReadHexPoint(group kyber.Group, r io.Reader) (kyber.Point, error) { } // WriteHexPoint writes a point in hex representation to w. -func WriteHexPoint(group kyber.Group, w io.Writer, point kyber.Point) error { +func WriteHexPoint(w io.Writer, point kyber.Point) error { buf, err := point.MarshalBinary() if err != nil { return err @@ -41,12 +41,17 @@ func ReadHexScalar(group kyber.Group, r io.Reader) (kyber.Scalar, error) { if err != nil { return nil, err } - s.UnmarshalBinary(buf) + + err = s.UnmarshalBinary(buf) + if err != nil { + return nil, err + } + return s, nil } // WriteHexScalar converts a scalar key to a hex-string -func WriteHexScalar(group kyber.Group, w io.Writer, scalar kyber.Scalar) error { +func WriteHexScalar(_ kyber.Group, w io.Writer, scalar kyber.Scalar) error { buf, err := scalar.MarshalBinary() if err != nil { return err @@ -57,7 +62,7 @@ func WriteHexScalar(group kyber.Group, w io.Writer, scalar kyber.Scalar) error { } // PointToStringHex converts a point to a hexadecimal representation -func PointToStringHex(group kyber.Group, point kyber.Point) (string, error) { +func PointToStringHex(_ kyber.Group, point kyber.Point) (string, error) { pbuf, err := point.MarshalBinary() return hex.EncodeToString(pbuf), err } @@ -68,7 +73,7 @@ func StringHexToPoint(group kyber.Group, s string) (kyber.Point, error) { } // ScalarToStringHex encodes a scalar to hexadecimal. -func ScalarToStringHex(group kyber.Group, scalar kyber.Scalar) (string, error) { +func ScalarToStringHex(_ kyber.Group, scalar kyber.Scalar) (string, error) { sbuf, err := scalar.MarshalBinary() return hex.EncodeToString(sbuf), err } diff --git a/util/encoding/encoding_test.go b/util/encoding/encoding_test.go index e8c042bc4..9e8da016b 100644 --- a/util/encoding/encoding_test.go +++ b/util/encoding/encoding_test.go @@ -21,8 +21,8 @@ func ErrFatal(err error) { func TestPubHexStream(t *testing.T) { b := &bytes.Buffer{} p := s.Point().Pick(s.RandomStream()) - ErrFatal(WriteHexPoint(s, b, p)) - ErrFatal(WriteHexPoint(s, b, p)) + ErrFatal(WriteHexPoint(b, p)) + ErrFatal(WriteHexPoint(b, p)) p2, err := ReadHexPoint(s, b) ErrFatal(err) require.Equal(t, p.String(), p2.String()) @@ -73,7 +73,7 @@ type MockEmptyReader struct { func (m *MockFailingReader) Read(p []byte) (n int, err error) { return copy(p, m.data), io.EOF } -func (m *MockEmptyReader) Read(p []byte) (n int, err error) { +func (m *MockEmptyReader) Read(_ []byte) (n int, err error) { return 0, nil } diff --git a/util/key/key_test.go b/util/key/key_test.go index 56ef6b20b..69490eb09 100644 --- a/util/key/key_test.go +++ b/util/key/key_test.go @@ -21,7 +21,7 @@ func TestNewKeyPair(t *testing.T) { // A type to test interface Generator by intentionally creating a fixed private key. type fixedPrivSuiteEd25519 edwards25519.SuiteEd25519 -func (s *fixedPrivSuiteEd25519) NewKey(stream cipher.Stream) kyber.Scalar { +func (s *fixedPrivSuiteEd25519) NewKey(_ cipher.Stream) kyber.Scalar { return s.Scalar().SetInt64(33) } diff --git a/util/random/rand_test.go b/util/random/rand_test.go index 36f62f76e..05c39b46e 100644 --- a/util/random/rand_test.go +++ b/util/random/rand_test.go @@ -32,7 +32,7 @@ func TestMixedEntropy(t *testing.T) { } func TestEmptyReader(t *testing.T) { - //expecting a panic + // expecting a panic defer func() { if r := recover(); r == nil { t.Fatal("code did not panicked but should have") @@ -75,7 +75,7 @@ func TestUserOnly(t *testing.T) { } func TestIncorrectSize(t *testing.T) { - //expecting a panic + // expecting a panic defer func() { if r := recover(); r == nil { t.Fatal("code did not panicked but should have") diff --git a/util/test/test.go b/util/test/test.go index c7bf6a89a..1a6ffefdb 100644 --- a/util/test/test.go +++ b/util/test/test.go @@ -3,6 +3,7 @@ package test import ( "bytes" "crypto/cipher" + "github.com/stretchr/testify/require" "testing" "go.dedis.ch/kyber/v4" @@ -44,13 +45,11 @@ func testEmbed(t *testing.T, g kyber.Group, rand cipher.Stream, points *[]kyber. if err != nil { t.Errorf("Point extraction failed for %v: %v", p, err) } - //println("extracted data (", len(x), " bytes): ", string(x)) - //println("EmbedLen(): ", g.Point().EmbedLen()) - max := g.Point().EmbedLen() - if max > len(b) { - max = len(b) + maxLen := g.Point().EmbedLen() + if maxLen > len(b) { + maxLen = len(b) } - if !bytes.Equal(append(x, b[max:]...), b) { + if !bytes.Equal(append(x, b[maxLen:]...), b) { t.Errorf("Point embedding corrupted the data") } @@ -132,40 +131,15 @@ func testScalarClone(t *testing.T, g kyber.Group, rand cipher.Stream) { } } -// Apply a generic set of validation tests to a cryptographic Group, -// using a given source of [pseudo-]randomness. -// -// Returns a log of the pseudorandom Points produced in the test, -// for comparison across alternative implementations -// that are supposed to be equivalent. -func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { - t.Logf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n", - g.String(), g.PointLen(), g.ScalarLen()) - - points := make([]kyber.Point, 0) - ptmp := g.Point() - stmp := g.Scalar() - pzero := g.Point().Null() - szero := g.Scalar().Zero() - sone := g.Scalar().One() - - // Do a simple Diffie-Hellman test - s1 := g.Scalar().Pick(rand) - s2 := g.Scalar().Pick(rand) - if s1.Equal(szero) { - t.Errorf("first secret is scalar zero %v", s1) - } - if s2.Equal(szero) { - t.Errorf("second secret is scalar zero %v", s2) - } - if s1.Equal(s2) { - t.Errorf("not getting unique secrets: picked %s twice", s1) - } - - gen := g.Point().Base() - points = append(points, gen) - +func testSanityCheck( + t *testing.T, + points []kyber.Point, + g kyber.Group, + stmp, s1, s2 kyber.Scalar, + gen, ptmp kyber.Point, +) ([]kyber.Point, kyber.Point, kyber.Point, kyber.Point, bool) { // Sanity-check relationship between addition and multiplication + pzero := g.Point().Null() p1 := g.Point().Add(gen, gen) p2 := g.Point().Mul(stmp.SetInt64(2), nil) if !p1.Equal(p2) { @@ -223,23 +197,15 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { points = append(points, dh1) t.Logf("shared secret = %v", dh1) - // Test secret inverse to get from dh1 back to p1 - if primeOrder { - ptmp.Mul(g.Scalar().Inv(s2), dh1) - if !ptmp.Equal(p1) { - t.Errorf("Scalar inverse didn't work: %v != (-)%v (x) %v == %v", p1, s2, dh1, ptmp) - } - } - - // Zero and One identity secrets - //println("dh1^0 = ",ptmp.Mul(dh1, szero).String()) - if !ptmp.Mul(szero, dh1).Equal(pzero) { - t.Errorf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero) - } - if !ptmp.Mul(sone, dh1).Equal(dh1) { - t.Errorf("Encryption with secret=1 didn't work: %v (x) %v == %v != %[2]v", sone, dh1, ptmp) - } + return points, dh1, p1, p2, primeOrder +} +func testHomomorphicIdentities( + t *testing.T, + primeOrder bool, + g kyber.Group, + gen, ptmp, p1, p2, dh1 kyber.Point, + stmp, s1, s2 kyber.Scalar) { // Additive homomorphic identities ptmp.Add(p1, p2) stmp.Add(s1, s2) @@ -286,8 +252,18 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { stmp, s2, st2, s1) } } +} - // Test randomly picked points +func testRandomlyPickedPoint( + t *testing.T, + primeOrder bool, + points []kyber.Point, + g kyber.Group, + gen, ptmp kyber.Point, + stmp kyber.Scalar, + rand cipher.Stream, +) []kyber.Point { + pzero := g.Point().Null() last := gen for i := 0; i < 5; i++ { rgen := g.Point().Pick(rand) @@ -312,13 +288,10 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { points = append(points, rgen) } - // Test embedding data - testEmbed(t, g, rand, &points, "Hi!") - testEmbed(t, g, rand, &points, "The quick brown fox jumps over the lazy dog") - - // Test verifiable secret sharing + return points +} - // Test encoding and decoding +func testEncodingDecoding(t *testing.T, g kyber.Group, ptmp kyber.Point, stmp kyber.Scalar, rand cipher.Stream) { buf := new(bytes.Buffer) for i := 0; i < 5; i++ { buf.Reset() @@ -345,6 +318,73 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { t.Errorf("decoding produces different point than encoded") } } +} + +// Apply a generic set of validation tests to a cryptographic Group, +// using a given source of [pseudo-]randomness. +// +// Returns a log of the pseudorandom Points produced in the test, +// for comparison across alternative implementations +// that are supposed to be equivalent. +func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { + t.Logf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n", + g.String(), g.PointLen(), g.ScalarLen()) + + points := make([]kyber.Point, 0) + ptmp := g.Point() + stmp := g.Scalar() + pzero := g.Point().Null() + szero := g.Scalar().Zero() + sone := g.Scalar().One() + + // Do a simple Diffie-Hellman test + s1 := g.Scalar().Pick(rand) + s2 := g.Scalar().Pick(rand) + if s1.Equal(szero) { + t.Errorf("first secret is scalar zero %v", s1) + } + if s2.Equal(szero) { + t.Errorf("second secret is scalar zero %v", s2) + } + if s1.Equal(s2) { + t.Errorf("not getting unique secrets: picked %s twice", s1) + } + + gen := g.Point().Base() + points = append(points, gen) + + // Sanity-check relationship between addition and multiplication + points, dh1, p1, p2, primeOrder := testSanityCheck(t, points, g, stmp, s1, s2, gen, ptmp) + + // Test secret inverse to get from dh1 back to p1 + if primeOrder { + ptmp.Mul(g.Scalar().Inv(s2), dh1) + if !ptmp.Equal(p1) { + t.Errorf("Scalar inverse didn't work: %v != (-)%v (x) %v == %v", p1, s2, dh1, ptmp) + } + } + + // Zero and One identity secrets + if !ptmp.Mul(szero, dh1).Equal(pzero) { + t.Errorf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero) + } + if !ptmp.Mul(sone, dh1).Equal(dh1) { + t.Errorf("Encryption with secret=1 didn't work: %v (x) %v == %v != %[2]v", sone, dh1, ptmp) + } + + // homomorphic identities + testHomomorphicIdentities(t, primeOrder, g, gen, ptmp, p1, p2, dh1, stmp, s1, s2) + + // Test randomly picked points + points = testRandomlyPickedPoint(t, primeOrder, points, g, gen, ptmp, stmp, rand) + + // Test embedding data + testEmbed(t, g, rand, &points, "Hi!") + testEmbed(t, g, rand, &points, "The quick brown fox jumps over the lazy dog") + + // Test verifiable secret sharing + // Test encoding and decoding + testEncodingDecoding(t, g, ptmp, stmp, rand) // Test that we can marshal/ unmarshal null point pzero = g.Point().Null() @@ -393,12 +433,9 @@ func SuiteTest(t *testing.T, suite suite) { // Try hashing something h := suite.Hash() l := h.Size() - //println("HashLen: ", l) _, _ = h.Write([]byte("abc")) hb := h.Sum(nil) - //println("Hash:") - //println(hex.Dump(hb)) if h.Size() != l || len(hb) != l { t.Errorf("inconsistent hash output length: %v vs %v vs %v", l, h.Size(), len(hb)) } @@ -406,9 +443,8 @@ func SuiteTest(t *testing.T, suite suite) { // Generate some pseudorandom bits x := suite.XOF(hb) sb := make([]byte, 128) - x.Read(sb) - //fmt.Println("Stream:") - //fmt.Println(hex.Dump(sb)) + _, err := x.Read(sb) + require.NoError(t, err) // Test if it generates two fresh keys p1 := key.NewKeyPair(suite) diff --git a/xof/blake2xb/blake.go b/xof/blake2xb/blake.go index ba90af4e5..8706dec70 100644 --- a/xof/blake2xb/blake.go +++ b/xof/blake2xb/blake.go @@ -59,7 +59,11 @@ func (x *xof) Reseed() { } else { x.key = x.key[0:128] } - x.Read(x.key) + _, err := x.Read(x.key) + if err != nil { + panic("blake xof error: " + err.Error()) + } + y := New(x.key) // Steal the XOF implementation, and put it inside of x. x.impl = y.(*xof).impl @@ -67,7 +71,7 @@ func (x *xof) Reseed() { func (x *xof) Reset() { x.impl.Reset() - x.impl.Write(x.seed) + _, _ = x.impl.Write(x.seed) } func (x *xof) XORKeyStream(dst, src []byte) { diff --git a/xof/blake2xs/blake.go b/xof/blake2xs/blake.go index 125babbd9..6336556b2 100644 --- a/xof/blake2xs/blake.go +++ b/xof/blake2xs/blake.go @@ -59,7 +59,11 @@ func (x *xof) Reseed() { } else { x.key = x.key[0:128] } - x.Read(x.key) + _, err := x.Read(x.key) + if err != nil { + panic("blake xof error: " + err.Error()) + } + y := New(x.key) // Steal the XOF implementation, and put it inside of x. x.impl = y.(*xof).impl @@ -67,7 +71,7 @@ func (x *xof) Reseed() { func (x *xof) Reset() { x.impl.Reset() - x.impl.Write(x.seed) + _, _ = x.impl.Write(x.seed) } func (x *xof) XORKeyStream(dst, src []byte) { diff --git a/xof/keccak/keccak.go b/xof/keccak/keccak.go index 8dfceb458..b7a9422ec 100644 --- a/xof/keccak/keccak.go +++ b/xof/keccak/keccak.go @@ -34,9 +34,15 @@ func (x *xof) Reseed() { } else { x.key = x.key[0:128] } - x.Read(x.key) + _, err := x.Read(x.key) + if err != nil { + panic("xof error getting key: " + err.Error()) + } x.sh = sha3.NewShake256() - x.sh.Write(x.key) + _, err = x.sh.Write(x.key) + if err != nil { + panic("xof error writing key: " + err.Error()) + } } func (x *xof) Reset() {