You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
6.1 KiB

crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
crypto: Use a different library for ed25519/sr25519 (#6526) At Oasis we have spend some time writing a new Ed25519/X25519/sr25519 implementation called curve25519-voi. This PR switches the import from ed25519consensus/go-schnorrkel, which should lead to performance gains on most systems. Summary of changes: * curve25519-voi is now used for Ed25519 operations, following the existing ZIP-215 semantics. * curve25519-voi's public key cache is enabled (hardcoded size of 4096 entries, should be tuned, see the code comment) to accelerate repeated Ed25519 verification with the same public key(s). * (BREAKING) curve25519-voi is now used for sr25519 operations. This is a breaking change as the current sr25519 support does something decidedly non-standard when going from a MiniSecretKey to a SecretKey and or PublicKey (The expansion routine is called twice). While I believe the new behavior (that expands once and only once) to be more "correct", this changes the semantics as implemented. * curve25519-voi is now used for merlin since the included STROBE implementation produces much less garbage on the heap. Side issues fixed: * The version of go-schnorrkel that is currently imported by tendermint has a badly broken batch verification implementation. Upstream has fixed the issue after I reported it, so the version should be bumped in the interim. Open design questions/issues: * As noted, the public key cache size should be tuned. It is currently backed by a trivial thread-safe LRU cache, which is not scan-resistant, but replacing it with something better is a matter of implementing an interface. * As far as I can tell, the only reason why serial verification on batch failure is necessary is to provide more detailed error messages (that are only used in some unit tests). If you trust the batch verification to be consistent with serial verification then the fallback can be eliminated entirely (the BatchVerifier provided by the new library supports an option that omits the fallback if this is chosen as the way forward). * curve25519-voi's sr25519 support could use more optimization and more eyes on the code. The algorithm unfortunately is woefully under-specified, and the implementation was done primarily because I got really sad when I actually looked at go-schnorrkel, and we do not use the algorithm at this time.
3 years ago
  1. package ed25519
  2. import (
  3. "bytes"
  4. "crypto/subtle"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "github.com/oasisprotocol/curve25519-voi/primitives/ed25519"
  9. "github.com/oasisprotocol/curve25519-voi/primitives/ed25519/extra/cache"
  10. "github.com/tendermint/tendermint/crypto"
  11. "github.com/tendermint/tendermint/crypto/tmhash"
  12. tmjson "github.com/tendermint/tendermint/libs/json"
  13. )
  14. //-------------------------------------
  15. var (
  16. _ crypto.PrivKey = PrivKey{}
  17. // curve25519-voi's Ed25519 implementation supports configurable
  18. // verification behavior, and tendermint uses the ZIP-215 verification
  19. // semantics.
  20. verifyOptions = &ed25519.Options{
  21. Verify: ed25519.VerifyOptionsZIP_215,
  22. }
  23. cachingVerifier = cache.NewVerifier(cache.NewLRUCache(cacheSize))
  24. )
  25. const (
  26. PrivKeyName = "tendermint/PrivKeyEd25519"
  27. PubKeyName = "tendermint/PubKeyEd25519"
  28. // PubKeySize is is the size, in bytes, of public keys as used in this package.
  29. PubKeySize = 32
  30. // PrivateKeySize is the size, in bytes, of private keys as used in this package.
  31. PrivateKeySize = 64
  32. // Size of an Edwards25519 signature. Namely the size of a compressed
  33. // Edwards25519 point, and a field element. Both of which are 32 bytes.
  34. SignatureSize = 64
  35. // SeedSize is the size, in bytes, of private key seeds. These are the
  36. // private key representations used by RFC 8032.
  37. SeedSize = 32
  38. KeyType = "ed25519"
  39. // cacheSize is the number of public keys that will be cached in
  40. // an expanded format for repeated signature verification.
  41. //
  42. // TODO/perf: Either this should exclude single verification, or be
  43. // tuned to `> validatorSize + maxTxnsPerBlock` to avoid cache
  44. // thrashing.
  45. cacheSize = 4096
  46. )
  47. func init() {
  48. tmjson.RegisterType(PubKey{}, PubKeyName)
  49. tmjson.RegisterType(PrivKey{}, PrivKeyName)
  50. }
  51. // PrivKey implements crypto.PrivKey.
  52. type PrivKey []byte
  53. // Bytes returns the privkey byte format.
  54. func (privKey PrivKey) Bytes() []byte {
  55. return []byte(privKey)
  56. }
  57. // Sign produces a signature on the provided message.
  58. // This assumes the privkey is wellformed in the golang format.
  59. // The first 32 bytes should be random,
  60. // corresponding to the normal ed25519 private key.
  61. // The latter 32 bytes should be the compressed public key.
  62. // If these conditions aren't met, Sign will panic or produce an
  63. // incorrect signature.
  64. func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
  65. signatureBytes := ed25519.Sign(ed25519.PrivateKey(privKey), msg)
  66. return signatureBytes, nil
  67. }
  68. // PubKey gets the corresponding public key from the private key.
  69. //
  70. // Panics if the private key is not initialized.
  71. func (privKey PrivKey) PubKey() crypto.PubKey {
  72. // If the latter 32 bytes of the privkey are all zero, privkey is not
  73. // initialized.
  74. initialized := false
  75. for _, v := range privKey[32:] {
  76. if v != 0 {
  77. initialized = true
  78. break
  79. }
  80. }
  81. if !initialized {
  82. panic("Expected ed25519 PrivKey to include concatenated pubkey bytes")
  83. }
  84. pubkeyBytes := make([]byte, PubKeySize)
  85. copy(pubkeyBytes, privKey[32:])
  86. return PubKey(pubkeyBytes)
  87. }
  88. // Equals - you probably don't need to use this.
  89. // Runs in constant time based on length of the keys.
  90. func (privKey PrivKey) Equals(other crypto.PrivKey) bool {
  91. if otherEd, ok := other.(PrivKey); ok {
  92. return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1
  93. }
  94. return false
  95. }
  96. func (privKey PrivKey) Type() string {
  97. return KeyType
  98. }
  99. // GenPrivKey generates a new ed25519 private key.
  100. // It uses OS randomness in conjunction with the current global random seed
  101. // in tendermint/libs/common to generate the private key.
  102. func GenPrivKey() PrivKey {
  103. return genPrivKey(crypto.CReader())
  104. }
  105. // genPrivKey generates a new ed25519 private key using the provided reader.
  106. func genPrivKey(rand io.Reader) PrivKey {
  107. _, priv, err := ed25519.GenerateKey(rand)
  108. if err != nil {
  109. panic(err)
  110. }
  111. return PrivKey(priv)
  112. }
  113. // GenPrivKeyFromSecret hashes the secret with SHA2, and uses
  114. // that 32 byte output to create the private key.
  115. // NOTE: secret should be the output of a KDF like bcrypt,
  116. // if it's derived from user input.
  117. func GenPrivKeyFromSecret(secret []byte) PrivKey {
  118. seed := crypto.Sha256(secret) // Not Ripemd160 because we want 32 bytes.
  119. return PrivKey(ed25519.NewKeyFromSeed(seed))
  120. }
  121. //-------------------------------------
  122. var _ crypto.PubKey = PubKey{}
  123. // PubKeyEd25519 implements crypto.PubKey for the Ed25519 signature scheme.
  124. type PubKey []byte
  125. // Address is the SHA256-20 of the raw pubkey bytes.
  126. func (pubKey PubKey) Address() crypto.Address {
  127. if len(pubKey) != PubKeySize {
  128. panic("pubkey is incorrect size")
  129. }
  130. return crypto.Address(tmhash.SumTruncated(pubKey))
  131. }
  132. // Bytes returns the PubKey byte format.
  133. func (pubKey PubKey) Bytes() []byte {
  134. return []byte(pubKey)
  135. }
  136. func (pubKey PubKey) VerifySignature(msg []byte, sig []byte) bool {
  137. // make sure we use the same algorithm to sign
  138. if len(sig) != SignatureSize {
  139. return false
  140. }
  141. return cachingVerifier.VerifyWithOptions(ed25519.PublicKey(pubKey), msg, sig, verifyOptions)
  142. }
  143. func (pubKey PubKey) String() string {
  144. return fmt.Sprintf("PubKeyEd25519{%X}", []byte(pubKey))
  145. }
  146. func (pubKey PubKey) Type() string {
  147. return KeyType
  148. }
  149. func (pubKey PubKey) Equals(other crypto.PubKey) bool {
  150. if otherEd, ok := other.(PubKey); ok {
  151. return bytes.Equal(pubKey[:], otherEd[:])
  152. }
  153. return false
  154. }
  155. var _ crypto.BatchVerifier = &BatchVerifier{}
  156. // BatchVerifier implements batch verification for ed25519.
  157. type BatchVerifier struct {
  158. *ed25519.BatchVerifier
  159. }
  160. func NewBatchVerifier() crypto.BatchVerifier {
  161. return &BatchVerifier{ed25519.NewBatchVerifier()}
  162. }
  163. func (b *BatchVerifier) Add(key crypto.PubKey, msg, signature []byte) error {
  164. pkEd, ok := key.(PubKey)
  165. if !ok {
  166. return fmt.Errorf("pubkey is not Ed25519")
  167. }
  168. pkBytes := pkEd.Bytes()
  169. if l := len(pkBytes); l != PubKeySize {
  170. return fmt.Errorf("pubkey size is incorrect; expected: %d, got %d", PubKeySize, l)
  171. }
  172. // check that the signature is the correct length
  173. if len(signature) != SignatureSize {
  174. return errors.New("invalid signature")
  175. }
  176. cachingVerifier.AddWithOptions(b.BatchVerifier, ed25519.PublicKey(pkBytes), msg, signature, verifyOptions)
  177. return nil
  178. }
  179. func (b *BatchVerifier) Verify() (bool, []bool) {
  180. return b.BatchVerifier.Verify(crypto.CReader())
  181. }