From b40a3684ae6be57005b8916a8b13a2c4fa0d1b8a Mon Sep 17 00:00:00 2001 From: Jingchen Date: Mon, 11 Aug 2025 11:21:26 +0100 Subject: [PATCH 01/16] perf: Optimize hash performance by avoiding allocating hash state object (#5469) We're currently calling `XXH3_createState` and `XXH3_freeState` when hashing an object. However, it may be slow because they call `malloc` and `free`, which may affect the performance. This change avoids the use of the streaming API as much as possible by using an internal buffer. --- include/xrpl/beast/hash/xxhasher.h | 120 ++++++++++++--- src/test/beast/xxhasher_test.cpp | 232 +++++++++++++++++++++++++++++ 2 files changed, 331 insertions(+), 21 deletions(-) create mode 100644 src/test/beast/xxhasher_test.cpp diff --git a/include/xrpl/beast/hash/xxhasher.h b/include/xrpl/beast/hash/xxhasher.h index 381980902a..9cd343f544 100644 --- a/include/xrpl/beast/hash/xxhasher.h +++ b/include/xrpl/beast/hash/xxhasher.h @@ -24,32 +24,110 @@ #include +#include #include -#include -#include +#include +#include +#include namespace beast { class xxhasher { -private: - // requires 64-bit std::size_t - static_assert(sizeof(std::size_t) == 8, ""); +public: + using result_type = std::size_t; - XXH3_state_t* state_; +private: + static_assert(sizeof(std::size_t) == 8, "requires 64-bit std::size_t"); + // Have an internal buffer to avoid the streaming API + // A 64-byte buffer should to be big enough for us + static constexpr std::size_t INTERNAL_BUFFER_SIZE = 64; + + alignas(64) std::array buffer_; + std::span readBuffer_; + std::span writeBuffer_; + + std::optional seed_; + XXH3_state_t* state_ = nullptr; + + void + resetBuffers() + { + writeBuffer_ = std::span{buffer_}; + readBuffer_ = {}; + } + + void + updateHash(void const* data, std::size_t len) + { + if (writeBuffer_.size() < len) + { + flushToState(data, len); + } + else + { + std::memcpy(writeBuffer_.data(), data, len); + writeBuffer_ = writeBuffer_.subspan(len); + readBuffer_ = std::span{ + std::begin(buffer_), buffer_.size() - writeBuffer_.size()}; + } + } static XXH3_state_t* allocState() { auto ret = XXH3_createState(); if (ret == nullptr) - throw std::bad_alloc(); + throw std::bad_alloc(); // LCOV_EXCL_LINE return ret; } -public: - using result_type = std::size_t; + void + flushToState(void const* data, std::size_t len) + { + if (!state_) + { + state_ = allocState(); + if (seed_.has_value()) + { + XXH3_64bits_reset_withSeed(state_, *seed_); + } + else + { + XXH3_64bits_reset(state_); + } + } + XXH3_64bits_update(state_, readBuffer_.data(), readBuffer_.size()); + resetBuffers(); + if (data && len) + { + XXH3_64bits_update(state_, data, len); + } + } + result_type + retrieveHash() + { + if (state_) + { + flushToState(nullptr, 0); + return XXH3_64bits_digest(state_); + } + else + { + if (seed_.has_value()) + { + return XXH3_64bits_withSeed( + readBuffer_.data(), readBuffer_.size(), *seed_); + } + else + { + return XXH3_64bits(readBuffer_.data(), readBuffer_.size()); + } + } + } + +public: static constexpr auto const endian = boost::endian::order::native; xxhasher(xxhasher const&) = delete; @@ -58,43 +136,43 @@ public: xxhasher() { - state_ = allocState(); - XXH3_64bits_reset(state_); + resetBuffers(); } ~xxhasher() noexcept { - XXH3_freeState(state_); + if (state_) + { + XXH3_freeState(state_); + } } template < class Seed, std::enable_if_t::value>* = nullptr> - explicit xxhasher(Seed seed) + explicit xxhasher(Seed seed) : seed_(seed) { - state_ = allocState(); - XXH3_64bits_reset_withSeed(state_, seed); + resetBuffers(); } template < class Seed, std::enable_if_t::value>* = nullptr> - xxhasher(Seed seed, Seed) + xxhasher(Seed seed, Seed) : seed_(seed) { - state_ = allocState(); - XXH3_64bits_reset_withSeed(state_, seed); + resetBuffers(); } void operator()(void const* key, std::size_t len) noexcept { - XXH3_64bits_update(state_, key, len); + updateHash(key, len); } explicit - operator std::size_t() noexcept + operator result_type() noexcept { - return XXH3_64bits_digest(state_); + return retrieveHash(); } }; diff --git a/src/test/beast/xxhasher_test.cpp b/src/test/beast/xxhasher_test.cpp new file mode 100644 index 0000000000..6c65fea601 --- /dev/null +++ b/src/test/beast/xxhasher_test.cpp @@ -0,0 +1,232 @@ +//------------------------------------------------------------------------------ +/* +This file is part of rippled: https://github.com/ripple/rippled +Copyright (c) 2025 Ripple Labs Inc. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include + +namespace beast { + +class XXHasher_test : public unit_test::suite +{ +public: + void + testWithoutSeed() + { + testcase("Without seed"); + + xxhasher hasher{}; + + std::string objectToHash{"Hello, xxHash!"}; + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 16042857369214894119ULL); + } + + void + testWithSeed() + { + testcase("With seed"); + + xxhasher hasher{static_cast(102)}; + + std::string objectToHash{"Hello, xxHash!"}; + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 14440132435660934800ULL); + } + + void + testWithTwoSeeds() + { + testcase("With two seeds"); + xxhasher hasher{ + static_cast(102), static_cast(103)}; + + std::string objectToHash{"Hello, xxHash!"}; + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 14440132435660934800ULL); + } + + void + testBigObjectWithMultiupleSmallUpdatesWithoutSeed() + { + testcase("Big object with multiple small updates without seed"); + xxhasher hasher{}; + + std::string objectToHash{"Hello, xxHash!"}; + for (int i = 0; i < 100; i++) + { + hasher(objectToHash.data(), objectToHash.size()); + } + + BEAST_EXPECT( + static_cast(hasher) == + 15296278154063476002ULL); + } + + void + testBigObjectWithMultiupleSmallUpdatesWithSeed() + { + testcase("Big object with multiple small updates with seed"); + xxhasher hasher{static_cast(103)}; + + std::string objectToHash{"Hello, xxHash!"}; + for (int i = 0; i < 100; i++) + { + hasher(objectToHash.data(), objectToHash.size()); + } + + BEAST_EXPECT( + static_cast(hasher) == + 17285302196561698791ULL); + } + + void + testBigObjectWithSmallAndBigUpdatesWithoutSeed() + { + testcase("Big object with small and big updates without seed"); + xxhasher hasher{}; + + std::string objectToHash{"Hello, xxHash!"}; + std::string bigObject; + for (int i = 0; i < 20; i++) + { + bigObject += "Hello, xxHash!"; + } + hasher(objectToHash.data(), objectToHash.size()); + hasher(bigObject.data(), bigObject.size()); + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 1865045178324729219ULL); + } + + void + testBigObjectWithSmallAndBigUpdatesWithSeed() + { + testcase("Big object with small and big updates with seed"); + xxhasher hasher{static_cast(103)}; + + std::string objectToHash{"Hello, xxHash!"}; + std::string bigObject; + for (int i = 0; i < 20; i++) + { + bigObject += "Hello, xxHash!"; + } + hasher(objectToHash.data(), objectToHash.size()); + hasher(bigObject.data(), bigObject.size()); + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 16189862915636005281ULL); + } + + void + testBigObjectWithOneUpdateWithoutSeed() + { + testcase("Big object with one update without seed"); + xxhasher hasher{}; + + std::string objectToHash; + for (int i = 0; i < 100; i++) + { + objectToHash += "Hello, xxHash!"; + } + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 15296278154063476002ULL); + } + + void + testBigObjectWithOneUpdateWithSeed() + { + testcase("Big object with one update with seed"); + xxhasher hasher{static_cast(103)}; + + std::string objectToHash; + for (int i = 0; i < 100; i++) + { + objectToHash += "Hello, xxHash!"; + } + hasher(objectToHash.data(), objectToHash.size()); + + BEAST_EXPECT( + static_cast(hasher) == + 17285302196561698791ULL); + } + + void + testOperatorResultTypeDoesNotChangeInternalState() + { + testcase("Operator result type doesn't change the internal state"); + { + xxhasher hasher; + + std::string object{"Hello xxhash"}; + hasher(object.data(), object.size()); + auto xxhashResult1 = static_cast(hasher); + auto xxhashResult2 = static_cast(hasher); + + BEAST_EXPECT(xxhashResult1 == xxhashResult2); + } + { + xxhasher hasher; + + std::string object; + for (int i = 0; i < 100; i++) + { + object += "Hello, xxHash!"; + } + hasher(object.data(), object.size()); + auto xxhashResult1 = hasher.operator xxhasher::result_type(); + auto xxhashResult2 = hasher.operator xxhasher::result_type(); + + BEAST_EXPECT(xxhashResult1 == xxhashResult2); + } + } + + void + run() override + { + testWithoutSeed(); + testWithSeed(); + testWithTwoSeeds(); + testBigObjectWithMultiupleSmallUpdatesWithoutSeed(); + testBigObjectWithMultiupleSmallUpdatesWithSeed(); + testBigObjectWithSmallAndBigUpdatesWithoutSeed(); + testBigObjectWithSmallAndBigUpdatesWithSeed(); + testBigObjectWithOneUpdateWithoutSeed(); + testBigObjectWithOneUpdateWithSeed(); + testOperatorResultTypeDoesNotChangeInternalState(); + } +}; + +BEAST_DEFINE_TESTSUITE(XXHasher, beast_core, beast); +} // namespace beast From bdfc3769513d0b6735b97ce4f29cc0351db04dae Mon Sep 17 00:00:00 2001 From: Bart Date: Mon, 11 Aug 2025 07:24:24 -0400 Subject: [PATCH 02/16] chore: Cleanup bin/ directory (#5660) This change removes ancient and unused files from the `bin/` directory. --- bin/browser.js | 470 ---------------------------------------- bin/debug_local_sign.js | 64 ------ bin/email_hash.js | 18 -- bin/flash_policy.js | 31 --- bin/getRippledInfo | 150 ------------- bin/hexify.js | 23 -- bin/jsonrpc_request.js | 42 ---- bin/jsonrpc_server.js | 68 ------ bin/physical.sh | 218 ------------------- bin/rlint.js | 252 --------------------- bin/sh/install-vcpkg.sh | 51 ----- bin/sh/setup-msvc.sh | 40 ---- bin/start_sync_stop.py | 246 --------------------- bin/stop-test.js | 133 ------------ bin/update_binformat.js | 119 ---------- conanfile.py | 1 - 16 files changed, 1926 deletions(-) delete mode 100755 bin/browser.js delete mode 100644 bin/debug_local_sign.js delete mode 100755 bin/email_hash.js delete mode 100755 bin/flash_policy.js delete mode 100755 bin/getRippledInfo delete mode 100755 bin/hexify.js delete mode 100755 bin/jsonrpc_request.js delete mode 100755 bin/jsonrpc_server.js delete mode 100755 bin/physical.sh delete mode 100755 bin/rlint.js delete mode 100755 bin/sh/install-vcpkg.sh delete mode 100755 bin/sh/setup-msvc.sh delete mode 100644 bin/start_sync_stop.py delete mode 100644 bin/stop-test.js delete mode 100644 bin/update_binformat.js diff --git a/bin/browser.js b/bin/browser.js deleted file mode 100755 index 81618bd002..0000000000 --- a/bin/browser.js +++ /dev/null @@ -1,470 +0,0 @@ -#!/usr/bin/node -// -// ledger?l=L -// transaction?h=H -// ledger_entry?l=L&h=H -// account?l=L&a=A -// directory?l=L&dir_root=H&i=I -// directory?l=L&o=A&i=I // owner directory -// offer?l=L&offer=H -// offer?l=L&account=A&i=I -// ripple_state=l=L&a=A&b=A&c=C -// account_lines?l=L&a=A -// -// A=address -// C=currency 3 letter code -// H=hash -// I=index -// L=current | closed | validated | index | hash -// - -var async = require("async"); -var extend = require("extend"); -var http = require("http"); -var url = require("url"); - -var Remote = require("ripple-lib").Remote; - -var program = process.argv[1]; - -var httpd_response = function (res, opts) { - var self=this; - - res.statusCode = opts.statusCode; - res.end( - "" - + "Title" - + "" - + "State:" + self.state - + "" - + (opts.body || '') - + '
'
-      + (opts.url || '')
-      + '
' - + "" - + "" - ); -}; - -var html_link = function (generic) { - return '' + generic + ''; -}; - -// Build a link to a type. -var build_uri = function (params, opts) { - var c; - - if (params.type === 'account') { - c = { - pathname: 'account', - query: { - l: params.ledger, - a: params.account, - }, - }; - - } else if (params.type === 'ledger') { - c = { - pathname: 'ledger', - query: { - l: params.ledger, - }, - }; - - } else if (params.type === 'transaction') { - c = { - pathname: 'transaction', - query: { - h: params.hash, - }, - }; - } else { - c = {}; - } - - opts = opts || {}; - - c.protocol = "http"; - c.hostname = opts.hostname || self.base.hostname; - c.port = opts.port || self.base.port; - - return url.format(c); -}; - -var build_link = function (item, link) { -console.log(link); - return "" + item + ""; -}; - -var rewrite_field = function (type, obj, field, opts) { - if (field in obj) { - obj[field] = rewrite_type(type, obj[field], opts); - } -}; - -var rewrite_type = function (type, obj, opts) { - if ('amount' === type) { - if ('string' === typeof obj) { - // XRP. - return '' + obj + ''; - - } else { - rewrite_field('address', obj, 'issuer', opts); - - return obj; - } - return build_link( - obj, - build_uri({ - type: 'account', - account: obj - }, opts) - ); - } - if ('address' === type) { - return build_link( - obj, - build_uri({ - type: 'account', - account: obj - }, opts) - ); - } - else if ('ledger' === type) { - return build_link( - obj, - build_uri({ - type: 'ledger', - ledger: obj, - }, opts) - ); - } - else if ('node' === type) { - // A node - if ('PreviousTxnID' in obj) - obj.PreviousTxnID = rewrite_type('transaction', obj.PreviousTxnID, opts); - - if ('Offer' === obj.LedgerEntryType) { - if ('NewFields' in obj) { - if ('TakerGets' in obj.NewFields) - obj.NewFields.TakerGets = rewrite_type('amount', obj.NewFields.TakerGets, opts); - - if ('TakerPays' in obj.NewFields) - obj.NewFields.TakerPays = rewrite_type('amount', obj.NewFields.TakerPays, opts); - } - } - - obj.LedgerEntryType = '' + obj.LedgerEntryType + ''; - - return obj; - } - else if ('transaction' === type) { - // Reference to a transaction. - return build_link( - obj, - build_uri({ - type: 'transaction', - hash: obj - }, opts) - ); - } - - return 'ERROR: ' + type; -}; - -var rewrite_object = function (obj, opts) { - var out = extend({}, obj); - - rewrite_field('address', out, 'Account', opts); - - rewrite_field('ledger', out, 'parent_hash', opts); - rewrite_field('ledger', out, 'ledger_index', opts); - rewrite_field('ledger', out, 'ledger_current_index', opts); - rewrite_field('ledger', out, 'ledger_hash', opts); - - if ('ledger' in obj) { - // It's a ledger header. - out.ledger = rewrite_object(out.ledger, opts); - - if ('ledger_hash' in out.ledger) - out.ledger.ledger_hash = '' + out.ledger.ledger_hash + ''; - - delete out.ledger.hash; - delete out.ledger.totalCoins; - } - - if ('TransactionType' in obj) { - // It's a transaction. - out.TransactionType = '' + obj.TransactionType + ''; - - rewrite_field('amount', out, 'TakerGets', opts); - rewrite_field('amount', out, 'TakerPays', opts); - rewrite_field('ledger', out, 'inLedger', opts); - - out.meta.AffectedNodes = out.meta.AffectedNodes.map(function (node) { - var kind = 'CreatedNode' in node - ? 'CreatedNode' - : 'ModifiedNode' in node - ? 'ModifiedNode' - : 'DeletedNode' in node - ? 'DeletedNode' - : undefined; - - if (kind) { - node[kind] = rewrite_type('node', node[kind], opts); - } - return node; - }); - } - else if ('node' in obj && 'LedgerEntryType' in obj.node) { - // Its a ledger entry. - - if (obj.node.LedgerEntryType === 'AccountRoot') { - rewrite_field('address', out.node, 'Account', opts); - rewrite_field('transaction', out.node, 'PreviousTxnID', opts); - rewrite_field('ledger', out.node, 'PreviousTxnLgrSeq', opts); - } - - out.node.LedgerEntryType = '' + out.node.LedgerEntryType + ''; - } - - return out; -}; - -var augment_object = function (obj, opts, done) { - if (obj.node.LedgerEntryType == 'AccountRoot') { - var tx_hash = obj.node.PreviousTxnID; - var tx_ledger = obj.node.PreviousTxnLgrSeq; - - obj.history = []; - - async.whilst( - function () { return tx_hash; }, - function (callback) { -// console.log("augment_object: request: %s %s", tx_hash, tx_ledger); - opts.remote.request_tx(tx_hash) - .on('success', function (m) { - tx_hash = undefined; - tx_ledger = undefined; - -//console.log("augment_object: ", JSON.stringify(m)); - m.meta.AffectedNodes.filter(function(n) { -// console.log("augment_object: ", JSON.stringify(n)); -// if (n.ModifiedNode) -// console.log("augment_object: %s %s %s %s %s %s/%s", 'ModifiedNode' in n, n.ModifiedNode && (n.ModifiedNode.LedgerEntryType === 'AccountRoot'), n.ModifiedNode && n.ModifiedNode.FinalFields && (n.ModifiedNode.FinalFields.Account === obj.node.Account), Object.keys(n)[0], n.ModifiedNode && (n.ModifiedNode.LedgerEntryType), obj.node.Account, n.ModifiedNode && n.ModifiedNode.FinalFields && n.ModifiedNode.FinalFields.Account); -// if ('ModifiedNode' in n && n.ModifiedNode.LedgerEntryType === 'AccountRoot') -// { -// console.log("***: ", JSON.stringify(m)); -// console.log("***: ", JSON.stringify(n)); -// } - return 'ModifiedNode' in n - && n.ModifiedNode.LedgerEntryType === 'AccountRoot' - && n.ModifiedNode.FinalFields - && n.ModifiedNode.FinalFields.Account === obj.node.Account; - }) - .forEach(function (n) { - tx_hash = n.ModifiedNode.PreviousTxnID; - tx_ledger = n.ModifiedNode.PreviousTxnLgrSeq; - - obj.history.push({ - tx_hash: tx_hash, - tx_ledger: tx_ledger - }); -console.log("augment_object: next: %s %s", tx_hash, tx_ledger); - }); - - callback(); - }) - .on('error', function (m) { - callback(m); - }) - .request(); - }, - function (err) { - if (err) { - done(); - } - else { - async.forEach(obj.history, function (o, callback) { - opts.remote.request_account_info(obj.node.Account) - .ledger_index(o.tx_ledger) - .on('success', function (m) { -//console.log("augment_object: ", JSON.stringify(m)); - o.Balance = m.account_data.Balance; -// o.account_data = m.account_data; - callback(); - }) - .on('error', function (m) { - o.error = m; - callback(); - }) - .request(); - }, - function (err) { - done(err); - }); - } - }); - } - else { - done(); - } -}; - -if (process.argv.length < 4 || process.argv.length > 7) { - console.log("Usage: %s ws_ip ws_port [ [ []]]", program); -} -else { - var ws_ip = process.argv[2]; - var ws_port = process.argv[3]; - var ip = process.argv.length > 4 ? process.argv[4] : "127.0.0.1"; - var port = process.argv.length > 5 ? process.argv[5] : "8080"; - -// console.log("START"); - var self = this; - - var remote = (new Remote({ - websocket_ip: ws_ip, - websocket_port: ws_port, - trace: false - })) - .on('state', function (m) { - console.log("STATE: %s", m); - - self.state = m; - }) -// .once('ledger_closed', callback) - .connect() - ; - - self.base = { - hostname: ip, - port: port, - remote: remote, - }; - -// console.log("SERVE"); - var server = http.createServer(function (req, res) { - var input = ""; - - req.setEncoding(); - - req.on('data', function (buffer) { - // console.log("DATA: %s", buffer); - input = input + buffer; - }); - - req.on('end', function () { - // console.log("URL: %s", req.url); - // console.log("HEADERS: %s", JSON.stringify(req.headers, undefined, 2)); - - var _parsed = url.parse(req.url, true); - var _url = JSON.stringify(_parsed, undefined, 2); - - // console.log("HEADERS: %s", JSON.stringify(_parsed, undefined, 2)); - if (_parsed.pathname === "/account") { - var request = remote - .request_ledger_entry('account_root') - .ledger_index(-1) - .account_root(_parsed.query.a) - .on('success', function (m) { - // console.log("account_root: %s", JSON.stringify(m, undefined, 2)); - - augment_object(m, self.base, function() { - httpd_response(res, - { - statusCode: 200, - url: _url, - body: "
"
-                              + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
-                              + "
" - }); - }); - }) - .request(); - - } else if (_parsed.pathname === "/ledger") { - var request = remote - .request_ledger(undefined, { expand: true, transactions: true }) - .on('success', function (m) { - // console.log("Ledger: %s", JSON.stringify(m, undefined, 2)); - - httpd_response(res, - { - statusCode: 200, - url: _url, - body: "
"
-                          + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
-                          +"
" - }); - }) - - if (_parsed.query.l && _parsed.query.l.length === 64) { - request.ledger_hash(_parsed.query.l); - } - else if (_parsed.query.l) { - request.ledger_index(Number(_parsed.query.l)); - } - else { - request.ledger_index(-1); - } - - request.request(); - - } else if (_parsed.pathname === "/transaction") { - var request = remote - .request_tx(_parsed.query.h) -// .request_transaction_entry(_parsed.query.h) -// .ledger_select(_parsed.query.l) - .on('success', function (m) { - // console.log("transaction: %s", JSON.stringify(m, undefined, 2)); - - httpd_response(res, - { - statusCode: 200, - url: _url, - body: "
"
-                            + JSON.stringify(rewrite_object(m, self.base), undefined, 2)
-                            +"
" - }); - }) - .on('error', function (m) { - httpd_response(res, - { - statusCode: 200, - url: _url, - body: "
"
-                            + 'ERROR: ' + JSON.stringify(m, undefined, 2)
-                            +"
" - }); - }) - .request(); - - } else { - var test = build_uri({ - type: 'account', - ledger: 'closed', - account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', - }, self.base); - - httpd_response(res, - { - statusCode: req.url === "/" ? 200 : 404, - url: _url, - }); - } - }); - }); - - server.listen(port, ip, undefined, - function () { - console.log("Listening at: http://%s:%s", ip, port); - }); -} - -// vim:sw=2:sts=2:ts=8:et diff --git a/bin/debug_local_sign.js b/bin/debug_local_sign.js deleted file mode 100644 index 24f9aab481..0000000000 --- a/bin/debug_local_sign.js +++ /dev/null @@ -1,64 +0,0 @@ -var ripple = require('ripple-lib'); - -var v = { - seed: "snoPBrXtMeMyMHUVTgbuqAfg1SUTb", - addr: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" -}; - -var remote = ripple.Remote.from_config({ - "trusted" : true, - "websocket_ip" : "127.0.0.1", - "websocket_port" : 5006, - "websocket_ssl" : false, - "local_signing" : true -}); - -var tx_json = { - "Account" : v.addr, - "Amount" : "10000000", - "Destination" : "rEu2ULPiEQm1BAL8pYzmXnNX1aFX9sCks", - "Fee" : "10", - "Flags" : 0, - "Sequence" : 3, - "TransactionType" : "Payment" - - //"SigningPubKey": '0396941B22791A448E5877A44CE98434DB217D6FB97D63F0DAD23BE49ED45173C9' -}; - -remote.on('connected', function () { - var req = remote.request_sign(v.seed, tx_json); - req.message.debug_signing = true; - req.on('success', function (result) { - console.log("SERVER RESULT"); - console.log(result); - - var sim = {}; - var tx = remote.transaction(); - tx.tx_json = tx_json; - tx._secret = v.seed; - tx.complete(); - var unsigned = tx.serialize().to_hex(); - tx.sign(); - - sim.tx_blob = tx.serialize().to_hex(); - sim.tx_json = tx.tx_json; - sim.tx_signing_hash = tx.signing_hash().to_hex(); - sim.tx_unsigned = unsigned; - - console.log("\nLOCAL RESULT"); - console.log(sim); - - remote.connect(false); - }); - req.on('error', function (err) { - if (err.error === "remoteError" && err.remote.error === "srcActNotFound") { - console.log("Please fund account "+v.addr+" to run this test."); - } else { - console.log('error', err); - } - remote.connect(false); - }); - req.request(); - -}); -remote.connect(); diff --git a/bin/email_hash.js b/bin/email_hash.js deleted file mode 100755 index ab4f97c47b..0000000000 --- a/bin/email_hash.js +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/node -// -// Returns a Gravatar style hash as per: http://en.gravatar.com/site/implement/hash/ -// - -if (3 != process.argv.length) { - process.stderr.write("Usage: " + process.argv[1] + " email_address\n\nReturns gravatar style hash.\n"); - process.exit(1); - -} else { - var md5 = require('crypto').createHash('md5'); - - md5.update(process.argv[2].trim().toLowerCase()); - - process.stdout.write(md5.digest('hex') + "\n"); -} - -// vim:sw=2:sts=2:ts=8:et diff --git a/bin/flash_policy.js b/bin/flash_policy.js deleted file mode 100755 index e1361d46dc..0000000000 --- a/bin/flash_policy.js +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/node -// -// This program allows IE 9 ripple-clients to make websocket connections to -// rippled using flash. As IE 9 does not have websocket support, this required -// if you wish to support IE 9 ripple-clients. -// -// http://www.lightsphere.com/dev/articles/flash_socket_policy.html -// -// For better security, be sure to set the Port below to the port of your -// [websocket_public_port]. -// - -var net = require("net"), - port = "*", - domains = ["*:"+port]; // Domain:Port - -net.createServer( - function(socket) { - socket.write("\n"); - socket.write("\n"); - socket.write("\n"); - domains.forEach( - function(domain) { - var parts = domain.split(':'); - socket.write("\t\n"); - } - ); - socket.write("\n"); - socket.end(); - } -).listen(843); diff --git a/bin/getRippledInfo b/bin/getRippledInfo deleted file mode 100755 index abfa449bac..0000000000 --- a/bin/getRippledInfo +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env bash - -# This script generates information about your rippled installation -# and system. It can be used to help debug issues that you may face -# in your installation. While this script endeavors to not display any -# sensitive information, it is recommended that you read the output -# before sharing with any third parties. - - -rippled_exe=/opt/ripple/bin/rippled -conf_file=/etc/opt/ripple/rippled.cfg - -while getopts ":e:c:" opt; do - case $opt in - e) - rippled_exe=${OPTARG} - ;; - c) - conf_file=${OPTARG} - ;; - \?) - echo "Invalid option: -$OPTARG" - exit -1 - esac -done - -tmp_loc=$(mktemp -d --tmpdir ripple_info.XXXXX) -chmod 751 ${tmp_loc} -awk_prog=${tmp_loc}/cfg.awk -summary_out=${tmp_loc}/rippled_info.md -printf "# rippled report info\n\n> generated at %s\n" "$(date -R)" > ${summary_out} - -function log_section { - printf "\n## %s\n" "$*" >> ${summary_out} - - while read -r l; do - echo " $l" >> ${summary_out} - done > ${awk_prog} - BEGIN {FS="[[:space:]]*=[[:space:]]*"; skip=0; db_path=""; print > OUT_FILE; split(exl,exa,"|")} - /^#/ {next} - save==2 && /^[[:space:]]*$/ {next} - /^\[.+\]$/ { - section=tolower(gensub(/^\[[[:space:]]*([a-zA-Z_]+)[[:space:]]*\]$/, "\\1", "g")) - skip = 0 - for (i in exa) { - if (section == exa[i]) - skip = 1 - } - if (section == "database_path") - save = 1 - } - skip==1 {next} - save==2 {save=0; db_path=$0} - save==1 {save=2} - $1 ~ /password/ {$0=$1"="} - {print >> OUT_FILE} - END {print db_path} -EOP - - db=$(\ - sed -r -e 's/\//g;s/^[[:space:]]*//;s/[[:space:]]*$//' ${conf_file} |\ - awk -v OUT_FILE=${cleaned_conf} -v exl="$(join_by '|' "${exclude[@]}")" -f ${awk_prog}) - rm ${awk_prog} - cat ${cleaned_conf} | log_section "cleaned config file" - rm ${cleaned_conf} - echo "${db}" | log_section "database path" - df ${db} | log_section "df: database" -fi - -# Send output from this script to a log file -## this captures any messages -## or errors from the script itself - -log_file=${tmp_loc}/get_info.log -exec 3>&1 1>>${log_file} 2>&1 - -## Send all stdout files to /tmp - -if [[ -x ${rippled_exe} ]] ; then - pgrep rippled && \ - ${rippled_exe} --conf ${conf_file} \ - -- server_info | log_section "server info" -fi - -cat /proc/meminfo | log_section "meminfo" -cat /proc/swaps | log_section "swap space" -ulimit -a | log_section "ulimit" - -if command -v lshw >/dev/null 2>&1 ; then - lshw 2>/dev/null | log_section "hardware info" -else - lscpu > ${tmp_loc}/hw_info.txt - hwinfo >> ${tmp_loc}/hw_info.txt - lspci >> ${tmp_loc}/hw_info.txt - lsblk >> ${tmp_loc}/hw_info.txt - cat ${tmp_loc}/hw_info.txt | log_section "hardware info" - rm ${tmp_loc}/hw_info.txt -fi - -if command -v iostat >/dev/null 2>&1 ; then - iostat -t -d -x 2 6 | log_section "iostat" -fi - -df -h | log_section "free disk space" -drives=($(df | awk '$1 ~ /^\/dev\// {print $1}' | xargs -n 1 basename)) -block_devs=($(ls /sys/block/)) -for d in "${drives[@]}"; do - for dev in "${block_devs[@]}"; do - #echo "D: [$d], DEV: [$dev]" - if [[ $d =~ $dev ]]; then - # this file (if exists) has 0 for SSD and 1 for HDD - if [[ "$(cat /sys/block/${dev}/queue/rotational 2>/dev/null)" == 0 ]] ; then - echo "${d} : SSD" >> ${tmp_loc}/is_ssd.txt - else - echo "${d} : NO SSD" >> ${tmp_loc}/is_ssd.txt - fi - fi - done -done - -if [[ -f ${tmp_loc}/is_ssd.txt ]] ; then - cat ${tmp_loc}/is_ssd.txt | log_section "SSD" - rm ${tmp_loc}/is_ssd.txt -fi - -cat ${log_file} | log_section "script log" - -cat << MSG | tee /dev/fd/3 -#################################################### - rippled info has been gathered. Please copy the - contents of ${summary_out} - to a github gist at https://gist.github.com/ - - PLEASE REVIEW THIS FILE FOR ANY SENSITIVE DATA - BEFORE POSTING! We have tried our best to omit - any sensitive information from this file, but you - should verify before posting. -#################################################### -MSG - diff --git a/bin/hexify.js b/bin/hexify.js deleted file mode 100755 index 1e2fb70009..0000000000 --- a/bin/hexify.js +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/node -// -// Returns hex of lowercasing a string. -// - -var stringToHex = function (s) { - return Array.prototype.map.call(s, function (c) { - var b = c.charCodeAt(0); - - return b < 16 ? "0" + b.toString(16) : b.toString(16); - }).join(""); -}; - -if (3 != process.argv.length) { - process.stderr.write("Usage: " + process.argv[1] + " string\n\nReturns hex of lowercasing string.\n"); - process.exit(1); - -} else { - - process.stdout.write(stringToHex(process.argv[2].toLowerCase()) + "\n"); -} - -// vim:sw=2:sts=2:ts=8:et diff --git a/bin/jsonrpc_request.js b/bin/jsonrpc_request.js deleted file mode 100755 index 0b9c08666d..0000000000 --- a/bin/jsonrpc_request.js +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/node -// -// This is a tool to issue JSON-RPC requests from the command line. -// -// This can be used to test a JSON-RPC server. -// -// Requires: npm simple-jsonrpc -// - -var jsonrpc = require('simple-jsonrpc'); - -var program = process.argv[1]; - -if (5 !== process.argv.length) { - console.log("Usage: %s ", program); -} -else { - var url = process.argv[2]; - var method = process.argv[3]; - var json_raw = process.argv[4]; - var json; - - try { - json = JSON.parse(json_raw); - } - catch (e) { - console.log("JSON parse error: %s", e.message); - throw e; - } - - var client = jsonrpc.client(url); - - client.call(method, json, - function (result) { - console.log(JSON.stringify(result, undefined, 2)); - }, - function (error) { - console.log(JSON.stringify(error, undefined, 2)); - }); -} - -// vim:sw=2:sts=2:ts=8:et diff --git a/bin/jsonrpc_server.js b/bin/jsonrpc_server.js deleted file mode 100755 index 4cd3ffb95c..0000000000 --- a/bin/jsonrpc_server.js +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/node -// -// This is a tool to listen for JSON-RPC requests at an IP and port. -// -// This will report the request to console and echo back the request as the response. -// - -var http = require("http"); - -var program = process.argv[1]; - -if (4 !== process.argv.length) { - console.log("Usage: %s ", program); -} -else { - var ip = process.argv[2]; - var port = process.argv[3]; - - var server = http.createServer(function (req, res) { - console.log("CONNECT"); - var input = ""; - - req.setEncoding(); - - req.on('data', function (buffer) { - // console.log("DATA: %s", buffer); - input = input + buffer; - }); - - req.on('end', function () { - // console.log("END"); - - var json_req; - - console.log("URL: %s", req.url); - console.log("HEADERS: %s", JSON.stringify(req.headers, undefined, 2)); - - try { - json_req = JSON.parse(input); - - console.log("REQ: %s", JSON.stringify(json_req, undefined, 2)); - } - catch (e) { - console.log("BAD JSON: %s", e.message); - - json_req = { error : e.message } - } - - res.statusCode = 200; - res.end(JSON.stringify({ - jsonrpc: "2.0", - result: { request : json_req }, - id: req.id - })); - }); - - req.on('close', function () { - console.log("CLOSE"); - }); - }); - - server.listen(port, ip, undefined, - function () { - console.log("Listening at: %s:%s", ip, port); - }); -} - -// vim:sw=2:sts=2:ts=8:et diff --git a/bin/physical.sh b/bin/physical.sh deleted file mode 100755 index c2c5aad68d..0000000000 --- a/bin/physical.sh +++ /dev/null @@ -1,218 +0,0 @@ -#!/bin/bash - -set -o errexit - -marker_base=985c80fbc6131f3a8cedd0da7e8af98dfceb13c7 -marker_commit=${1:-${marker_base}} - -if [ $(git merge-base ${marker_commit} ${marker_base}) != ${marker_base} ]; then - echo "first marker commit not an ancestor: ${marker_commit}" - exit 1 -fi - -if [ $(git merge-base ${marker_commit} HEAD) != $(git rev-parse --verify ${marker_commit}) ]; then - echo "given marker commit not an ancestor: ${marker_commit}" - exit 1 -fi - -if [ -e Builds/CMake ]; then - echo move CMake - git mv Builds/CMake cmake - git add --update . - git commit -m 'Move CMake directory' --author 'Pretty Printer ' -fi - -if [ -e src/ripple ]; then - - echo move protocol buffers - mkdir -p include/xrpl - if [ -e src/ripple/proto ]; then - git mv src/ripple/proto include/xrpl - fi - - extract_list() { - git show ${marker_commit}:Builds/CMake/RippledCore.cmake | \ - awk "/END ${1}/ { p = 0 } p && /src\/ripple/; /BEGIN ${1}/ { p = 1 }" | \ - sed -e 's#src/ripple/##' -e 's#[^a-z]\+$##' - } - - move_files() { - oldroot="$1"; shift - newroot="$1"; shift - detail="$1"; shift - files=("$@") - for file in ${files[@]}; do - if [ ! -e ${oldroot}/${file} ]; then - continue - fi - dir=$(dirname ${file}) - if [ $(basename ${dir}) == 'details' ]; then - dir=$(dirname ${dir}) - fi - if [ $(basename ${dir}) == 'impl' ]; then - dir="$(dirname ${dir})/${detail}" - fi - mkdir -p ${newroot}/${dir} - git mv ${oldroot}/${file} ${newroot}/${dir} - done - } - - echo move libxrpl headers - files=$(extract_list 'LIBXRPL HEADERS') - files+=( - basics/SlabAllocator.h - - beast/asio/io_latency_probe.h - beast/container/aged_container.h - beast/container/aged_container_utility.h - beast/container/aged_map.h - beast/container/aged_multimap.h - beast/container/aged_multiset.h - beast/container/aged_set.h - beast/container/aged_unordered_map.h - beast/container/aged_unordered_multimap.h - beast/container/aged_unordered_multiset.h - beast/container/aged_unordered_set.h - beast/container/detail/aged_associative_container.h - beast/container/detail/aged_container_iterator.h - beast/container/detail/aged_ordered_container.h - beast/container/detail/aged_unordered_container.h - beast/container/detail/empty_base_optimization.h - beast/core/LockFreeStack.h - beast/insight/Collector.h - beast/insight/Counter.h - beast/insight/CounterImpl.h - beast/insight/Event.h - beast/insight/EventImpl.h - beast/insight/Gauge.h - beast/insight/GaugeImpl.h - beast/insight/Group.h - beast/insight/Groups.h - beast/insight/Hook.h - beast/insight/HookImpl.h - beast/insight/Insight.h - beast/insight/Meter.h - beast/insight/MeterImpl.h - beast/insight/NullCollector.h - beast/insight/StatsDCollector.h - beast/test/fail_counter.h - beast/test/fail_stream.h - beast/test/pipe_stream.h - beast/test/sig_wait.h - beast/test/string_iostream.h - beast/test/string_istream.h - beast/test/string_ostream.h - beast/test/test_allocator.h - beast/test/yield_to.h - beast/utility/hash_pair.h - beast/utility/maybe_const.h - beast/utility/temp_dir.h - - # included by only json/impl/json_assert.h - json/json_errors.h - - protocol/PayChan.h - protocol/RippleLedgerHash.h - protocol/messages.h - protocol/st.h - ) - files+=( - basics/README.md - crypto/README.md - json/README.md - protocol/README.md - resource/README.md - ) - move_files src/ripple include/xrpl detail ${files[@]} - - echo move libxrpl sources - files=$(extract_list 'LIBXRPL SOURCES') - move_files src/ripple src/libxrpl "" ${files[@]} - - echo check leftovers - dirs=$(cd include/xrpl; ls -d */) - dirs=$(cd src/ripple; ls -d ${dirs} 2>/dev/null || true) - files="$(cd src/ripple; find ${dirs} -type f)" - if [ -n "${files}" ]; then - echo "leftover files:" - echo ${files} - exit - fi - - echo remove empty directories - empty_dirs="$(cd src/ripple; find ${dirs} -depth -type d)" - for dir in ${empty_dirs[@]}; do - if [ -e ${dir} ]; then - rmdir ${dir} - fi - done - - echo move xrpld sources - files=$( - extract_list 'XRPLD SOURCES' - cd src/ripple - find * -regex '.*\.\(h\|ipp\|md\|pu\|uml\|png\)' - ) - move_files src/ripple src/xrpld detail ${files[@]} - - files="$(cd src/ripple; find . -type f)" - if [ -n "${files}" ]; then - echo "leftover files:" - echo ${files} - exit - fi - -fi - -rm -rf src/ripple - -echo rename .hpp to .h -find include src -name '*.hpp' -exec bash -c 'f="{}"; git mv "${f}" "${f%hpp}h"' \; - -echo move PerfLog.h -if [ -e include/xrpl/basics/PerfLog.h ]; then - git mv include/xrpl/basics/PerfLog.h src/xrpld/perflog -fi - -# Make sure all protobuf includes have the correct prefix. -protobuf_replace='s:^#include\s*["<].*org/xrpl\([^">]\+\)[">]:#include :' -# Make sure first-party includes use angle brackets and .h extension. -ripple_replace='s:include\s*["<]ripple/\(.*\)\.h\(pp\)\?[">]:include :' -beast_replace='s:include\s*:#include :" \ - -e "s:^#include ' -find include src -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format-10 -i {} + -git add --update . -git commit -m 'Rewrite includes' --author 'Pretty Printer ' -./Builds/levelization/levelization.sh -git add --update . -git commit -m 'Recompute loops' --author 'Pretty Printer ' diff --git a/bin/rlint.js b/bin/rlint.js deleted file mode 100755 index ce12e9560a..0000000000 --- a/bin/rlint.js +++ /dev/null @@ -1,252 +0,0 @@ -#!/usr/bin/node - -var async = require('async'); -var Remote = require('ripple-lib').Remote; -var Transaction = require('ripple-lib').Transaction; -var UInt160 = require('ripple-lib').UInt160; -var Amount = require('ripple-lib').Amount; - -var book_key = function (book) { - return book.taker_pays.currency - + ":" + book.taker_pays.issuer - + ":" + book.taker_gets.currency - + ":" + book.taker_gets.issuer; -}; - -var book_key_cross = function (book) { - return book.taker_gets.currency - + ":" + book.taker_gets.issuer - + ":" + book.taker_pays.currency - + ":" + book.taker_pays.issuer; -}; - -var ledger_verify = function (ledger) { - var dir_nodes = ledger.accountState.filter(function (entry) { - return entry.LedgerEntryType === 'DirectoryNode' // Only directories - && entry.index === entry.RootIndex // Only root nodes - && 'TakerGetsCurrency' in entry; // Only offer directories - }); - - var books = {}; - - dir_nodes.forEach(function (node) { - var book = { - taker_gets: { - currency: UInt160.from_generic(node.TakerGetsCurrency).to_json(), - issuer: UInt160.from_generic(node.TakerGetsIssuer).to_json() - }, - taker_pays: { - currency: UInt160.from_generic(node.TakerPaysCurrency).to_json(), - issuer: UInt160.from_generic(node.TakerPaysIssuer).to_json() - }, - quality: Amount.from_quality(node.RootIndex), - index: node.RootIndex - }; - - books[book_key(book)] = book; - -// console.log(JSON.stringify(node, undefined, 2)); - }); - -// console.log(JSON.stringify(dir_entry, undefined, 2)); - console.log("#%s books: %s", ledger.ledger_index, Object.keys(books).length); - - Object.keys(books).forEach(function (key) { - var book = books[key]; - var key_cross = book_key_cross(book); - var book_cross = books[key_cross]; - - if (book && book_cross && !book_cross.done) - { - var book_cross_quality_inverted = Amount.from_json("1.0/1/1").divide(book_cross.quality); - - if (book_cross_quality_inverted.compareTo(book.quality) >= 0) - { - // Crossing books - console.log("crossing: #%s :: %s :: %s :: %s :: %s :: %s :: %s", ledger.ledger_index, key, book.quality.to_text(), book_cross.quality.to_text(), book_cross_quality_inverted.to_text(), - book.index, book_cross.index); - } - - book_cross.done = true; - } - }); - - var ripple_selfs = {}; - - var accounts = {}; - var counts = {}; - - ledger.accountState.forEach(function (entry) { - if (entry.LedgerEntryType === 'Offer') - { - counts[entry.Account] = (counts[entry.Account] || 0) + 1; - } - else if (entry.LedgerEntryType === 'RippleState') - { - if (entry.Flags & (0x10000 | 0x40000)) - { - counts[entry.LowLimit.issuer] = (counts[entry.LowLimit.issuer] || 0) + 1; - } - - if (entry.Flags & (0x20000 | 0x80000)) - { - counts[entry.HighLimit.issuer] = (counts[entry.HighLimit.issuer] || 0) + 1; - } - - if (entry.HighLimit.issuer === entry.LowLimit.issuer) - ripple_selfs[entry.Account] = entry; - } - else if (entry.LedgerEntryType == 'AccountRoot') - { - accounts[entry.Account] = entry; - } - }); - - var low = 0; // Accounts with too low a count. - var high = 0; - var missing_accounts = 0; // Objects with no referencing account. - var missing_objects = 0; // Accounts specifying an object but having none. - - Object.keys(counts).forEach(function (account) { - if (account in accounts) - { - if (counts[account] !== accounts[account].OwnerCount) - { - if (counts[account] < accounts[account].OwnerCount) - { - high += 1; - console.log("%s: high count %s/%s", account, counts[account], accounts[account].OwnerCount); - } - else - { - low += 1; - console.log("%s: low count %s/%s", account, counts[account], accounts[account].OwnerCount); - } - } - } - else - { - missing_accounts += 1; - - console.log("%s: missing : count %s", account, counts[account]); - } - }); - - Object.keys(accounts).forEach(function (account) { - if (!('OwnerCount' in accounts[account])) - { - console.log("%s: bad entry : %s", account, JSON.stringify(accounts[account], undefined, 2)); - } - else if (!(account in counts) && accounts[account].OwnerCount) - { - missing_objects += 1; - - console.log("%s: no objects : %s/%s", account, 0, accounts[account].OwnerCount); - } - }); - - if (low) - console.log("counts too low = %s", low); - - if (high) - console.log("counts too high = %s", high); - - if (missing_objects) - console.log("missing_objects = %s", missing_objects); - - if (missing_accounts) - console.log("missing_accounts = %s", missing_accounts); - - if (Object.keys(ripple_selfs).length) - console.log("RippleState selfs = %s", Object.keys(ripple_selfs).length); - -}; - -var ledger_request = function (remote, ledger_index, done) { - remote.request_ledger(undefined, { - accounts: true, - expand: true, - }) - .ledger_index(ledger_index) - .on('success', function (m) { - // console.log("ledger: ", ledger_index); - // console.log("ledger: ", JSON.stringify(m, undefined, 2)); - done(m.ledger); - }) - .on('error', function (m) { - console.log("error"); - done(); - }) - .request(); -}; - -var usage = function () { - console.log("rlint.js _websocket_ip_ _websocket_port_ "); -}; - -var finish = function (remote) { - remote.disconnect(); - - // XXX Because remote.disconnect() doesn't work: - process.exit(); -}; - -console.log("args: ", process.argv.length); -console.log("args: ", process.argv); - -if (process.argv.length < 4) { - usage(); -} -else { - var remote = Remote.from_config({ - websocket_ip: process.argv[2], - websocket_port: process.argv[3], - }) - .once('ledger_closed', function (m) { - console.log("ledger_closed: ", JSON.stringify(m, undefined, 2)); - - if (process.argv.length === 5) { - var ledger_index = process.argv[4]; - - ledger_request(remote, ledger_index, function (l) { - if (l) { - ledger_verify(l); - } - - finish(remote); - }); - - } else if (process.argv.length === 6) { - var ledger_start = Number(process.argv[4]); - var ledger_end = Number(process.argv[5]); - var ledger_cursor = ledger_end; - - async.whilst( - function () { - return ledger_start <= ledger_cursor && ledger_cursor <=ledger_end; - }, - function (callback) { - // console.log(ledger_cursor); - - ledger_request(remote, ledger_cursor, function (l) { - if (l) { - ledger_verify(l); - } - - --ledger_cursor; - - callback(); - }); - }, - function (error) { - finish(remote); - }); - - } else { - finish(remote); - } - }) - .connect(); -} - -// vim:sw=2:sts=2:ts=8:et diff --git a/bin/sh/install-vcpkg.sh b/bin/sh/install-vcpkg.sh deleted file mode 100755 index 8cf8f2d088..0000000000 --- a/bin/sh/install-vcpkg.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash -set -exu - -: ${TRAVIS_BUILD_DIR:=""} -: ${VCPKG_DIR:=".vcpkg"} -export VCPKG_ROOT=${VCPKG_DIR} -: ${VCPKG_DEFAULT_TRIPLET:="x64-windows-static"} - -export VCPKG_DEFAULT_TRIPLET - -EXE="vcpkg" -if [[ -z ${COMSPEC:-} ]]; then - EXE="${EXE}.exe" -fi - -if [[ -d "${VCPKG_DIR}" && -x "${VCPKG_DIR}/${EXE}" && -d "${VCPKG_DIR}/installed" ]] ; then - echo "Using cached vcpkg at ${VCPKG_DIR}" - ${VCPKG_DIR}/${EXE} list -else - if [[ -d "${VCPKG_DIR}" ]] ; then - rm -rf "${VCPKG_DIR}" - fi - git clone --branch 2021.04.30 https://github.com/Microsoft/vcpkg.git ${VCPKG_DIR} - pushd ${VCPKG_DIR} - BSARGS=() - if [[ "$(uname)" == "Darwin" ]] ; then - BSARGS+=(--allowAppleClang) - fi - if [[ -z ${COMSPEC:-} ]]; then - chmod +x ./bootstrap-vcpkg.sh - time ./bootstrap-vcpkg.sh "${BSARGS[@]}" - else - time ./bootstrap-vcpkg.bat - fi - popd -fi - -# TODO: bring boost in this way as well ? -# NOTE: can pin specific ports to a commit/version like this: -# git checkout ports/boost -if [ $# -eq 0 ]; then - echo "No extra packages specified..." - PKGS=() -else - PKGS=( "$@" ) -fi -for LIB in "${PKGS[@]}"; do - time ${VCPKG_DIR}/${EXE} --clean-after-build install ${LIB} -done - - diff --git a/bin/sh/setup-msvc.sh b/bin/sh/setup-msvc.sh deleted file mode 100755 index 8d61c9757f..0000000000 --- a/bin/sh/setup-msvc.sh +++ /dev/null @@ -1,40 +0,0 @@ - -# NOTE: must be sourced from a shell so it can export vars - -cat << BATCH > ./getenv.bat -CALL %* -ENV -BATCH - -while read line ; do - IFS='"' read x path arg <<<"${line}" - if [ -f "${path}" ] ; then - echo "FOUND: $path" - export VCINSTALLDIR=$(./getenv.bat "${path}" ${arg} | grep "^VCINSTALLDIR=" | sed -E "s/^VCINSTALLDIR=//g") - if [ "${VCINSTALLDIR}" != "" ] ; then - echo "USING ${VCINSTALLDIR}" - export LIB=$(./getenv.bat "${path}" ${arg} | grep "^LIB=" | sed -E "s/^LIB=//g") - export LIBPATH=$(./getenv.bat "${path}" ${arg} | grep "^LIBPATH=" | sed -E "s/^LIBPATH=//g") - export INCLUDE=$(./getenv.bat "${path}" ${arg} | grep "^INCLUDE=" | sed -E "s/^INCLUDE=//g") - ADDPATH=$(./getenv.bat "${path}" ${arg} | grep "^PATH=" | sed -E "s/^PATH=//g") - export PATH="${ADDPATH}:${PATH}" - break - fi - fi -done <= 7 - -import argparse -import asyncio -import configparser -import contextlib -import json -import logging -import os -from pathlib import Path -import platform -import subprocess -import time -import urllib.error -import urllib.request - -# Enable asynchronous subprocesses on Windows. The default changed in 3.8. -# https://docs.python.org/3.7/library/asyncio-platforms.html#subprocess-support-on-windows -if (platform.system() == 'Windows' and sys.version_info.major == 3 - and sys.version_info.minor < 8): - asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) - -DEFAULT_EXE = 'rippled' -DEFAULT_CONFIGURATION_FILE = 'rippled.cfg' -# Number of seconds to wait before forcefully terminating. -PATIENCE = 120 -# Number of contiguous seconds in a sync state to be considered synced. -DEFAULT_SYNC_DURATION = 60 -# Number of seconds between polls of state. -DEFAULT_POLL_INTERVAL = 5 -SYNC_STATES = ('full', 'validating', 'proposing') - - -def read_config(config_file): - # strict = False: Allow duplicate keys, e.g. [rpc_startup]. - # allow_no_value = True: Allow keys with no values. Generally, these - # instances use the "key" as the value, and the section name is the key, - # e.g. [debug_logfile]. - # delimiters = ('='): Allow ':' as a character in Windows paths. Some of - # our "keys" are actually values, and we don't want to split them on ':'. - config = configparser.ConfigParser( - strict=False, - allow_no_value=True, - delimiters=('='), - ) - config.read(config_file) - return config - - -def to_list(value, separator=','): - """Parse a list from a delimited string value.""" - return [s.strip() for s in value.split(separator) if s] - - -def find_log_file(config_file): - """Try to figure out what log file the user has chosen. Raises all kinds - of exceptions if there is any possibility of ambiguity.""" - config = read_config(config_file) - values = list(config['debug_logfile'].keys()) - if len(values) < 1: - raise ValueError( - f'no [debug_logfile] in configuration file: {config_file}') - if len(values) > 1: - raise ValueError( - f'too many [debug_logfile] in configuration file: {config_file}') - return values[0] - - -def find_http_port(config_file): - config = read_config(config_file) - names = list(config['server'].keys()) - for name in names: - server = config[name] - if 'http' in to_list(server.get('protocol', '')): - return int(server['port']) - raise ValueError(f'no server in [server] for "http" protocol') - - -@contextlib.asynccontextmanager -async def rippled(exe=DEFAULT_EXE, config_file=DEFAULT_CONFIGURATION_FILE): - """A context manager for a rippled process.""" - # Start the server. - process = await asyncio.create_subprocess_exec( - str(exe), - '--conf', - str(config_file), - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL, - ) - logging.info(f'rippled started with pid {process.pid}') - try: - yield process - finally: - # Ask it to stop. - logging.info(f'asking rippled (pid: {process.pid}) to stop') - start = time.time() - process.terminate() - - # Wait nicely. - try: - await asyncio.wait_for(process.wait(), PATIENCE) - except asyncio.TimeoutError: - # Ask the operating system to kill it. - logging.warning(f'killing rippled ({process.pid})') - try: - process.kill() - except ProcessLookupError: - pass - - code = await process.wait() - end = time.time() - logging.info( - f'rippled stopped after {end - start:.1f} seconds with code {code}' - ) - - -async def sync( - port, - *, - duration=DEFAULT_SYNC_DURATION, - interval=DEFAULT_POLL_INTERVAL, -): - """Poll rippled on an interval until it has been synced for a duration.""" - start = time.perf_counter() - while (time.perf_counter() - start) < duration: - await asyncio.sleep(interval) - - request = urllib.request.Request( - f'http://127.0.0.1:{port}', - data=json.dumps({ - 'method': 'server_state' - }).encode(), - headers={'Content-Type': 'application/json'}, - ) - with urllib.request.urlopen(request) as response: - try: - body = json.loads(response.read()) - except urllib.error.HTTPError as cause: - logging.warning(f'server_state returned not JSON: {cause}') - start = time.perf_counter() - continue - - try: - state = body['result']['state']['server_state'] - except KeyError as cause: - logging.warning(f'server_state response missing key: {cause.key}') - start = time.perf_counter() - continue - logging.info(f'server_state: {state}') - if state not in SYNC_STATES: - # Require a contiguous sync state. - start = time.perf_counter() - - -async def loop(test, - *, - exe=DEFAULT_EXE, - config_file=DEFAULT_CONFIGURATION_FILE): - """ - Start-test-stop rippled in an infinite loop. - - Moves log to a different file after each iteration. - """ - log_file = find_log_file(config_file) - id = 0 - while True: - logging.info(f'iteration: {id}') - async with rippled(exe, config_file) as process: - start = time.perf_counter() - exited = asyncio.create_task(process.wait()) - tested = asyncio.create_task(test()) - # Try to sync as long as the process is running. - done, pending = await asyncio.wait( - {exited, tested}, - return_when=asyncio.FIRST_COMPLETED, - ) - if done == {exited}: - code = exited.result() - logging.warning( - f'server halted for unknown reason with code {code}') - else: - assert done == {tested} - assert tested.exception() is None - end = time.perf_counter() - logging.info(f'synced after {end - start:.0f} seconds') - os.replace(log_file, f'debug.{id}.log') - id += 1 - - -logging.basicConfig( - format='%(asctime)s %(levelname)-8s %(message)s', - level=logging.INFO, - datefmt='%Y-%m-%d %H:%M:%S', -) - -parser = argparse.ArgumentParser( - formatter_class=argparse.ArgumentDefaultsHelpFormatter) -parser.add_argument( - 'rippled', - type=Path, - nargs='?', - default=DEFAULT_EXE, - help='Path to rippled.', -) -parser.add_argument( - '--conf', - type=Path, - default=DEFAULT_CONFIGURATION_FILE, - help='Path to configuration file.', -) -parser.add_argument( - '--duration', - type=int, - default=DEFAULT_SYNC_DURATION, - help='Number of contiguous seconds required in a synchronized state.', -) -parser.add_argument( - '--interval', - type=int, - default=DEFAULT_POLL_INTERVAL, - help='Number of seconds to wait between polls of state.', -) -args = parser.parse_args() - -port = find_http_port(args.conf) - - -def test(): - return sync(port, duration=args.duration, interval=args.interval) - - -try: - asyncio.run(loop(test, exe=args.rippled, config_file=args.conf)) -except KeyboardInterrupt: - # Squelch the message. This is a normal mode of exit. - pass diff --git a/bin/stop-test.js b/bin/stop-test.js deleted file mode 100644 index 45aa15e271..0000000000 --- a/bin/stop-test.js +++ /dev/null @@ -1,133 +0,0 @@ -/* -------------------------------- REQUIRES -------------------------------- */ - -var child = require("child_process"); -var assert = require("assert"); - -/* --------------------------------- CONFIG --------------------------------- */ - -if (process.argv[2] == null) { - [ - 'Usage: ', - '', - ' `node bin/stop-test.js i,j [rippled_path] [rippled_conf]`', - '', - ' Launch rippled and stop it after n seconds for all n in [i, j}', - ' For all even values of n launch rippled with `--fg`', - ' For values of n where n % 3 == 0 launch rippled with `--fg`\n', - 'Examples: ', - '', - ' $ node bin/stop-test.js 5,10', - (' $ node bin/stop-test.js 1,4 ' + - 'build/clang.debug/rippled $HOME/.confs/rippled.cfg') - ] - .forEach(function(l){console.log(l)}); - - process.exit(); -} else { - var testRange = process.argv[2].split(',').map(Number); - var rippledPath = process.argv[3] || 'build/rippled' - var rippledConf = process.argv[4] || 'rippled.cfg' -} - -var options = { - env: process.env, - stdio: 'ignore' // we could dump the child io when it fails abnormally -}; - -// default args -var conf_args = ['--conf='+rippledConf]; -var start_args = conf_args.concat([/*'--net'*/]) -var stop_args = conf_args.concat(['stop']); - -/* --------------------------------- HELPERS -------------------------------- */ - -function start(args) { - return child.spawn(rippledPath, args, options); -} -function stop(rippled) { child.execFile(rippledPath, stop_args, options)} -function secs_l8r(ms, f) {setTimeout(f, ms * 1000); } - -function show_results_and_exit(results) { - console.log(JSON.stringify(results, undefined, 2)); - process.exit(); -} - -var timeTakes = function (range) { - function sumRange(n) {return (n+1) * n /2} - var ret = sumRange(range[1]); - if (range[0] > 1) { - ret = ret - sumRange(range[0] - 1) - } - var stopping = (range[1] - range[0]) * 0.5; - return ret + stopping; -} - -/* ---------------------------------- TEST ---------------------------------- */ - -console.log("Test will take ~%s seconds", timeTakes(testRange)); - -(function oneTest(n /* seconds */, results) { - if (n >= testRange[1]) { - // show_results_and_exit(results); - console.log(JSON.stringify(results, undefined, 2)); - oneTest(testRange[0], []); - return; - } - - var args = start_args; - if (n % 2 == 0) {args = args.concat(['--fg'])} - if (n % 3 == 0) {args = args.concat(['--net'])} - - var result = {args: args, alive_for: n}; - results.push(result); - - console.log("\nLaunching `%s` with `%s` for %d seconds", - rippledPath, JSON.stringify(args), n); - - rippled = start(args); - console.log("Rippled pid: %d", rippled.pid); - - // defaults - var b4StopSent = false; - var stopSent = false; - var stop_took = null; - - rippled.once('exit', function(){ - if (!stopSent && !b4StopSent) { - console.warn('\nRippled exited itself b4 stop issued'); - process.exit(); - }; - - // The io handles close AFTER exit, may have implications for - // `stdio:'inherit'` option to `child.spawn`. - rippled.once('close', function() { - result.stop_took = (+new Date() - stop_took) / 1000; // seconds - console.log("Stopping after %d seconds took %s seconds", - n, result.stop_took); - oneTest(n+1, results); - }); - }); - - secs_l8r(n, function(){ - console.log("Stopping rippled after %d seconds", n); - - // possible race here ? - // seems highly unlikely, but I was having issues at one point - b4StopSent=true; - stop_took = (+new Date()); - // when does `exit` actually get sent? - stop(); - stopSent=true; - - // Sometimes we want to attach with a debugger. - if (process.env.ABORT_TESTS_ON_STALL != null) { - // We wait 30 seconds, and if it hasn't stopped, we abort the process - secs_l8r(30, function() { - if (result.stop_took == null) { - console.log("rippled has stalled"); - process.exit(); - }; - }); - } - }) -}(testRange[0], [])); \ No newline at end of file diff --git a/bin/update_binformat.js b/bin/update_binformat.js deleted file mode 100644 index 7987f72c82..0000000000 --- a/bin/update_binformat.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * bin/update_bintypes.js - * - * This unholy abomination of a script generates the JavaScript file - * src/js/bintypes.js from various parts of the C++ source code. - * - * This should *NOT* be part of any automatic build process unless the C++ - * source data are brought into a more easily parseable format. Until then, - * simply run this script manually and fix as needed. - */ - -// XXX: Process LedgerFormats.(h|cpp) as well. - -var filenameProto = __dirname + '/../src/cpp/ripple/SerializeProto.h', - filenameTxFormatsH = __dirname + '/../src/cpp/ripple/TransactionFormats.h', - filenameTxFormats = __dirname + '/../src/cpp/ripple/TransactionFormats.cpp'; - -var fs = require('fs'); - -var output = []; - -// Stage 1: Get the field types and codes from SerializeProto.h -var types = {}, - fields = {}; -String(fs.readFileSync(filenameProto)).split('\n').forEach(function (line) { - line = line.replace(/^\s+|\s+$/g, '').replace(/\s+/g, ''); - if (!line.length || line.slice(0, 2) === '//' || line.slice(-1) !== ')') return; - - var tmp = line.slice(0, -1).split('('), - type = tmp[0], - opts = tmp[1].split(','); - - if (type === 'TYPE') types[opts[1]] = [opts[0], +opts[2]]; - else if (type === 'FIELD') fields[opts[0]] = [types[opts[1]][0], +opts[2]]; -}); - -output.push('var ST = require("./serializedtypes");'); -output.push(''); -output.push('var REQUIRED = exports.REQUIRED = 0,'); -output.push(' OPTIONAL = exports.OPTIONAL = 1,'); -output.push(' DEFAULT = exports.DEFAULT = 2;'); -output.push(''); - -function pad(s, n) { while (s.length < n) s += ' '; return s; } -function padl(s, n) { while (s.length < n) s = ' '+s; return s; } - -Object.keys(types).forEach(function (type) { - output.push(pad('ST.'+types[type][0]+'.id', 25) + ' = '+types[type][1]+';'); -}); -output.push(''); - -// Stage 2: Get the transaction type IDs from TransactionFormats.h -var ttConsts = {}; -String(fs.readFileSync(filenameTxFormatsH)).split('\n').forEach(function (line) { - var regex = /tt([A-Z_]+)\s+=\s+([0-9-]+)/; - var match = line.match(regex); - if (match) ttConsts[match[1]] = +match[2]; -}); - -// Stage 3: Get the transaction formats from TransactionFormats.cpp -var base = [], - sections = [], - current = base; -String(fs.readFileSync(filenameTxFormats)).split('\n').forEach(function (line) { - line = line.replace(/^\s+|\s+$/g, '').replace(/\s+/g, ''); - - var d_regex = /DECLARE_TF\(([A-Za-z]+),tt([A-Z_]+)/; - var d_match = line.match(d_regex); - - var s_regex = /SOElement\(sf([a-z]+),SOE_(REQUIRED|OPTIONAL|DEFAULT)/i; - var s_match = line.match(s_regex); - - if (d_match) sections.push(current = [d_match[1], ttConsts[d_match[2]]]); - else if (s_match) current.push([s_match[1], s_match[2]]); -}); - -function removeFinalComma(arr) { - arr[arr.length-1] = arr[arr.length-1].slice(0, -1); -} - -output.push('var base = ['); -base.forEach(function (field) { - var spec = fields[field[0]]; - output.push(' [ '+ - pad("'"+field[0]+"'", 21)+', '+ - pad(field[1], 8)+', '+ - padl(""+spec[1], 2)+', '+ - 'ST.'+pad(spec[0], 3)+ - ' ],'); -}); -removeFinalComma(output); -output.push('];'); -output.push(''); - - -output.push('exports.tx = {'); -sections.forEach(function (section) { - var name = section.shift(), - ttid = section.shift(); - - output.push(' '+name+': ['+ttid+'].concat(base, ['); - section.forEach(function (field) { - var spec = fields[field[0]]; - output.push(' [ '+ - pad("'"+field[0]+"'", 21)+', '+ - pad(field[1], 8)+', '+ - padl(""+spec[1], 2)+', '+ - 'ST.'+pad(spec[0], 3)+ - ' ],'); - }); - removeFinalComma(output); - output.push(' ]),'); -}); -removeFinalComma(output); -output.push('};'); -output.push(''); - -console.log(output.join('\n')); - diff --git a/conanfile.py b/conanfile.py index 399c9d6e1f..ab4657277c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -117,7 +117,6 @@ class Xrpl(ConanFile): exports_sources = ( 'CMakeLists.txt', - 'bin/getRippledInfo', 'cfg/*', 'cmake/*', 'external/*', From abf12db788ccb6b5cae439872bf1d09b98a6c24b Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Mon, 11 Aug 2025 14:02:03 +0100 Subject: [PATCH 03/16] chore: Set CONAN_REMOTE_URL also for forks (#5662) This change replaces the configuration variable with the hardcoded `https://conan.ripplex.io`, making it possible for PRs from forks to use our Conan remote containing workarounds. --- .github/workflows/libxrpl.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/nix.yml | 2 +- .github/workflows/windows.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/libxrpl.yml b/.github/workflows/libxrpl.yml index 8223b7996f..40797ddee5 100644 --- a/.github/workflows/libxrpl.yml +++ b/.github/workflows/libxrpl.yml @@ -1,6 +1,6 @@ name: Check libXRPL compatibility with Clio env: - CONAN_REMOTE_URL: ${{ vars.CONAN_REMOTE_URL }} + CONAN_REMOTE_URL: https://conan.ripplex.io CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.CONAN_REMOTE_USERNAME }} CONAN_PASSWORD_XRPLF: ${{ secrets.CONAN_REMOTE_PASSWORD }} on: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 6c6091cc2e..3cbe4c4197 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -18,7 +18,7 @@ concurrency: # This part of Conan configuration is specific to this workflow only; we do not want # to pollute conan/profiles directory with settings which might not work for others env: - CONAN_REMOTE_URL: ${{ vars.CONAN_REMOTE_URL }} + CONAN_REMOTE_URL: https://conan.ripplex.io CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} # This part of the Conan configuration is specific to this workflow only; we diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 5beb5d291d..5ee5f317f2 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -17,7 +17,7 @@ concurrency: cancel-in-progress: true env: - CONAN_REMOTE_URL: ${{ vars.CONAN_REMOTE_URL }} + CONAN_REMOTE_URL: https://conan.ripplex.io CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} # This part of the Conan configuration is specific to this workflow only; we diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 9e2322b119..90446e8135 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -19,7 +19,7 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: - CONAN_REMOTE_URL: ${{ vars.CONAN_REMOTE_URL }} + CONAN_REMOTE_URL: https://conan.ripplex.io CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} # This part of the Conan configuration is specific to this workflow only; we From 97f0747e103f13e26e45b731731059b32f7679ac Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 11 Aug 2025 12:15:42 -0400 Subject: [PATCH 04/16] chore: Run prettier on all files (#5657) --- .clang-format | 81 +- .codecov.yml | 2 +- .github/ISSUE_TEMPLATE/bug_report.md | 13 +- .github/ISSUE_TEMPLATE/feature_request.md | 8 +- .github/workflows/libxrpl.yml | 6 +- .github/workflows/macos.yml | 5 +- .github/workflows/missing-commits.yml | 84 +- .github/workflows/nix.yml | 96 +- .github/workflows/windows.yml | 11 +- .pre-commit-config.yaml | 8 +- BUILD.md | 179 +- Builds/levelization/README.md | 68 +- CONTRIBUTING.md | 292 +- LICENSE.md | 3 +- README.md | 22 +- SECURITY.md | 14 +- docs/0001-negative-unl/README.md | 358 +- docs/0010-ledger-replay/README.md | 2 + docs/CheatSheet.md | 4 +- docs/CodingStyle.md | 66 +- docs/HeapProfiling.md | 3 +- docs/README.md | 22 +- docs/build/conan.md | 14 +- docs/build/depend.md | 5 +- docs/build/environment.md | 4 +- docs/build/install.md | 42 +- docs/consensus.md | 232 +- external/README.md | 10 +- external/antithesis-sdk/README.md | 7 +- external/ed25519-donna/README.md | 97 +- external/ed25519-donna/fuzz/README.md | 99 +- external/secp256k1/CHANGELOG.md | 144 +- external/secp256k1/CMakePresets.json | 6 +- external/secp256k1/CONTRIBUTING.md | 74 +- external/secp256k1/README.md | 130 +- external/secp256k1/SECURITY.md | 10 +- external/secp256k1/doc/ellswift.md | 410 +- external/secp256k1/doc/musig.md | 3 +- external/secp256k1/doc/release-process.md | 40 +- .../secp256k1/doc/safegcd_implementation.md | 301 +- .../ecdsa_secp256k1_sha256_bitcoin_test.json | 8086 ++++++++--------- include/xrpl/basics/README.md | 43 +- include/xrpl/proto/org/xrpl/rpc/v1/README.md | 1 - include/xrpl/protocol/README.md | 6 +- include/xrpl/resource/README.md | 32 +- src/test/README.md | 5 +- src/test/csf/README.md | 27 +- src/tests/README.md | 1 + src/xrpld/app/consensus/README.md | 15 +- src/xrpld/app/ledger/README.md | 249 +- src/xrpld/app/misc/FeeEscalation.md | 279 +- src/xrpld/app/misc/README.md | 34 +- src/xrpld/app/rdb/README.md | 46 +- src/xrpld/consensus/README.md | 5 +- src/xrpld/nodestore/README.md | 154 +- src/xrpld/overlay/README.md | 146 +- src/xrpld/peerfinder/README.md | 76 +- src/xrpld/rpc/README.md | 17 +- src/xrpld/shamap/README.md | 173 +- tests/README.md | 1 + 60 files changed, 6244 insertions(+), 6127 deletions(-) diff --git a/.clang-format b/.clang-format index 7b0fda27c9..cfd991e64b 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,5 @@ --- -Language: Cpp +Language: Cpp AccessModifierOffset: -4 AlignAfterOpenBracket: AlwaysBreak AlignConsecutiveAssignments: false @@ -19,52 +19,52 @@ AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false BraceWrapping: - AfterClass: true + AfterClass: true AfterControlStatement: true - AfterEnum: false - AfterFunction: true - AfterNamespace: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false AfterObjCDeclaration: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false BreakBeforeBinaryOperators: false BreakBeforeBraces: Custom BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: true -ColumnLimit: 80 -CommentPragmas: '^ IWYU pragma:' +ColumnLimit: 80 +CommentPragmas: "^ IWYU pragma:" ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DerivePointerAlignment: false -DisableFormat: false +DisableFormat: false ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ Q_FOREACH, BOOST_FOREACH ] -IncludeBlocks: Regroup +ForEachMacros: [Q_FOREACH, BOOST_FOREACH] +IncludeBlocks: Regroup IncludeCategories: - - Regex: '^<(test)/' - Priority: 0 - - Regex: '^<(xrpld)/' - Priority: 1 - - Regex: '^<(xrpl)/' - Priority: 2 - - Regex: '^<(boost)/' - Priority: 3 - - Regex: '^.*/' - Priority: 4 - - Regex: '^.*\.h' - Priority: 5 - - Regex: '.*' - Priority: 6 -IncludeIsMainRegex: '$' + - Regex: "^<(test)/" + Priority: 0 + - Regex: "^<(xrpld)/" + Priority: 1 + - Regex: "^<(xrpl)/" + Priority: 2 + - Regex: "^<(boost)/" + Priority: 3 + - Regex: "^.*/" + Priority: 4 + - Regex: '^.*\.h' + Priority: 5 + - Regex: ".*" + Priority: 6 +IncludeIsMainRegex: "$" IndentCaseLabels: true IndentFunctionDeclarationAfterType: false IndentRequiresClause: true -IndentWidth: 4 +IndentWidth: 4 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: false MaxEmptyLinesToKeep: 1 @@ -78,20 +78,25 @@ PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left -ReflowComments: true +ReflowComments: true RequiresClausePosition: OwnLine -SortIncludes: true +SortIncludes: true SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 -SpacesInAngles: false +SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 8 -UseTab: Never -QualifierAlignment: Right \ No newline at end of file +Standard: Cpp11 +TabWidth: 8 +UseTab: Never +QualifierAlignment: Right +--- +Language: JavaScript +--- +Language: Json +IndentWidth: 2 diff --git a/.codecov.yml b/.codecov.yml index b97039e8b6..d28d7c80df 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -27,7 +27,7 @@ github_checks: parsers: cobertura: partials_as_hits: true - handle_missing_conditions : true + handle_missing_conditions: true slack_app: false diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e2df996005..cc921f5a55 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,30 +2,35 @@ name: Bug Report about: Create a report to help us improve rippled title: "[Title with short description] (Version: [rippled version])" -labels: '' -assignees: '' - +labels: "" +assignees: "" --- + ## Issue Description + ## Steps to Reproduce + ## Expected Result + ## Actual Result + ## Environment + ## Supporting Files + - diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 2e19746f52..967b3c1817 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -3,19 +3,23 @@ name: Feature Request about: Suggest a new feature for the rippled project title: "[Title with short description] (Version: [rippled version])" labels: Feature Request -assignees: '' - +assignees: "" --- + ## Summary + ## Motivation + ## Solution + ## Paths Not Taken + diff --git a/.github/workflows/libxrpl.yml b/.github/workflows/libxrpl.yml index 40797ddee5..5880c03d71 100644 --- a/.github/workflows/libxrpl.yml +++ b/.github/workflows/libxrpl.yml @@ -6,8 +6,8 @@ env: on: pull_request: paths: - - 'src/libxrpl/protocol/BuildInfo.cpp' - - '.github/workflows/libxrpl.yml' + - "src/libxrpl/protocol/BuildInfo.cpp" + - ".github/workflows/libxrpl.yml" types: [opened, reopened, synchronize, ready_for_review] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -29,7 +29,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha || github.sha }} running-workflow-name: wait-for-check-regexp - check-regexp: '(dependencies|test).*linux.*' # Ignore windows and mac tests but make sure linux passes + check-regexp: "(dependencies|test).*linux.*" # Ignore windows and mac tests but make sure linux passes repo-token: ${{ secrets.GITHUB_TOKEN }} wait-interval: 10 - name: Checkout diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 3cbe4c4197..73e25c357f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -11,7 +11,7 @@ on: - release - master # Branches that opt-in to running - - 'ci/**' + - "ci/**" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true @@ -32,7 +32,6 @@ env: tools.compilation:verbosity=verbose jobs: - test: if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} strategy: @@ -89,7 +88,7 @@ jobs: sysctl -n hw.logicalcpu clang --version - name: configure Conan - run : | + run: | echo "${CONAN_GLOBAL_CONF}" > $(conan config home)/global.conf conan config install conan/profiles/ -tf $(conan config home)/profiles/ conan profile show diff --git a/.github/workflows/missing-commits.yml b/.github/workflows/missing-commits.yml index 8715671f33..ed478a2327 100644 --- a/.github/workflows/missing-commits.yml +++ b/.github/workflows/missing-commits.yml @@ -12,49 +12,49 @@ jobs: up_to_date: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Check for missing commits - id: commits - env: - SUGGESTION: | + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Check for missing commits + id: commits + env: + SUGGESTION: | - If you are reading this, then the commits indicated above are - missing from "develop" and/or "release". Do a reverse-merge - as soon as possible. See CONTRIBUTING.md for instructions. - run: | - set -o pipefail - # Branches ordered by how "canonical" they are. Every commit in - # one branch should be in all the branches behind it - order=( master release develop ) - branches=() - for branch in "${order[@]}" - do - # Check that the branches exist so that this job will work on - # forked repos, which don't necessarily have master and - # release branches. - if git ls-remote --exit-code --heads origin \ - refs/heads/${branch} > /dev/null - then - branches+=( origin/${branch} ) - fi - done + If you are reading this, then the commits indicated above are + missing from "develop" and/or "release". Do a reverse-merge + as soon as possible. See CONTRIBUTING.md for instructions. + run: | + set -o pipefail + # Branches ordered by how "canonical" they are. Every commit in + # one branch should be in all the branches behind it + order=( master release develop ) + branches=() + for branch in "${order[@]}" + do + # Check that the branches exist so that this job will work on + # forked repos, which don't necessarily have master and + # release branches. + if git ls-remote --exit-code --heads origin \ + refs/heads/${branch} > /dev/null + then + branches+=( origin/${branch} ) + fi + done - prior=() - for branch in "${branches[@]}" - do - if [[ ${#prior[@]} -ne 0 ]] + prior=() + for branch in "${branches[@]}" + do + if [[ ${#prior[@]} -ne 0 ]] + then + echo "Checking ${prior[@]} for commits missing from ${branch}" + git log --oneline --no-merges "${prior[@]}" \ + ^$branch | tee -a "missing-commits.txt" + echo + fi + prior+=( "${branch}" ) + done + if [[ $( cat missing-commits.txt | wc -l ) -ne 0 ]] then - echo "Checking ${prior[@]} for commits missing from ${branch}" - git log --oneline --no-merges "${prior[@]}" \ - ^$branch | tee -a "missing-commits.txt" - echo + echo "${SUGGESTION}" + exit 1 fi - prior+=( "${branch}" ) - done - if [[ $( cat missing-commits.txt | wc -l ) -ne 0 ]] - then - echo "${SUGGESTION}" - exit 1 - fi diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 5ee5f317f2..395bd72b8d 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -364,59 +364,59 @@ jobs: env: build_dir: .build steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: linux-clang-Debug + - name: download cache + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 + with: + name: linux-clang-Debug - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} + - name: extract cache + run: | + mkdir -p ${CONAN_HOME} + tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - env | sort - ls ${CONAN_HOME} + - name: check environment + run: | + echo ${PATH} | tr ':' '\n' + conan --version + cmake --version + env | sort + ls ${CONAN_HOME} - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - name: checkout + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: Debug + - name: dependencies + uses: ./.github/actions/dependencies + with: + configuration: Debug - - name: prepare environment - run: | - mkdir -p ${build_dir} - echo "SOURCE_DIR=$(pwd)" >> $GITHUB_ENV - echo "BUILD_DIR=$(pwd)/${build_dir}" >> $GITHUB_ENV + - name: prepare environment + run: | + mkdir -p ${build_dir} + echo "SOURCE_DIR=$(pwd)" >> $GITHUB_ENV + echo "BUILD_DIR=$(pwd)/${build_dir}" >> $GITHUB_ENV - - name: build with instrumentation - run: | - cd ${BUILD_DIR} - cmake -S ${SOURCE_DIR} -B ${BUILD_DIR} \ - -Dvoidstar=ON \ - -Dtests=ON \ - -Dxrpld=ON \ - -DCMAKE_BUILD_TYPE=Debug \ - -DSECP256K1_BUILD_BENCHMARK=OFF \ - -DSECP256K1_BUILD_TESTS=OFF \ - -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \ - -DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/build/generators/conan_toolchain.cmake - cmake --build . --parallel $(nproc) + - name: build with instrumentation + run: | + cd ${BUILD_DIR} + cmake -S ${SOURCE_DIR} -B ${BUILD_DIR} \ + -Dvoidstar=ON \ + -Dtests=ON \ + -Dxrpld=ON \ + -DCMAKE_BUILD_TYPE=Debug \ + -DSECP256K1_BUILD_BENCHMARK=OFF \ + -DSECP256K1_BUILD_TESTS=OFF \ + -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \ + -DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/build/generators/conan_toolchain.cmake + cmake --build . --parallel $(nproc) - - name: verify instrumentation enabled - run: | - cd ${BUILD_DIR} - ./rippled --version | grep libvoidstar + - name: verify instrumentation enabled + run: | + cd ${BUILD_DIR} + ./rippled --version | grep libvoidstar - - name: run unit tests - run: | - cd ${BUILD_DIR} - ./rippled -u --unittest-jobs $(( $(nproc)/4 )) - ctest -j $(nproc) --output-on-failure + - name: run unit tests + run: | + cd ${BUILD_DIR} + ./rippled -u --unittest-jobs $(( $(nproc)/4 )) + ctest -j $(nproc) --output-on-failure diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 90446e8135..b81ffc8d3a 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ on: - release - master # Branches that opt-in to running - - 'ci/**' + - "ci/**" # https://docs.github.com/en/actions/using-jobs/using-concurrency concurrency: @@ -33,7 +33,6 @@ env: tools.compilation:verbosity=verbose jobs: - test: if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} strategy: @@ -69,8 +68,8 @@ jobs: - name: restore Python cache directory uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 with: - path: ${{ steps.pip-cache.outputs.dir }} - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/windows.yml') }} + path: ${{ steps.pip-cache.outputs.dir }} + key: ${{ runner.os }}-${{ hashFiles('.github/workflows/windows.yml') }} - name: install Conan run: pip install wheel conan - name: check environment @@ -93,10 +92,10 @@ jobs: - name: build uses: ./.github/actions/build with: - generator: '${{ matrix.version.generator }}' + generator: "${{ matrix.version.generator }}" configuration: ${{ matrix.configuration.type }} # Hard code for now. Move to the matrix if varied options are needed - cmake-args: '-Dassert=TRUE -Dwerr=TRUE -Dreporting=OFF -Dunity=ON' + cmake-args: "-Dassert=TRUE -Dwerr=TRUE -Dreporting=OFF -Dunity=ON" cmake-target: install - name: test shell: bash diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index abfbd887c7..7daecdb5ec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ # .pre-commit-config.yaml repos: -- repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.8 - hooks: - - id: clang-format + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v18.1.8 + hooks: + - id: clang-format diff --git a/BUILD.md b/BUILD.md index e1567e297c..958bf19b8c 100644 --- a/BUILD.md +++ b/BUILD.md @@ -41,21 +41,23 @@ found here](./docs/build/environment.md). - [Conan 2.17](https://conan.io/downloads.html)[^1], or higher - [CMake 3.22](https://cmake.org/download/)[^2], or higher -[^1]: It is possible to build with Conan 1.60+, but the instructions are -significantly different, which is why we are not recommending it. +[^1]: + It is possible to build with Conan 1.60+, but the instructions are + significantly different, which is why we are not recommending it. -[^2]: CMake 4 is not yet supported by all dependencies required by this project. -If you are affected by this issue, follow [conan workaround for cmake -4](#workaround-for-cmake-4) +[^2]: + CMake 4 is not yet supported by all dependencies required by this project. + If you are affected by this issue, follow [conan workaround for cmake + 4](#workaround-for-cmake-4) `rippled` is written in the C++20 dialect and includes the `` header. The [minimum compiler versions][2] required are: -| Compiler | Version | -|-------------|-----| -| GCC | 12 | -| Clang | 16 | -| Apple Clang | 16 | +| Compiler | Version | +| ----------- | --------- | +| GCC | 12 | +| Clang | 16 | +| Apple Clang | 16 | | MSVC | 19.44[^3] | ### Linux @@ -92,6 +94,7 @@ unfamiliar with Conan, then please read [this crash course](./docs/build/conan.m [Getting Started][3] walkthrough. #### Default profile + We recommend that you import the provided `conan/profiles/default` profile: ```bash @@ -173,10 +176,34 @@ you need to amend the list of compiler versions in to the `version` array specific for your compiler. For example: ```yaml - apple-clang: - version: ["5.0", "5.1", "6.0", "6.1", "7.0", "7.3", "8.0", "8.1", "9.0", - "9.1", "10.0", "11.0", "12.0", "13", "13.0", "13.1", "14", - "14.0", "15", "15.0", "16", "16.0", "17", "17.0"] +apple-clang: + version: + [ + "5.0", + "5.1", + "6.0", + "6.1", + "7.0", + "7.3", + "8.0", + "8.1", + "9.0", + "9.1", + "10.0", + "11.0", + "12.0", + "13", + "13.0", + "13.1", + "14", + "14.0", + "15", + "15.0", + "16", + "16.0", + "17", + "17.0", + ] ``` #### Multiple compilers @@ -189,11 +216,11 @@ For example, if you are running MacOS and have [homebrew LLVM@18](https://formulae.brew.sh/formula/llvm@18), and want to use it as a compiler in the new Conan profile: - ```bash - export CC=$(brew --prefix llvm@18)/bin/clang - export CXX=$(brew --prefix llvm@18)/bin/clang++ - conan profile detect - ``` +```bash +export CC=$(brew --prefix llvm@18)/bin/clang +export CXX=$(brew --prefix llvm@18)/bin/clang++ +conan profile detect +``` You should also explicitly set the path to the compiler in the profile file, which helps to avoid errors when `CC` and/or `CXX` are set and disagree with the @@ -343,61 +370,61 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS'] 2. Use conan to generate CMake files for every configuration you want to build: - ``` - conan install .. --output-folder . --build missing --settings build_type=Release - conan install .. --output-folder . --build missing --settings build_type=Debug - ``` + ``` + conan install .. --output-folder . --build missing --settings build_type=Release + conan install .. --output-folder . --build missing --settings build_type=Debug + ``` - To build Debug, in the next step, be sure to set `-DCMAKE_BUILD_TYPE=Debug` + To build Debug, in the next step, be sure to set `-DCMAKE_BUILD_TYPE=Debug` - For a single-configuration generator, e.g. `Unix Makefiles` or `Ninja`, - you only need to run this command once. - For a multi-configuration generator, e.g. `Visual Studio`, you may want to - run it more than once. + For a single-configuration generator, e.g. `Unix Makefiles` or `Ninja`, + you only need to run this command once. + For a multi-configuration generator, e.g. `Visual Studio`, you may want to + run it more than once. - Each of these commands should also have a different `build_type` setting. - A second command with the same `build_type` setting will overwrite the files - generated by the first. You can pass the build type on the command line with - `--settings build_type=$BUILD_TYPE` or in the profile itself, - under the section `[settings]` with the key `build_type`. + Each of these commands should also have a different `build_type` setting. + A second command with the same `build_type` setting will overwrite the files + generated by the first. You can pass the build type on the command line with + `--settings build_type=$BUILD_TYPE` or in the profile itself, + under the section `[settings]` with the key `build_type`. - If you are using a Microsoft Visual C++ compiler, - then you will need to ensure consistency between the `build_type` setting - and the `compiler.runtime` setting. + If you are using a Microsoft Visual C++ compiler, + then you will need to ensure consistency between the `build_type` setting + and the `compiler.runtime` setting. - When `build_type` is `Release`, `compiler.runtime` should be `MT`. + When `build_type` is `Release`, `compiler.runtime` should be `MT`. - When `build_type` is `Debug`, `compiler.runtime` should be `MTd`. + When `build_type` is `Debug`, `compiler.runtime` should be `MTd`. - ``` - conan install .. --output-folder . --build missing --settings build_type=Release --settings compiler.runtime=MT - conan install .. --output-folder . --build missing --settings build_type=Debug --settings compiler.runtime=MTd - ``` + ``` + conan install .. --output-folder . --build missing --settings build_type=Release --settings compiler.runtime=MT + conan install .. --output-folder . --build missing --settings build_type=Debug --settings compiler.runtime=MTd + ``` 3. Configure CMake and pass the toolchain file generated by Conan, located at `$OUTPUT_FOLDER/build/generators/conan_toolchain.cmake`. - Single-config generators: + Single-config generators: - Pass the CMake variable [`CMAKE_BUILD_TYPE`][build_type] - and make sure it matches the one of the `build_type` settings - you chose in the previous step. + Pass the CMake variable [`CMAKE_BUILD_TYPE`][build_type] + and make sure it matches the one of the `build_type` settings + you chose in the previous step. - For example, to build Debug, in the next command, replace "Release" with "Debug" + For example, to build Debug, in the next command, replace "Release" with "Debug" - ``` - cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -Dxrpld=ON -Dtests=ON .. - ``` + ``` + cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -Dxrpld=ON -Dtests=ON .. + ``` - Multi-config generators: + Multi-config generators: - ``` - cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -Dxrpld=ON -Dtests=ON .. - ``` + ``` + cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -Dxrpld=ON -Dtests=ON .. + ``` - **Note:** You can pass build options for `rippled` in this step. + **Note:** You can pass build options for `rippled` in this step. -5. Build `rippled`. +4. Build `rippled`. For a single-configuration generator, it will build whatever configuration you passed for `CMAKE_BUILD_TYPE`. For a multi-configuration generator, you @@ -416,7 +443,7 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS'] cmake --build . --config Debug ``` -6. Test rippled. +5. Test rippled. Single-config generators: @@ -438,7 +465,6 @@ tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS'] The location of `rippled` binary in your build directory depends on your CMake generator. Pass `--help` to see the rest of the command line options. - ## Coverage report The coverage report is intended for developers using compilers GCC @@ -478,7 +504,7 @@ variable in `cmake`. The specific command line used to run the `gcovr` tool will displayed if the `CODE_COVERAGE_VERBOSE` variable is set. By default, the code coverage tool runs parallel unit tests with `--unittest-jobs` - set to the number of available CPU cores. This may cause spurious test +set to the number of available CPU cores. This may cause spurious test errors on Apple. Developers can override the number of unit test jobs with the `coverage_test_parallelism` variable in `cmake`. @@ -497,26 +523,24 @@ stored inside the build directory, as either of: - file named `coverage.`_extension_, with a suitable extension for the report format, or - directory named `coverage`, with the `index.html` and other files inside, for the `html-details` or `html-nested` report formats. - ## Options -| Option | Default Value | Description | -| --- | ---| ---| -| `assert` | OFF | Enable assertions. | -| `coverage` | OFF | Prepare the coverage report. | -| `san` | N/A | Enable a sanitizer with Clang. Choices are `thread` and `address`. | -| `tests` | OFF | Build tests. | -| `unity` | OFF | Configure a unity build. | -| `xrpld` | OFF | Build the xrpld (`rippled`) application, and not just the libxrpl library. | -| `werr` | OFF | Treat compilation warnings as errors | -| `wextra` | OFF | Enable additional compilation warnings | +| Option | Default Value | Description | +| ---------- | ------------- | -------------------------------------------------------------------------- | +| `assert` | OFF | Enable assertions. | +| `coverage` | OFF | Prepare the coverage report. | +| `san` | N/A | Enable a sanitizer with Clang. Choices are `thread` and `address`. | +| `tests` | OFF | Build tests. | +| `unity` | OFF | Configure a unity build. | +| `xrpld` | OFF | Build the xrpld (`rippled`) application, and not just the libxrpl library. | +| `werr` | OFF | Treat compilation warnings as errors | +| `wextra` | OFF | Enable additional compilation warnings | [Unity builds][5] may be faster for the first build (at the cost of much more memory) since they concatenate sources into fewer translation units. Non-unity builds may be faster for incremental builds, and can be helpful for detecting `#include` omissions. - ## Troubleshooting ### Conan @@ -565,16 +589,15 @@ If you want to experiment with a new package, follow these steps: 1. Search for the package on [Conan Center](https://conan.io/center/). 2. Modify [`conanfile.py`](./conanfile.py): - - Add a version of the package to the `requires` property. - - Change any default options for the package by adding them to the - `default_options` property (with syntax `'$package:$option': $value`). + - Add a version of the package to the `requires` property. + - Change any default options for the package by adding them to the + `default_options` property (with syntax `'$package:$option': $value`). 3. Modify [`CMakeLists.txt`](./CMakeLists.txt): - - Add a call to `find_package($package REQUIRED)`. - - Link a library from the package to the target `ripple_libs` - (search for the existing call to `target_link_libraries(ripple_libs INTERFACE ...)`). + - Add a call to `find_package($package REQUIRED)`. + - Link a library from the package to the target `ripple_libs` + (search for the existing call to `target_link_libraries(ripple_libs INTERFACE ...)`). 4. Start coding! Don't forget to include whatever headers you need from the package. - [1]: https://github.com/conan-io/conan-center-index/issues/13168 [2]: https://en.cppreference.com/w/cpp/compiler_support/20 [3]: https://docs.conan.io/en/latest/getting_started.html diff --git a/Builds/levelization/README.md b/Builds/levelization/README.md index 4ff3a54236..93aa316b61 100644 --- a/Builds/levelization/README.md +++ b/Builds/levelization/README.md @@ -25,28 +25,28 @@ more dependencies listed later. **tl;dr:** The modules listed first are more independent than the modules listed later. -| Level / Tier | Module(s) | -|--------------|-----------------------------------------------| -| 01 | ripple/beast ripple/unity -| 02 | ripple/basics -| 03 | ripple/json ripple/crypto -| 04 | ripple/protocol -| 05 | ripple/core ripple/conditions ripple/consensus ripple/resource ripple/server -| 06 | ripple/peerfinder ripple/ledger ripple/nodestore ripple/net -| 07 | ripple/shamap ripple/overlay -| 08 | ripple/app -| 09 | ripple/rpc -| 10 | ripple/perflog -| 11 | test/jtx test/beast test/csf -| 12 | test/unit_test -| 13 | test/crypto test/conditions test/json test/resource test/shamap test/peerfinder test/basics test/overlay -| 14 | test -| 15 | test/net test/protocol test/ledger test/consensus test/core test/server test/nodestore -| 16 | test/rpc test/app +| Level / Tier | Module(s) | +| ------------ | -------------------------------------------------------------------------------------------------------- | +| 01 | ripple/beast ripple/unity | +| 02 | ripple/basics | +| 03 | ripple/json ripple/crypto | +| 04 | ripple/protocol | +| 05 | ripple/core ripple/conditions ripple/consensus ripple/resource ripple/server | +| 06 | ripple/peerfinder ripple/ledger ripple/nodestore ripple/net | +| 07 | ripple/shamap ripple/overlay | +| 08 | ripple/app | +| 09 | ripple/rpc | +| 10 | ripple/perflog | +| 11 | test/jtx test/beast test/csf | +| 12 | test/unit_test | +| 13 | test/crypto test/conditions test/json test/resource test/shamap test/peerfinder test/basics test/overlay | +| 14 | test | +| 15 | test/net test/protocol test/ledger test/consensus test/core test/server test/nodestore | +| 16 | test/rpc test/app | -(Note that `test` levelization is *much* less important and *much* less +(Note that `test` levelization is _much_ less important and _much_ less strictly enforced than `ripple` levelization, other than the requirement -that `test` code should *never* be included in `ripple` code.) +that `test` code should _never_ be included in `ripple` code.) ## Validation @@ -59,48 +59,48 @@ the rippled source. The only caveat is that it runs much slower under Windows than in Linux. It hasn't yet been tested under MacOS. It generates many files of [results](results): -* `rawincludes.txt`: The raw dump of the `#includes` -* `paths.txt`: A second dump grouping the source module +- `rawincludes.txt`: The raw dump of the `#includes` +- `paths.txt`: A second dump grouping the source module to the destination module, deduped, and with frequency counts. -* `includes/`: A directory where each file represents a module and +- `includes/`: A directory where each file represents a module and contains a list of modules and counts that the module _includes_. -* `includedby/`: Similar to `includes/`, but the other way around. Each +- `includedby/`: Similar to `includes/`, but the other way around. Each file represents a module and contains a list of modules and counts that _include_ the module. -* [`loops.txt`](results/loops.txt): A list of direct loops detected +- [`loops.txt`](results/loops.txt): A list of direct loops detected between modules as they actually exist, as opposed to how they are desired as described above. In a perfect repo, this file will be empty. This file is committed to the repo, and is used by the [levelization Github workflow](../../.github/workflows/levelization.yml) to validate that nothing changed. -* [`ordering.txt`](results/ordering.txt): A list showing relationships +- [`ordering.txt`](results/ordering.txt): A list showing relationships between modules where there are no loops as they actually exist, as opposed to how they are desired as described above. This file is committed to the repo, and is used by the [levelization Github workflow](../../.github/workflows/levelization.yml) to validate that nothing changed. -* [`levelization.yml`](../../.github/workflows/levelization.yml) +- [`levelization.yml`](../../.github/workflows/levelization.yml) Github Actions workflow to test that levelization loops haven't - changed. Unfortunately, if changes are detected, it can't tell if + changed. Unfortunately, if changes are detected, it can't tell if they are improvements or not, so if you have resolved any issues or done anything else to improve levelization, run `levelization.sh`, and commit the updated results. -The `loops.txt` and `ordering.txt` files relate the modules +The `loops.txt` and `ordering.txt` files relate the modules using comparison signs, which indicate the number of times each module is included in the other. -* `A > B` means that A should probably be at a higher level than B, +- `A > B` means that A should probably be at a higher level than B, because B is included in A significantly more than A is included in B. These results can be included in both `loops.txt` and `ordering.txt`. Because `ordering.txt`only includes relationships where B is not included in A at all, it will only include these types of results. -* `A ~= B` means that A and B are included in each other a different +- `A ~= B` means that A and B are included in each other a different number of times, but the values are so close that the script can't definitively say that one should be above the other. These results will only be included in `loops.txt`. -* `A == B` means that A and B include each other the same number of +- `A == B` means that A and B include each other the same number of times, so the script has no clue which should be higher. These results will only be included in `loops.txt`. @@ -110,5 +110,5 @@ get those details locally. 1. Run `levelization.sh` 2. Grep the modules in `paths.txt`. - * For example, if a cycle is found `A ~= B`, simply `grep -w - A Builds/levelization/results/paths.txt | grep -w B` + - For example, if a cycle is found `A ~= B`, simply `grep -w +A Builds/levelization/results/paths.txt | grep -w B` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb3eb6f048..fb29de5b7e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,13 +8,12 @@ We assume you are familiar with the general practice of [making contributions on GitHub][contrib]. This file includes only special instructions specific to this project. - ## Before you start The following branches exist in the main project repository: - `develop`: The latest set of unreleased features, and the most common - starting point for contributions. + starting point for contributions. - `release`: The latest beta release or release candidate. - `master`: The latest stable release. - `gh-pages`: The documentation for this project, built by Doxygen. @@ -27,18 +26,18 @@ In general, external contributions should be developed in your personal [fork][forking]. Contributions from developers with write permissions should be done in [the main repository][rippled] in a branch with a permitted prefix. Permitted prefixes are: -* XLS-[a-zA-Z0-9]+/.+ - * e.g. XLS-0033d/mpt-clarify-STEitherAmount -* [GitHub username]/.+ - * e.g. JoelKatz/fix-rpc-webhook-queue -* [Organization name]/.+ - * e.g. ripple/antithesis -Regardless of where the branch is created, please open a *draft* pull +- XLS-[a-zA-Z0-9]+/.+ + - e.g. XLS-0033d/mpt-clarify-STEitherAmount +- [GitHub username]/.+ + - e.g. JoelKatz/fix-rpc-webhook-queue +- [Organization name]/.+ + - e.g. ripple/antithesis + +Regardless of where the branch is created, please open a _draft_ pull request as soon as possible after pushing the branch to Github, to increase visibility, and ease feedback during the development process. - ## Major contributions If your contribution is a major feature or breaking change, then you @@ -55,8 +54,8 @@ responsibility of the XLS author to update the draft to match the final implementation when its corresponding pull request is merged, unless the author delegates that responsibility to others. - ## Before making a pull request + (Or marking a draft pull request as ready.) Changes that alter transaction processing must be guarded by an @@ -73,11 +72,12 @@ automatic test run by `rippled --unittest`. Otherwise, it must be a manual test. If you create new source files, they must be organized as follows: -* If the files are in any of the `libxrpl` modules, the headers (`.h`) must go + +- If the files are in any of the `libxrpl` modules, the headers (`.h`) must go under `include/xrpl`, and source (`.cpp`) files must go under `src/libxrpl`. -* All other non-test files must go under `src/xrpld`. -* All test source files must go under `src/test`. +- All other non-test files must go under `src/xrpld`. +- All test source files must go under `src/test`. The source must be formatted according to the style guide below. @@ -87,16 +87,17 @@ Changes should be usually squashed down into a single commit. Some larger or more complicated change sets make more sense, and are easier to review if organized into multiple logical commits. Either way, all commits should fit the following criteria: -* Changes should be presented in a single commit or a logical + +- Changes should be presented in a single commit or a logical sequence of commits. Specifically, chronological commits that simply reflect the history of how the author implemented the change, "warts and all", are not useful to reviewers. -* Every commit should have a [good message](#good-commit-messages). +- Every commit should have a [good message](#good-commit-messages). to explain a specific aspects of the change. -* Every commit should be signed. -* Every commit should be well-formed (builds successfully, +- Every commit should be signed. +- Every commit should be well-formed (builds successfully, unit tests passing), as this helps to resolve merge conflicts, and makes it easier to use `git bisect` to find bugs. @@ -108,13 +109,14 @@ Refer to for general rules on writing a good commit message. tl;dr + > 1. Separate subject from body with a blank line. > 2. Limit the subject line to 50 characters. -> * [...]shoot for 50 characters, but consider 72 the hard limit. +> - [...]shoot for 50 characters, but consider 72 the hard limit. > 3. Capitalize the subject line. > 4. Do not end the subject line with a period. > 5. Use the imperative mood in the subject line. -> * A properly formed Git commit subject line should always be able +> - A properly formed Git commit subject line should always be able > to complete the following sentence: "If applied, this commit will > _your subject line here_". > 6. Wrap the body at 72 characters. @@ -122,16 +124,17 @@ tl;dr In addition to those guidelines, please add one of the following prefixes to the subject line if appropriate. -* `fix:` - The primary purpose is to fix an existing bug. -* `perf:` - The primary purpose is performance improvements. -* `refactor:` - The changes refactor code without affecting + +- `fix:` - The primary purpose is to fix an existing bug. +- `perf:` - The primary purpose is performance improvements. +- `refactor:` - The changes refactor code without affecting functionality. -* `test:` - The changes _only_ affect unit tests. -* `docs:` - The changes _only_ affect documentation. This can +- `test:` - The changes _only_ affect unit tests. +- `docs:` - The changes _only_ affect documentation. This can include code comments in addition to `.md` files like this one. -* `build:` - The changes _only_ affect the build process, +- `build:` - The changes _only_ affect the build process, including CMake and/or Conan settings. -* `chore:` - Other tasks that don't affect the binary, but don't fit +- `chore:` - Other tasks that don't affect the binary, but don't fit any of the other cases. e.g. formatting, git settings, updating Github Actions jobs. @@ -143,9 +146,10 @@ unit tests for Feature X (#1234)`. In general, pull requests use `develop` as the base branch. The exceptions are -* Fixes and improvements to a release candidate use `release` as the + +- Fixes and improvements to a release candidate use `release` as the base. -* Hotfixes use `master` as the base. +- Hotfixes use `master` as the base. If your changes are not quite ready, but you want to make it easily available for preliminary examination or review, you can create a "Draft" pull request. @@ -182,11 +186,11 @@ meets a few criteria: 2. All CI checks must be complete and passed. (One-off failures may be acceptable if they are related to a known issue.) 3. The PR must have a [good commit message](#good-commit-messages). - * If the PR started with a good commit message, and it doesn't + - If the PR started with a good commit message, and it doesn't need to be updated, the author can indicate that in a comment. - * Any contributor, preferably the author, can leave a comment + - Any contributor, preferably the author, can leave a comment suggesting a commit message. - * If the author squashes and rebases the code in preparation for + - If the author squashes and rebases the code in preparation for merge, they should also ensure the commit message(s) are updated as well. 4. The PR branch must be up to date with the base branch (usually @@ -208,7 +212,6 @@ This is a non-exhaustive list of recommended style guidelines. These are not always strictly enforced and serve as a way to keep the codebase coherent rather than a set of _thou shalt not_ commandments. - ## Formatting All code must conform to `clang-format` version 18, @@ -237,6 +240,7 @@ To download the patch file: 5. Commit and push. You can install a pre-commit hook to automatically run `clang-format` before every commit: + ``` pip3 install pre-commit pre-commit install @@ -267,49 +271,51 @@ locations, where the reporting of contract violations on the Antithesis platform is either not possible or not useful. For this reason: -* The locations where `assert` or `assert(false)` contracts should continue to be used: - * `constexpr` functions - * unit tests i.e. files under `src/test` - * unit tests-related modules (files under `beast/test` and `beast/unit_test`) -* Outside of the listed locations, do not use `assert`; use `XRPL_ASSERT` instead, + +- The locations where `assert` or `assert(false)` contracts should continue to be used: + - `constexpr` functions + - unit tests i.e. files under `src/test` + - unit tests-related modules (files under `beast/test` and `beast/unit_test`) +- Outside of the listed locations, do not use `assert`; use `XRPL_ASSERT` instead, giving it unique name, with the short description of the contract. -* Outside of the listed locations, do not use `assert(false)`; use +- Outside of the listed locations, do not use `assert(false)`; use `UNREACHABLE` instead, giving it unique name, with the description of the condition being violated -* The contract name should start with a full name (including scope) of the - function, optionally a named lambda, followed by a colon ` : ` and a brief +- The contract name should start with a full name (including scope) of the + function, optionally a named lambda, followed by a colon `:` and a brief (typically at most five words) description. `UNREACHABLE` contracts can use slightly longer descriptions. If there are multiple overloads of the function, use common sense to balance both brevity and unambiguity of the function name. NOTE: the purpose of name is to provide stable means of unique identification of every contract; for this reason try to avoid elements which can change in some obvious refactors or when reinforcing the condition. -* Contract description typically (except for `UNREACHABLE`) should describe the +- Contract description typically (except for `UNREACHABLE`) should describe the _expected_ condition, as in "I assert that _expected_ is true". -* Contract description for `UNREACHABLE` should describe the _unexpected_ +- Contract description for `UNREACHABLE` should describe the _unexpected_ situation which caused the line to have been reached. -* Example good name for an +- Example good name for an `UNREACHABLE` macro `"Json::operator==(Value, Value) : invalid type"`; example good name for an `XRPL_ASSERT` macro `"Json::Value::asCString : valid type"`. -* Example **bad** name +- Example **bad** name `"RFC1751::insert(char* s, int x, int start, int length) : length is greater than or equal zero"` (missing namespace, unnecessary full function signature, description too verbose). Good name: `"ripple::RFC1751::insert : minimum length"`. -* In **few** well-justified cases a non-standard name can be used, in which case a +- In **few** well-justified cases a non-standard name can be used, in which case a comment should be placed to explain the rationale (example in `contract.cpp`) -* Do **not** rename a contract without a good reason (e.g. the name no longer +- Do **not** rename a contract without a good reason (e.g. the name no longer reflects the location or the condition being checked) -* Do not use `std::unreachable` -* Do not put contracts where they can be violated by an external condition +- Do not use `std::unreachable` +- Do not put contracts where they can be violated by an external condition (e.g. timing, data payload before mandatory validation etc.) as this creates bogus bug reports (and causes crashes of Debug builds) ## Unit Tests + To execute all unit tests: -```rippled --unittest --unittest-jobs=``` +`rippled --unittest --unittest-jobs=` -(Note: Using multiple cores on a Mac M1 can cause spurious test failures. The +(Note: Using multiple cores on a Mac M1 can cause spurious test failures. The cause is still under investigation. If you observe this problem, try specifying fewer jobs.) To run a specific set of test suites: @@ -317,10 +323,11 @@ To run a specific set of test suites: ``` rippled --unittest TestSuiteName ``` + Note: In this example, all tests with prefix `TestSuiteName` will be run, so if -`TestSuiteName1` and `TestSuiteName2` both exist, then both tests will run. -Alternatively, if the unit test name finds an exact match, it will stop -doing partial matches, i.e. if a unit test with a title of `TestSuiteName` +`TestSuiteName1` and `TestSuiteName2` both exist, then both tests will run. +Alternatively, if the unit test name finds an exact match, it will stop +doing partial matches, i.e. if a unit test with a title of `TestSuiteName` exists, then no other unit test will be executed, apart from `TestSuiteName`. ## Avoid @@ -336,7 +343,6 @@ exists, then no other unit test will be executed, apart from `TestSuiteName`. explanatory comments. 8. Importing new libraries unless there is a very good reason to do so. - ## Seek to 9. Extend functionality of existing code rather than creating new code. @@ -351,14 +357,12 @@ exists, then no other unit test will be executed, apart from `TestSuiteName`. 14. Provide as many comments as you feel that a competent programmer would need to understand what your code does. - # Maintainers Maintainers are ecosystem participants with elevated access to the repository. They are able to push new code, make decisions on when a release should be made, etc. - ## Adding and removing New maintainers can be proposed by two existing maintainers, subject to a vote @@ -373,47 +377,45 @@ A minimum of 60% agreement and 50% participation are required. The XRP Ledger Foundation will have the ability, for cause, to remove an existing maintainer without a vote. - ## Current Maintainers Maintainers are users with maintain or admin access to the repo. -* [bthomee](https://github.com/bthomee) (Ripple) -* [intelliot](https://github.com/intelliot) (Ripple) -* [JoelKatz](https://github.com/JoelKatz) (Ripple) -* [nixer89](https://github.com/nixer89) (XRP Ledger Foundation) -* [RichardAH](https://github.com/RichardAH) (XRP Ledger Foundation) -* [Silkjaer](https://github.com/Silkjaer) (XRP Ledger Foundation) -* [WietseWind](https://github.com/WietseWind) (XRPL Labs + XRP Ledger Foundation) -* [ximinez](https://github.com/ximinez) (Ripple) - +- [bthomee](https://github.com/bthomee) (Ripple) +- [intelliot](https://github.com/intelliot) (Ripple) +- [JoelKatz](https://github.com/JoelKatz) (Ripple) +- [nixer89](https://github.com/nixer89) (XRP Ledger Foundation) +- [RichardAH](https://github.com/RichardAH) (XRP Ledger Foundation) +- [Silkjaer](https://github.com/Silkjaer) (XRP Ledger Foundation) +- [WietseWind](https://github.com/WietseWind) (XRPL Labs + XRP Ledger Foundation) +- [ximinez](https://github.com/ximinez) (Ripple) ## Current Code Reviewers Code Reviewers are developers who have the ability to review, approve, and in some cases merge source code changes. -* [HowardHinnant](https://github.com/HowardHinnant) (Ripple) -* [scottschurr](https://github.com/scottschurr) (Ripple) -* [seelabs](https://github.com/seelabs) (Ripple) -* [Ed Hennis](https://github.com/ximinez) (Ripple) -* [mvadari](https://github.com/mvadari) (Ripple) -* [thejohnfreeman](https://github.com/thejohnfreeman) (Ripple) -* [Bronek](https://github.com/Bronek) (Ripple) -* [manojsdoshi](https://github.com/manojsdoshi) (Ripple) -* [godexsoft](https://github.com/godexsoft) (Ripple) -* [mDuo13](https://github.com/mDuo13) (Ripple) -* [ckniffen](https://github.com/ckniffen) (Ripple) -* [arihantkothari](https://github.com/arihantkothari) (Ripple) -* [pwang200](https://github.com/pwang200) (Ripple) -* [sophiax851](https://github.com/sophiax851) (Ripple) -* [shawnxie999](https://github.com/shawnxie999) (Ripple) -* [gregtatcam](https://github.com/gregtatcam) (Ripple) -* [mtrippled](https://github.com/mtrippled) (Ripple) -* [ckeshava](https://github.com/ckeshava) (Ripple) -* [nbougalis](https://github.com/nbougalis) None -* [RichardAH](https://github.com/RichardAH) (XRPL Labs + XRP Ledger Foundation) -* [dangell7](https://github.com/dangell7) (XRPL Labs) +- [HowardHinnant](https://github.com/HowardHinnant) (Ripple) +- [scottschurr](https://github.com/scottschurr) (Ripple) +- [seelabs](https://github.com/seelabs) (Ripple) +- [Ed Hennis](https://github.com/ximinez) (Ripple) +- [mvadari](https://github.com/mvadari) (Ripple) +- [thejohnfreeman](https://github.com/thejohnfreeman) (Ripple) +- [Bronek](https://github.com/Bronek) (Ripple) +- [manojsdoshi](https://github.com/manojsdoshi) (Ripple) +- [godexsoft](https://github.com/godexsoft) (Ripple) +- [mDuo13](https://github.com/mDuo13) (Ripple) +- [ckniffen](https://github.com/ckniffen) (Ripple) +- [arihantkothari](https://github.com/arihantkothari) (Ripple) +- [pwang200](https://github.com/pwang200) (Ripple) +- [sophiax851](https://github.com/sophiax851) (Ripple) +- [shawnxie999](https://github.com/shawnxie999) (Ripple) +- [gregtatcam](https://github.com/gregtatcam) (Ripple) +- [mtrippled](https://github.com/mtrippled) (Ripple) +- [ckeshava](https://github.com/ckeshava) (Ripple) +- [nbougalis](https://github.com/nbougalis) None +- [RichardAH](https://github.com/RichardAH) (XRPL Labs + XRP Ledger Foundation) +- [dangell7](https://github.com/dangell7) (XRPL Labs) Developers not on this list are able and encouraged to submit feedback on pending code changes (open pull requests). @@ -423,6 +425,7 @@ on pending code changes (open pull requests). These instructions assume you have your git upstream remotes configured to avoid accidental pushes to the main repo, and a remote group specifying both of them. e.g. + ``` $ git remote -v | grep upstream upstream https://github.com/XRPLF/rippled.git (fetch) @@ -437,6 +440,7 @@ upstream upstream-push You can use the [setup-upstreams] script to set this up. It also assumes you have a default gpg signing key set up in git. e.g. + ``` $ git config user.signingkey 968479A1AFF927E37D1A566BB5690EEEBB952194 @@ -461,8 +465,8 @@ the suggested commit message, or modify it as needed. #### Slightly more complicated pull requests Some pull requests need to be pushed to `develop` as more than one -commit. A PR author may *request* to merge as separate commits. They -must *justify* why separate commits are needed, and *specify* how they +commit. A PR author may _request_ to merge as separate commits. They +must _justify_ why separate commits are needed, and _specify_ how they would like the commits to be merged. If you disagree with the author, discuss it with them directly. @@ -471,20 +475,22 @@ fast forward only merge (`--ff-only`) on the command line and push to `develop`. Some examples of when separate commits are worthwhile are: + 1. PRs where source files are reorganized in multiple steps. -2. PRs where the commits are mostly independent and *could* be separate +2. PRs where the commits are mostly independent and _could_ be separate PRs, but are pulled together into one PR under a commit theme or issue. 3. PRs that are complicated enough that `git bisect` would not be much help if it determined this PR introduced a problem. Either way, check that: -* The commits are based on the current tip of `develop`. -* The commits are clean: No merge commits (except when reverse + +- The commits are based on the current tip of `develop`. +- The commits are clean: No merge commits (except when reverse merging), no "[FOLD]" or "fixup!" messages. -* All commits are signed. If the commits are not signed by the author, use +- All commits are signed. If the commits are not signed by the author, use `git commit --amend -S` to sign them yourself. -* At least one (but preferably all) of the commits has the PR number +- At least one (but preferably all) of the commits has the PR number in the commit message. The "Create a merge commit" and "Rebase and merge" options should be @@ -502,13 +508,13 @@ Rippled uses a linear workflow model that can be summarized as: 1. In between releases, developers work against the `develop` branch. 2. Periodically, a maintainer will build and tag a beta version from `develop`, which is pushed to `release`. - * Betas are usually released every two to three weeks, though that + - Betas are usually released every two to three weeks, though that schedule can vary depending on progress, availability, and other factors. 3. When the changes in `develop` are considered stable and mature enough to be ready to release, a release candidate (RC) is built and tagged from `develop`, and merged to `release`. - * Further development for that release (primarily fixes) then + - Further development for that release (primarily fixes) then continues against `release`, while other development continues on `develop`. Effectively, `release` is forked from `develop`. Changes to `release` must be reverse merged to `develop`. @@ -543,6 +549,7 @@ Rippled uses a linear workflow model that can be summarized as: the version number, etc. The workflow may look something like: + ``` git fetch --multiple upstreams user1 user2 user3 [...] git checkout -B release-next --no-track upstream/develop @@ -581,8 +588,9 @@ This includes, betas, and the first release candidate (RC). 1. If you didn't create one [preparing the `develop` branch](#preparing-the-develop-branch), Ensure there is no old - `release-next` branch hanging around. Then make a `release-next` + `release-next` branch hanging around. Then make a `release-next` branch that only changes the version number. e.g. + ``` git fetch upstreams @@ -603,25 +611,30 @@ git push upstream-push git fetch upstreams git branch --set-upstream-to=upstream/release-next ``` - You can also use the [update-version] script. -2. Create a Pull Request for `release-next` with **`develop`** as - the base branch. - 1. Use the title "[TRIVIAL] Set version to X.X.X-bX". - 2. Instead of the default description template, use the following: + +You can also use the [update-version] script. 2. Create a Pull Request for `release-next` with **`develop`** as +the base branch. + +1. Use the title "[TRIVIAL] Set version to X.X.X-bX". +2. Instead of the default description template, use the following: + ``` ## High Level Overview of Change This PR only changes the version number. It will be merged as soon as Github CI actions successfully complete. ``` + 3. Wait for CI to successfully complete, and get someone to approve the PR. (It is safe to ignore known CI issues.) 4. Push the updated `develop` branch using your `release-next` branch. **Do not use the Github UI. It's important to preserve commit IDs.** + ``` git push upstream-push release-next:develop ``` + 5. In the unlikely event that the push fails because someone has merged something else in the meantime, rebase your branch onto the updated `develop` branch, push again, and go back to step 3. @@ -630,22 +643,25 @@ git push upstream-push release-next:develop 7. Once this is done, forward progress on `develop` can continue (other PRs may be merged). 8. Now create a Pull Request for `release-next` with **`release`** as - the base branch. Instead of the default template, reuse and update + the base branch. Instead of the default template, reuse and update the message from the previous release. Include the following verbiage somewhere in the description: + ``` The base branch is `release`. [All releases (including betas)](https://github.com/XRPLF/rippled/blob/develop/CONTRIBUTING.md#before-you-start) go in `release`. This PR branch will be pushed directly to `release` (not squashed or rebased, and not using the GitHub UI). ``` + 7. Sign-offs for the three platforms (Linux, Mac, Windows) usually occur offline, but at least one approval will be needed on the PR. - * If issues are discovered during testing, simply abandon the - release. It's easy to start a new release, it should be easy to + - If issues are discovered during testing, simply abandon the + release. It's easy to start a new release, it should be easy to abandon one. **DO NOT REUSE THE VERSION NUMBER.** e.g. If you abandon 2.4.0-b1, the next attempt will be 2.4.0-b2. 8. Once everything is ready to go, push to `release`. + ``` git fetch upstreams @@ -666,23 +682,28 @@ git log -1 --oneline # Other branches, including some from upstream-push, may also be # present. ``` + 9. Tag the release, too. + ``` git tag git push upstream-push ``` + 10. Delete the `release-next` branch on the repo. Use the Github UI or: + ``` git push --delete upstream-push release-next ``` + 11. Finally [create a new release on Github](https://github.com/XRPLF/rippled/releases). #### Release candidates after the first Once the first release candidate is [merged into -release](#making-the-release), then `release` and `develop` *are allowed -to diverge*. +release](#making-the-release), then `release` and `develop` _are allowed +to diverge_. If a bug or issue is discovered in a version that has a release candidate being tested, any fix and new version will need to be applied @@ -690,7 +711,7 @@ against `release`, then reverse-merged to `develop`. This helps keep git history as linear as possible. A `release-next` branch will be created from `release`, and any further -work for that release must be based on `release-next`. Specifically, +work for that release must be based on `release-next`. Specifically, PRs must use `release-next` as the base, and those PRs will be merged directly to `release-next` when approved. Changes should be restricted to bug fixes, but other changes may be necessary from time to time. @@ -713,17 +734,21 @@ Once the RC is merged and tagged, it needs to be reverse merged into 1. Create a branch, based on `upstream/develop`. The branch name is not important, but could include "mergeNNNrcN". E.g. For release A.B.C-rcD, use `mergeABCrcD`. + ``` git fetch upstreams git checkout --no-track -b mergeABCrcD upstream/develop ``` + 2. Merge `release` into your branch. + ``` # I like the "--edit --log --verbose" parameters, but they are # not required. git merge upstream/release ``` + 3. `BuildInfo.cpp` will have a conflict with the version number. Resolve it with the version from `develop` - the higher version. 4. Push your branch to your repo (or `upstream` if you have permission), @@ -731,22 +756,27 @@ git merge upstream/release simply indicate that this is a merge of the RC. The "Context" should summarize the changes from the RC. Include the following text prominently: + ``` This PR must be merged manually using a push. Do not use the Github UI. ``` + 5. Depending on the complexity of the changes, and/or merge conflicts, the PR may need a thorough review, or just a sign-off that the merge was done correctly. 6. If `develop` is updated before this PR is merged, do not merge `develop` back into your branch. Instead rebase preserving merges, or do the merge again. (See also the `rerere` git config setting.) + ``` git rebase --rebase-merges upstream/develop # OR git reset --hard upstream/develop git merge upstream/release ``` + 7. When the PR is ready, push it to `develop`. + ``` git fetch upstreams @@ -757,8 +787,8 @@ git push upstream-push mergeABCrcD:develop git fetch upstreams ``` -Development on `develop` can proceed as normal. +Development on `develop` can proceed as normal. #### Final releases @@ -773,7 +803,7 @@ internally as if they were RCs (at minimum, ensuring unit tests pass, and the app starts, syncs, and stops cleanly across all three platforms.) -*If in doubt, make an RC first.* +_If in doubt, make an RC first._ The process for building a final release is very similar to [the process for building a beta](#making-the-release), except the code will be @@ -785,20 +815,23 @@ moving from `release` to `master` instead of from `develop` to number. As above, or using the [update-version] script. 2. Create a Pull Request for `master-next` with **`master`** as - the base branch. Instead of the default template, reuse and update + the base branch. Instead of the default template, reuse and update the message from the previous final release. Include the following verbiage somewhere in the description: + ``` The base branch is `master`. This PR branch will be pushed directly to `release` and `master` (not squashed or rebased, and not using the GitHub UI). ``` + 7. Sign-offs for the three platforms (Linux, Mac, Windows) usually occur offline, but at least one approval will be needed on the PR. - * If issues are discovered during testing, close the PR, delete + - If issues are discovered during testing, close the PR, delete `master-next`, and move development back to `release`, [issuing more RCs as necessary](#release-candidates-after-the-first) 8. Once everything is ready to go, push to `release` and `master`. + ``` git fetch upstreams @@ -821,15 +854,20 @@ git log -1 --oneline # Other branches, including some from upstream-push, may also be # present. ``` + 9. Tag the release, too. + ``` git tag git push upstream-push ``` + 10. Delete the `master-next` branch on the repo. Use the Github UI or: + ``` git push --delete upstream-push master-next ``` + 11. [Create a new release on Github](https://github.com/XRPLF/rippled/releases). Be sure that "Set as the latest release" is checked. @@ -856,11 +894,13 @@ any branch. When it's ready to merge, jump to step 3 using your branch instead of `master-next`. 1. Create a `master-next` branch from `master`. + ``` git checkout --no-track -b master-next upstream/master git push upstream-push git fetch upstreams ``` + 2. Open any PRs for the pending hotfix using `master-next` as the base, so they can be merged directly in to it. Unlike `develop`, though, `master-next` can be thrown away and recreated if necessary. @@ -868,19 +908,22 @@ git fetch upstreams steps as above, or use the [update-version] script. 4. Create a Pull Request for `master-next` with **`master`** as - the base branch. Instead of the default template, reuse and update + the base branch. Instead of the default template, reuse and update the message from the previous final release. Include the following verbiage somewhere in the description: + ``` The base branch is `master`. This PR branch will be pushed directly to `master` (not squashed or rebased, and not using the GitHub UI). ``` + 7. Sign-offs for the three platforms (Linux, Mac, Windows) usually occur offline, but at least one approval will be needed on the PR. - * If issues are discovered during testing, update `master-next` as + - If issues are discovered during testing, update `master-next` as needed, but ensure that the changes are properly squashed, and the version setting commit remains last 8. Once everything is ready to go, push to `master` **only**. + ``` git fetch upstreams @@ -901,15 +944,20 @@ git log -1 --oneline # Other branches, including some from upstream-push, may also be # present. ``` + 9. Tag the release, too. + ``` git tag git push upstream-push ``` + 9. Delete the `master-next` branch on the repo. + ``` git push --delete upstream-push master-next ``` + 10. [Create a new release on Github](https://github.com/XRPLF/rippled/releases). Be sure that "Set as the latest release" is checked. @@ -921,17 +969,21 @@ Once the hotfix is released, it needs to be reverse merged into 1. Create a branch in your own repo, based on `upstream/develop`. The branch name is not important, but could include "mergeNNN". E.g. For release 2.2.3, use `merge223`. + ``` git fetch upstreams git checkout --no-track -b merge223 upstream/develop ``` + 2. Merge master into your branch. + ``` # I like the "--edit --log --verbose" parameters, but they are # not required. git merge upstream/master ``` + 3. `BuildInfo.cpp` will have a conflict with the version number. Resolve it with the version from `develop` - the higher version. 4. Push your branch to your repo, and open a normal PR against @@ -939,22 +991,27 @@ git merge upstream/master is a merge of the hotfix version. The "Context" should summarize the changes from the hotfix. Include the following text prominently: + ``` This PR must be merged manually using a --ff-only merge. Do not use the Github UI. ``` + 5. Depending on the complexity of the hotfix, and/or merge conflicts, the PR may need a thorough review, or just a sign-off that the merge was done correctly. 6. If `develop` is updated before this PR is merged, do not merge `develop` back into your branch. Instead rebase preserving merges, or do the merge again. (See also the `rerere` git config setting.) + ``` git rebase --rebase-merges upstream/develop # OR git reset --hard upstream/develop git merge upstream/master ``` + 7. When the PR is ready, push it to `develop`. + ``` git fetch upstreams @@ -963,6 +1020,7 @@ git log --show-signature "upstream/develop..HEAD" git push upstream-push HEAD:develop ``` + Development on `develop` can proceed as normal. It is recommended to create a beta (or RC) immediately to ensure that everything worked as expected. @@ -977,12 +1035,13 @@ a significant fraction of users, which would necessitate a hotfix / point release to that version as well as any later versions. This scenario would follow the same basic procedure as above, -except that *none* of `develop`, `release`, or `master` +except that _none_ of `develop`, `release`, or `master` would be touched during the release process. In this example, consider if version 2.1.1 needed to be patched. 1. Create two branches in the main (`upstream`) repo. + ``` git fetch upstreams @@ -996,6 +1055,7 @@ git push upstream-push git fetch upstreams ``` + 2. Work continues as above, except using `master-2.1.2`as the base branch for any merging, packaging, etc. 3. After the release is tagged and packages are built, you could diff --git a/LICENSE.md b/LICENSE.md index 9282ed78ba..8aca84866f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -ISC License +ISC License Copyright (c) 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant. Copyright (c) 2012-2020, the XRP Ledger developers. @@ -14,4 +14,3 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/README.md b/README.md index 0315c37428..4fdb89dffa 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,19 @@ The [XRP Ledger](https://xrpl.org/) is a decentralized cryptographic ledger powered by a network of peer-to-peer nodes. The XRP Ledger uses a novel Byzantine Fault Tolerant consensus algorithm to settle and record transactions in a secure distributed database without a central operator. ## XRP + [XRP](https://xrpl.org/xrp.html) is a public, counterparty-free asset native to the XRP Ledger, and is designed to bridge the many different currencies in use worldwide. XRP is traded on the open-market and is available for anyone to access. The XRP Ledger was created in 2012 with a finite supply of 100 billion units of XRP. ## rippled + The server software that powers the XRP Ledger is called `rippled` and is available in this repository under the permissive [ISC open-source license](LICENSE.md). The `rippled` server software is written primarily in C++ and runs on a variety of platforms. The `rippled` server software can run in several modes depending on its [configuration](https://xrpl.org/rippled-server-modes.html). If you are interested in running an **API Server** (including a **Full History Server**), take a look at [Clio](https://github.com/XRPLF/clio). (rippled Reporting Mode has been replaced by Clio.) ### Build from Source -* [Read the build instructions in `BUILD.md`](BUILD.md) -* If you encounter any issues, please [open an issue](https://github.com/XRPLF/rippled/issues) +- [Read the build instructions in `BUILD.md`](BUILD.md) +- If you encounter any issues, please [open an issue](https://github.com/XRPLF/rippled/issues) ## Key Features of the XRP Ledger @@ -35,7 +37,6 @@ If you are interested in running an **API Server** (including a **Full History S [Modern Features for Smart Contracts]: https://xrpl.org/xrp-ledger-overview.html#modern-features-for-smart-contracts [On-Ledger Decentralized Exchange]: https://xrpl.org/xrp-ledger-overview.html#on-ledger-decentralized-exchange - ## Source Code Here are some good places to start learning the source code: @@ -47,7 +48,7 @@ Here are some good places to start learning the source code: ### Repository Contents | Folder | Contents | -|:-----------|:-------------------------------------------------| +| :--------- | :----------------------------------------------- | | `./bin` | Scripts and data files for Ripple integrators. | | `./Builds` | Platform-specific guides for building `rippled`. | | `./docs` | Source documentation files and doxygen config. | @@ -57,15 +58,14 @@ Here are some good places to start learning the source code: Some of the directories under `src` are external repositories included using git-subtree. See those directories' README files for more details. - ## Additional Documentation -* [XRP Ledger Dev Portal](https://xrpl.org/) -* [Setup and Installation](https://xrpl.org/install-rippled.html) -* [Source Documentation (Doxygen)](https://xrplf.github.io/rippled/) +- [XRP Ledger Dev Portal](https://xrpl.org/) +- [Setup and Installation](https://xrpl.org/install-rippled.html) +- [Source Documentation (Doxygen)](https://xrplf.github.io/rippled/) ## See Also -* [Clio API Server for the XRP Ledger](https://github.com/XRPLF/clio) -* [Mailing List for Release Announcements](https://groups.google.com/g/ripple-server) -* [Learn more about the XRP Ledger (YouTube)](https://www.youtube.com/playlist?list=PLJQ55Tj1hIVZtJ_JdTvSum2qMTsedWkNi) +- [Clio API Server for the XRP Ledger](https://github.com/XRPLF/clio) +- [Mailing List for Release Announcements](https://groups.google.com/g/ripple-server) +- [Learn more about the XRP Ledger (YouTube)](https://www.youtube.com/playlist?list=PLJQ55Tj1hIVZtJ_JdTvSum2qMTsedWkNi) diff --git a/SECURITY.md b/SECURITY.md index eb7437d2f9..3fd85bad0a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,6 @@ For more details on operating an XRP Ledger server securely, please visit https://xrpl.org/manage-the-rippled-server.html. - # Security Policy ## Supported Versions @@ -77,13 +76,14 @@ The amount paid varies dramatically. Vulnerabilities that are harmless on their To report a qualifying bug, please send a detailed report to: -|Email Address|bugs@ripple.com | -|:-----------:|:----------------------------------------------------| -|Short Key ID | `0xC57929BE` | -|Long Key ID | `0xCD49A0AFC57929BE` | -|Fingerprint | `24E6 3B02 37E0 FA9C 5E96 8974 CD49 A0AF C579 29BE` | +| Email Address | bugs@ripple.com | +| :-----------: | :-------------------------------------------------- | +| Short Key ID | `0xC57929BE` | +| Long Key ID | `0xCD49A0AFC57929BE` | +| Fingerprint | `24E6 3B02 37E0 FA9C 5E96 8974 CD49 A0AF C579 29BE` | + +The full PGP key for this address, which is also available on several key servers (e.g. on [keyserver.ubuntu.com](https://keyserver.ubuntu.com)), is: -The full PGP key for this address, which is also available on several key servers (e.g. on [keyserver.ubuntu.com](https://keyserver.ubuntu.com)), is: ``` -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFUwGHYBEAC0wpGpBPkd8W1UdQjg9+cEFzeIEJRaoZoeuJD8mofwI5Ejnjdt diff --git a/docs/0001-negative-unl/README.md b/docs/0001-negative-unl/README.md index 606b30aab1..f28ff63c6f 100644 --- a/docs/0001-negative-unl/README.md +++ b/docs/0001-negative-unl/README.md @@ -30,7 +30,7 @@ the ledger (so the entire network has the same view). This will help the network see which validators are **currently** unreliable, and adjust their quorum calculation accordingly. -*Improving the liveness of the network is the main motivation for the negative UNL.* +_Improving the liveness of the network is the main motivation for the negative UNL._ ### Targeted Faults @@ -53,16 +53,17 @@ even if the number of remaining validators gets to 60%. Say we have a network with 10 validators on the UNL and everything is operating correctly. The quorum required for this network would be 8 (80% of 10). When validators fail, the quorum required would be as low as 6 (60% of 10), which is the absolute -***minimum quorum***. We need the absolute minimum quorum to be strictly greater +**_minimum quorum_**. We need the absolute minimum quorum to be strictly greater than 50% of the original UNL so that there cannot be two partitions of well-behaved nodes headed in different directions. We arbitrarily choose 60% as the minimum quorum to give a margin of safety. Consider these events in the absence of negative UNL: + 1. 1:00pm - validator1 fails, votes vs. quorum: 9 >= 8, we have quorum 1. 3:00pm - validator2 fails, votes vs. quorum: 8 >= 8, we have quorum 1. 5:00pm - validator3 fails, votes vs. quorum: 7 < 8, we don’t have quorum - * **network cannot validate new ledgers with 3 failed validators** + - **network cannot validate new ledgers with 3 failed validators** We're below 80% agreement, so new ledgers cannot be validated. This is how the XRP Ledger operates today, but if the negative UNL was enabled, the events would @@ -70,18 +71,20 @@ happen as follows. (Please note that the events below are from a simplified version of our protocol.) 1. 1:00pm - validator1 fails, votes vs. quorum: 9 >= 8, we have quorum -1. 1:40pm - network adds validator1 to negative UNL, quorum changes to ceil(9 * 0.8), or 8 +1. 1:40pm - network adds validator1 to negative UNL, quorum changes to ceil(9 \* 0.8), or 8 1. 3:00pm - validator2 fails, votes vs. quorum: 8 >= 8, we have quorum -1. 3:40pm - network adds validator2 to negative UNL, quorum changes to ceil(8 * 0.8), or 7 +1. 3:40pm - network adds validator2 to negative UNL, quorum changes to ceil(8 \* 0.8), or 7 1. 5:00pm - validator3 fails, votes vs. quorum: 7 >= 7, we have quorum -1. 5:40pm - network adds validator3 to negative UNL, quorum changes to ceil(7 * 0.8), or 6 +1. 5:40pm - network adds validator3 to negative UNL, quorum changes to ceil(7 \* 0.8), or 6 1. 7:00pm - validator4 fails, votes vs. quorum: 6 >= 6, we have quorum - * **network can still validate new ledgers with 4 failed validators** + - **network can still validate new ledgers with 4 failed validators** ## External Interactions ### Message Format Changes + This proposal will: + 1. add a new pseudo-transaction type 1. add the negative UNL to the ledger data structure. @@ -89,19 +92,20 @@ Any tools or systems that rely on the format of this data will have to be updated. ### Amendment + This feature **will** need an amendment to activate. ## Design This section discusses the following topics about the Negative UNL design: -* [Negative UNL protocol overview](#Negative-UNL-Protocol-Overview) -* [Validator reliability measurement](#Validator-Reliability-Measurement) -* [Format Changes](#Format-Changes) -* [Negative UNL maintenance](#Negative-UNL-Maintenance) -* [Quorum size calculation](#Quorum-Size-Calculation) -* [Filter validation messages](#Filter-Validation-Messages) -* [High level sequence diagram of code +- [Negative UNL protocol overview](#Negative-UNL-Protocol-Overview) +- [Validator reliability measurement](#Validator-Reliability-Measurement) +- [Format Changes](#Format-Changes) +- [Negative UNL maintenance](#Negative-UNL-Maintenance) +- [Quorum size calculation](#Quorum-Size-Calculation) +- [Filter validation messages](#Filter-Validation-Messages) +- [High level sequence diagram of code changes](#High-Level-Sequence-Diagram-of-Code-Changes) ### Negative UNL Protocol Overview @@ -114,9 +118,9 @@ with V in their UNL adjust the quorum and V’s validation message is not counte when verifying if a ledger is fully validated. V’s flow of messages and network interactions, however, will remain the same. -We define the ***effective UNL** = original UNL - negative UNL*, and the -***effective quorum*** as the quorum of the *effective UNL*. And we set -*effective quorum = Ceiling(80% * effective UNL)*. +We define the **\*effective UNL** = original UNL - negative UNL\*, and the +**_effective quorum_** as the quorum of the _effective UNL_. And we set +_effective quorum = Ceiling(80% _ effective UNL)\*. ### Validator Reliability Measurement @@ -126,16 +130,16 @@ measure about its validators, but we have chosen ledger validation messages. This is because every validator shall send one and only one signed validation message per ledger. This keeps the measurement simple and removes timing/clock-sync issues. A node will measure the percentage of agreeing -validation messages (*PAV*) received from each validator on the node's UNL. Note +validation messages (_PAV_) received from each validator on the node's UNL. Note that the node will only count the validation messages that agree with its own validations. We define the **PAV** as the **P**ercentage of **A**greed **V**alidation messages received for the last N ledgers, where N = 256 by default. -When the PAV drops below the ***low-water mark***, the validator is considered +When the PAV drops below the **_low-water mark_**, the validator is considered unreliable, and is a candidate to be disabled by being added to the negative -UNL. A validator must have a PAV higher than the ***high-water mark*** to be +UNL. A validator must have a PAV higher than the **_high-water mark_** to be re-enabled. The validator is re-enabled by removing it from the negative UNL. In the implementation, we plan to set the low-water mark as 50% and the high-water mark as 80%. @@ -143,22 +147,24 @@ mark as 80%. ### Format Changes The negative UNL component in a ledger contains three fields. -* ***NegativeUNL***: The current negative UNL, a list of unreliable validators. -* ***ToDisable***: The validator to be added to the negative UNL on the next + +- **_NegativeUNL_**: The current negative UNL, a list of unreliable validators. +- **_ToDisable_**: The validator to be added to the negative UNL on the next flag ledger. -* ***ToReEnable***: The validator to be removed from the negative UNL on the +- **_ToReEnable_**: The validator to be removed from the negative UNL on the next flag ledger. -All three fields are optional. When the *ToReEnable* field exists, the -*NegativeUNL* field cannot be empty. +All three fields are optional. When the _ToReEnable_ field exists, the +_NegativeUNL_ field cannot be empty. -A new pseudo-transaction, ***UNLModify***, is added. It has three fields -* ***Disabling***: A flag indicating whether the modification is to disable or +A new pseudo-transaction, **_UNLModify_**, is added. It has three fields + +- **_Disabling_**: A flag indicating whether the modification is to disable or to re-enable a validator. -* ***Seq***: The ledger sequence number. -* ***Validator***: The validator to be disabled or re-enabled. +- **_Seq_**: The ledger sequence number. +- **_Validator_**: The validator to be disabled or re-enabled. -There would be at most one *disable* `UNLModify` and one *re-enable* `UNLModify` +There would be at most one _disable_ `UNLModify` and one _re-enable_ `UNLModify` transaction per flag ledger. The full machinery is described further on. ### Negative UNL Maintenance @@ -167,19 +173,19 @@ The negative UNL can only be modified on the flag ledgers. If a validator's reliability status changes, it takes two flag ledgers to modify the negative UNL. Let's see an example of the algorithm: -* Ledger seq = 100: A validator V goes offline. -* Ledger seq = 256: This is a flag ledger, and V's reliability measurement *PAV* +- Ledger seq = 100: A validator V goes offline. +- Ledger seq = 256: This is a flag ledger, and V's reliability measurement _PAV_ is lower than the low-water mark. Other validators add `UNLModify` pseudo-transactions `{true, 256, V}` to the transaction set which goes through the consensus. Then the pseudo-transaction is applied to the negative UNL ledger component by setting `ToDisable = V`. -* Ledger seq = 257 ~ 511: The negative UNL ledger component is copied from the +- Ledger seq = 257 ~ 511: The negative UNL ledger component is copied from the parent ledger. -* Ledger seq=512: This is a flag ledger, and the negative UNL is updated +- Ledger seq=512: This is a flag ledger, and the negative UNL is updated `NegativeUNL = NegativeUNL + ToDisable`. The negative UNL may have up to `MaxNegativeListed = floor(original UNL * 25%)` -validators. The 25% is because of 75% * 80% = 60%, where 75% = 100% - 25%, 80% +validators. The 25% is because of 75% \* 80% = 60%, where 75% = 100% - 25%, 80% is the quorum of the effective UNL, and 60% is the absolute minimum quorum of the original UNL. Adding more than 25% validators to the negative UNL does not improve the liveness of the network, because adding more validators to the @@ -187,52 +193,43 @@ negative UNL cannot lower the effective quorum. The following is the detailed algorithm: -* **If** the ledger seq = x is a flag ledger +- **If** the ledger seq = x is a flag ledger + 1. Compute `NegativeUNL = NegativeUNL + ToDisable - ToReEnable` if they + exist in the parent ledger - 1. Compute `NegativeUNL = NegativeUNL + ToDisable - ToReEnable` if they - exist in the parent ledger + 1. Try to find a candidate to disable if `sizeof NegativeUNL < MaxNegativeListed` - 1. Try to find a candidate to disable if `sizeof NegativeUNL < MaxNegativeListed` + 1. Find a validator V that has a _PAV_ lower than the low-water + mark, but is not in `NegativeUNL`. - 1. Find a validator V that has a *PAV* lower than the low-water - mark, but is not in `NegativeUNL`. + 1. If two or more are found, their public keys are XORed with the hash + of the parent ledger and the one with the lowest XOR result is chosen. + 1. If V is found, create a `UNLModify` pseudo-transaction + `TxDisableValidator = {true, x, V}` + 1. Try to find a candidate to re-enable if `sizeof NegativeUNL > 0`: + 1. Find a validator U that is in `NegativeUNL` and has a _PAV_ higher + than the high-water mark. + 1. If U is not found, try to find one in `NegativeUNL` but not in the + local _UNL_. + 1. If two or more are found, their public keys are XORed with the hash + of the parent ledger and the one with the lowest XOR result is chosen. + 1. If U is found, create a `UNLModify` pseudo-transaction + `TxReEnableValidator = {false, x, U}` - 1. If two or more are found, their public keys are XORed with the hash - of the parent ledger and the one with the lowest XOR result is chosen. - - 1. If V is found, create a `UNLModify` pseudo-transaction - `TxDisableValidator = {true, x, V}` - - 1. Try to find a candidate to re-enable if `sizeof NegativeUNL > 0`: - - 1. Find a validator U that is in `NegativeUNL` and has a *PAV* higher - than the high-water mark. - - 1. If U is not found, try to find one in `NegativeUNL` but not in the - local *UNL*. - - 1. If two or more are found, their public keys are XORed with the hash - of the parent ledger and the one with the lowest XOR result is chosen. - - 1. If U is found, create a `UNLModify` pseudo-transaction - `TxReEnableValidator = {false, x, U}` - - 1. If any `UNLModify` pseudo-transactions are created, add them to the - transaction set. The transaction set goes through the consensus algorithm. - - 1. If have enough support, the `UNLModify` pseudo-transactions remain in the - transaction set agreed by the validators. Then the pseudo-transactions are - applied to the ledger: - - 1. If have `TxDisableValidator`, set `ToDisable=TxDisableValidator.V`. - Else clear `ToDisable`. - - 1. If have `TxReEnableValidator`, set - `ToReEnable=TxReEnableValidator.U`. Else clear `ToReEnable`. - -* **Else** (not a flag ledger) + 1. If any `UNLModify` pseudo-transactions are created, add them to the + transaction set. The transaction set goes through the consensus algorithm. + 1. If have enough support, the `UNLModify` pseudo-transactions remain in the + transaction set agreed by the validators. Then the pseudo-transactions are + applied to the ledger: - 1. Copy the negative UNL ledger component from the parent ledger + 1. If have `TxDisableValidator`, set `ToDisable=TxDisableValidator.V`. + Else clear `ToDisable`. + + 1. If have `TxReEnableValidator`, set + `ToReEnable=TxReEnableValidator.U`. Else clear `ToReEnable`. + +- **Else** (not a flag ledger) + 1. Copy the negative UNL ledger component from the parent ledger The negative UNL is stored on each ledger because we don't know when a validator may reconnect to the network. If the negative UNL was stored only on every flag @@ -273,31 +270,26 @@ not counted when checking if the ledger is fully validated. The diagram below is the sequence of one round of consensus. Classes and components with non-trivial changes are colored green. -* The `ValidatorList` class is modified to compute the quorum of the effective +- The `ValidatorList` class is modified to compute the quorum of the effective UNL. -* The `Validations` class provides an interface for querying the validation +- The `Validations` class provides an interface for querying the validation messages from trusted validators. -* The `ConsensusAdaptor` component: - - * The `RCLConsensus::Adaptor` class is modified for creating `UNLModify` - Pseudo-Transactions. - - * The `Change` class is modified for applying `UNLModify` - Pseudo-Transactions. - - * The `Ledger` class is modified for creating and adjusting the negative UNL - ledger component. - - * The `LedgerMaster` class is modified for filtering out validation messages - from negative UNL validators when verifying if a ledger is fully - validated. +- The `ConsensusAdaptor` component: + - The `RCLConsensus::Adaptor` class is modified for creating `UNLModify` + Pseudo-Transactions. + - The `Change` class is modified for applying `UNLModify` + Pseudo-Transactions. + - The `Ledger` class is modified for creating and adjusting the negative UNL + ledger component. + - The `LedgerMaster` class is modified for filtering out validation messages + from negative UNL validators when verifying if a ledger is fully + validated. ![Sequence diagram](./negativeUNL_highLevel_sequence.png?raw=true "Negative UNL Changes") - ## Roads Not Taken ### Use a Mechanism Like Fee Voting to Process UNLModify Pseudo-Transactions @@ -311,7 +303,7 @@ and different quorums for the same ledger. As a result, the network's safety is impacted. This updated version does not impact safety though operates a bit more slowly. -The negative UNL modifications in the *UNLModify* pseudo-transaction approved by +The negative UNL modifications in the _UNLModify_ pseudo-transaction approved by the consensus will take effect at the next flag ledger. The extra time of the 256 ledgers should be enough for nodes to be in sync of the negative UNL modifications. @@ -334,29 +326,28 @@ expiration approach cannot be simply applied. ### Validator Reliability Measurement and Flag Ledger Frequency If the ledger time is about 4.5 seconds and the low-water mark is 50%, then in -the worst case, it takes 48 minutes *((0.5 * 256 + 256 + 256) * 4.5 / 60 = 48)* +the worst case, it takes 48 minutes _((0.5 _ 256 + 256 + 256) _ 4.5 / 60 = 48)_ to put an offline validator on the negative UNL. We considered lowering the flag ledger frequency so that the negative UNL can be more responsive. We also considered decoupling the reliability measurement and flag ledger frequency to be more flexible. In practice, however, their benefits are not clear. - ## New Attack Vectors A group of malicious validators may try to frame a reliable validator and put it on the negative UNL. But they cannot succeed. Because: 1. A reliable validator sends a signed validation message every ledger. A -sufficient peer-to-peer network will propagate the validation messages to other -validators. The validators will decide if another validator is reliable or not -only by its local observation of the validation messages received. So an honest -validator’s vote on another validator’s reliability is accurate. + sufficient peer-to-peer network will propagate the validation messages to other + validators. The validators will decide if another validator is reliable or not + only by its local observation of the validation messages received. So an honest + validator’s vote on another validator’s reliability is accurate. 1. Given the votes are accurate, and one vote per validator, an honest validator -will not create a UNLModify transaction of a reliable validator. + will not create a UNLModify transaction of a reliable validator. 1. A validator can be added to a negative UNL only through a UNLModify -transaction. + transaction. Assuming the group of malicious validators is less than the quorum, they cannot frame a reliable validator. @@ -365,32 +356,32 @@ frame a reliable validator. The bullet points below briefly summarize the current proposal: -* The motivation of the negative UNL is to improve the liveness of the network. +- The motivation of the negative UNL is to improve the liveness of the network. -* The targeted faults are the ones frequently observed in the production +- The targeted faults are the ones frequently observed in the production network. -* Validators propose negative UNL candidates based on their local measurements. +- Validators propose negative UNL candidates based on their local measurements. -* The absolute minimum quorum is 60% of the original UNL. +- The absolute minimum quorum is 60% of the original UNL. -* The format of the ledger is changed, and a new *UNLModify* pseudo-transaction +- The format of the ledger is changed, and a new _UNLModify_ pseudo-transaction is added. Any tools or systems that rely on the format of these data will have to be updated. -* The negative UNL can only be modified on the flag ledgers. +- The negative UNL can only be modified on the flag ledgers. -* At most one validator can be added to the negative UNL at a flag ledger. +- At most one validator can be added to the negative UNL at a flag ledger. -* At most one validator can be removed from the negative UNL at a flag ledger. +- At most one validator can be removed from the negative UNL at a flag ledger. -* If a validator's reliability status changes, it takes two flag ledgers to +- If a validator's reliability status changes, it takes two flag ledgers to modify the negative UNL. -* The quorum is the larger of 80% of the effective UNL and 60% of the original +- The quorum is the larger of 80% of the effective UNL and 60% of the original UNL. -* If a validator is on the negative UNL, its validation messages are ignored +- If a validator is on the negative UNL, its validation messages are ignored when the local node verifies if a ledger is fully validated. ## FAQ @@ -415,7 +406,7 @@ lower quorum size while keeping the network safe. validator removed from the negative UNL? A validator’s reliability is measured by other validators. If a validator -becomes unreliable, at a flag ledger, other validators propose *UNLModify* +becomes unreliable, at a flag ledger, other validators propose _UNLModify_ pseudo-transactions which vote the validator to add to the negative UNL during the consensus session. If agreed, the validator is added to the negative UNL at the next flag ledger. The mechanism of removing a validator from the negative @@ -423,32 +414,32 @@ UNL is the same. ### Question: Given a negative UNL, what happens if the UNL changes? -Answer: Let’s consider the cases: +Answer: Let’s consider the cases: -1. A validator is added to the UNL, and it is already in the negative UNL. This -case could happen when not all the nodes have the same UNL. Note that the -negative UNL on the ledger lists unreliable nodes that are not necessarily the -validators for everyone. +1. A validator is added to the UNL, and it is already in the negative UNL. This + case could happen when not all the nodes have the same UNL. Note that the + negative UNL on the ledger lists unreliable nodes that are not necessarily the + validators for everyone. - In this case, the liveness is affected negatively. Because the minimum - quorum could be larger but the usable validators are not increased. + In this case, the liveness is affected negatively. Because the minimum + quorum could be larger but the usable validators are not increased. -1. A validator is removed from the UNL, and it is in the negative UNL. +1. A validator is removed from the UNL, and it is in the negative UNL. In this case, the liveness is affected positively. Because the quorum could be smaller but the usable validators are not reduced. -1. A validator is added to the UNL, and it is not in the negative UNL. -1. A validator is removed from the UNL, and it is not in the negative UNL. - +1. A validator is added to the UNL, and it is not in the negative UNL. +1. A validator is removed from the UNL, and it is not in the negative UNL. + Case 3 and 4 are not affected by the negative UNL protocol. -### Question: Can we simply lower the quorum to 60% without the negative UNL? +### Question: Can we simply lower the quorum to 60% without the negative UNL? Answer: No, because the negative UNL approach is safer. -First let’s compare the two approaches intuitively, (1) the *negative UNL* -approach, and (2) *lower quorum*: simply lowering the quorum from 80% to 60% +First let’s compare the two approaches intuitively, (1) the _negative UNL_ +approach, and (2) _lower quorum_: simply lowering the quorum from 80% to 60% without the negative UNL. The negative UNL approach uses consensus to come up with a list of unreliable validators, which are then removed from the effective UNL temporarily. With this approach, the list of unreliable validators is agreed @@ -462,75 +453,75 @@ Next we compare the two approaches quantitatively with examples, and apply Theorem 8 of [Analysis of the XRP Ledger Consensus Protocol](https://arxiv.org/abs/1802.07242) paper: -*XRP LCP guarantees fork safety if **Oi,j > nj / 2 + +_XRP LCP guarantees fork safety if **Oi,j > nj / 2 + ni − qi + ti,j** for every pair of nodes -Pi, Pj,* +Pi, Pj,_ -where *Oi,j* is the overlapping requirement, nj and +where _Oi,j_ is the overlapping requirement, nj and ni are UNL sizes, qi is the quorum size of Pi, -*ti,j = min(ti, tj, Oi,j)*, and +_ti,j = min(ti, tj, Oi,j)_, and ti and tj are the number of faults can be tolerated by Pi and Pj. -We denote *UNLi* as *Pi's UNL*, and *|UNLi|* as -the size of *Pi's UNL*. +We denote _UNLi_ as _Pi's UNL_, and _|UNLi|_ as +the size of _Pi's UNL_. -Assuming *|UNLi| = |UNLj|*, let's consider the following +Assuming _|UNLi| = |UNLj|_, let's consider the following three cases: -1. With 80% quorum and 20% faults, *Oi,j > 100% / 2 + 100% - 80% + -20% = 90%*. I.e. fork safety requires > 90% UNL overlaps. This is one of the -results in the analysis paper. +1. With 80% quorum and 20% faults, _Oi,j > 100% / 2 + 100% - 80% + + 20% = 90%_. I.e. fork safety requires > 90% UNL overlaps. This is one of the + results in the analysis paper. -1. If the quorum is 60%, the relationship between the overlapping requirement -and the faults that can be tolerated is *Oi,j > 90% + -ti,j*. Under the same overlapping condition (i.e. 90%), to guarantee -the fork safety, the network cannot tolerate any faults. So under the same -overlapping condition, if the quorum is simply lowered, the network can tolerate -fewer faults. +1. If the quorum is 60%, the relationship between the overlapping requirement + and the faults that can be tolerated is _Oi,j > 90% + + ti,j_. Under the same overlapping condition (i.e. 90%), to guarantee + the fork safety, the network cannot tolerate any faults. So under the same + overlapping condition, if the quorum is simply lowered, the network can tolerate + fewer faults. -1. With the negative UNL approach, we want to argue that the inequation -*Oi,j > nj / 2 + ni − qi + -ti,j* is always true to guarantee fork safety, while the negative UNL -protocol runs, i.e. the effective quorum is lowered without weakening the -network's fault tolerance. To make the discussion easier, we rewrite the -inequation as *Oi,j > nj / 2 + (ni − -qi) + min(ti, tj)*, where Oi,j is -dropped from the definition of ti,j because *Oi,j > -min(ti, tj)* always holds under the parameters we will -use. Assuming a validator V is added to the negative UNL, now let's consider the -4 cases: +1. With the negative UNL approach, we want to argue that the inequation + _Oi,j > nj / 2 + ni − qi + + ti,j_ is always true to guarantee fork safety, while the negative UNL + protocol runs, i.e. the effective quorum is lowered without weakening the + network's fault tolerance. To make the discussion easier, we rewrite the + inequation as _Oi,j > nj / 2 + (ni − + qi) + min(ti, tj)_, where Oi,j is + dropped from the definition of ti,j because _Oi,j > + min(ti, tj)_ always holds under the parameters we will + use. Assuming a validator V is added to the negative UNL, now let's consider the + 4 cases: - 1. V is not on UNLi nor UNLj + 1. V is not on UNLi nor UNLj - The inequation holds because none of the variables change. + The inequation holds because none of the variables change. - 1. V is on UNLi but not on UNLj + 1. V is on UNLi but not on UNLj - The value of *(ni − qi)* is smaller. The value of - *min(ti, tj)* could be smaller too. Other - variables do not change. Overall, the left side of the inequation does - not change, but the right side is smaller. So the inequation holds. - - 1. V is not on UNLi but on UNLj + The value of *(ni − qi)* is smaller. The value of + *min(ti, tj)* could be smaller too. Other + variables do not change. Overall, the left side of the inequation does + not change, but the right side is smaller. So the inequation holds. - The value of *nj / 2* is smaller. The value of - *min(ti, tj)* could be smaller too. Other - variables do not change. Overall, the left side of the inequation does - not change, but the right side is smaller. So the inequation holds. - - 1. V is on both UNLi and UNLj + 1. V is not on UNLi but on UNLj - The value of *Oi,j* is reduced by 1. The values of - *nj / 2*, *(ni − qi)*, and - *min(ti, tj)* are reduced by 0.5, 0.2, and 1 - respectively. The right side is reduced by 1.7. Overall, the left side - of the inequation is reduced by 1, and the right side is reduced by 1.7. - So the inequation holds. + The value of *nj / 2* is smaller. The value of + *min(ti, tj)* could be smaller too. Other + variables do not change. Overall, the left side of the inequation does + not change, but the right side is smaller. So the inequation holds. - The inequation holds for all the cases. So with the negative UNL approach, - the network's fork safety is preserved, while the quorum is lowered that - increases the network's liveness. + 1. V is on both UNLi and UNLj + + The value of *Oi,j* is reduced by 1. The values of + *nj / 2*, *(ni − qi)*, and + *min(ti, tj)* are reduced by 0.5, 0.2, and 1 + respectively. The right side is reduced by 1.7. Overall, the left side + of the inequation is reduced by 1, and the right side is reduced by 1.7. + So the inequation holds. + + The inequation holds for all the cases. So with the negative UNL approach, + the network's fork safety is preserved, while the quorum is lowered that + increases the network's liveness.

Question: We have observed that occasionally a validator wanders off on its own chain. How is this case handled by the negative UNL algorithm?

@@ -565,11 +556,11 @@ will be used after that. We want to see the test cases still pass with real network delay. A test case specifies: 1. a UNL with different number of validators for different test cases, -1. a network with zero or more non-validator nodes, +1. a network with zero or more non-validator nodes, 1. a sequence of validator reliability change events (by killing/restarting nodes, or by running modified rippled that does not send all validation messages), -1. the correct outcomes. +1. the correct outcomes. For all the test cases, the correct outcomes are verified by examining logs. We will grep the log to see if the correct negative UNLs are generated, and whether @@ -579,6 +570,7 @@ timing parameters of rippled will be changed to have faster ledger time. Most if not all test cases do not need client transactions. For example, the test cases for the prototype: + 1. A 10-validator UNL. 1. The network does not have other nodes. 1. The validators will be started from the genesis. Once they start to produce @@ -587,11 +579,11 @@ For example, the test cases for the prototype: 1. A sequence of events (or the lack of events) such as a killed validator is added to the negative UNL. -#### Roads Not Taken: Test with Extended CSF +#### Roads Not Taken: Test with Extended CSF We considered testing with the current unit test framework, specifically the [Consensus Simulation Framework](https://github.com/ripple/rippled/blob/develop/src/test/csf/README.md) (CSF). However, the CSF currently can only test the generic consensus algorithm as in the paper: [Analysis of the XRP Ledger Consensus -Protocol](https://arxiv.org/abs/1802.07242). \ No newline at end of file +Protocol](https://arxiv.org/abs/1802.07242). diff --git a/docs/0010-ledger-replay/README.md b/docs/0010-ledger-replay/README.md index 170fd15c43..c82d9b1906 100644 --- a/docs/0010-ledger-replay/README.md +++ b/docs/0010-ledger-replay/README.md @@ -82,7 +82,9 @@ pattern and the way coroutines are implemented, where every yield saves the spot in the code where it left off and every resume jumps back to that spot. ### Sequence Diagram + ![Sequence diagram](./ledger_replay_sequence.png?raw=true "A successful ledger replay") ### Class Diagram + ![Class diagram](./ledger_replay_classes.png?raw=true "Ledger replay classes") diff --git a/docs/CheatSheet.md b/docs/CheatSheet.md index 3b70c7c8f7..60a99f587a 100644 --- a/docs/CheatSheet.md +++ b/docs/CheatSheet.md @@ -16,5 +16,5 @@ ## Function - Minimize external dependencies - * Pass options in the ctor instead of using theConfig - * Use as few other classes as possible + - Pass options in the ctor instead of using theConfig + - Use as few other classes as possible diff --git a/docs/CodingStyle.md b/docs/CodingStyle.md index 0ff50c780d..3c26709047 100644 --- a/docs/CodingStyle.md +++ b/docs/CodingStyle.md @@ -1,18 +1,18 @@ # Coding Standards -Coding standards used here gradually evolve and propagate through +Coding standards used here gradually evolve and propagate through code reviews. Some aspects are enforced more strictly than others. ## Rules -These rules only apply to our own code. We can't enforce any sort of +These rules only apply to our own code. We can't enforce any sort of style on the external repositories and libraries we include. The best guideline is to maintain the standards that are used in those libraries. -* Tab inserts 4 spaces. No tab characters. -* Braces are indented in the [Allman style][1]. -* Modern C++ principles. No naked ```new``` or ```delete```. -* Line lengths limited to 80 characters. Exceptions limited to data and tables. +- Tab inserts 4 spaces. No tab characters. +- Braces are indented in the [Allman style][1]. +- Modern C++ principles. No naked `new` or `delete`. +- Line lengths limited to 80 characters. Exceptions limited to data and tables. ## Guidelines @@ -21,17 +21,17 @@ why you're doing it. Think, use common sense, and consider that this your changes will probably need to be maintained long after you've moved on to other projects. -* Use white space and blank lines to guide the eye and keep your intent clear. -* Put private data members at the top of a class, and the 6 public special -members immediately after, in the following order: - * Destructor - * Default constructor - * Copy constructor - * Copy assignment - * Move constructor - * Move assignment -* Don't over-inline by defining large functions within the class -declaration, not even for template classes. +- Use white space and blank lines to guide the eye and keep your intent clear. +- Put private data members at the top of a class, and the 6 public special + members immediately after, in the following order: + - Destructor + - Default constructor + - Copy constructor + - Copy assignment + - Move constructor + - Move assignment +- Don't over-inline by defining large functions within the class + declaration, not even for template classes. ## Formatting @@ -39,44 +39,44 @@ The goal of source code formatting should always be to make things as easy to read as possible. White space is used to guide the eye so that details are not overlooked. Blank lines are used to separate code into "paragraphs." -* Always place a space before and after all binary operators, +- Always place a space before and after all binary operators, especially assignments (`operator=`). -* The `!` operator should be preceded by a space, but not followed by one. -* The `~` operator should be preceded by a space, but not followed by one. -* The `++` and `--` operators should have no spaces between the operator and +- The `!` operator should be preceded by a space, but not followed by one. +- The `~` operator should be preceded by a space, but not followed by one. +- The `++` and `--` operators should have no spaces between the operator and the operand. -* A space never appears before a comma, and always appears after a comma. -* Don't put spaces after a parenthesis. A typical member function call might +- A space never appears before a comma, and always appears after a comma. +- Don't put spaces after a parenthesis. A typical member function call might look like this: `foobar (1, 2, 3);` -* In general, leave a blank line before an `if` statement. -* In general, leave a blank line after a closing brace `}`. -* Do not place code on the same line as any opening or +- In general, leave a blank line before an `if` statement. +- In general, leave a blank line after a closing brace `}`. +- Do not place code on the same line as any opening or closing brace. -* Do not write `if` statements all-on-one-line. The exception to this is when +- Do not write `if` statements all-on-one-line. The exception to this is when you've got a sequence of similar `if` statements, and are aligning them all vertically to highlight their similarities. -* In an `if-else` statement, if you surround one half of the statement with +- In an `if-else` statement, if you surround one half of the statement with braces, you also need to put braces around the other half, to match. -* When writing a pointer type, use this spacing: `SomeObject* myObject`. +- When writing a pointer type, use this spacing: `SomeObject* myObject`. Technically, a more correct spacing would be `SomeObject *myObject`, but it makes more sense for the asterisk to be grouped with the type name, since being a pointer is part of the type, not the variable name. The only time that this can lead to any problems is when you're declaring multiple pointers of the same type in the same statement - which leads on to the next rule: -* When declaring multiple pointers, never do so in a single statement, e.g. +- When declaring multiple pointers, never do so in a single statement, e.g. `SomeObject* p1, *p2;` - instead, always split them out onto separate lines and write the type name again, to make it quite clear what's going on, and avoid the danger of missing out any vital asterisks. -* The previous point also applies to references, so always put the `&` next to +- The previous point also applies to references, so always put the `&` next to the type rather than the variable, e.g. `void foo (Thing const& thing)`. And don't put a space on both sides of the `*` or `&` - always put a space after it, but never before it. -* The word `const` should be placed to the right of the thing that it modifies, +- The word `const` should be placed to the right of the thing that it modifies, for consistency. For example `int const` refers to an int which is const. `int const*` is a pointer to an int which is const. `int *const` is a const pointer to an int. -* Always place a space in between the template angle brackets and the type +- Always place a space in between the template angle brackets and the type name. Template code is already hard enough to read! [1]: http://en.wikipedia.org/wiki/Indent_style#Allman_style diff --git a/docs/HeapProfiling.md b/docs/HeapProfiling.md index c8de1eb26f..2871cccaba 100644 --- a/docs/HeapProfiling.md +++ b/docs/HeapProfiling.md @@ -31,7 +31,7 @@ and header under /opt/local/include: $ scons clang profile-jemalloc=/opt/local ----------------------- +--- ## Using the jemalloc library from within the code @@ -60,4 +60,3 @@ Linking against the jemalloc library will override the system's default `malloc()` and related functions with jemalloc's implementation. This is the case even if the code is not instrumented to use jemalloc's specific API. - diff --git a/docs/README.md b/docs/README.md index 55b9e30e04..c95a871729 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,6 @@ Install these dependencies: - [Doxygen](http://www.doxygen.nl): All major platforms have [official binary distributions](http://www.doxygen.nl/download.html#srcbin), or you can build from [source](http://www.doxygen.nl/download.html#srcbin). - - MacOS: We recommend installing via Homebrew: `brew install doxygen`. The executable will be installed in `/usr/local/bin` which is already in the default `PATH`. @@ -21,18 +20,15 @@ Install these dependencies: $ ln -s /Applications/Doxygen.app/Contents/Resources/doxygen /usr/local/bin/doxygen ``` -- [PlantUML](http://plantuml.com): - +- [PlantUML](http://plantuml.com): 1. Install a functioning Java runtime, if you don't already have one. 2. Download [`plantuml.jar`](http://sourceforge.net/projects/plantuml/files/plantuml.jar/download). - [Graphviz](https://www.graphviz.org): - - Linux: Install from your package manager. - Windows: Use an [official installer](https://graphviz.gitlab.io/_pages/Download/Download_windows.html). - MacOS: Install via Homebrew: `brew install graphviz`. - ## Docker Instead of installing the above dependencies locally, you can use the official @@ -40,14 +36,16 @@ build environment Docker image, which has all of them installed already. 1. Install [Docker](https://docs.docker.com/engine/installation/) 2. Pull the image: - ``` - sudo docker pull rippleci/rippled-ci-builder:2944b78d22db - ``` -3. Run the image from the project folder: - ``` - sudo docker run -v $PWD:/opt/rippled --rm rippleci/rippled-ci-builder:2944b78d22db - ``` +``` +sudo docker pull rippleci/rippled-ci-builder:2944b78d22db +``` + +3. Run the image from the project folder: + +``` +sudo docker run -v $PWD:/opt/rippled --rm rippleci/rippled-ci-builder:2944b78d22db +``` ## Build diff --git a/docs/build/conan.md b/docs/build/conan.md index 5f1ff7ae98..9dcd2c8f1c 100644 --- a/docs/build/conan.md +++ b/docs/build/conan.md @@ -5,7 +5,6 @@ we should first understand _why_ we use Conan, and to understand that, we need to understand how we use CMake. - ### CMake Technically, you don't need CMake to build this project. @@ -33,9 +32,9 @@ Parameters include: - where to find the compiler and linker - where to find dependencies, e.g. libraries and headers - how to link dependencies, e.g. any special compiler or linker flags that - need to be used with them, including preprocessor definitions + need to be used with them, including preprocessor definitions - how to compile translation units, e.g. with optimizations, debug symbols, - position-independent code, etc. + position-independent code, etc. - on Windows, which runtime library to link with For some of these parameters, like the build system and compiler, @@ -54,7 +53,6 @@ Most humans prefer to put them into a configuration file, once, that CMake can read every time it is configured. For CMake, that file is a [toolchain file][toolchain]. - ### Conan These next few paragraphs on Conan are going to read much like the ones above @@ -79,10 +77,10 @@ Those files include: - A single toolchain file. - For every dependency, a CMake [package configuration file][pcf], - [package version file][pvf], and for every build type, a package - targets file. - Together, these files implement version checking and define `IMPORTED` - targets for the dependencies. + [package version file][pvf], and for every build type, a package + targets file. + Together, these files implement version checking and define `IMPORTED` + targets for the dependencies. The toolchain file itself amends the search path ([`CMAKE_PREFIX_PATH`][prefix_path]) so that [`find_package()`][find_package] diff --git a/docs/build/depend.md b/docs/build/depend.md index 42fd41a26e..2fa14378aa 100644 --- a/docs/build/depend.md +++ b/docs/build/depend.md @@ -2,8 +2,7 @@ We recommend two different methods to depend on libxrpl in your own [CMake][] project. Both methods add a CMake library target named `xrpl::libxrpl`. - -## Conan requirement +## Conan requirement The first method adds libxrpl as a [Conan][] requirement. With this method, there is no need for a Git [submodule][]. @@ -48,7 +47,6 @@ cmake \ cmake --build . --parallel ``` - ## CMake subdirectory The second method adds the [rippled][] project as a CMake @@ -90,7 +88,6 @@ cmake \ cmake --build . --parallel ``` - [add_subdirectory]: https://cmake.org/cmake/help/latest/command/add_subdirectory.html [submodule]: https://git-scm.com/book/en/v2/Git-Tools-Submodules [rippled]: https://github.com/ripple/rippled diff --git a/docs/build/environment.md b/docs/build/environment.md index 7301879d09..c6b735ba48 100644 --- a/docs/build/environment.md +++ b/docs/build/environment.md @@ -5,7 +5,6 @@ platforms: Linux, macOS, or Windows. [BUILD.md]: ../../BUILD.md - ## Linux Package ecosystems vary across Linux distributions, @@ -53,11 +52,10 @@ clang --version ### Install Xcode Specific Version (Optional) -If you develop other applications using XCode you might be consistently updating to the newest version of Apple Clang. +If you develop other applications using XCode you might be consistently updating to the newest version of Apple Clang. This will likely cause issues building rippled. You may want to install a specific version of Xcode: 1. **Download Xcode** - - Visit [Apple Developer Downloads](https://developer.apple.com/download/more/) - Sign in with your Apple Developer account - Search for an Xcode version that includes **Apple Clang (Expected Version)** diff --git a/docs/build/install.md b/docs/build/install.md index af0d6f335c..7be01ce726 100644 --- a/docs/build/install.md +++ b/docs/build/install.md @@ -6,7 +6,6 @@ like CentOS. Installing from source is an option for all platforms, and the only supported option for installing custom builds. - ## From source From a source build, you can install rippled and libxrpl using CMake's @@ -21,25 +20,23 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and [1]: https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html - ## With the APT package manager -1. Update repositories: +1. Update repositories: sudo apt update -y -2. Install utilities: +2. Install utilities: sudo apt install -y apt-transport-https ca-certificates wget gnupg -3. Add Ripple's package-signing GPG key to your list of trusted keys: +3. Add Ripple's package-signing GPG key to your list of trusted keys: sudo mkdir /usr/local/share/keyrings/ wget -q -O - "https://repos.ripple.com/repos/api/gpg/key/public" | gpg --dearmor > ripple-key.gpg sudo mv ripple-key.gpg /usr/local/share/keyrings - -4. Check the fingerprint of the newly-added key: +4. Check the fingerprint of the newly-added key: gpg /usr/local/share/keyrings/ripple-key.gpg @@ -51,37 +48,34 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and uid TechOps Team at Ripple sub rsa3072 2019-02-14 [E] [expires: 2026-02-17] - In particular, make sure that the fingerprint matches. (In the above example, the fingerprint is on the third line, starting with `C001`.) -4. Add the appropriate Ripple repository for your operating system version: +5. Add the appropriate Ripple repository for your operating system version: echo "deb [signed-by=/usr/local/share/keyrings/ripple-key.gpg] https://repos.ripple.com/repos/rippled-deb focal stable" | \ sudo tee -a /etc/apt/sources.list.d/ripple.list The above example is appropriate for **Ubuntu 20.04 Focal Fossa**. For other operating systems, replace the word `focal` with one of the following: - - `jammy` for **Ubuntu 22.04 Jammy Jellyfish** - `bionic` for **Ubuntu 18.04 Bionic Beaver** - `bullseye` for **Debian 11 Bullseye** - `buster` for **Debian 10 Buster** If you want access to development or pre-release versions of `rippled`, use one of the following instead of `stable`: - - `unstable` - Pre-release builds ([`release` branch](https://github.com/ripple/rippled/tree/release)) - `nightly` - Experimental/development builds ([`develop` branch](https://github.com/ripple/rippled/tree/develop)) **Warning:** Unstable and nightly builds may be broken at any time. Do not use these builds for production servers. -5. Fetch the Ripple repository. +6. Fetch the Ripple repository. sudo apt -y update -6. Install the `rippled` software package: +7. Install the `rippled` software package: sudo apt -y install rippled -7. Check the status of the `rippled` service: +8. Check the status of the `rippled` service: systemctl status rippled.service @@ -89,24 +83,22 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and sudo systemctl start rippled.service -8. Optional: allow `rippled` to bind to privileged ports. +9. Optional: allow `rippled` to bind to privileged ports. This allows you to serve incoming API requests on port 80 or 443. (If you want to do so, you must also update the config file's port settings.) sudo setcap 'cap_net_bind_service=+ep' /opt/ripple/bin/rippled - ## With the YUM package manager -1. Install the Ripple RPM repository: +1. Install the Ripple RPM repository: Choose the appropriate RPM repository for the stability of releases you want: - - `stable` for the latest production release (`master` branch) - `unstable` for pre-release builds (`release` branch) - `nightly` for experimental/development builds (`develop` branch) - *Stable* + _Stable_ cat << REPOFILE | sudo tee /etc/yum.repos.d/ripple.repo [ripple-stable] @@ -118,7 +110,7 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and gpgkey=https://repos.ripple.com/repos/rippled-rpm/stable/repodata/repomd.xml.key REPOFILE - *Unstable* + _Unstable_ cat << REPOFILE | sudo tee /etc/yum.repos.d/ripple.repo [ripple-unstable] @@ -130,7 +122,7 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and gpgkey=https://repos.ripple.com/repos/rippled-rpm/unstable/repodata/repomd.xml.key REPOFILE - *Nightly* + _Nightly_ cat << REPOFILE | sudo tee /etc/yum.repos.d/ripple.repo [ripple-nightly] @@ -142,18 +134,18 @@ The default [prefix][1] is typically `/usr/local` on Linux and macOS and gpgkey=https://repos.ripple.com/repos/rippled-rpm/nightly/repodata/repomd.xml.key REPOFILE -2. Fetch the latest repo updates: +2. Fetch the latest repo updates: sudo yum -y update -3. Install the new `rippled` package: +3. Install the new `rippled` package: sudo yum install -y rippled -4. Configure the `rippled` service to start on boot: +4. Configure the `rippled` service to start on boot: sudo systemctl enable rippled.service -5. Start the `rippled` service: +5. Start the `rippled` service: sudo systemctl start rippled.service diff --git a/docs/consensus.md b/docs/consensus.md index 4ee5aa70dc..067e15d0c8 100644 --- a/docs/consensus.md +++ b/docs/consensus.md @@ -3,7 +3,7 @@ **This section is a work in progress!!** Consensus is the task of reaching agreement within a distributed system in the -presence of faulty or even malicious participants. This document outlines the +presence of faulty or even malicious participants. This document outlines the [XRP Ledger Consensus Algorithm](https://arxiv.org/abs/1802.07242) as implemented in [rippled](https://github.com/ripple/rippled), but focuses on its utility as a generic consensus algorithm independent of the @@ -15,38 +15,38 @@ collectively trusted subnetworks. ## Distributed Agreement A challenge for distributed systems is reaching agreement on changes in shared -state. For the Ripple network, the shared state is the current ledger--account -information, account balances, order books and other financial data. We will +state. For the Ripple network, the shared state is the current ledger--account +information, account balances, order books and other financial data. We will refer to shared distributed state as a /ledger/ throughout the remainder of this document. ![Ledger Chain](images/consensus/ledger_chain.png "Ledger Chain") As shown above, new ledgers are made by applying a set of transactions to the -prior ledger. For the Ripple network, transactions include payments, +prior ledger. For the Ripple network, transactions include payments, modification of account settings, updates to offers and more. In a centralized system, generating the next ledger is trivial since there is a single unique arbiter of which transactions to include and how to apply them to -a ledger. For decentralized systems, participants must resolve disagreements on +a ledger. For decentralized systems, participants must resolve disagreements on the set of transactions to include, the order to apply those transactions, and -even the resulting ledger after applying the transactions. This is even more +even the resulting ledger after applying the transactions. This is even more difficult when some participants are faulty or malicious. -The Ripple network is a decentralized and **trust-full** network. Anyone is free +The Ripple network is a decentralized and **trust-full** network. Anyone is free to join and participants are free to choose a subset of peers that are collectively trusted to not collude in an attempt to defraud the participant. Leveraging this network of trust, the Ripple algorithm has two main components. -* *Consensus* in which network participants agree on the transactions to apply +- _Consensus_ in which network participants agree on the transactions to apply to a prior ledger, based on the positions of their chosen peers. -* *Validation* in which network participants agree on what ledger was +- _Validation_ in which network participants agree on what ledger was generated, based on the ledgers generated by chosen peers. These phases are continually repeated to process transactions submitted to the network, generating successive ledgers and giving rise to the blockchain ledger -history depicted below. In this diagram, time is flowing to the right, but -links between ledgers point backward to the parent. Also note the alternate +history depicted below. In this diagram, time is flowing to the right, but +links between ledgers point backward to the parent. Also note the alternate Ledger 2 that was generated by some participants, but which failed validation and was abandoned. @@ -54,7 +54,7 @@ and was abandoned. The remainder of this section describes the Consensus and Validation algorithms in more detail and is meant as a companion guide to understanding the generic -implementation in `rippled`. The document **does not** discuss correctness, +implementation in `rippled`. The document **does not** discuss correctness, fault-tolerance or liveness properties of the algorithms or the full details of how they integrate within `rippled` to support the Ripple Consensus Ledger. @@ -62,76 +62,76 @@ how they integrate within `rippled` to support the Ripple Consensus Ledger. ### Definitions -* The *ledger* is the shared distributed state. Each ledger has a unique ID to - distinguish it from all other ledgers. During consensus, the *previous*, - *prior* or *last-closed* ledger is the most recent ledger seen by consensus +- The _ledger_ is the shared distributed state. Each ledger has a unique ID to + distinguish it from all other ledgers. During consensus, the _previous_, + _prior_ or _last-closed_ ledger is the most recent ledger seen by consensus and is the basis upon which it will build the next ledger. -* A *transaction* is an instruction for an atomic change in the ledger state. A +- A _transaction_ is an instruction for an atomic change in the ledger state. A unique ID distinguishes a transaction from other transactions. -* A *transaction set* is a set of transactions under consideration by consensus. - The goal of consensus is to reach agreement on this set. The generic +- A _transaction set_ is a set of transactions under consideration by consensus. + The goal of consensus is to reach agreement on this set. The generic consensus algorithm does not rely on an ordering of transactions within the set, nor does it specify how to apply a transaction set to a ledger to - generate a new ledger. A unique ID distinguishes a set of transactions from + generate a new ledger. A unique ID distinguishes a set of transactions from all other sets of transactions. -* A *node* is one of the distributed actors running the consensus algorithm. It +- A _node_ is one of the distributed actors running the consensus algorithm. It has a unique ID to distinguish it from all other nodes. -* A *peer* of a node is another node that it has chosen to follow and which it - believes will not collude with other chosen peers. The choice of peers is not +- A _peer_ of a node is another node that it has chosen to follow and which it + believes will not collude with other chosen peers. The choice of peers is not symmetric, since participants can decide on their chosen sets independently. -* A /position/ is the current belief of the next ledger's transaction set and +- A /position/ is the current belief of the next ledger's transaction set and close time. Position can refer to the node's own position or the position of a peer. -* A *proposal* is one of a sequence of positions a node shares during consensus. +- A _proposal_ is one of a sequence of positions a node shares during consensus. An initial proposal contains the starting position taken by a node before it - considers any peer positions. If a node subsequently updates its position in - response to its peers, it will issue an updated proposal. A proposal is + considers any peer positions. If a node subsequently updates its position in + response to its peers, it will issue an updated proposal. A proposal is uniquely identified by the ID of the proposing node, the ID of the position taken, the ID of the prior ledger the proposal is for, and the sequence number of the proposal. -* A *dispute* is a transaction that is either not part of a node's position or +- A _dispute_ is a transaction that is either not part of a node's position or not in a peer's position. During consensus, the node will add or remove disputed transactions from its position based on that transaction's support amongst its peers. Note that most types have an ID as a lightweight identifier of instances of that -type. Consensus often operates on the IDs directly since the underlying type is -potentially expensive to share over the network. For example, proposal's only -contain the ID of the position of a peer. Since many peers likely have the same +type. Consensus often operates on the IDs directly since the underlying type is +potentially expensive to share over the network. For example, proposal's only +contain the ID of the position of a peer. Since many peers likely have the same position, this reduces the need to send the full transaction set multiple times. Instead, a node can request the transaction set from the network if necessary. -### Overview +### Overview ![Consensus Overview](images/consensus/consensus_overview.png "Consensus Overview") The diagram above is an overview of the consensus process from the perspective -of a single participant. Recall that during a single consensus round, a node is +of a single participant. Recall that during a single consensus round, a node is trying to agree with its peers on which transactions to apply to its prior -ledger when generating the next ledger. It also attempts to agree on the -[network time when the ledger closed](#effective_close_time). There are +ledger when generating the next ledger. It also attempts to agree on the +[network time when the ledger closed](#effective_close_time). There are 3 main phases to a consensus round: -* A call to `startRound` places the node in the `Open` phase. In this phase, -the node is waiting for transactions to include in its open ledger. -* At some point, the node will `Close` the open ledger and transition to the -`Establish` phase. In this phase, the node shares/receives peer proposals on -which transactions should be accepted in the closed ledger. -* At some point, the node determines it has reached consensus with its peers on -which transactions to include. It transitions to the `Accept` phase. In this -phase, the node works on applying the transactions to the prior ledger to -generate a new closed ledger. Once the new ledger is completed, the node shares -the validated ledger hash with the network and makes a call to `startRound` to -start the cycle again for the next ledger. +- A call to `startRound` places the node in the `Open` phase. In this phase, + the node is waiting for transactions to include in its open ledger. +- At some point, the node will `Close` the open ledger and transition to the + `Establish` phase. In this phase, the node shares/receives peer proposals on + which transactions should be accepted in the closed ledger. +- At some point, the node determines it has reached consensus with its peers on + which transactions to include. It transitions to the `Accept` phase. In this + phase, the node works on applying the transactions to the prior ledger to + generate a new closed ledger. Once the new ledger is completed, the node shares + the validated ledger hash with the network and makes a call to `startRound` to + start the cycle again for the next ledger. Throughout, a heartbeat timer calls `timerEntry` at a regular frequency to drive the process forward. Although the `startRound` call occurs at arbitrary times based on when the initial round began and the time it takes to apply transactions, the transitions from `Open` to `Establish` and `Establish` to -`Accept` only occur during calls to `timerEntry`. Similarly, transactions can +`Accept` only occur during calls to `timerEntry`. Similarly, transactions can arrive at arbitrary times, independent of the heartbeat timer. Transactions received after the `Open` to `Close` transition and not part of peer proposals -won't be considered until the next consensus round. They are represented above +won't be considered until the next consensus round. They are represented above by the light green triangles. Peer proposals are issued by a node during a `timerEntry` call, but since peers @@ -139,16 +139,16 @@ do not synchronize `timerEntry` calls, they are received by other peers at arbitrary times. Peer proposals are only considered if received prior to the `Establish` to `Accept` transition, and only if the peer is working on the same prior ledger. Peer proposals received after consensus is reached will not be -meaningful and are represented above by the circle with the X in it. Only +meaningful and are represented above by the circle with the X in it. Only proposals from chosen peers are considered. -### Effective Close Time ### {#effective_close_time} - +### Effective Close Time ### {#effective_close_time} + In addition to agreeing on a transaction set, each consensus round tries to -agree on the time the ledger closed. Each node calculates its own close time -when it closes the open ledger. This exact close time is rounded to the nearest -multiple of the current *effective close time resolution*. It is this -*effective close time* that nodes seek to agree on. This allows servers to +agree on the time the ledger closed. Each node calculates its own close time +when it closes the open ledger. This exact close time is rounded to the nearest +multiple of the current _effective close time resolution_. It is this +_effective close time_ that nodes seek to agree on. This allows servers to derive a common time for a ledger without the need for perfectly synchronized clocks. As depicted below, the 3 pink arrows represent exact close times from 3 consensus nodes that round to the same effective close time given the current @@ -158,9 +158,9 @@ different effective close time given the current resolution. ![Effective Close Time](images/consensus/EffCloseTime.png "Effective Close Time") The effective close time is part of the node's position and is shared with peers -in its proposals. Just like the position on the consensus transaction set, a +in its proposals. Just like the position on the consensus transaction set, a node will update its close time position in response to its peers' effective -close time positions. Peers can agree to disagree on the close time, in which +close time positions. Peers can agree to disagree on the close time, in which case the effective close time is taken as 1 second past the prior close. The close time resolution is itself dynamic, decreasing (coarser) resolution in @@ -173,12 +173,12 @@ reach close time consensus. Internally, a node operates under one of the following consensus modes. Either of the first two modes may be chosen when a consensus round starts. -* *Proposing* indicates the node is a full-fledged consensus participant. It +- _Proposing_ indicates the node is a full-fledged consensus participant. It takes on positions and sends proposals to its peers. -* *Observing* indicates the node is a passive consensus participant. It +- _Observing_ indicates the node is a passive consensus participant. It maintains a position internally, but does not propose that position to its peers. Instead, it receives peer proposals and updates its position - to track the majority of its peers. This may be preferred if the node is only + to track the majority of its peers. This may be preferred if the node is only being used to track the state of the network or during a start-up phase while it is still synchronizing with the network. @@ -186,14 +186,14 @@ The other two modes are set internally during the consensus round when the node believes it is no longer working on the dominant ledger chain based on peer validations. It checks this on every call to `timerEntry`. -* *Wrong Ledger* indicates the node is not working on the correct prior ledger - and does not have it available. It requests that ledger from the network, but - continues to work towards consensus this round while waiting. If it had been - *proposing*, it will send a special "bowout" proposal to its peers to indicate +- _Wrong Ledger_ indicates the node is not working on the correct prior ledger + and does not have it available. It requests that ledger from the network, but + continues to work towards consensus this round while waiting. If it had been + _proposing_, it will send a special "bowout" proposal to its peers to indicate its change in mode for the rest of this round. For the duration of the round, it defers to peer positions for determining the consensus outcome as if it - were just *observing*. -* *Switch Ledger* indicates that the node has acquired the correct prior ledger + were just _observing_. +- _Switch Ledger_ indicates that the node has acquired the correct prior ledger from the network. Although it now has the correct prior ledger, the fact that it had the wrong one at some point during this round means it is likely behind and should defer to peer positions for determining the consensus outcome. @@ -201,7 +201,7 @@ validations. It checks this on every call to `timerEntry`. ![Consensus Modes](images/consensus/consensus_modes.png "Consensus Modes") Once either wrong ledger or switch ledger are reached, the node cannot -return to proposing or observing until the next consensus round. However, +return to proposing or observing until the next consensus round. However, the node could change its view of the correct prior ledger, so going from switch ledger to wrong ledger and back again is possible. @@ -215,16 +215,16 @@ decide how best to generate the next ledger once it declares consensus. ### Phases As depicted in the overview diagram, consensus is best viewed as a progression -through 3 phases. There are 4 public methods of the generic consensus algorithm +through 3 phases. There are 4 public methods of the generic consensus algorithm that determine this progression -* `startRound` begins a consensus round. -* `timerEntry` is called at a regular frequency (`LEDGER_MIN_CLOSE`) and is the - only call to consensus that can change the phase from `Open` to `Establish` +- `startRound` begins a consensus round. +- `timerEntry` is called at a regular frequency (`LEDGER_MIN_CLOSE`) and is the + only call to consensus that can change the phase from `Open` to `Establish` or `Accept`. -* `peerProposal` is called whenever a peer proposal is received and is what +- `peerProposal` is called whenever a peer proposal is received and is what allows a node to update its position in a subsequent `timerEntry` call. -* `gotTxSet` is called when a transaction set is received from the network. This +- `gotTxSet` is called when a transaction set is received from the network. This is typically in response to a prior request from the node to acquire the transaction set corresponding to a disagreeing peer's position. @@ -234,13 +234,13 @@ actions are taken in response to these calls. #### Open The `Open` phase is a quiescent period to allow transactions to build up in the -node's open ledger. The duration is a trade-off between latency and throughput. +node's open ledger. The duration is a trade-off between latency and throughput. A shorter window reduces the latency to generating the next ledger, but also reduces transaction throughput due to fewer transactions accepted into the ledger. A call to `startRound` would forcibly begin the next consensus round, skipping -completion of the current round. This is not expected during normal operation. +completion of the current round. This is not expected during normal operation. Calls to `peerProposal` or `gotTxSet` simply store the proposal or transaction set for use in the coming `Establish` phase. @@ -254,28 +254,27 @@ the ledger. Under normal circumstances, the open ledger period ends when one of the following is true -* if there are transactions in the open ledger and more than `LEDGER_MIN_CLOSE` - have elapsed. This is the typical behavior. -* if there are no open transactions and a suitably longer idle interval has - elapsed. This increases the opportunity to get some transaction into +- if there are transactions in the open ledger and more than `LEDGER_MIN_CLOSE` + have elapsed. This is the typical behavior. +- if there are no open transactions and a suitably longer idle interval has + elapsed. This increases the opportunity to get some transaction into the next ledger and avoids doing useless work closing an empty ledger. -* if more than half the number of prior round peers have already closed or finished +- if more than half the number of prior round peers have already closed or finished this round. This indicates the node is falling behind and needs to catch up. - When closing the ledger, the node takes its initial position based on the transactions in the open ledger and uses the current time as -its initial close time estimate. If in the proposing mode, the node shares its -initial position with peers. Now that the node has taken a position, it will -consider any peer positions for this round that arrived earlier. The node +its initial close time estimate. If in the proposing mode, the node shares its +initial position with peers. Now that the node has taken a position, it will +consider any peer positions for this round that arrived earlier. The node generates disputed transactions for each transaction not in common with a peer's -position. The node also records the vote of each peer for each disputed +position. The node also records the vote of each peer for each disputed transaction. -In the example below, we suppose our node has closed with transactions 1,2 and 3. It creates disputes +In the example below, we suppose our node has closed with transactions 1,2 and 3. It creates disputes for transactions 2,3 and 4, since at least one peer position differs on each. -##### disputes ##### {#disputes_image} +##### disputes ##### {#disputes_image} ![Disputes](images/consensus/disputes.png "Disputes") @@ -286,22 +285,22 @@ exchanges proposals with peers in an attempt to reach agreement on the consensus transactions and effective close time. A call to `startRound` would forcibly begin the next consensus round, skipping -completion of the current round. This is not expected during normal operation. +completion of the current round. This is not expected during normal operation. Calls to `peerProposal` or `gotTxSet` that reflect new positions will generate disputed transactions for any new disagreements and will update the peer's vote for all disputed transactions. A call to `timerEntry` first checks that the node is working from the correct -prior ledger. If not, the node will update the mode and request the correct -ledger. Otherwise, the node updates the node's position and considers whether -to switch to the `Accepted` phase and declare consensus reached. However, at -least `LEDGER_MIN_CONSENSUS` time must have elapsed before doing either. This +prior ledger. If not, the node will update the mode and request the correct +ledger. Otherwise, the node updates the node's position and considers whether +to switch to the `Accepted` phase and declare consensus reached. However, at +least `LEDGER_MIN_CONSENSUS` time must have elapsed before doing either. This allows peers an opportunity to take an initial position and share it. ##### Update Position In order to achieve consensus, the node is looking for a transaction set that is -supported by a super-majority of peers. The node works towards this set by +supported by a super-majority of peers. The node works towards this set by adding or removing disputed transactions from its position based on an increasing threshold for inclusion. @@ -310,23 +309,23 @@ increasing threshold for inclusion. By starting with a lower threshold, a node initially allows a wide set of transactions into its position. If the establish round continues and the node is "stuck", a higher threshold can focus on accepting transactions with the most -support. The constants that define the thresholds and durations at which the +support. The constants that define the thresholds and durations at which the thresholds change are given by `AV_XXX_CONSENSUS_PCT` and `AV_XXX_CONSENSUS_TIME` respectively, where `XXX` is `INIT`,`MID`,`LATE` and -`STUCK`. The effective close time position is updated using the same +`STUCK`. The effective close time position is updated using the same thresholds. Given the [example disputes above](#disputes_image) and an initial threshold of 50%, our node would retain its position since transaction 1 was not in -dispute and transactions 2 and 3 have 75% support. Since its position did not -change, it would not need to send a new proposal to peers. Peer C would not +dispute and transactions 2 and 3 have 75% support. Since its position did not +change, it would not need to send a new proposal to peers. Peer C would not change either. Peer A would add transaction 3 to its position and Peer B would remove transaction 4 from its position; both would then send an updated position. Conversely, if the diagram reflected a later call to =timerEntry= that occurs in the stuck region with a threshold of say 95%, our node would remove transactions -2 and 3 from its candidate set and send an updated position. Likewise, all the +2 and 3 from its candidate set and send an updated position. Likewise, all the other peers would end up with only transaction 1 in their position. Lastly, if our node were not in the proposing mode, it would not include its own @@ -336,7 +335,7 @@ our node would maintain its position of transactions 1, 2 and 3. ##### Checking Consensus After updating its position, the node checks for supermajority agreement with -its peers on its current position. This agreement is of the exact transaction +its peers on its current position. This agreement is of the exact transaction set, not just the support of individual transactions. That is, if our position is a subset of a peer's position, that counts as a disagreement. Also recall that effective close time agreement allows a supermajority of participants @@ -344,10 +343,10 @@ agreeing to disagree. Consensus is declared when the following 3 clauses are true: -* `LEDGER_MIN_CONSENSUS` time has elapsed in the establish phase -* At least 75% of the prior round proposers have proposed OR this establish +- `LEDGER_MIN_CONSENSUS` time has elapsed in the establish phase +- At least 75% of the prior round proposers have proposed OR this establish phase is `LEDGER_MIN_CONSENSUS` longer than the last round's establish phase -* `minimumConsensusPercentage` of ourself and our peers share the same position +- `minimumConsensusPercentage` of ourself and our peers share the same position The middle condition ensures slower peers have a chance to share positions, but prevents waiting too long on peers that have disconnected. Additionally, a node @@ -364,22 +363,22 @@ logic. Once consensus is reached (or moved on), the node switches to the `Accept` phase and signals to the implementing code that the round is complete. That code is responsible for using the consensus transaction set to generate the next ledger -and calling `startRound` to begin the next round. The implementation has total +and calling `startRound` to begin the next round. The implementation has total freedom on ordering transactions, deciding what to do if consensus moved on, determining whether to retry or abandon local transactions that did not make the consensus set and updating any internal state based on the consensus progress. #### Accept -The `Accept` phase is the terminal phase of the consensus algorithm. Calls to +The `Accept` phase is the terminal phase of the consensus algorithm. Calls to `timerEntry`, `peerProposal` and `gotTxSet` will not change the internal -consensus state while in the accept phase. The expectation is that the +consensus state while in the accept phase. The expectation is that the application specific code is working to generate the new ledger based on the consensus outcome. Once complete, that code should make a call to `startRound` to kick off the next consensus round. The `startRound` call includes the new prior ledger, prior ledger ID and whether the round should begin in the -proposing or observing mode. After setting some initial state, the phase -transitions to `Open`. The node will also check if the provided prior ledger +proposing or observing mode. After setting some initial state, the phase +transitions to `Open`. The node will also check if the provided prior ledger and ID are correct, updating the mode and requesting the proper ledger from the network if necessary. @@ -448,9 +447,9 @@ struct TxSet ### Ledger The `Ledger` type represents the state shared amongst the -distributed participants. Notice that the details of how the next ledger is +distributed participants. Notice that the details of how the next ledger is generated from the prior ledger and the consensus accepted transaction set is -not part of the interface. Within the generic code, this type is primarily used +not part of the interface. Within the generic code, this type is primarily used to know that peers are working on the same tip of the ledger chain and to provide some basic timing data for consensus. @@ -626,7 +625,7 @@ struct Adaptor // Called when consensus operating mode changes void onModeChange(ConsensuMode before, ConsensusMode after); - + // Called when ledger closes. Implementation should generate an initial Result // with position based on the current open ledger's transactions. ConsensusResult onClose(Ledger const &, Ledger const & prev, ConsensusMode mode); @@ -657,27 +656,24 @@ struct Adaptor The implementing class hides many details of the peer communication model from the generic code. -* The `share` member functions are responsible for sharing the given type with a +- The `share` member functions are responsible for sharing the given type with a node's peers, but are agnostic to the mechanism. Ideally, messages are delivered - faster than `LEDGER_GRANULARITY`. -* The generic code does not specify how transactions are submitted by clients, + faster than `LEDGER_GRANULARITY`. +- The generic code does not specify how transactions are submitted by clients, propagated through the network or stored in the open ledger. Indeed, the open ledger is only conceptual from the perspective of the generic code---the initial position and transaction set are opaquely generated in a `Consensus::Result` instance returned from the `onClose` callback. -* The calls to `acquireLedger` and `acquireTxSet` only have non-trivial return - if the ledger or transaction set of interest is available. The implementing +- The calls to `acquireLedger` and `acquireTxSet` only have non-trivial return + if the ledger or transaction set of interest is available. The implementing class is free to block while acquiring, or return the empty option while - servicing the request asynchronously. Due to legacy reasons, the two calls + servicing the request asynchronously. Due to legacy reasons, the two calls are not symmetric. `acquireTxSet` requires the host application to call `gotTxSet` when an asynchronous `acquire` completes. Conversely, `acquireLedger` will be called again later by the consensus code if it still desires the ledger with the hope that the asynchronous acquisition is complete. - ## Validation Coming Soon! - - diff --git a/external/README.md b/external/README.md index a3d04da264..99ce2c337e 100644 --- a/external/README.md +++ b/external/README.md @@ -3,8 +3,8 @@ The subdirectories in this directory contain copies of external libraries used by rippled. -| Folder | Upstream | Description | -|:----------------|:---------------------------------------------|:------------| -| `antithesis-sdk`| [Project](https://github.com/antithesishq/antithesis-sdk-cpp/) | [Antithesis](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html) SDK for C++ | -| `ed25519-donna` | [Project](https://github.com/floodyberry/ed25519-donna) | [Ed25519](http://ed25519.cr.yp.to/) digital signatures | -| `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve | +| Folder | Upstream | Description | +| :--------------- | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | +| `antithesis-sdk` | [Project](https://github.com/antithesishq/antithesis-sdk-cpp/) | [Antithesis](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html) SDK for C++ | +| `ed25519-donna` | [Project](https://github.com/floodyberry/ed25519-donna) | [Ed25519](http://ed25519.cr.yp.to/) digital signatures | +| `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve | diff --git a/external/antithesis-sdk/README.md b/external/antithesis-sdk/README.md index eb0237868d..46056ec512 100644 --- a/external/antithesis-sdk/README.md +++ b/external/antithesis-sdk/README.md @@ -1,8 +1,9 @@ # Antithesis C++ SDK This library provides methods for C++ programs to configure the [Antithesis](https://antithesis.com) platform. It contains three kinds of functionality: -* Assertion macros that allow you to define test properties about your software or workload. -* Randomness functions for requesting both structured and unstructured randomness from the Antithesis platform. -* Lifecycle functions that inform the Antithesis environment that particular test phases or milestones have been reached. + +- Assertion macros that allow you to define test properties about your software or workload. +- Randomness functions for requesting both structured and unstructured randomness from the Antithesis platform. +- Lifecycle functions that inform the Antithesis environment that particular test phases or milestones have been reached. For general usage guidance see the [Antithesis C++ SDK Documentation](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview/) diff --git a/external/ed25519-donna/README.md b/external/ed25519-donna/README.md index e09fc27e31..31b2431632 100644 --- a/external/ed25519-donna/README.md +++ b/external/ed25519-donna/README.md @@ -1,12 +1,12 @@ -[ed25519](http://ed25519.cr.yp.to/) is an -[Elliptic Curve Digital Signature Algortithm](http://en.wikipedia.org/wiki/Elliptic_Curve_DSA), -developed by [Dan Bernstein](http://cr.yp.to/djb.html), -[Niels Duif](http://www.nielsduif.nl/), -[Tanja Lange](http://hyperelliptic.org/tanja), -[Peter Schwabe](http://www.cryptojedi.org/users/peter/), +[ed25519](http://ed25519.cr.yp.to/) is an +[Elliptic Curve Digital Signature Algortithm](http://en.wikipedia.org/wiki/Elliptic_Curve_DSA), +developed by [Dan Bernstein](http://cr.yp.to/djb.html), +[Niels Duif](http://www.nielsduif.nl/), +[Tanja Lange](http://hyperelliptic.org/tanja), +[Peter Schwabe](http://www.cryptojedi.org/users/peter/), and [Bo-Yin Yang](http://www.iis.sinica.edu.tw/pages/byyang/). -This project provides performant, portable 32-bit & 64-bit implementations. All implementations are +This project provides performant, portable 32-bit & 64-bit implementations. All implementations are of course constant time in regard to secret data. #### Performance @@ -52,35 +52,35 @@ are made. #### Compilation -No configuration is needed **if you are compiling against OpenSSL**. +No configuration is needed **if you are compiling against OpenSSL**. ##### Hash Options If you are not compiling aginst OpenSSL, you will need a hash function. -To use a simple/**slow** implementation of SHA-512, use `-DED25519_REFHASH` when compiling `ed25519.c`. +To use a simple/**slow** implementation of SHA-512, use `-DED25519_REFHASH` when compiling `ed25519.c`. This should never be used except to verify the code works when OpenSSL is not available. -To use a custom hash function, use `-DED25519_CUSTOMHASH` when compiling `ed25519.c` and put your +To use a custom hash function, use `-DED25519_CUSTOMHASH` when compiling `ed25519.c` and put your custom hash implementation in ed25519-hash-custom.h. The hash must have a 512bit digest and implement - struct ed25519_hash_context; + struct ed25519_hash_context; - void ed25519_hash_init(ed25519_hash_context *ctx); - void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen); - void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash); - void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen); + void ed25519_hash_init(ed25519_hash_context *ctx); + void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen); + void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash); + void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen); ##### Random Options If you are not compiling aginst OpenSSL, you will need a random function for batch verification. -To use a custom random function, use `-DED25519_CUSTOMRANDOM` when compiling `ed25519.c` and put your +To use a custom random function, use `-DED25519_CUSTOMRANDOM` when compiling `ed25519.c` and put your custom hash implementation in ed25519-randombytes-custom.h. The random function must implement: - void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len); + void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len); -Use `-DED25519_TEST` when compiling `ed25519.c` to use a deterministically seeded, non-thread safe CSPRNG +Use `-DED25519_TEST` when compiling `ed25519.c` to use a deterministically seeded, non-thread safe CSPRNG variant of Bob Jenkins [ISAAC](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29) ##### Minor options @@ -91,80 +91,79 @@ Use `-DED25519_FORCE_32BIT` to force the use of 32 bit routines even when compil ##### 32-bit - gcc ed25519.c -m32 -O3 -c + gcc ed25519.c -m32 -O3 -c ##### 64-bit - gcc ed25519.c -m64 -O3 -c + gcc ed25519.c -m64 -O3 -c ##### SSE2 - gcc ed25519.c -m32 -O3 -c -DED25519_SSE2 -msse2 - gcc ed25519.c -m64 -O3 -c -DED25519_SSE2 + gcc ed25519.c -m32 -O3 -c -DED25519_SSE2 -msse2 + gcc ed25519.c -m64 -O3 -c -DED25519_SSE2 clang and icc are also supported - #### Usage To use the code, link against `ed25519.o -mbits` and: - #include "ed25519.h" + #include "ed25519.h" Add `-lssl -lcrypto` when using OpenSSL (Some systems don't need -lcrypto? It might be trial and error). To generate a private key, simply generate 32 bytes from a secure cryptographic source: - ed25519_secret_key sk; - randombytes(sk, sizeof(ed25519_secret_key)); + ed25519_secret_key sk; + randombytes(sk, sizeof(ed25519_secret_key)); To generate a public key: - ed25519_public_key pk; - ed25519_publickey(sk, pk); + ed25519_public_key pk; + ed25519_publickey(sk, pk); To sign a message: - ed25519_signature sig; - ed25519_sign(message, message_len, sk, pk, signature); + ed25519_signature sig; + ed25519_sign(message, message_len, sk, pk, signature); To verify a signature: - int valid = ed25519_sign_open(message, message_len, pk, signature) == 0; + int valid = ed25519_sign_open(message, message_len, pk, signature) == 0; To batch verify signatures: - const unsigned char *mp[num] = {message1, message2..} - size_t ml[num] = {message_len1, message_len2..} - const unsigned char *pkp[num] = {pk1, pk2..} - const unsigned char *sigp[num] = {signature1, signature2..} - int valid[num] + const unsigned char *mp[num] = {message1, message2..} + size_t ml[num] = {message_len1, message_len2..} + const unsigned char *pkp[num] = {pk1, pk2..} + const unsigned char *sigp[num] = {signature1, signature2..} + int valid[num] - /* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */ - int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0; + /* valid[i] will be set to 1 if the individual signature was valid, 0 otherwise */ + int all_valid = ed25519_sign_open_batch(mp, ml, pkp, sigp, num, valid) == 0; -**Note**: Batch verification uses `ed25519_randombytes_unsafe`, implemented in -`ed25519-randombytes.h`, to generate random scalars for the verification code. +**Note**: Batch verification uses `ed25519_randombytes_unsafe`, implemented in +`ed25519-randombytes.h`, to generate random scalars for the verification code. The default implementation now uses OpenSSLs `RAND_bytes`. Unlike the [SUPERCOP](http://bench.cr.yp.to/supercop.html) version, signatures are -not appended to messages, and there is no need for padding in front of messages. -Additionally, the secret key does not contain a copy of the public key, so it is +not appended to messages, and there is no need for padding in front of messages. +Additionally, the secret key does not contain a copy of the public key, so it is 32 bytes instead of 64 bytes, and the public key must be provided to the signing function. ##### Curve25519 -Curve25519 public keys can be generated thanks to -[Adam Langley](http://www.imperialviolet.org/2013/05/10/fastercurve25519.html) +Curve25519 public keys can be generated thanks to +[Adam Langley](http://www.imperialviolet.org/2013/05/10/fastercurve25519.html) leveraging Ed25519's precomputed basepoint scalar multiplication. - curved25519_key sk, pk; - randombytes(sk, sizeof(curved25519_key)); - curved25519_scalarmult_basepoint(pk, sk); + curved25519_key sk, pk; + randombytes(sk, sizeof(curved25519_key)); + curved25519_scalarmult_basepoint(pk, sk); -Note the name is curved25519, a combination of curve and ed25519, to prevent +Note the name is curved25519, a combination of curve and ed25519, to prevent name clashes. Performance is slightly faster than short message ed25519 signing due to both using the same code for the scalar multiply. @@ -180,4 +179,4 @@ with extreme values to ensure they function correctly. SSE2 is now supported. #### Papers -[Available on the Ed25519 website](http://ed25519.cr.yp.to/papers.html) \ No newline at end of file +[Available on the Ed25519 website](http://ed25519.cr.yp.to/papers.html) diff --git a/external/ed25519-donna/fuzz/README.md b/external/ed25519-donna/fuzz/README.md index 306ddfe08c..0a5cd49177 100644 --- a/external/ed25519-donna/fuzz/README.md +++ b/external/ed25519-donna/fuzz/README.md @@ -1,78 +1,78 @@ This code fuzzes ed25519-donna (and optionally ed25519-donna-sse2) against the ref10 implementations of -[curve25519](https://github.com/floodyberry/supercop/tree/master/crypto_scalarmult/curve25519/ref10) and +[curve25519](https://github.com/floodyberry/supercop/tree/master/crypto_scalarmult/curve25519/ref10) and [ed25519](https://github.com/floodyberry/supercop/tree/master/crypto_sign/ed25519/ref10). Curve25519 tests that generating a public key from a secret key # Building -## *nix + PHP +## \*nix + PHP `php build-nix.php (required parameters) (optional parameters)` Required parameters: -* `--function=[curve25519,ed25519]` -* `--bits=[32,64]` +- `--function=[curve25519,ed25519]` +- `--bits=[32,64]` Optional parameters: -* `--with-sse2` +- `--with-sse2` - Also fuzz against ed25519-donna-sse2 -* `--with-openssl` + Also fuzz against ed25519-donna-sse2 - Build with OpenSSL's SHA-512. +- `--with-openssl` - Default: Reference SHA-512 implementation (slow!) + Build with OpenSSL's SHA-512. -* `--compiler=[gcc,clang,icc]` + Default: Reference SHA-512 implementation (slow!) - Default: gcc +- `--compiler=[gcc,clang,icc]` -* `--no-asm` + Default: gcc - Do not use platform specific assembler +- `--no-asm` + Do not use platform specific assembler example: - - php build-nix.php --bits=64 --function=ed25519 --with-sse2 --compiler=icc + + php build-nix.php --bits=64 --function=ed25519 --with-sse2 --compiler=icc ## Windows Create a project with access to the ed25519 files. -If you are not using OpenSSL, add the `ED25519_REFHASH` define to the projects +If you are not using OpenSSL, add the `ED25519_REFHASH` define to the projects "Properties/Preprocessor/Preprocessor Definitions" option Add the following files to the project: -* `fuzz/curve25519-ref10.c` -* `fuzz/ed25519-ref10.c` -* `fuzz/ed25519-donna.c` -* `fuzz/ed25519-donna-sse2.c` (optional) -* `fuzz-[curve25519/ed25519].c` (depending on which you want to fuzz) +- `fuzz/curve25519-ref10.c` +- `fuzz/ed25519-ref10.c` +- `fuzz/ed25519-donna.c` +- `fuzz/ed25519-donna-sse2.c` (optional) +- `fuzz-[curve25519/ed25519].c` (depending on which you want to fuzz) -If you are also fuzzing against ed25519-donna-sse2, add the `ED25519_SSE2` define for `fuzz-[curve25519/ed25519].c` under +If you are also fuzzing against ed25519-donna-sse2, add the `ED25519_SSE2` define for `fuzz-[curve25519/ed25519].c` under its "Properties/Preprocessor/Preprocessor Definitions" option. # Running -If everything agrees, the program will only output occasional status dots (every 0x1000 passes) +If everything agrees, the program will only output occasional status dots (every 0x1000 passes) and a 64bit progress count (every 0x20000 passes): fuzzing: ref10 curved25519 curved25519-sse2 - + ................................ [0000000000020000] ................................ [0000000000040000] ................................ [0000000000060000] ................................ [0000000000080000] ................................ [00000000000a0000] ................................ [00000000000c0000] - + If any of the implementations do not agree with the ref10 implementation, the program will dump -the random data that was used, the data generated by the ref10 implementation, and diffs of the +the random data that was used, the data generated by the ref10 implementation, and diffs of the ed25519-donna data against the ref10 data. ## Example errors @@ -83,21 +83,21 @@ These are example error dumps (with intentionally introduced errors). Random data: -* sk, or Secret Key -* m, or Message +- sk, or Secret Key +- m, or Message Generated data: -* pk, or Public Key -* sig, or Signature -* valid, or if the signature of the message is valid with the public key +- pk, or Public Key +- sig, or Signature +- valid, or if the signature of the message is valid with the public key Dump: sk: 0x3b,0xb7,0x17,0x7a,0x66,0xdc,0xb7,0x9a,0x90,0x25,0x07,0x99,0x96,0xf3,0x92,0xef, 0x78,0xf8,0xad,0x6c,0x35,0x87,0x81,0x67,0x03,0xe6,0x95,0xba,0x06,0x18,0x7c,0x9c, - + m: 0x7c,0x8d,0x3d,0xe1,0x92,0xee,0x7a,0xb8,0x4d,0xc9,0xfb,0x02,0x34,0x1e,0x5a,0x91, 0xee,0x01,0xa6,0xb8,0xab,0x37,0x3f,0x3d,0x6d,0xa2,0x47,0xe3,0x27,0x93,0x7c,0xb7, @@ -107,67 +107,66 @@ Dump: 0x63,0x14,0xe0,0x81,0x52,0xec,0xcd,0xcf,0x70,0x54,0x7d,0xa3,0x49,0x8b,0xf0,0x89, 0x70,0x07,0x12,0x2a,0xd9,0xaa,0x16,0x01,0xb2,0x16,0x3a,0xbb,0xfc,0xfa,0x13,0x5b, 0x69,0x83,0x92,0x70,0x95,0x76,0xa0,0x8e,0x16,0x79,0xcc,0xaa,0xb5,0x7c,0xf8,0x7a, - + ref10: pk: 0x71,0xb0,0x5e,0x62,0x1b,0xe3,0xe7,0x36,0x91,0x8b,0xc0,0x13,0x36,0x0c,0xc9,0x04, 0x16,0xf5,0xff,0x48,0x0c,0x83,0x6b,0x88,0x53,0xa2,0xc6,0x0f,0xf7,0xac,0x42,0x04, - + sig: 0x3e,0x05,0xc5,0x37,0x16,0x0b,0x29,0x30,0x89,0xa3,0xe7,0x83,0x08,0x16,0xdd,0x96, 0x02,0xfa,0x0d,0x44,0x2c,0x43,0xaa,0x80,0x93,0x04,0x58,0x22,0x09,0xbf,0x11,0xa5, 0xcc,0xa5,0x3c,0x9f,0xa0,0xa4,0x64,0x5a,0x4a,0xdb,0x20,0xfb,0xc7,0x9b,0xfd,0x3f, 0x08,0xae,0xc4,0x3c,0x1e,0xd8,0xb6,0xb4,0xd2,0x6d,0x80,0x92,0xcb,0x71,0xf3,0x02, - + valid: yes - + ed25519-donna: pk diff: ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____, ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____, - + sig diff: 0x2c,0xb9,0x25,0x14,0xd0,0x94,0xeb,0xfe,0x46,0x02,0xc2,0xe8,0xa3,0xeb,0xbf,0xb5, 0x72,0x84,0xbf,0xc1,0x8a,0x32,0x30,0x99,0xf7,0x58,0xfe,0x06,0xa8,0xdc,0xdc,0xab, 0xb5,0x57,0x03,0x33,0x87,0xce,0x54,0x55,0x6a,0x69,0x8a,0xc4,0xb7,0x2a,0xed,0x97, 0xb4,0x68,0xe7,0x52,0x7a,0x07,0x55,0x3b,0xa2,0x94,0xd6,0x5e,0xa1,0x61,0x80,0x08, - + valid: no -In this case, the generated public key matches, but the generated signature is completely +In this case, the generated public key matches, but the generated signature is completely different and does not validate. ### Curve25519 Random data: -* sk, or Secret Key +- sk, or Secret Key Generated data: -* pk, or Public Key +- pk, or Public Key Dump: sk: 0x44,0xec,0x0b,0x0e,0xa2,0x0e,0x9c,0x5b,0x8c,0xce,0x7b,0x1d,0x68,0xae,0x0f,0x9e, 0x81,0xe2,0x04,0x76,0xda,0x87,0xa4,0x9e,0xc9,0x4f,0x3b,0xf9,0xc3,0x89,0x63,0x70, - - + + ref10: 0x24,0x55,0x55,0xc0,0xf9,0x80,0xaf,0x02,0x43,0xee,0x8c,0x7f,0xc1,0xad,0x90,0x95, 0x57,0x91,0x14,0x2e,0xf2,0x14,0x22,0x80,0xdd,0x4e,0x3c,0x85,0x71,0x84,0x8c,0x62, - - + + curved25519 diff: 0x12,0xd1,0x61,0x2b,0x16,0xb3,0xd8,0x29,0xf8,0xa3,0xba,0x70,0x4e,0x49,0x4f,0x43, 0xa1,0x3c,0x6b,0x42,0x11,0x61,0xcc,0x30,0x87,0x73,0x46,0xfb,0x85,0xc7,0x9a,0x35, - - + + curved25519-sse2 diff: ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____, ____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____, - -In this case, curved25519 is totally wrong, while curved25519-sse2 matches the reference -implementation. \ No newline at end of file +In this case, curved25519 is totally wrong, while curved25519-sse2 matches the reference +implementation. diff --git a/external/secp256k1/CHANGELOG.md b/external/secp256k1/CHANGELOG.md index ee447c0c1c..a000672887 100644 --- a/external/secp256k1/CHANGELOG.md +++ b/external/secp256k1/CHANGELOG.md @@ -8,153 +8,189 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.6.0] - 2024-11-04 #### Added - - New module `musig` implements the MuSig2 multisignature scheme according to the [BIP 327 specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). See: - - Header file `include/secp256k1_musig.h` which defines the new API. - - Document `doc/musig.md` for further notes on API usage. - - Usage example `examples/musig.c`. - - New CMake variable `SECP256K1_APPEND_LDFLAGS` for appending linker flags to the build command. + +- New module `musig` implements the MuSig2 multisignature scheme according to the [BIP 327 specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). See: + - Header file `include/secp256k1_musig.h` which defines the new API. + - Document `doc/musig.md` for further notes on API usage. + - Usage example `examples/musig.c`. +- New CMake variable `SECP256K1_APPEND_LDFLAGS` for appending linker flags to the build command. #### Changed - - API functions now use a significantly more robust method to clear secrets from the stack before returning. However, secret clearing remains a best-effort security measure and cannot guarantee complete removal. - - Any type `secp256k1_foo` can now be forward-declared using `typedef struct secp256k1_foo secp256k1_foo;` (or also `struct secp256k1_foo;` in C++). - - Organized CMake build artifacts into dedicated directories (`bin/` for executables, `lib/` for libraries) to improve build output structure and Windows shared library compatibility. + +- API functions now use a significantly more robust method to clear secrets from the stack before returning. However, secret clearing remains a best-effort security measure and cannot guarantee complete removal. +- Any type `secp256k1_foo` can now be forward-declared using `typedef struct secp256k1_foo secp256k1_foo;` (or also `struct secp256k1_foo;` in C++). +- Organized CMake build artifacts into dedicated directories (`bin/` for executables, `lib/` for libraries) to improve build output structure and Windows shared library compatibility. #### Removed - - Removed the `secp256k1_scratch_space` struct and its associated functions `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` because the scratch space was unused in the API. + +- Removed the `secp256k1_scratch_space` struct and its associated functions `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` because the scratch space was unused in the API. #### ABI Compatibility + The symbols `secp256k1_scratch_space_create` and `secp256k1_scratch_space_destroy` were removed. Otherwise, the library maintains backward compatibility with versions 0.3.x through 0.5.x. ## [0.5.1] - 2024-08-01 #### Added - - Added usage example for an ElligatorSwift key exchange. + +- Added usage example for an ElligatorSwift key exchange. #### Changed - - The default size of the precomputed table for signing was changed from 22 KiB to 86 KiB. The size can be changed with the configure option `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake). - - "auto" is no longer an accepted value for the `--with-ecmult-window` and `--with-ecmult-gen-kb` configure options (this also applies to `SECP256K1_ECMULT_WINDOW_SIZE` and `SECP256K1_ECMULT_GEN_KB` in CMake). To achieve the same configuration as previously provided by the "auto" value, omit setting the configure option explicitly. + +- The default size of the precomputed table for signing was changed from 22 KiB to 86 KiB. The size can be changed with the configure option `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake). +- "auto" is no longer an accepted value for the `--with-ecmult-window` and `--with-ecmult-gen-kb` configure options (this also applies to `SECP256K1_ECMULT_WINDOW_SIZE` and `SECP256K1_ECMULT_GEN_KB` in CMake). To achieve the same configuration as previously provided by the "auto" value, omit setting the configure option explicitly. #### Fixed - - Fixed compilation when the extrakeys module is disabled. + +- Fixed compilation when the extrakeys module is disabled. #### ABI Compatibility + The ABI is backward compatible with versions 0.5.0, 0.4.x and 0.3.x. ## [0.5.0] - 2024-05-06 #### Added - - New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order. + +- New function `secp256k1_ec_pubkey_sort` that sorts public keys using lexicographic (of compressed serialization) order. #### Changed - - The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations. - - The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake). - - This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB). + +- The implementation of the point multiplication algorithm used for signing and public key generation was changed, resulting in improved performance for those operations. + - The related configure option `--ecmult-gen-precision` was replaced with `--ecmult-gen-kb` (`SECP256K1_ECMULT_GEN_KB` for CMake). + - This changes the supported precomputed table sizes for these operations. The new supported sizes are 2 KiB, 22 KiB, or 86 KiB (while the old supported sizes were 32 KiB, 64 KiB, or 512 KiB). #### ABI Compatibility + The ABI is backward compatible with versions 0.4.x and 0.3.x. ## [0.4.1] - 2023-12-21 #### Changed - - The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one. - - Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`. + +- The point multiplication algorithm used for ECDH operations (module `ecdh`) was replaced with a slightly faster one. +- Optional handwritten x86_64 assembly for field operations was removed because modern C compilers are able to output more efficient assembly. This change results in a significant speedup of some library functions when handwritten x86_64 assembly is enabled (`--with-asm=x86_64` in GNU Autotools, `-DSECP256K1_ASM=x86_64` in CMake), which is the default on x86_64. Benchmarks with GCC 10.5.0 show a 10% speedup for `secp256k1_ecdsa_verify` and `secp256k1_schnorrsig_verify`. #### ABI Compatibility + The ABI is backward compatible with versions 0.4.0 and 0.3.x. ## [0.4.0] - 2023-09-04 #### Added - - New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them. - ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See: - - Header file `include/secp256k1_ellswift.h` which defines the new API. - - Document `doc/ellswift.md` which explains the mathematical background of the scheme. - - The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based. - - We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases). + +- New module `ellswift` implements ElligatorSwift encoding for public keys and x-only Diffie-Hellman key exchange for them. + ElligatorSwift permits representing secp256k1 public keys as 64-byte arrays which cannot be distinguished from uniformly random. See: + - Header file `include/secp256k1_ellswift.h` which defines the new API. + - Document `doc/ellswift.md` which explains the mathematical background of the scheme. + - The [paper](https://eprint.iacr.org/2022/759) on which the scheme is based. +- We now test the library with unreleased development snapshots of GCC and Clang. This gives us an early chance to catch miscompilations and constant-time issues introduced by the compiler (such as those that led to the previous two releases). #### Fixed - - Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported. + +- Fixed symbol visibility in Windows DLL builds, where three internal library symbols were wrongly exported. #### Changed - - When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`. + +- When consuming libsecp256k1 as a static library on Windows, the user must now define the `SECP256K1_STATIC` macro before including `secp256k1.h`. #### ABI Compatibility + This release is backward compatible with the ABI of 0.3.0, 0.3.1, and 0.3.2. Symbol visibility is now believed to be handled properly on supported platforms and is now considered to be part of the ABI. Please report any improperly exported symbols as a bug. ## [0.3.2] - 2023-05-13 + We strongly recommend updating to 0.3.2 if you use or plan to use GCC >=13 to compile libsecp256k1. When in doubt, check the GCC version using `gcc -v`. #### Security - - Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1. + +- Module `ecdh`: Fix "constant-timeness" issue with GCC 13.1 (and potentially future versions of GCC) that could leave applications using libsecp256k1's ECDH module vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow during ECDH computations when libsecp256k1 is compiled with GCC 13.1. #### Fixed - - Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far. + +- Fixed an old bug that permitted compilers to potentially output bad assembly code on x86_64. In theory, it could lead to a crash or a read of unrelated memory, but this has never been observed on any compilers so far. #### Changed - - Various improvements and changes to CMake builds. CMake builds remain experimental. - - Made API versioning consistent with GNU Autotools builds. - - Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library. - - Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts. - - Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake). + +- Various improvements and changes to CMake builds. CMake builds remain experimental. + - Made API versioning consistent with GNU Autotools builds. + - Switched to `BUILD_SHARED_LIBS` variable for controlling whether to build a static or a shared library. + - Added `SECP256K1_INSTALL` variable for the controlling whether to install the build artefacts. +- Renamed asm build option `arm` to `arm32`. Use `--with-asm=arm32` instead of `--with-asm=arm` (GNU Autotools), and `-DSECP256K1_ASM=arm32` instead of `-DSECP256K1_ASM=arm` (CMake). #### ABI Compatibility + The ABI is compatible with versions 0.3.0 and 0.3.1. ## [0.3.1] - 2023-04-10 + We strongly recommend updating to 0.3.1 if you use or plan to use Clang >=14 to compile libsecp256k1, e.g., Xcode >=14 on macOS has Clang >=14. When in doubt, check the Clang version using `clang -v`. #### Security - - Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14. + +- Fix "constant-timeness" issue with Clang >=14 that could leave applications using libsecp256k1 vulnerable to a timing side-channel attack. The fix avoids secret-dependent control flow and secret-dependent memory accesses in conditional moves of memory objects when libsecp256k1 is compiled with Clang >=14. #### Added - - Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases. + +- Added tests against [Project Wycheproof's](https://github.com/google/wycheproof/) set of ECDSA test vectors (Bitcoin "low-S" variant), a fixed set of test cases designed to trigger various edge cases. #### Changed - - Increased minimum required CMake version to 3.13. CMake builds remain experimental. + +- Increased minimum required CMake version to 3.13. CMake builds remain experimental. #### ABI Compatibility + The ABI is compatible with version 0.3.0. ## [0.3.0] - 2023-03-08 #### Added - - Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported. - - Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory. - - Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target. + +- Added experimental support for CMake builds. Traditional GNU Autotools builds (`./configure` and `make`) remain fully supported. +- Usage examples: Added a recommended method for securely clearing sensitive data, e.g., secret keys, from memory. +- Tests: Added a new test binary `noverify_tests`. This binary runs the tests without some additional checks present in the ordinary `tests` binary and is thereby closer to production binaries. The `noverify_tests` binary is automatically run as part of the `make check` target. #### Fixed - - Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning. + +- Fixed declarations of API variables for MSVC (`__declspec(dllimport)`). This fixes MSVC builds of programs which link against a libsecp256k1 DLL dynamically and use API variables (and not only API functions). Unfortunately, the MSVC linker now will emit warning `LNK4217` when trying to link against libsecp256k1 statically. Pass `/ignore:4217` to the linker to suppress this warning. #### Changed - - Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.) - - Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization. + +- Forbade cloning or destroying `secp256k1_context_static`. Create a new context instead of cloning the static context. (If this change breaks your code, your code is probably wrong.) +- Forbade randomizing (copies of) `secp256k1_context_static`. Randomizing a copy of `secp256k1_context_static` did not have any effect and did not provide defense-in-depth protection against side-channel attacks. Create a new context if you want to benefit from randomization. #### Removed - - Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags). + +- Removed the configuration header `src/libsecp256k1-config.h`. We recommend passing flags to `./configure` or `cmake` to set configuration options (see `./configure --help` or `cmake -LH`). If you cannot or do not want to use one of the supported build systems, pass configuration flags such as `-DSECP256K1_ENABLE_MODULE_SCHNORRSIG` manually to the compiler (see the file `configure.ac` for supported flags). #### ABI Compatibility -Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is *not* compatible with previous versions. + +Due to changes in the API regarding `secp256k1_context_static` described above, the ABI is _not_ compatible with previous versions. ## [0.2.0] - 2022-12-12 #### Added - - Added usage examples for common use cases in a new `examples/` directory. - - Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`. - - Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms. + +- Added usage examples for common use cases in a new `examples/` directory. +- Added `secp256k1_selftest`, to be used in conjunction with `secp256k1_context_static`. +- Added support for 128-bit wide multiplication on MSVC for x86_64 and arm64, giving roughly a 20% speedup on those platforms. #### Changed - - Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`. - - The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API. + +- Enabled modules `schnorrsig`, `extrakeys` and `ecdh` by default in `./configure`. +- The `secp256k1_nonce_function_rfc6979` nonce function, used by default by `secp256k1_ecdsa_sign`, now reduces the message hash modulo the group order to match the specification. This only affects improper use of ECDSA signing API. #### Deprecated - - Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead. - - Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`. - - Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`. + +- Deprecated context flags `SECP256K1_CONTEXT_VERIFY` and `SECP256K1_CONTEXT_SIGN`. Use `SECP256K1_CONTEXT_NONE` instead. +- Renamed `secp256k1_context_no_precomp` to `secp256k1_context_static`. +- Module `schnorrsig`: renamed `secp256k1_schnorrsig_sign` to `secp256k1_schnorrsig_sign32`. #### ABI Compatibility + Since this is the first release, we do not compare application binary interfaces. -However, there are earlier unreleased versions of libsecp256k1 that are *not* ABI compatible with this version. +However, there are earlier unreleased versions of libsecp256k1 that are _not_ ABI compatible with this version. ## [0.1.0] - 2013-03-05 to 2021-12-25 diff --git a/external/secp256k1/CMakePresets.json b/external/secp256k1/CMakePresets.json index b35cd80579..60138c16bf 100644 --- a/external/secp256k1/CMakePresets.json +++ b/external/secp256k1/CMakePresets.json @@ -1,5 +1,9 @@ { - "cmakeMinimumRequired": {"major": 3, "minor": 21, "patch": 0}, + "cmakeMinimumRequired": { + "major": 3, + "minor": 21, + "patch": 0 + }, "version": 3, "configurePresets": [ { diff --git a/external/secp256k1/CONTRIBUTING.md b/external/secp256k1/CONTRIBUTING.md index a366d38b0e..88c22af02b 100644 --- a/external/secp256k1/CONTRIBUTING.md +++ b/external/secp256k1/CONTRIBUTING.md @@ -12,15 +12,15 @@ The libsecp256k1 project welcomes contributions in the form of new functionality It is the responsibility of the contributors to convince the maintainers that the proposed functionality is within the project's scope, high-quality and maintainable. Contributors are recommended to provide the following in addition to the new code: -* **Specification:** - A specification can help significantly in reviewing the new code as it provides documentation and context. - It may justify various design decisions, give a motivation and outline security goals. - If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code. -* **Security Arguments:** - In addition to a defining the security goals, it should be argued that the new functionality meets these goals. - Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security. -* **Relevance Arguments:** - The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases. +- **Specification:** + A specification can help significantly in reviewing the new code as it provides documentation and context. + It may justify various design decisions, give a motivation and outline security goals. + If the specification contains pseudocode, a reference implementation or test vectors, these can be used to compare with the proposed libsecp256k1 code. +- **Security Arguments:** + In addition to a defining the security goals, it should be argued that the new functionality meets these goals. + Depending on the nature of the new functionality, a wide range of security arguments are acceptable, ranging from being "obviously secure" to rigorous proofs of security. +- **Relevance Arguments:** + The relevance of the new functionality for the Bitcoin ecosystem should be argued by outlining clear use cases. These are not the only factors taken into account when considering to add new functionality. The proposed new libsecp256k1 code must be of high quality, including API documentation and tests, as well as featuring a misuse-resistant API design. @@ -44,36 +44,36 @@ The Contributor Workflow & Peer Review in libsecp256k1 are similar to Bitcoin Co In addition, libsecp256k1 tries to maintain the following coding conventions: -* No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations. -* The tests should cover all lines and branches of the library (see [Test coverage](#coverage)). -* Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)). -* Local variables containing secret data should be cleared explicitly to try to delete secrets from memory. -* Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)). -* As a rule of thumb, the default values for configuration options should target standard desktop machines and align with Bitcoin Core's defaults, and the tests should mostly exercise the default configuration (see [#1549](https://github.com/bitcoin-core/secp256k1/issues/1549#issuecomment-2200559257)). +- No runtime heap allocation (e.g., no `malloc`) unless explicitly requested by the caller (via `secp256k1_context_create` or `secp256k1_scratch_space_create`, for example). Moreover, it should be possible to use the library without any heap allocations. +- The tests should cover all lines and branches of the library (see [Test coverage](#coverage)). +- Operations involving secret data should be tested for being constant time with respect to the secrets (see [src/ctime_tests.c](src/ctime_tests.c)). +- Local variables containing secret data should be cleared explicitly to try to delete secrets from memory. +- Use `secp256k1_memcmp_var` instead of `memcmp` (see [#823](https://github.com/bitcoin-core/secp256k1/issues/823)). +- As a rule of thumb, the default values for configuration options should target standard desktop machines and align with Bitcoin Core's defaults, and the tests should mostly exercise the default configuration (see [#1549](https://github.com/bitcoin-core/secp256k1/issues/1549#issuecomment-2200559257)). #### Style conventions -* Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures. -* New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting. -* The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block: - ```C - void secp256k_foo(void) { - unsigned int x; /* declaration */ - int y = 2*x; /* declaration */ - x = 17; /* statement */ - { - int a, b; /* declaration */ - a = x + y; /* statement */ - secp256k_bar(x, &b); /* statement */ - } - } - ``` -* Use `unsigned int` instead of just `unsigned`. -* Use `void *ptr` instead of `void* ptr`. -* Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h). -* User-facing comment lines in headers should be limited to 80 chars if possible. -* All identifiers in file scope should start with `secp256k1_`. -* Avoid trailing whitespace. +- Commits should be atomic and diffs should be easy to read. For this reason, do not mix any formatting fixes or code moves with actual code changes. Make sure each individual commit is hygienic: that it builds successfully on its own without warnings, errors, regressions, or test failures. +- New code should adhere to the style of existing, in particular surrounding, code. Other than that, we do not enforce strict rules for code formatting. +- The code conforms to C89. Most notably, that means that only `/* ... */` comments are allowed (no `//` line comments). Moreover, any declarations in a `{ ... }` block (e.g., a function) must appear at the beginning of the block before any statements. When you would like to declare a variable in the middle of a block, you can open a new block: + ```C + void secp256k_foo(void) { + unsigned int x; /* declaration */ + int y = 2*x; /* declaration */ + x = 17; /* statement */ + { + int a, b; /* declaration */ + a = x + y; /* statement */ + secp256k_bar(x, &b); /* statement */ + } + } + ``` +- Use `unsigned int` instead of just `unsigned`. +- Use `void *ptr` instead of `void* ptr`. +- Arguments of the publicly-facing API must have a specific order defined in [include/secp256k1.h](include/secp256k1.h). +- User-facing comment lines in headers should be limited to 80 chars if possible. +- All identifiers in file scope should start with `secp256k1_`. +- Avoid trailing whitespace. ### Tests @@ -101,7 +101,7 @@ To create a HTML report with coloured and annotated source code: #### Exhaustive tests There are tests of several functions in which a small group replaces secp256k1. -These tests are *exhaustive* since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)). +These tests are _exhaustive_ since they provide all elements and scalars of the small group as input arguments (see [src/tests_exhaustive.c](src/tests_exhaustive.c)). ### Benchmarks diff --git a/external/secp256k1/README.md b/external/secp256k1/README.md index 222e5fb768..4cd64c7fee 100644 --- a/external/secp256k1/README.md +++ b/external/secp256k1/README.md @@ -1,5 +1,4 @@ -libsecp256k1 -============ +# libsecp256k1 ![Dependencies: None](https://img.shields.io/badge/dependencies-none-success) [![irc.libera.chat #secp256k1](https://img.shields.io/badge/irc.libera.chat-%23secp256k1-success)](https://web.libera.chat/#secp256k1) @@ -9,60 +8,59 @@ High-performance high-assurance C library for digital signatures and other crypt This library is intended to be the highest quality publicly available library for cryptography on the secp256k1 curve. However, the primary focus of its development has been for usage in the Bitcoin system and usage unlike Bitcoin's may be less well tested, verified, or suffer from a less well thought out interface. Correct usage requires some care and consideration that the library is fit for your application's purpose. Features: -* secp256k1 ECDSA signing/verification and key generation. -* Additive and multiplicative tweaking of secret/public keys. -* Serialization/parsing of secret keys, public keys, signatures. -* Constant time, constant memory access signing and public key generation. -* Derandomized ECDSA (via RFC6979 or with a caller provided function.) -* Very efficient implementation. -* Suitable for embedded systems. -* No runtime dependencies. -* Optional module for public key recovery. -* Optional module for ECDH key exchange. -* Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). -* Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki). -* Optional module for MuSig2 Schnorr multi-signatures according to [BIP-327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). -Implementation details ----------------------- +- secp256k1 ECDSA signing/verification and key generation. +- Additive and multiplicative tweaking of secret/public keys. +- Serialization/parsing of secret keys, public keys, signatures. +- Constant time, constant memory access signing and public key generation. +- Derandomized ECDSA (via RFC6979 or with a caller provided function.) +- Very efficient implementation. +- Suitable for embedded systems. +- No runtime dependencies. +- Optional module for public key recovery. +- Optional module for ECDH key exchange. +- Optional module for Schnorr signatures according to [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). +- Optional module for ElligatorSwift key exchange according to [BIP-324](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki). +- Optional module for MuSig2 Schnorr multi-signatures according to [BIP-327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki). -* General - * No runtime heap allocation. - * Extensive testing infrastructure. - * Structured to facilitate review and analysis. - * Intended to be portable to any system with a C89 compiler and uint64_t support. - * No use of floating types. - * Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") -* Field operations - * Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). - * Using 5 52-bit limbs - * Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan). - * This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community. -* Scalar operations - * Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. - * Using 4 64-bit limbs (relying on __int128 support in the compiler). - * Using 8 32-bit limbs. -* Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman). -* Group operations - * Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). - * Use addition between points in Jacobian and affine coordinates where possible. - * Use a unified addition/doubling formula where necessary to avoid data-dependent branches. - * Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. -* Point multiplication for verification (a*P + b*G). - * Use wNAF notation for point multiplicands. - * Use a much larger window for multiples of G, using precomputed multiples. - * Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. - * Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. -* Point multiplication for signing - * Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. - * Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains) - * Access the table with branch-free conditional moves so memory access is uniform. - * No data-dependent branches - * Optional runtime blinding which attempts to frustrate differential power analysis. - * The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally. +## Implementation details -Building with Autotools ------------------------ +- General + - No runtime heap allocation. + - Extensive testing infrastructure. + - Structured to facilitate review and analysis. + - Intended to be portable to any system with a C89 compiler and uint64_t support. + - No use of floating types. + - Expose only higher level interfaces to minimize the API surface and improve application security. ("Be difficult to use insecurely.") +- Field operations + - Optimized implementation of arithmetic modulo the curve's field size (2^256 - 0x1000003D1). + - Using 5 52-bit limbs + - Using 10 26-bit limbs (including hand-optimized assembly for 32-bit ARM, by Wladimir J. van der Laan). + - This is an experimental feature that has not received enough scrutiny to satisfy the standard of quality of this library but is made available for testing and review by the community. +- Scalar operations + - Optimized implementation without data-dependent branches of arithmetic modulo the curve's order. + - Using 4 64-bit limbs (relying on \_\_int128 support in the compiler). + - Using 8 32-bit limbs. +- Modular inverses (both field elements and scalars) based on [safegcd](https://gcd.cr.yp.to/index.html) with some modifications, and a variable-time variant (by Peter Dettman). +- Group operations + - Point addition formula specifically simplified for the curve equation (y^2 = x^3 + 7). + - Use addition between points in Jacobian and affine coordinates where possible. + - Use a unified addition/doubling formula where necessary to avoid data-dependent branches. + - Point/x comparison without a field inversion by comparison in the Jacobian coordinate space. +- Point multiplication for verification (a*P + b*G). + - Use wNAF notation for point multiplicands. + - Use a much larger window for multiples of G, using precomputed multiples. + - Use Shamir's trick to do the multiplication with the public key and the generator simultaneously. + - Use secp256k1's efficiently-computable endomorphism to split the P multiplicand into 2 half-sized ones. +- Point multiplication for signing + - Use a precomputed table of multiples of powers of 16 multiplied with the generator, so general multiplication becomes a series of additions. + - Intended to be completely free of timing sidechannels for secret-key operations (on reasonable hardware/toolchains) + - Access the table with branch-free conditional moves so memory access is uniform. + - No data-dependent branches + - Optional runtime blinding which attempts to frustrate differential power analysis. + - The precomputed tables add and eventually subtract points for which no known scalar (secret key) is known, preventing even an attacker with control over the secret key used to control the data internally. + +## Building with Autotools $ ./autogen.sh $ ./configure @@ -72,8 +70,7 @@ Building with Autotools To compile optional modules (such as Schnorr signatures), you need to run `./configure` with additional flags (such as `--enable-module-schnorrsig`). Run `./configure --help` to see the full list of available flags. -Building with CMake (experimental) ----------------------------------- +## Building with CMake (experimental) To maintain a pristine source tree, CMake encourages to perform an out-of-source build by using a separate dedicated build tree. @@ -109,18 +106,19 @@ In "Developer Command Prompt for VS 2022": >cmake -G "Visual Studio 17 2022" -A x64 -S . -B build >cmake --build build --config RelWithDebInfo -Usage examples ------------ +## Usage examples + Usage examples can be found in the [examples](examples) directory. To compile them you need to configure with `--enable-examples`. - * [ECDSA example](examples/ecdsa.c) - * [Schnorr signatures example](examples/schnorr.c) - * [Deriving a shared secret (ECDH) example](examples/ecdh.c) - * [ElligatorSwift key exchange example](examples/ellswift.c) + +- [ECDSA example](examples/ecdsa.c) +- [Schnorr signatures example](examples/schnorr.c) +- [Deriving a shared secret (ECDH) example](examples/ecdh.c) +- [ElligatorSwift key exchange example](examples/ellswift.c) To compile the Schnorr signature and ECDH examples, you also need to configure with `--enable-module-schnorrsig` and `--enable-module-ecdh`. -Benchmark ------------- +## Benchmark + If configured with `--enable-benchmark` (which is the default), binaries for benchmarking the libsecp256k1 functions will be present in the root directory after the build. To print the benchmark result to the command line: @@ -131,12 +129,10 @@ To create a CSV file for the benchmark result : $ ./bench_name | sed '2d;s/ \{1,\}//g' > bench_name.csv -Reporting a vulnerability ------------- +## Reporting a vulnerability See [SECURITY.md](SECURITY.md) -Contributing to libsecp256k1 ------------- +## Contributing to libsecp256k1 See [CONTRIBUTING.md](CONTRIBUTING.md) diff --git a/external/secp256k1/SECURITY.md b/external/secp256k1/SECURITY.md index b515cc1c8e..cb438707ce 100644 --- a/external/secp256k1/SECURITY.md +++ b/external/secp256k1/SECURITY.md @@ -6,10 +6,10 @@ To report security issues send an email to secp256k1-security@bitcoincore.org (n The following keys may be used to communicate sensitive information to developers: -| Name | Fingerprint | -|------|-------------| -| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | -| Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 | -| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 | +| Name | Fingerprint | +| ------------- | ------------------------------------------------- | +| Pieter Wuille | 133E AC17 9436 F14A 5CF1 B794 860F EB80 4E66 9320 | +| Jonas Nick | 36C7 1A37 C9D9 88BD E825 08D9 B1A7 0E4F 8DCD 0366 | +| Tim Ruffing | 09E0 3F87 1092 E40E 106E 902B 33BC 86AB 80FF 5516 | You can import a key by running the following command with that individual’s fingerprint: `gpg --keyserver hkps://keys.openpgp.org --recv-keys ""` Ensure that you put quotes around fingerprints containing spaces. diff --git a/external/secp256k1/doc/ellswift.md b/external/secp256k1/doc/ellswift.md index 9d60e6be0b..ffbe9d02ac 100644 --- a/external/secp256k1/doc/ellswift.md +++ b/external/secp256k1/doc/ellswift.md @@ -5,17 +5,17 @@ construction in the ["SwiftEC: Shallue–van de Woestijne Indifferentiable Function To Elliptic Curves"](https://eprint.iacr.org/2022/759) paper by Jorge Chávez-Saab, Francisco Rodríguez-Henríquez, and Mehdi Tibouchi. -* [1. Introduction](#1-introduction) -* [2. The decoding function](#2-the-decoding-function) - + [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1) -* [3. The encoding function](#3-the-encoding-function) - + [3.1 Switching to *v, w* coordinates](#31-switching-to-v-w-coordinates) - + [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses) - + [3.3 Finding the inverse](#33-finding-the-inverse) - + [3.4 Dealing with special cases](#34-dealing-with-special-cases) - + [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1) -* [4. Encoding and decoding full *(x, y)* coordinates](#4-encoding-and-decoding-full-x-y-coordinates) - + [4.1 Full *(x, y)* coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1) +- [1. Introduction](#1-introduction) +- [2. The decoding function](#2-the-decoding-function) + - [2.1 Decoding for `secp256k1`](#21-decoding-for-secp256k1) +- [3. The encoding function](#3-the-encoding-function) + - [3.1 Switching to _v, w_ coordinates](#31-switching-to-v-w-coordinates) + - [3.2 Avoiding computing all inverses](#32-avoiding-computing-all-inverses) + - [3.3 Finding the inverse](#33-finding-the-inverse) + - [3.4 Dealing with special cases](#34-dealing-with-special-cases) + - [3.5 Encoding for `secp256k1`](#35-encoding-for-secp256k1) +- [4. Encoding and decoding full _(x, y)_ coordinates](#4-encoding-and-decoding-full-x-y-coordinates) + - [4.1 Full _(x, y)_ coordinates for `secp256k1`](#41-full-x-y-coordinates-for-secp256k1) ## 1. Introduction @@ -34,13 +34,14 @@ are taken modulo $p$), and then evaluating $F_u(t)$, which for every $u$ and $t$ x-coordinate on the curve. The functions $F_u$ will be defined in [Section 2](#2-the-decoding-function). **Encoding** a given $x$ coordinate is conceptually done as follows: -* Loop: - * Pick a uniformly random field element $u.$ - * Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to *8* elements. - * With probability $1 - \dfrac{\\#L}{8}$, restart the loop. - * Select a uniformly random $t \in L$ and return $(u, t).$ -This is the *ElligatorSwift* algorithm, here given for just x-coordinates. An extension to full +- Loop: + - Pick a uniformly random field element $u.$ + - Compute the set $L = F_u^{-1}(x)$ of $t$ values for which $F_u(t) = x$, which may have up to _8_ elements. + - With probability $1 - \dfrac{\\#L}{8}$, restart the loop. + - Select a uniformly random $t \in L$ and return $(u, t).$ + +This is the _ElligatorSwift_ algorithm, here given for just x-coordinates. An extension to full $(x, y)$ points will be given in [Section 4](#4-encoding-and-decoding-full-x-y-coordinates). The algorithm finds a uniformly random $(u, t)$ among (almost all) those for which $F_u(t) = x.$ Section 3.2 in the paper proves that the number of such encodings for @@ -50,37 +51,40 @@ almost all x-coordinates on the curve (all but at most 39) is close to two times ## 2. The decoding function First some definitions: -* $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$ - * For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement. -* Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$ + +- $\mathbb{F}$ is the finite field of size $q$, of characteristic 5 or more, and $q \equiv 1 \mod 3.$ + - For `secp256k1`, $q = 2^{256} - 2^{32} - 977$, which satisfies that requirement. +- Let $E$ be the elliptic curve of points $(x, y) \in \mathbb{F}^2$ for which $y^2 = x^3 + ax + b$, with $a$ and $b$ public constants, for which $\Delta_E = -16(4a^3 + 27b^2)$ is a square, and at least one of $(-b \pm \sqrt{-3 \Delta_E} / 36)/2$ is a square. - This implies that the order of $E$ is either odd, or a multiple of *4*. + This implies that the order of $E$ is either odd, or a multiple of _4_. If $a=0$, this condition is always fulfilled. - * For `secp256k1`, $a=0$ and $b=7.$ -* Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$ -* Let the function $h(x) = 3x^3 + 4a.$ -* Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$ -* Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$ -* $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below. -* $\psi_u$ is a function from $S_u$ to $V$ that will be defined below. + - For `secp256k1`, $a=0$ and $b=7.$ +- Let the function $g(x) = x^3 + ax + b$, so the $E$ curve equation is also $y^2 = g(x).$ +- Let the function $h(x) = 3x^3 + 4a.$ +- Define $V$ as the set of solutions $(x_1, x_2, x_3, z)$ to $z^2 = g(x_1)g(x_2)g(x_3).$ +- Define $S_u$ as the set of solutions $(X, Y)$ to $X^2 + h(u)Y^2 = -g(u)$ and $Y \neq 0.$ +- $P_u$ is a function from $\mathbb{F}$ to $S_u$ that will be defined below. +- $\psi_u$ is a function from $S_u$ to $V$ that will be defined below. **Note**: In the paper: -* $F_u$ corresponds to $F_{0,u}$ there. -* $P_u(t)$ is called $P$ there. -* All $S_u$ sets together correspond to $S$ there. -* All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there. + +- $F_u$ corresponds to $F_{0,u}$ there. +- $P_u(t)$ is called $P$ there. +- All $S_u$ sets together correspond to $S$ there. +- All $\psi_u$ functions together (operating on elements of $S$) correspond to $\psi$ there. Note that for $V$, the left hand side of the equation $z^2$ is square, and thus the right hand must also be square. As multiplying non-squares results in a square in $\mathbb{F}$, out of the three right-hand side factors an even number must be non-squares. -This implies that exactly *1* or exactly *3* out of +This implies that exactly _1_ or exactly _3_ out of $\\{g(x_1), g(x_2), g(x_3)\\}$ must be square, and thus that for any $(x_1,x_2,x_3,z) \in V$, at least one of $\\{x_1, x_2, x_3\\}$ must be a valid x-coordinate on $E.$ There is one exception to this, namely when $z=0$, but even then one of the three values is a valid x-coordinate. **Define** the decoding function $F_u(t)$ as: -* Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$ -* Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square). + +- Let $(x_1, x_2, x_3, z) = \psi_u(P_u(t)).$ +- Return the first element $x$ of $(x_3, x_2, x_1)$ which is a valid x-coordinate on $E$ (i.e., $g(x)$ is square). $P_u(t) = (X(u, t), Y(u, t))$, where: @@ -98,12 +102,13 @@ Y(u, t) & = & \left\\{\begin{array}{ll} $$ $P_u(t)$ is defined: -* For $a=0$, unless: - * $u = 0$ or $t = 0$ (division by zero) - * $g(u) = -t^2$ (would give $Y=0$). -* For $a \neq 0$, unless: - * $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero) - * $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$). + +- For $a=0$, unless: + - $u = 0$ or $t = 0$ (division by zero) + - $g(u) = -t^2$ (would give $Y=0$). +- For $a \neq 0$, unless: + - $X_0(u) = 0$ or $h(u)t^2 = -1$ (division by zero) + - $Y_0(u) (1 - h(u)t^2) = 2X_0(u)t$ (would give $Y=0$). The functions $X_0(u)$ and $Y_0(u)$ are defined in Appendix A of the paper, and depend on various properties of $E.$ @@ -123,20 +128,22 @@ $$ Put together and specialized for $a=0$ curves, decoding $(u, t)$ to an x-coordinate is: **Define** $F_u(t)$ as: -* Let $X = \dfrac{u^3 + b - t^2}{2t}.$ -* Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$ -* Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square. + +- Let $X = \dfrac{u^3 + b - t^2}{2t}.$ +- Let $Y = \dfrac{X + t}{u\sqrt{-3}}.$ +- Return the first $x$ in $(u + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u}{2}, \dfrac{X}{2Y} - \dfrac{u}{2})$ for which $g(x)$ is square. To make sure that every input decodes to a valid x-coordinate, we remap the inputs in case $P_u$ is not defined (when $u=0$, $t=0$, or $g(u) = -t^2$): **Define** $F_u(t)$ as: -* Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$). -* Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$). -* Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$). -* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$ -* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$ -* Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square. + +- Let $u'=u$ if $u \neq 0$; $1$ otherwise (guaranteeing $u' \neq 0$). +- Let $t'=t$ if $t \neq 0$; $1$ otherwise (guaranteeing $t' \neq 0$). +- Let $t''=t'$ if $g(u') \neq -t'^2$; $2t'$ otherwise (guaranteeing $t'' \neq 0$ and $g(u') \neq -t''^2$). +- Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$ +- Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$ +- Return the first $x$ in $(u' + 4Y^2, \dfrac{-X}{2Y} - \dfrac{u'}{2}, \dfrac{X}{2Y} - \dfrac{u'}{2})$ for which $x^3 + b$ is square. The choices here are not strictly necessary. Just returning a fixed constant in any of the undefined cases would suffice, but the approach here is simple enough and gives fairly uniform output even in these cases. @@ -150,10 +157,11 @@ in `secp256k1_ellswift_xswiftec_var` (which outputs the actual x-coordinate). ## 3. The encoding function To implement $F_u^{-1}(x)$, the function to find the set of inverses $t$ for which $F_u(t) = x$, we have to reverse the process: -* Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$ -* Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$ -* For each of the found $t$ values, verify that $F_u(t) = x.$ -* Return the remaining $t$ values. + +- Find all the $(X, Y) \in S_u$ that could have given rise to $x$, through the $x_1$, $x_2$, or $x_3$ formulas in $\psi_u.$ +- Map those $(X, Y)$ solutions to $t$ values using $P_u^{-1}(X, Y).$ +- For each of the found $t$ values, verify that $F_u(t) = x.$ +- Return the remaining $t$ values. The function $P_u^{-1}$, which finds $t$ given $(X, Y) \in S_u$, is significantly simpler than $P_u:$ @@ -185,13 +193,14 @@ precedence over both. Because of this, the $g(-u-x)$ being square test for $x_1$ values round-trip back to the input $x$ correctly. This is the reason for choosing the $(x_3, x_2, x_1)$ precedence order in the decoder; any order which does not place $x_3$ first requires more complicated round-trip checks in the encoder. -### 3.1 Switching to *v, w* coordinates +### 3.1 Switching to _v, w_ coordinates Before working out the formulas for all this, we switch to different variables for $S_u.$ Let $v = (X/Y - u)/2$, and $w = 2Y.$ Or in the other direction, $X = w(u/2 + v)$ and $Y = w/2:$ -* $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$ -* For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$ -* $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where + +- $S_u'$ becomes the set of $(v, w)$ for which $w^2 (u^2 + uv + v^2 + a) = -g(u)$ and $w \neq 0.$ +- For $a=0$ curves, $P_u^{-1}$ can be stated for $(v,w)$ as $P_u^{'-1}(v, w) = w\left(\frac{\sqrt{-3}-1}{2}u - v\right).$ +- $\psi_u$ can be stated for $(v, w)$ as $\psi_u'(v, w) = (x_1, x_2, x_3, z)$, where $$ \begin{array}{lcl} @@ -204,34 +213,37 @@ $$ We can now write the expressions for finding $(v, w)$ given $x$ explicitly, by solving each of the $\\{x_1, x_2, x_3\\}$ expressions for $v$ or $w$, and using the $S_u'$ equation to find the other variable: -* Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions). -* Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions). -* Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions). + +- Assuming $x = x_1$, we find $v = x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions). +- Assuming $x = x_2$, we find $v = -u-x$ and $w = \pm\sqrt{-g(u)/(u^2 + uv + v^2 + a)}$ (two solutions). +- Assuming $x = x_3$, we find $w = \pm\sqrt{x-u}$ and $v = -u/2 \pm \sqrt{-w^2(4g(u) + w^2h(u))}/(2w^2)$ (four solutions). ### 3.2 Avoiding computing all inverses -The *ElligatorSwift* algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the +The _ElligatorSwift_ algorithm as stated in Section 1 requires the computation of $L = F_u^{-1}(x)$ (the set of all $t$ such that $(u, t)$ decode to $x$) in full. This is unnecessary. Observe that the procedure of restarting with probability $(1 - \frac{\\#L}{8})$ and otherwise returning a uniformly random element from $L$ is actually equivalent to always padding $L$ with $\bot$ values up to length 8, picking a uniformly random element from that, restarting whenever $\bot$ is picked: -**Define** *ElligatorSwift(x)* as: -* Loop: - * Pick a uniformly random field element $u.$ - * Compute the set $L = F_u^{-1}(x).$ - * Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$ - * Select a uniformly random $t \in T.$ - * If $t \neq \bot$, return $(u, t)$; restart loop otherwise. +**Define** _ElligatorSwift(x)_ as: + +- Loop: + - Pick a uniformly random field element $u.$ + - Compute the set $L = F_u^{-1}(x).$ + - Let $T$ be the 8-element vector consisting of the elements of $L$, plus $8 - \\#L$ times $\\{\bot\\}.$ + - Select a uniformly random $t \in T.$ + - If $t \neq \bot$, return $(u, t)$; restart loop otherwise. Now notice that the order of elements in $T$ does not matter, as all we do is pick a uniformly random element in it, so we do not need to have all $\bot$ values at the end. As we have 8 distinct formulas for finding $(v, w)$ (taking the variants due to $\pm$ into account), we can associate every index in $T$ with exactly one of those formulas, making sure that: -* Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$ -* For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check). -* In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those. + +- Formulas that yield no solutions (due to division by zero or non-existing square roots) or invalid solutions are made to return $\bot.$ +- For the $x_1$ and $x_2$ cases, if $g(-u-x)$ is a square, $\bot$ is returned instead (the round-trip check). +- In case multiple formulas would return the same non- $\bot$ result, all but one of those must be turned into $\bot$ to avoid biasing those. The last condition above only occurs with negligible probability for cryptographically-sized curves, but is interesting to take into account as it allows exhaustive testing in small groups. See [Section 3.4](#34-dealing-with-special-cases) @@ -240,12 +252,13 @@ for an analysis of all the negligible cases. If we define $T = (G_{0,u}(x), G_{1,u}(x), \ldots, G_{7,u}(x))$, with each $G_{i,u}$ matching one of the formulas, the loop can be simplified to only compute one of the inverses instead of all of them: -**Define** *ElligatorSwift(x)* as: -* Loop: - * Pick a uniformly random field element $u.$ - * Pick a uniformly random integer $c$ in $[0,8).$ - * Let $t = G_{c,u}(x).$ - * If $t \neq \bot$, return $(u, t)$; restart loop otherwise. +**Define** _ElligatorSwift(x)_ as: + +- Loop: + - Pick a uniformly random field element $u.$ + - Pick a uniformly random integer $c$ in $[0,8).$ + - Let $t = G_{c,u}(x).$ + - If $t \neq \bot$, return $(u, t)$; restart loop otherwise. This is implemented in `secp256k1_ellswift_xelligatorswift_var`. @@ -256,18 +269,19 @@ Those are then repeated as $c=4$ through $c=7$ for the other sign of $w$ (noting Ignoring the negligible cases, we get: **Define** $G_{c,u}(x)$ as: -* If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas): - * If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence). - * If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula) - * Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows). -* Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas): - * Let $s = x-u.$ - * Let $r = \sqrt{-s(4g(u) + sh(u))}.$ - * Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise. -* Let $w = \sqrt{s}.$ -* Depending on $c:$ - * If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$ - * If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$ + +- If $c \in \\{0, 1, 4, 5\\}$ (for $x_1$ and $x_2$ formulas): + - If $g(-u-x)$ is square, return $\bot$ (as $x_3$ would be valid and take precedence). + - If $c \in \\{0, 4\\}$ (the $x_1$ formula) let $v = x$, otherwise let $v = -u-x$ (the $x_2$ formula) + - Let $s = -g(u)/(u^2 + uv + v^2 + a)$ (using $s = w^2$ in what follows). +- Otherwise, when $c \in \\{2, 3, 6, 7\\}$ (for $x_3$ formulas): + - Let $s = x-u.$ + - Let $r = \sqrt{-s(4g(u) + sh(u))}.$ + - Let $v = (r/s - u)/2$ if $c \in \\{3, 7\\}$; $(-r/s - u)/2$ otherwise. +- Let $w = \sqrt{s}.$ +- Depending on $c:$ + - If $c \in \\{0, 1, 2, 3\\}:$ return $P_u^{'-1}(v, w).$ + - If $c \in \\{4, 5, 6, 7\\}:$ return $P_u^{'-1}(v, -w).$ Whenever a square root of a non-square is taken, $\bot$ is returned; for both square roots this happens with roughly 50% on random inputs. Similarly, when a division by 0 would occur, $\bot$ is returned as well; this will only happen @@ -284,20 +298,21 @@ transformation. Furthermore, that transformation has no effect on $s$ in the fir as $u^2 + ux + x^2 + a = u^2 + u(-u-x) + (-u-x)^2 + a.$ Thus we can extract it out and move it down: **Define** $G_{c,u}(x)$ as: -* If $c \in \\{0, 1, 4, 5\\}:$ - * If $g(-u-x)$ is square, return $\bot.$ - * Let $s = -g(u)/(u^2 + ux + x^2 + a).$ - * Let $v = x.$ -* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ - * Let $s = x-u.$ - * Let $r = \sqrt{-s(4g(u) + sh(u))}.$ - * Let $v = (r/s - u)/2.$ -* Let $w = \sqrt{s}.$ -* Depending on $c:$ - * If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$ - * If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$ - * If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$ - * If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$ + +- If $c \in \\{0, 1, 4, 5\\}:$ + - If $g(-u-x)$ is square, return $\bot.$ + - Let $s = -g(u)/(u^2 + ux + x^2 + a).$ + - Let $v = x.$ +- Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ + - Let $s = x-u.$ + - Let $r = \sqrt{-s(4g(u) + sh(u))}.$ + - Let $v = (r/s - u)/2.$ +- Let $w = \sqrt{s}.$ +- Depending on $c:$ + - If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w).$ + - If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w).$ + - If $c \in \\{4, 6\\}:$ return $P_u^{'-1}(v, -w).$ + - If $c \in \\{5, 7\\}:$ return $P_u^{'-1}(-u-v, -w).$ This shows there will always be exactly 0, 4, or 8 $t$ values for a given $(u, x)$ input. There can be 0, 1, or 2 $(v, w)$ pairs before invoking $P_u^{'-1}$, and each results in 4 distinct $t$ values. @@ -310,58 +325,60 @@ we analyse them here. They generally fall into two categories: cases in which th do not decode back to $x$ (or at least cannot guarantee that they do), and cases in which the encoder might produce the same $t$ value for multiple $c$ inputs (thereby biasing that encoding): -* In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$): - * When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves. +- In the branch for $x_1$ and $x_2$ (where $c \in \\{0, 1, 4, 5\\}$): + - When $g(u) = 0$, we would have $s=w=Y=0$, which is not on $S_u.$ This is only possible on even-ordered curves. Excluding this also removes the one condition under which the simplified check for $x_3$ on the curve fails (namely when $g(x_1)=g(x_2)=0$ but $g(x_3)$ is not square). This does exclude some valid encodings: when both $g(u)=0$ and $u^2+ux+x^2+a=0$ (also implying $g(x)=0$), the $S_u'$ equation degenerates to $0 = 0$, and many valid $t$ values may exist. Yet, these cannot be targeted uniformly by the encoder anyway as there will generally be more than 8. - * When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence + - When $g(x) = 0$, the same $t$ would be produced as in the $x_3$ branch (where $c \in \\{2, 3, 6, 7\\}$) which we give precedence as it can deal with $g(u)=0$. This is again only possible on even-ordered curves. -* In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$): - * When $s=0$, a division by zero would occur. - * When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases. +- In the branch for $x_3$ (where $c \in \\{2, 3, 6, 7\\}$): + - When $s=0$, a division by zero would occur. + - When $v = -u-v$ and $c \in \\{3, 7\\}$, the same $t$ would be returned as in the $c \in \\{2, 6\\}$ cases. It is equivalent to checking whether $r=0$. This cannot occur in the $x_1$ or $x_2$ branches, as it would trigger the $g(-u-x)$ is square condition. A similar concern for $w = -w$ does not exist, as $w=0$ is already impossible in both branches: in the first it requires $g(u)=0$ which is already outlawed on even-ordered curves and impossible on others; in the second it would trigger division by zero. -* Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder: - * For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve. - * For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$. +- Curve-specific special cases also exist that need to be rejected, because they result in $(u,t)$ which is invalid to the decoder, or because of division by zero in the encoder: + - For $a=0$ curves, when $u=0$ or when $t=0$. The latter can only be reached by the encoder when $g(u)=0$, which requires an even-ordered curve. + - For $a \neq 0$ curves, when $X_0(u)=0$, when $h(u)t^2 = -1$, or when $w(u + 2v) = 2X_0(u)$ while also either $w \neq 2Y_0(u)$ or $h(u)=0$. **Define** a version of $G_{c,u}(x)$ which deals with all these cases: -* If $a=0$ and $u=0$, return $\bot.$ -* If $a \neq 0$ and $X_0(u)=0$, return $\bot.$ -* If $c \in \\{0, 1, 4, 5\\}:$ - * If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only). - * If $g(-u-x)$ is square, return $\bot.$ - * Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero). - * Let $v = x.$ -* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ - * Let $s = x-u.$ - * Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square. - * If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$ - * If $s = 0$, return $\bot.$ - * Let $v = (r/s - u)/2.$ -* Let $w = \sqrt{s}$; return $\bot$ if not square. -* If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$ -* Depending on $c:$ - * If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$ - * If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$ - * If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$ - * If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$ -* If $a=0$ and $t=0$, return $\bot$ (even curves only). -* If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$ -* Return $t.$ + +- If $a=0$ and $u=0$, return $\bot.$ +- If $a \neq 0$ and $X_0(u)=0$, return $\bot.$ +- If $c \in \\{0, 1, 4, 5\\}:$ + - If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only). + - If $g(-u-x)$ is square, return $\bot.$ + - Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero). + - Let $v = x.$ +- Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ + - Let $s = x-u.$ + - Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square. + - If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$ + - If $s = 0$, return $\bot.$ + - Let $v = (r/s - u)/2.$ +- Let $w = \sqrt{s}$; return $\bot$ if not square. +- If $a \neq 0$ and $w(u+2v) = 2X_0(u)$ and either $w \neq 2Y_0(u)$ or $h(u) = 0$, return $\bot.$ +- Depending on $c:$ + - If $c \in \\{0, 2\\}$, let $t = P_u^{'-1}(v, w).$ + - If $c \in \\{1, 3\\}$, let $t = P_u^{'-1}(-u-v, w).$ + - If $c \in \\{4, 6\\}$, let $t = P_u^{'-1}(v, -w).$ + - If $c \in \\{5, 7\\}$, let $t = P_u^{'-1}(-u-v, -w).$ +- If $a=0$ and $t=0$, return $\bot$ (even curves only). +- If $a \neq 0$ and $h(u)t^2 = -1$, return $\bot.$ +- Return $t.$ Given any $u$, using this algorithm over all $x$ and $c$ values, every $t$ value will be reached exactly once, for an $x$ for which $F_u(t) = x$ holds, except for these cases that will not be reached: -* All cases where $P_u(t)$ is not defined: - * For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$ - * For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$ -* When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch. + +- All cases where $P_u(t)$ is not defined: + - For $a=0$ curves, when $u=0$, $t=0$, or $g(u) = -t^2.$ + - For $a \neq 0$ curves, when $h(u)t^2 = -1$, $X_0(u) = 0$, or $Y_0(u) (1 - h(u) t^2) = 2X_0(u)t.$ +- When $g(u)=0$, the potentially many $t$ values that decode to an $x$ satisfying $g(x)=0$ using the $x_2$ formula. These were excluded by the $g(u)=0$ condition in the $c \in \\{0, 1, 4, 5\\}$ branch. These cases form a negligible subset of all $(u, t)$ for cryptographically sized curves. @@ -370,40 +387,42 @@ These cases form a negligible subset of all $(u, t)$ for cryptographically sized Specialized for odd-ordered $a=0$ curves: **Define** $G_{c,u}(x)$ as: -* If $u=0$, return $\bot.$ -* If $c \in \\{0, 1, 4, 5\\}:$ - * If $(-u-x)^3 + b$ is square, return $\bot$ - * Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0). - * Let $v = x.$ -* Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ - * Let $s = x-u.$ - * Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square. - * If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$ - * If $s = 0$, return $\bot.$ - * Let $v = (r/s - u)/2.$ -* Let $w = \sqrt{s}$; return $\bot$ if not square. -* Depending on $c:$ - * If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$ - * If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$ - * If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$ - * If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$ + +- If $u=0$, return $\bot.$ +- If $c \in \\{0, 1, 4, 5\\}:$ + - If $(-u-x)^3 + b$ is square, return $\bot$ + - Let $s = -(u^3 + b)/(u^2 + ux + x^2)$ (cannot cause division by 0). + - Let $v = x.$ +- Otherwise, when $c \in \\{2, 3, 6, 7\\}:$ + - Let $s = x-u.$ + - Let $r = \sqrt{-s(4(u^3 + b) + 3su^2)}$; return $\bot$ if not square. + - If $c \in \\{3, 7\\}$ and $r=0$, return $\bot.$ + - If $s = 0$, return $\bot.$ + - Let $v = (r/s - u)/2.$ +- Let $w = \sqrt{s}$; return $\bot$ if not square. +- Depending on $c:$ + - If $c \in \\{0, 2\\}:$ return $w(\frac{\sqrt{-3}-1}{2}u - v).$ + - If $c \in \\{1, 3\\}:$ return $w(\frac{\sqrt{-3}+1}{2}u + v).$ + - If $c \in \\{4, 6\\}:$ return $w(\frac{-\sqrt{-3}+1}{2}u + v).$ + - If $c \in \\{5, 7\\}:$ return $w(\frac{-\sqrt{-3}-1}{2}u - v).$ This is implemented in `secp256k1_ellswift_xswiftec_inv_var`. And the x-only ElligatorSwift encoding algorithm is still: -**Define** *ElligatorSwift(x)* as: -* Loop: - * Pick a uniformly random field element $u.$ - * Pick a uniformly random integer $c$ in $[0,8).$ - * Let $t = G_{c,u}(x).$ - * If $t \neq \bot$, return $(u, t)$; restart loop otherwise. +**Define** _ElligatorSwift(x)_ as: + +- Loop: + - Pick a uniformly random field element $u.$ + - Pick a uniformly random integer $c$ in $[0,8).$ + - Let $t = G_{c,u}(x).$ + - If $t \neq \bot$, return $(u, t)$; restart loop otherwise. Note that this logic does not take the remapped $u=0$, $t=0$, and $g(u) = -t^2$ cases into account; it just avoids them. While it is not impossible to make the encoder target them, this would increase the maximum number of $t$ values for a given $(u, x)$ combination beyond 8, and thereby slow down the ElligatorSwift loop proportionally, for a negligible gain in uniformity. -## 4. Encoding and decoding full *(x, y)* coordinates +## 4. Encoding and decoding full _(x, y)_ coordinates So far we have only addressed encoding and decoding x-coordinates, but in some cases an encoding for full points with $(x, y)$ coordinates is desirable. It is possible to encode this information @@ -422,30 +441,32 @@ four distinct $P_u^{'-1}$ calls in the definition of $G_{u,c}.$ To encode the sign of $y$ in the sign of $Y:$ -**Define** *Decode(u, t)* for full $(x, y)$ as: -* Let $(X, Y) = P_u(t).$ -* Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square. -* Let $y = \sqrt{g(x)}.$ -* If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$ +**Define** _Decode(u, t)_ for full $(x, y)$ as: + +- Let $(X, Y) = P_u(t).$ +- Let $x$ be the first value in $(u + 4Y^2, \frac{-X}{2Y} - \frac{u}{2}, \frac{X}{2Y} - \frac{u}{2})$ for which $g(x)$ is square. +- Let $y = \sqrt{g(x)}.$ +- If $sign(y) = sign(Y)$, return $(x, y)$; otherwise return $(x, -y).$ And encoding would be done using a $G_{c,u}(x, y)$ function defined as: **Define** $G_{c,u}(x, y)$ as: -* If $c \in \\{0, 1\\}:$ - * If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only). - * If $g(-u-x)$ is square, return $\bot.$ - * Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero). - * Let $v = x.$ -* Otherwise, when $c \in \\{2, 3\\}:$ - * Let $s = x-u.$ - * Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square. - * If $c = 3$ and $r = 0$, return $\bot.$ - * Let $v = (r/s - u)/2.$ -* Let $w = \sqrt{s}$; return $\bot$ if not square. -* Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise. -* Depending on $c:$ - * If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$ - * If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$ + +- If $c \in \\{0, 1\\}:$ + - If $g(u) = 0$ or $g(x) = 0$, return $\bot$ (even curves only). + - If $g(-u-x)$ is square, return $\bot.$ + - Let $s = -g(u)/(u^2 + ux + x^2 + a)$ (cannot cause division by zero). + - Let $v = x.$ +- Otherwise, when $c \in \\{2, 3\\}:$ + - Let $s = x-u.$ + - Let $r = \sqrt{-s(4g(u) + sh(u))}$; return $\bot$ if not square. + - If $c = 3$ and $r = 0$, return $\bot.$ + - Let $v = (r/s - u)/2.$ +- Let $w = \sqrt{s}$; return $\bot$ if not square. +- Let $w' = w$ if $sign(w/2) = sign(y)$; $-w$ otherwise. +- Depending on $c:$ + - If $c \in \\{0, 2\\}:$ return $P_u^{'-1}(v, w').$ + - If $c \in \\{1, 3\\}:$ return $P_u^{'-1}(-u-v, w').$ Note that $c$ now only ranges $[0,4)$, as the sign of $w'$ is decided based on that of $y$, rather than on $c.$ This change makes some valid encodings unreachable: when $y = 0$ and $sign(Y) \neq sign(0)$. @@ -454,22 +475,23 @@ In the above logic, $sign$ can be implemented in several ways, such as parity of of the input field element (for prime-sized fields) or the quadratic residuosity (for fields where $-1$ is not square). The choice does not matter, as long as it only takes on two possible values, and for $x \neq 0$ it holds that $sign(x) \neq sign(-x)$. -### 4.1 Full *(x, y)* coordinates for `secp256k1` +### 4.1 Full _(x, y)_ coordinates for `secp256k1` For $a=0$ curves, there is another option. Note that for those, the $P_u(t)$ function translates negations of $t$ to negations of (both) $X$ and $Y.$ Thus, we can use $sign(t)$ to encode the y-coordinate directly. Combined with the earlier remapping to guarantee all inputs land on the curve, we get as decoder: -**Define** *Decode(u, t)* as: -* Let $u'=u$ if $u \neq 0$; $1$ otherwise. -* Let $t'=t$ if $t \neq 0$; $1$ otherwise. -* Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise. -* Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$ -* Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$ -* Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square. -* Let $y = \sqrt{g(x)}.$ -* Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise. +**Define** _Decode(u, t)_ as: + +- Let $u'=u$ if $u \neq 0$; $1$ otherwise. +- Let $t'=t$ if $t \neq 0$; $1$ otherwise. +- Let $t''=t'$ if $u'^3 + b + t'^2 \neq 0$; $2t'$ otherwise. +- Let $X = \dfrac{u'^3 + b - t''^2}{2t''}.$ +- Let $Y = \dfrac{X + t''}{u'\sqrt{-3}}.$ +- Let $x$ be the first element of $(u' + 4Y^2, \frac{-X}{2Y} - \frac{u'}{2}, \frac{X}{2Y} - \frac{u'}{2})$ for which $g(x)$ is square. +- Let $y = \sqrt{g(x)}.$ +- Return $(x, y)$ if $sign(y) = sign(t)$; $(x, -y)$ otherwise. This is implemented in `secp256k1_ellswift_swiftec_var`. The used $sign(x)$ function is the parity of $x$ when represented as in integer in $[0,q).$ diff --git a/external/secp256k1/doc/musig.md b/external/secp256k1/doc/musig.md index ae21f9b131..176b131da6 100644 --- a/external/secp256k1/doc/musig.md +++ b/external/secp256k1/doc/musig.md @@ -1,5 +1,4 @@ -Notes on the musig module API -=========================== +# Notes on the musig module API The following sections contain additional notes on the API of the musig module (`include/secp256k1_musig.h`). A usage example can be found in `examples/musig.c`. diff --git a/external/secp256k1/doc/release-process.md b/external/secp256k1/doc/release-process.md index a64bae0f0d..4ac9ca0d23 100644 --- a/external/secp256k1/doc/release-process.md +++ b/external/secp256k1/doc/release-process.md @@ -2,7 +2,7 @@ This document outlines the process for releasing versions of the form `$MAJOR.$MINOR.$PATCH`. -We distinguish between two types of releases: *regular* and *maintenance* releases. +We distinguish between two types of releases: _regular_ and _maintenance_ releases. Regular releases are releases of a new major or minor version as well as patches of the most recent release. Maintenance releases, on the other hand, are required for patches of older releases. @@ -15,6 +15,7 @@ This process also assumes that there will be no minor releases for old major rel We aim to cut a regular release every 3-4 months, approximately twice as frequent as major Bitcoin Core releases. Every second release should be published one month before the feature freeze of the next major Bitcoin Core release, allowing sufficient time to update the library in Core. ## Sanity checks + Perform these checks when reviewing the release PR (see below): 1. Ensure `make distcheck` doesn't fail. @@ -42,15 +43,15 @@ Perform these checks when reviewing the release PR (see below): ## Regular release 1. Open a PR to the master branch with a commit (using message `"release: prepare for $MAJOR.$MINOR.$PATCH"`, for example) that - * finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by - * adding a section for the release (make sure that the version number is a link to a diff between the previous and new version), - * removing the `[Unreleased]` section header, - * ensuring that the release notes are not missing entries (check the `needs-changelog` label on github), and - * including an entry for `### ABI Compatibility` if it doesn't exist, - * sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and, - * if this is not a patch release, - * updates `_PKG_VERSION_*` and `_LIB_VERSION_*` in `configure.ac`, and - * updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`. + - finalizes the release notes in [CHANGELOG.md](../CHANGELOG.md) by + - adding a section for the release (make sure that the version number is a link to a diff between the previous and new version), + - removing the `[Unreleased]` section header, + - ensuring that the release notes are not missing entries (check the `needs-changelog` label on github), and + - including an entry for `### ABI Compatibility` if it doesn't exist, + - sets `_PKG_VERSION_IS_RELEASE` to `true` in `configure.ac`, and, + - if this is not a patch release, + - updates `_PKG_VERSION_*` and `_LIB_VERSION_*` in `configure.ac`, and + - updates `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_*` in `CMakeLists.txt`. 2. Perform the [sanity checks](#sanity-checks) on the PR branch. 3. After the PR is merged, tag the commit, and push the tag: ``` @@ -59,11 +60,12 @@ Perform these checks when reviewing the release PR (see below): git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH ``` 4. Open a PR to the master branch with a commit (using message `"release cleanup: bump version after $MAJOR.$MINOR.$PATCH"`, for example) that - * sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`, - * increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`, and - * adds an `[Unreleased]` section header to the [CHANGELOG.md](../CHANGELOG.md). + - sets `_PKG_VERSION_IS_RELEASE` to `false` and increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac`, + - increments the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt`, and + - adds an `[Unreleased]` section header to the [CHANGELOG.md](../CHANGELOG.md). If other maintainers are not present to approve the PR, it can be merged without ACKs. + 5. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md). 6. Send an announcement email to the bitcoin-dev mailing list. @@ -77,9 +79,9 @@ Note that bug fixes need to be backported only to releases for which no compatib git push git@github.com:bitcoin-core/secp256k1.git $MAJOR.$MINOR ``` 2. Open a pull request to the `$MAJOR.$MINOR` branch that - * includes the bug fixes, - * finalizes the release notes similar to a regular release, - * increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac` + - includes the bug fixes, + - finalizes the release notes similar to a regular release, + - increments `_PKG_VERSION_PATCH` and `_LIB_VERSION_REVISION` in `configure.ac` and the `$PATCH` component of `project(libsecp256k1 VERSION ...)` and `${PROJECT_NAME}_LIB_VERSION_REVISION` in `CMakeLists.txt` (with commit message `"release: bump versions for $MAJOR.$MINOR.$PATCH"`, for example). 3. Perform the [sanity checks](#sanity-checks) on the PR branch. @@ -89,6 +91,6 @@ Note that bug fixes need to be backported only to releases for which no compatib git tag -s v$MAJOR.$MINOR.$PATCH -m "libsecp256k1 $MAJOR.$MINOR.$PATCH" git push git@github.com:bitcoin-core/secp256k1.git v$MAJOR.$MINOR.$PATCH ``` -6. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md). -7. Send an announcement email to the bitcoin-dev mailing list. -8. Open PR to the master branch that includes a commit (with commit message `"release notes: add $MAJOR.$MINOR.$PATCH"`, for example) that adds release notes to [CHANGELOG.md](../CHANGELOG.md). +5. Create a new GitHub release with a link to the corresponding entry in [CHANGELOG.md](../CHANGELOG.md). +6. Send an announcement email to the bitcoin-dev mailing list. +7. Open PR to the master branch that includes a commit (with commit message `"release notes: add $MAJOR.$MINOR.$PATCH"`, for example) that adds release notes to [CHANGELOG.md](../CHANGELOG.md). diff --git a/external/secp256k1/doc/safegcd_implementation.md b/external/secp256k1/doc/safegcd_implementation.md index 5dbbb7bbd2..72d99daad3 100644 --- a/external/secp256k1/doc/safegcd_implementation.md +++ b/external/secp256k1/doc/safegcd_implementation.md @@ -29,65 +29,67 @@ def gcd(f, g): return abs(f) ``` -It computes the greatest common divisor of an odd integer *f* and any integer *g*. Its inner loop -keeps rewriting the variables *f* and *g* alongside a state variable *δ* that starts at *1*, until -*g=0* is reached. At that point, *|f|* gives the GCD. Each of the transitions in the loop is called a +It computes the greatest common divisor of an odd integer _f_ and any integer _g_. Its inner loop +keeps rewriting the variables _f_ and _g_ alongside a state variable _δ_ that starts at _1_, until +_g=0_ is reached. At that point, _|f|_ gives the GCD. Each of the transitions in the loop is called a "division step" (referred to as divstep in what follows). -For example, *gcd(21, 14)* would be computed as: -- Start with *δ=1 f=21 g=14* -- Take the third branch: *δ=2 f=21 g=7* -- Take the first branch: *δ=-1 f=7 g=-7* -- Take the second branch: *δ=0 f=7 g=0* -- The answer *|f| = 7*. +For example, _gcd(21, 14)_ would be computed as: + +- Start with _δ=1 f=21 g=14_ +- Take the third branch: _δ=2 f=21 g=7_ +- Take the first branch: _δ=-1 f=7 g=-7_ +- Take the second branch: _δ=0 f=7 g=0_ +- The answer _|f| = 7_. Why it works: + - Divsteps can be decomposed into two steps (see paragraph 8.2 in the paper): - - (a) If *g* is odd, replace *(f,g)* with *(g,g-f)* or (f,g+f), resulting in an even *g*. - - (b) Replace *(f,g)* with *(f,g/2)* (where *g* is guaranteed to be even). + - (a) If _g_ is odd, replace _(f,g)_ with _(g,g-f)_ or (f,g+f), resulting in an even _g_. + - (b) Replace _(f,g)_ with _(f,g/2)_ (where _g_ is guaranteed to be even). - Neither of those two operations change the GCD: - - For (a), assume *gcd(f,g)=c*, then it must be the case that *f=a c* and *g=b c* for some integers *a* - and *b*. As *(g,g-f)=(b c,(b-a)c)* and *(f,f+g)=(a c,(a+b)c)*, the result clearly still has - common factor *c*. Reasoning in the other direction shows that no common factor can be added by + - For (a), assume _gcd(f,g)=c_, then it must be the case that _f=a c_ and _g=b c_ for some integers _a_ + and _b_. As _(g,g-f)=(b c,(b-a)c)_ and _(f,f+g)=(a c,(a+b)c)_, the result clearly still has + common factor _c_. Reasoning in the other direction shows that no common factor can be added by doing so either. - - For (b), we know that *f* is odd, so *gcd(f,g)* clearly has no factor *2*, and we can remove - it from *g*. -- The algorithm will eventually converge to *g=0*. This is proven in the paper (see theorem G.3). -- It follows that eventually we find a final value *f'* for which *gcd(f,g) = gcd(f',0)*. As the - gcd of *f'* and *0* is *|f'|* by definition, that is our answer. + - For (b), we know that _f_ is odd, so _gcd(f,g)_ clearly has no factor _2_, and we can remove + it from _g_. +- The algorithm will eventually converge to _g=0_. This is proven in the paper (see theorem G.3). +- It follows that eventually we find a final value _f'_ for which _gcd(f,g) = gcd(f',0)_. As the + gcd of _f'_ and _0_ is _|f'|_ by definition, that is our answer. Compared to more [traditional GCD algorithms](https://en.wikipedia.org/wiki/Euclidean_algorithm), this one has the property of only ever looking at the low-order bits of the variables to decide the next steps, and being easy to make -constant-time (in more low-level languages than Python). The *δ* parameter is necessary to +constant-time (in more low-level languages than Python). The _δ_ parameter is necessary to guide the algorithm towards shrinking the numbers' magnitudes without explicitly needing to look at high order bits. Properties that will become important later: -- Performing more divsteps than needed is not a problem, as *f* does not change anymore after *g=0*. -- Only even numbers are divided by *2*. This means that when reasoning about it algebraically we - do not need to worry about rounding. -- At every point during the algorithm's execution the next *N* steps only depend on the bottom *N* - bits of *f* and *g*, and on *δ*. +- Performing more divsteps than needed is not a problem, as _f_ does not change anymore after _g=0_. +- Only even numbers are divided by _2_. This means that when reasoning about it algebraically we + do not need to worry about rounding. +- At every point during the algorithm's execution the next _N_ steps only depend on the bottom _N_ + bits of _f_ and _g_, and on _δ_. ## 2. From GCDs to modular inverses -We want an algorithm to compute the inverse *a* of *x* modulo *M*, i.e. the number a such that *a x=1 -mod M*. This inverse only exists if the GCD of *x* and *M* is *1*, but that is always the case if *M* is -prime and *0 < x < M*. In what follows, assume that the modular inverse exists. +We want an algorithm to compute the inverse _a_ of _x_ modulo _M_, i.e. the number a such that _a x=1 +mod M_. This inverse only exists if the GCD of _x_ and _M_ is _1_, but that is always the case if _M_ is +prime and _0 < x < M_. In what follows, assume that the modular inverse exists. It turns out this inverse can be computed as a side effect of computing the GCD by keeping track of how the internal variables can be written as linear combinations of the inputs at every step (see the [extended Euclidean algorithm](https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm)). -Since the GCD is *1*, such an algorithm will compute numbers *a* and *b* such that a x + b M = 1*. +Since the GCD is _1_, such an algorithm will compute numbers _a_ and _b_ such that a x + b M = 1*. Taking that expression *mod M* gives *a x mod M = 1*, and we see that *a* is the modular inverse of *x -mod M*. +mod M\*. A similar approach can be used to calculate modular inverses using the divsteps-based GCD -algorithm shown above, if the modulus *M* is odd. To do so, compute *gcd(f=M,g=x)*, while keeping -track of extra variables *d* and *e*, for which at every step *d = f/x (mod M)* and *e = g/x (mod M)*. -*f/x* here means the number which multiplied with *x* gives *f mod M*. As *f* and *g* are initialized to *M* -and *x* respectively, *d* and *e* just start off being *0* (*M/x mod M = 0/x mod M = 0*) and *1* (*x/x mod M -= 1*). +algorithm shown above, if the modulus _M_ is odd. To do so, compute _gcd(f=M,g=x)_, while keeping +track of extra variables _d_ and _e_, for which at every step _d = f/x (mod M)_ and _e = g/x (mod M)_. +_f/x_ here means the number which multiplied with _x_ gives _f mod M_. As _f_ and _g_ are initialized to _M_ +and _x_ respectively, _d_ and _e_ just start off being _0_ (_M/x mod M = 0/x mod M = 0_) and _1_ (_x/x mod M += 1_). ```python def div2(M, x): @@ -119,17 +121,16 @@ def modinv(M, x): return (d * f) % M ``` -Also note that this approach to track *d* and *e* throughout the computation to determine the inverse +Also note that this approach to track _d_ and _e_ throughout the computation to determine the inverse is different from the paper. There (see paragraph 12.1 in the paper) a transition matrix for the entire computation is determined (see section 3 below) and the inverse is computed from that. The approach here avoids the need for 2x2 matrix multiplications of various sizes, and appears to be faster at the level of optimization we're able to do in C. - ## 3. Batching multiple divsteps -Every divstep can be expressed as a matrix multiplication, applying a transition matrix *(1/2 t)* -to both vectors *[f, g]* and *[d, e]* (see paragraph 8.1 in the paper): +Every divstep can be expressed as a matrix multiplication, applying a transition matrix _(1/2 t)_ +to both vectors _[f, g]_ and _[d, e]_ (see paragraph 8.1 in the paper): ``` t = [ u, v ] @@ -142,15 +143,15 @@ to both vectors *[f, g]* and *[d, e]* (see paragraph 8.1 in the paper): [ out_e ] [ in_e ] ``` -where *(u, v, q, r)* is *(0, 2, -1, 1)*, *(2, 0, 1, 1)*, or *(2, 0, 0, 1)*, depending on which branch is -taken. As above, the resulting *f* and *g* are always integers. +where _(u, v, q, r)_ is _(0, 2, -1, 1)_, _(2, 0, 1, 1)_, or _(2, 0, 0, 1)_, depending on which branch is +taken. As above, the resulting _f_ and _g_ are always integers. Performing multiple divsteps corresponds to a multiplication with the product of all the individual divsteps' transition matrices. As each transition matrix consists of integers -divided by *2*, the product of these matrices will consist of integers divided by *2N* (see also -theorem 9.2 in the paper). These divisions are expensive when updating *d* and *e*, so we delay -them: we compute the integer coefficients of the combined transition matrix scaled by *2N*, and -do one division by *2N* as a final step: +divided by _2_, the product of these matrices will consist of integers divided by _2N_ (see also +theorem 9.2 in the paper). These divisions are expensive when updating _d_ and _e_, so we delay +them: we compute the integer coefficients of the combined transition matrix scaled by _2N_, and +do one division by _2N_ as a final step: ```python def divsteps_n_matrix(delta, f, g): @@ -166,13 +167,13 @@ def divsteps_n_matrix(delta, f, g): return delta, (u, v, q, r) ``` -As the branches in the divsteps are completely determined by the bottom *N* bits of *f* and *g*, this +As the branches in the divsteps are completely determined by the bottom _N_ bits of _f_ and _g_, this function to compute the transition matrix only needs to see those bottom bits. Furthermore all -intermediate results and outputs fit in *(N+1)*-bit numbers (unsigned for *f* and *g*; signed for *u*, *v*, -*q*, and *r*) (see also paragraph 8.3 in the paper). This means that an implementation using 64-bit -integers could set *N=62* and compute the full transition matrix for 62 steps at once without any +intermediate results and outputs fit in _(N+1)_-bit numbers (unsigned for _f_ and _g_; signed for _u_, _v_, +_q_, and _r_) (see also paragraph 8.3 in the paper). This means that an implementation using 64-bit +integers could set _N=62_ and compute the full transition matrix for 62 steps at once without any big integer arithmetic at all. This is the reason why this algorithm is efficient: it only needs -to update the full-size *f*, *g*, *d*, and *e* numbers once every *N* steps. +to update the full-size _f_, _g_, _d_, and _e_ numbers once every _N_ steps. We still need functions to compute: @@ -184,8 +185,8 @@ We still need functions to compute: [ out_e ] ( [ q, r ]) [ in_e ] ``` -Because the divsteps transformation only ever divides even numbers by two, the result of *t [f,g]* is always even. When *t* is a composition of *N* divsteps, it follows that the resulting *f* -and *g* will be multiple of *2N*, and division by *2N* is simply shifting them down: +Because the divsteps transformation only ever divides even numbers by two, the result of _t [f,g]_ is always even. When _t_ is a composition of _N_ divsteps, it follows that the resulting _f_ +and _g_ will be multiple of _2N_, and division by _2N_ is simply shifting them down: ```python def update_fg(f, g, t): @@ -199,8 +200,8 @@ def update_fg(f, g, t): return cf >> N, cg >> N ``` -The same is not true for *d* and *e*, and we need an equivalent of the `div2` function for division by *2N mod M*. -This is easy if we have precomputed *1/M mod 2N* (which always exists for odd *M*): +The same is not true for _d_ and _e_, and we need an equivalent of the `div2` function for division by _2N mod M_. +This is easy if we have precomputed _1/M mod 2N_ (which always exists for odd _M_): ```python def div2n(M, Mi, x): @@ -224,7 +225,7 @@ def update_de(d, e, t, M, Mi): return div2n(M, Mi, cd), div2n(M, Mi, ce) ``` -With all of those, we can write a version of `modinv` that performs *N* divsteps at once: +With all of those, we can write a version of `modinv` that performs _N_ divsteps at once: ```python3 def modinv(M, Mi, x): @@ -242,20 +243,19 @@ def modinv(M, Mi, x): return (d * f) % M ``` -This means that in practice we'll always perform a multiple of *N* divsteps. This is not a problem -because once *g=0*, further divsteps do not affect *f*, *g*, *d*, or *e* anymore (only *δ* keeps +This means that in practice we'll always perform a multiple of _N_ divsteps. This is not a problem +because once _g=0_, further divsteps do not affect _f_, _g_, _d_, or _e_ anymore (only _δ_ keeps increasing). For variable time code such excess iterations will be mostly optimized away in later sections. - ## 4. Avoiding modulus operations -So far, there are two places where we compute a remainder of big numbers modulo *M*: at the end of -`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating *d* due to the -sign of *f*. These are relatively expensive operations when done generically. +So far, there are two places where we compute a remainder of big numbers modulo _M_: at the end of +`div2n` in every `update_de`, and at the very end of `modinv` after potentially negating _d_ due to the +sign of _f_. These are relatively expensive operations when done generically. -To deal with the modulus operation in `div2n`, we simply stop requiring *d* and *e* to be in range -*[0,M)* all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus +To deal with the modulus operation in `div2n`, we simply stop requiring _d_ and _e_ to be in range +_[0,M)_ all the time. Let's start by inlining `div2n` into `update_de`, and dropping the modulus operation at the end: ```python @@ -272,15 +272,15 @@ def update_de(d, e, t, M, Mi): return cd >> N, ce >> N ``` -Let's look at bounds on the ranges of these numbers. It can be shown that *|u|+|v|* and *|q|+|r|* -never exceed *2N* (see paragraph 8.3 in the paper), and thus a multiplication with *t* will have -outputs whose absolute values are at most *2N* times the maximum absolute input value. In case the -inputs *d* and *e* are in *(-M,M)*, which is certainly true for the initial values *d=0* and *e=1* assuming -*M > 1*, the multiplication results in numbers in range *(-2NM,2NM)*. Subtracting less than *2N* -times *M* to cancel out *N* bits brings that up to *(-2N+1M,2NM)*, and -dividing by *2N* at the end takes it to *(-2M,M)*. Another application of `update_de` would take that -to *(-3M,2M)*, and so forth. This progressive expansion of the variables' ranges can be -counteracted by incrementing *d* and *e* by *M* whenever they're negative: +Let's look at bounds on the ranges of these numbers. It can be shown that _|u|+|v|_ and _|q|+|r|_ +never exceed _2N_ (see paragraph 8.3 in the paper), and thus a multiplication with _t_ will have +outputs whose absolute values are at most _2N_ times the maximum absolute input value. In case the +inputs _d_ and _e_ are in _(-M,M)_, which is certainly true for the initial values _d=0_ and _e=1_ assuming +_M > 1_, the multiplication results in numbers in range _(-2NM,2NM)_. Subtracting less than _2N_ +times _M_ to cancel out _N_ bits brings that up to _(-2N+1M,2NM)_, and +dividing by _2N_ at the end takes it to _(-2M,M)_. Another application of `update_de` would take that +to _(-3M,2M)_, and so forth. This progressive expansion of the variables' ranges can be +counteracted by incrementing _d_ and _e_ by _M_ whenever they're negative: ```python ... @@ -293,12 +293,12 @@ counteracted by incrementing *d* and *e* by *M* whenever they're negative: ... ``` -With inputs in *(-2M,M)*, they will first be shifted into range *(-M,M)*, which means that the -output will again be in *(-2M,M)*, and this remains the case regardless of how many `update_de` +With inputs in _(-2M,M)_, they will first be shifted into range _(-M,M)_, which means that the +output will again be in _(-2M,M)_, and this remains the case regardless of how many `update_de` invocations there are. In what follows, we will try to make this more efficient. -Note that increasing *d* by *M* is equal to incrementing *cd* by *u M* and *ce* by *q M*. Similarly, -increasing *e* by *M* is equal to incrementing *cd* by *v M* and *ce* by *r M*. So we could instead write: +Note that increasing _d_ by _M_ is equal to incrementing _cd_ by _u M_ and _ce_ by _q M_. Similarly, +increasing _e_ by _M_ is equal to incrementing _cd_ by _v M_ and _ce_ by _r M_. So we could instead write: ```python ... @@ -318,10 +318,10 @@ increasing *e* by *M* is equal to incrementing *cd* by *v M* and *ce* by ... ``` -Now note that we have two steps of corrections to *cd* and *ce* that add multiples of *M*: this +Now note that we have two steps of corrections to _cd_ and _ce_ that add multiples of _M_: this increment, and the decrement that cancels out bottom bits. The second one depends on the first -one, but they can still be efficiently combined by only computing the bottom bits of *cd* and *ce* -at first, and using that to compute the final *md*, *me* values: +one, but they can still be efficiently combined by only computing the bottom bits of _cd_ and _ce_ +at first, and using that to compute the final _md_, _me_ values: ```python def update_de(d, e, t, M, Mi): @@ -346,8 +346,8 @@ def update_de(d, e, t, M, Mi): return cd >> N, ce >> N ``` -One last optimization: we can avoid the *md M* and *me M* multiplications in the bottom bits of *cd* -and *ce* by moving them to the *md* and *me* correction: +One last optimization: we can avoid the _md M_ and _me M_ multiplications in the bottom bits of _cd_ +and _ce_ by moving them to the _md_ and _me_ correction: ```python ... @@ -362,10 +362,10 @@ and *ce* by moving them to the *md* and *me* correction: ... ``` -The resulting function takes *d* and *e* in range *(-2M,M)* as inputs, and outputs values in the same -range. That also means that the *d* value at the end of `modinv` will be in that range, while we want -a result in *[0,M)*. To do that, we need a normalization function. It's easy to integrate the -conditional negation of *d* (based on the sign of *f*) into it as well: +The resulting function takes _d_ and _e_ in range _(-2M,M)_ as inputs, and outputs values in the same +range. That also means that the _d_ value at the end of `modinv` will be in that range, while we want +a result in _[0,M)_. To do that, we need a normalization function. It's easy to integrate the +conditional negation of _d_ (based on the sign of _f_) into it as well: ```python def normalize(sign, v, M): @@ -391,22 +391,21 @@ And calling it in `modinv` is simply: return normalize(f, d, M) ``` - ## 5. Constant-time operation The primary selling point of the algorithm is fast constant-time operation. What code flow still depends on the input data so far? -- the number of iterations of the while *g ≠ 0* loop in `modinv` +- the number of iterations of the while _g ≠ 0_ loop in `modinv` - the branches inside `divsteps_n_matrix` - the sign checks in `update_de` - the sign checks in `normalize` To make the while loop in `modinv` constant time it can be replaced with a constant number of -iterations. The paper proves (Theorem 11.2) that *741* divsteps are sufficient for any *256*-bit -inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound *724* is -sufficient even. Given that every loop iteration performs *N* divsteps, it will run a total of -*⌈724/N⌉* times. +iterations. The paper proves (Theorem 11.2) that _741_ divsteps are sufficient for any _256_-bit +inputs, and [safegcd-bounds](https://github.com/sipa/safegcd-bounds) shows that the slightly better bound _724_ is +sufficient even. Given that every loop iteration performs _N_ divsteps, it will run a total of +_⌈724/N⌉_ times. To deal with the branches in `divsteps_n_matrix` we will replace them with constant-time bitwise operations (and hope the C compiler isn't smart enough to turn them back into branches; see @@ -425,10 +424,10 @@ divstep can be written instead as (compare to the inner loop of `gcd` in section ``` To convert the above to bitwise operations, we rely on a trick to negate conditionally: per the -definition of negative numbers in two's complement, (*-v == ~v + 1*) holds for every number *v*. As -*-1* in two's complement is all *1* bits, bitflipping can be expressed as xor with *-1*. It follows -that *-v == (v ^ -1) - (-1)*. Thus, if we have a variable *c* that takes on values *0* or *-1*, then -*(v ^ c) - c* is *v* if *c=0* and *-v* if *c=-1*. +definition of negative numbers in two's complement, (_-v == ~v + 1_) holds for every number _v_. As +_-1_ in two's complement is all _1_ bits, bitflipping can be expressed as xor with _-1_. It follows +that _-v == (v ^ -1) - (-1)_. Thus, if we have a variable _c_ that takes on values _0_ or _-1_, then +_(v ^ c) - c_ is _v_ if _c=0_ and _-v_ if _c=-1_. Using this we can write: @@ -444,13 +443,13 @@ in constant-time form as: x = (f ^ c1) - c1 ``` -To use that trick, we need a helper mask variable *c1* that resolves the condition *δ>0* to *-1* -(if true) or *0* (if false). We compute *c1* using right shifting, which is equivalent to dividing by -the specified power of *2* and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see -`assumptions.h` for tests that this is the case). Right shifting by *63* thus maps all -numbers in range *[-263,0)* to *-1*, and numbers in range *[0,263)* to *0*. +To use that trick, we need a helper mask variable _c1_ that resolves the condition _δ>0_ to _-1_ +(if true) or _0_ (if false). We compute _c1_ using right shifting, which is equivalent to dividing by +the specified power of _2_ and rounding down (in Python, and also in C under the assumption of a typical two's complement system; see +`assumptions.h` for tests that this is the case). Right shifting by _63_ thus maps all +numbers in range _[-263,0)_ to _-1_, and numbers in range _[0,263)_ to _0_. -Using the facts that *x&0=0* and *x&(-1)=x* (on two's complement systems again), we can write: +Using the facts that _x&0=0_ and _x&(-1)=x_ (on two's complement systems again), we can write: ```python if g & 1: @@ -498,8 +497,8 @@ becomes: ``` It turns out that this can be implemented more efficiently by applying the substitution -*η=-δ*. In this representation, negating *δ* corresponds to negating *η*, and incrementing -*δ* corresponds to decrementing *η*. This allows us to remove the negation in the *c1* +_η=-δ_. In this representation, negating _δ_ corresponds to negating _η_, and incrementing +_δ_ corresponds to decrementing _η_. This allows us to remove the negation in the _c1_ computation: ```python @@ -519,12 +518,12 @@ computation: g >>= 1 ``` -A variant of divsteps with better worst-case performance can be used instead: starting *δ* at -*1/2* instead of *1*. This reduces the worst case number of iterations to *590* for *256*-bit inputs -(which can be shown using convex hull analysis). In this case, the substitution *ζ=-(δ+1/2)* -is used instead to keep the variable integral. Incrementing *δ* by *1* still translates to -decrementing *ζ* by *1*, but negating *δ* now corresponds to going from *ζ* to *-(ζ+1)*, or -*~ζ*. Doing that conditionally based on *c3* is simply: +A variant of divsteps with better worst-case performance can be used instead: starting _δ_ at +_1/2_ instead of _1_. This reduces the worst case number of iterations to _590_ for _256_-bit inputs +(which can be shown using convex hull analysis). In this case, the substitution _ζ=-(δ+1/2)_ +is used instead to keep the variable integral. Incrementing _δ_ by _1_ still translates to +decrementing _ζ_ by _1_, but negating _δ_ now corresponds to going from _ζ_ to _-(ζ+1)_, or +_~ζ_. Doing that conditionally based on _c3_ is simply: ```python ... @@ -534,13 +533,12 @@ decrementing *ζ* by *1*, but negating *δ* now corresponds to going fr ``` By replacing the loop in `divsteps_n_matrix` with a variant of the divstep code above (extended to -also apply all *f* operations to *u*, *v* and all *g* operations to *q*, *r*), a constant-time version of +also apply all _f_ operations to _u_, _v_ and all _g_ operations to _q_, _r_), a constant-time version of `divsteps_n_matrix` is obtained. The full code will be in section 7. These bit fiddling tricks can also be used to make the conditional negations and additions in `update_de` and `normalize` constant-time. - ## 6. Variable-time optimizations In section 5, we modified the `divsteps_n_matrix` function (and a few others) to be constant time. @@ -550,7 +548,7 @@ faster non-constant time `divsteps_n_matrix` function. To do so, first consider yet another way of writing the inner loop of divstep operations in `gcd` from section 1. This decomposition is also explained in the paper in section 8.2. We use -the original version with initial *δ=1* and *η=-δ* here. +the original version with initial _δ=1_ and _η=-δ_ here. ```python for _ in range(N): @@ -562,7 +560,7 @@ for _ in range(N): g >>= 1 ``` -Whenever *g* is even, the loop only shifts *g* down and decreases *η*. When *g* ends in multiple zero +Whenever _g_ is even, the loop only shifts _g_ down and decreases _η_. When _g_ ends in multiple zero bits, these iterations can be consolidated into one step. This requires counting the bottom zero bits efficiently, which is possible on most platforms; it is abstracted here as the function `count_trailing_zeros`. @@ -595,20 +593,20 @@ while True: # g is even now, and the eta decrement and g shift will happen in the next loop. ``` -We can now remove multiple bottom *0* bits from *g* at once, but still need a full iteration whenever -there is a bottom *1* bit. In what follows, we will get rid of multiple *1* bits simultaneously as +We can now remove multiple bottom _0_ bits from _g_ at once, but still need a full iteration whenever +there is a bottom _1_ bit. In what follows, we will get rid of multiple _1_ bits simultaneously as well. -Observe that as long as *η ≥ 0*, the loop does not modify *f*. Instead, it cancels out bottom -bits of *g* and shifts them out, and decreases *η* and *i* accordingly - interrupting only when *η* -becomes negative, or when *i* reaches *0*. Combined, this is equivalent to adding a multiple of *f* to -*g* to cancel out multiple bottom bits, and then shifting them out. +Observe that as long as _η ≥ 0_, the loop does not modify _f_. Instead, it cancels out bottom +bits of _g_ and shifts them out, and decreases _η_ and _i_ accordingly - interrupting only when _η_ +becomes negative, or when _i_ reaches _0_. Combined, this is equivalent to adding a multiple of _f_ to +_g_ to cancel out multiple bottom bits, and then shifting them out. -It is easy to find what that multiple is: we want a number *w* such that *g+w f* has a few bottom -zero bits. If that number of bits is *L*, we want *g+w f mod 2L = 0*, or *w = -g/f mod 2L*. Since *f* -is odd, such a *w* exists for any *L*. *L* cannot be more than *i* steps (as we'd finish the loop before -doing more) or more than *η+1* steps (as we'd run `eta, f, g = -eta, g, -f` at that point), but -apart from that, we're only limited by the complexity of computing *w*. +It is easy to find what that multiple is: we want a number _w_ such that _g+w f_ has a few bottom +zero bits. If that number of bits is _L_, we want _g+w f mod 2L = 0_, or _w = -g/f mod 2L_. Since _f_ +is odd, such a _w_ exists for any _L_. _L_ cannot be more than _i_ steps (as we'd finish the loop before +doing more) or more than _η+1_ steps (as we'd run `eta, f, g = -eta, g, -f` at that point), but +apart from that, we're only limited by the complexity of computing _w_. This code demonstrates how to cancel up to 4 bits per step: @@ -642,26 +640,25 @@ some can be found in Hacker's Delight second edition by Henry S. Warren, Jr. pag Here we need the negated modular inverse, which is a simple transformation of those: - Instead of a 3-bit table: - - *-f* or *f ^ 6* + - _-f_ or _f ^ 6_ - Instead of a 4-bit table: - - *1 - f(f + 1)* - - *-(f + (((f + 1) & 4) << 1))* -- For larger tables the following technique can be used: if *w=-1/f mod 2L*, then *w(w f+2)* is - *-1/f mod 22L*. This allows extending the previous formulas (or tables). In particular we + - _1 - f(f + 1)_ + - _-(f + (((f + 1) & 4) << 1))_ +- For larger tables the following technique can be used: if _w=-1/f mod 2L_, then _w(w f+2)_ is + _-1/f mod 22L_. This allows extending the previous formulas (or tables). In particular we have this 6-bit function (based on the 3-bit function above): - - *f(f2 - 2)* + - _f(f2 - 2)_ -This loop, again extended to also handle *u*, *v*, *q*, and *r* alongside *f* and *g*, placed in +This loop, again extended to also handle _u_, _v_, _q_, and _r_ alongside _f_ and _g_, placed in `divsteps_n_matrix`, gives a significantly faster, but non-constant time version. - ## 7. Final Python version All together we need the following functions: - A way to compute the transition matrix in constant time, using the `divsteps_n_matrix` function from section 2, but with its loop replaced by a variant of the constant-time divstep from - section 5, extended to handle *u*, *v*, *q*, *r*: + section 5, extended to handle _u_, _v_, _q_, _r_: ```python def divsteps_n_matrix(zeta, f, g): @@ -684,7 +681,7 @@ def divsteps_n_matrix(zeta, f, g): return zeta, (u, v, q, r) ``` -- The functions to update *f* and *g*, and *d* and *e*, from section 2 and section 4, with the constant-time +- The functions to update _f_ and _g_, and _d_ and _e_, from section 2 and section 4, with the constant-time changes to `update_de` from section 5: ```python @@ -723,7 +720,7 @@ def normalize(sign, v, M): return v ``` -- And finally the `modinv` function too, adapted to use *ζ* instead of *δ*, and using the fixed +- And finally the `modinv` function too, adapted to use _ζ_ instead of _δ_, and using the fixed iteration count from section 5: ```python @@ -772,20 +769,21 @@ def modinv_var(M, Mi, x): ## 8. From GCDs to Jacobi symbol -We can also use a similar approach to calculate Jacobi symbol *(x | M)* by keeping track of an -extra variable *j*, for which at every step *(x | M) = j (g | f)*. As we update *f* and *g*, we -make corresponding updates to *j* using +We can also use a similar approach to calculate Jacobi symbol _(x | M)_ by keeping track of an +extra variable _j_, for which at every step _(x | M) = j (g | f)_. As we update _f_ and _g_, we +make corresponding updates to _j_ using [properties of the Jacobi symbol](https://en.wikipedia.org/wiki/Jacobi_symbol#Properties): -* *((g/2) | f)* is either *(g | f)* or *-(g | f)*, depending on the value of *f mod 8* (negating if it's *3* or *5*). -* *(f | g)* is either *(g | f)* or *-(g | f)*, depending on *f mod 4* and *g mod 4* (negating if both are *3*). -These updates depend only on the values of *f* and *g* modulo *4* or *8*, and can thus be applied -very quickly, as long as we keep track of a few additional bits of *f* and *g*. Overall, this +- _((g/2) | f)_ is either _(g | f)_ or _-(g | f)_, depending on the value of _f mod 8_ (negating if it's _3_ or _5_). +- _(f | g)_ is either _(g | f)_ or _-(g | f)_, depending on _f mod 4_ and _g mod 4_ (negating if both are _3_). + +These updates depend only on the values of _f_ and _g_ modulo _4_ or _8_, and can thus be applied +very quickly, as long as we keep track of a few additional bits of _f_ and _g_. Overall, this calculation is slightly simpler than the one for the modular inverse because we no longer need to -keep track of *d* and *e*. +keep track of _d_ and _e_. -However, one difficulty of this approach is that the Jacobi symbol *(a | n)* is only defined for -positive odd integers *n*, whereas in the original safegcd algorithm, *f, g* can take negative +However, one difficulty of this approach is that the Jacobi symbol _(a | n)_ is only defined for +positive odd integers _n_, whereas in the original safegcd algorithm, _f, g_ can take negative values. We resolve this by using the following modified steps: ```python @@ -799,15 +797,16 @@ values. We resolve this by using the following modified steps: ``` The algorithm is still correct, since the changed divstep, called a "posdivstep" (see section 8.4 -and E.5 in the paper) preserves *gcd(f, g)*. However, there's no proof that the modified algorithm +and E.5 in the paper) preserves _gcd(f, g)_. However, there's no proof that the modified algorithm will converge. The justification for posdivsteps is completely empirical: in practice, it appears -that the vast majority of nonzero inputs converge to *f=g=gcd(f0, g0)* in a +that the vast majority of nonzero inputs converge to _f=g=gcd(f0, g0)_ in a number of steps proportional to their logarithm. Note that: -- We require inputs to satisfy *gcd(x, M) = 1*, as otherwise *f=1* is not reached. -- We require inputs *x &neq; 0*, because applying posdivstep with *g=0* has no effect. -- We need to update the termination condition from *g=0* to *f=1*. + +- We require inputs to satisfy _gcd(x, M) = 1_, as otherwise _f=1_ is not reached. +- We require inputs _x &neq; 0_, because applying posdivstep with _g=0_ has no effect. +- We need to update the termination condition from _g=0_ to _f=1_. We account for the possibility of nonconvergence by only performing a bounded number of posdivsteps, and then falling back to square-root based Jacobi calculation if a solution has not @@ -815,5 +814,5 @@ yet been found. The optimizations in sections 3-7 above are described in the context of the original divsteps, but in the C implementation we also adapt most of them (not including "avoiding modulus operations", -since it's not necessary to track *d, e*, and "constant-time operation", since we never calculate +since it's not necessary to track _d, e_, and "constant-time operation", since we never calculate Jacobi symbols for secret data) to the posdivsteps version. diff --git a/external/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json b/external/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json index 9c90747993..04e34f5a17 100644 --- a/external/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json +++ b/external/secp256k1/src/wycheproof/ecdsa_secp256k1_sha256_bitcoin_test.json @@ -1,6358 +1,6358 @@ { - "algorithm" : "ECDSA", - "schema" : "ecdsa_bitcoin_verify_schema.json", - "generatorVersion" : "0.9rc5", - "numberOfTests" : 463, - "header" : [ + "algorithm": "ECDSA", + "schema": "ecdsa_bitcoin_verify_schema.json", + "generatorVersion": "0.9rc5", + "numberOfTests": 463, + "header": [ "Test vectors of type EcdsaBitcoinVerify are meant for the verification", "of a ECDSA variant used for bitcoin, that add signature non-malleability." ], - "notes" : { - "ArithmeticError" : { - "bugType" : "EDGE_CASE", - "description" : "Some implementations of ECDSA have arithmetic errors that occur when intermediate results have extreme values. This test vector has been constructed to test such occurences.", - "cves" : [ + "notes": { + "ArithmeticError": { + "bugType": "EDGE_CASE", + "description": "Some implementations of ECDSA have arithmetic errors that occur when intermediate results have extreme values. This test vector has been constructed to test such occurences.", + "cves": [ "CVE-2017-18146" ] }, - "BerEncodedSignature" : { - "bugType" : "BER_ENCODING", - "description" : "ECDSA signatures are usually DER encoded. This signature contains valid values for r and s, but it uses alternative BER encoding.", - "effect" : "Accepting alternative BER encodings may be benign in some cases, or be an issue if protocol requires signature malleability.", - "cves" : [ + "BerEncodedSignature": { + "bugType": "BER_ENCODING", + "description": "ECDSA signatures are usually DER encoded. This signature contains valid values for r and s, but it uses alternative BER encoding.", + "effect": "Accepting alternative BER encodings may be benign in some cases, or be an issue if protocol requires signature malleability.", + "cves": [ "CVE-2020-14966", "CVE-2020-13822", "CVE-2019-14859", "CVE-2016-1000342" ] }, - "EdgeCasePublicKey" : { - "bugType" : "EDGE_CASE", - "description" : "The test vector uses a special case public key. " + "EdgeCasePublicKey": { + "bugType": "EDGE_CASE", + "description": "The test vector uses a special case public key. " }, - "EdgeCaseShamirMultiplication" : { - "bugType" : "EDGE_CASE", - "description" : "Shamir proposed a fast method for computing the sum of two scalar multiplications efficiently. This test vector has been constructed so that an intermediate result is the point at infinity if Shamir's method is used." + "EdgeCaseShamirMultiplication": { + "bugType": "EDGE_CASE", + "description": "Shamir proposed a fast method for computing the sum of two scalar multiplications efficiently. This test vector has been constructed so that an intermediate result is the point at infinity if Shamir's method is used." }, - "IntegerOverflow" : { - "bugType" : "CAN_OF_WORMS", - "description" : "The test vector contains an r and s that has been modified, so that the original value is restored if the implementation ignores the most significant bits.", - "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + "IntegerOverflow": { + "bugType": "CAN_OF_WORMS", + "description": "The test vector contains an r and s that has been modified, so that the original value is restored if the implementation ignores the most significant bits.", + "effect": "Without further analysis it is unclear if the modification can be used to forge signatures." }, - "InvalidEncoding" : { - "bugType" : "CAN_OF_WORMS", - "description" : "ECDSA signatures are encoded using ASN.1. This test vector contains an incorrectly encoded signature. The test vector itself was generated from a valid signature by modifying its encoding.", - "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + "InvalidEncoding": { + "bugType": "CAN_OF_WORMS", + "description": "ECDSA signatures are encoded using ASN.1. This test vector contains an incorrectly encoded signature. The test vector itself was generated from a valid signature by modifying its encoding.", + "effect": "Without further analysis it is unclear if the modification can be used to forge signatures." }, - "InvalidSignature" : { - "bugType" : "AUTH_BYPASS", - "description" : "The signature contains special case values such as r=0 and s=0. Buggy implementations may accept such values, if the implementation does not check boundaries and computes s^(-1) == 0.", - "effect" : "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.", - "cves" : [ + "InvalidSignature": { + "bugType": "AUTH_BYPASS", + "description": "The signature contains special case values such as r=0 and s=0. Buggy implementations may accept such values, if the implementation does not check boundaries and computes s^(-1) == 0.", + "effect": "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.", + "cves": [ "CVE-2022-21449", "CVE-2021-43572", "CVE-2022-24884" ] }, - "InvalidTypesInSignature" : { - "bugType" : "AUTH_BYPASS", - "description" : "The signature contains invalid types. Dynamic typed languages sometime coerce such values of different types into integers. If an implementation is careless and has additional bugs, such as not checking integer boundaries then it may be possible that such signatures are accepted.", - "effect" : "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.", - "cves" : [ + "InvalidTypesInSignature": { + "bugType": "AUTH_BYPASS", + "description": "The signature contains invalid types. Dynamic typed languages sometime coerce such values of different types into integers. If an implementation is careless and has additional bugs, such as not checking integer boundaries then it may be possible that such signatures are accepted.", + "effect": "Accepting such signatures can have the effect that an adversary can forge signatures without even knowning the message to sign.", + "cves": [ "CVE-2022-21449" ] }, - "ModifiedInteger" : { - "bugType" : "CAN_OF_WORMS", - "description" : "The test vector contains an r and s that has been modified. The goal is to check for arithmetic errors.", - "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + "ModifiedInteger": { + "bugType": "CAN_OF_WORMS", + "description": "The test vector contains an r and s that has been modified. The goal is to check for arithmetic errors.", + "effect": "Without further analysis it is unclear if the modification can be used to forge signatures." }, - "ModifiedSignature" : { - "bugType" : "CAN_OF_WORMS", - "description" : "The test vector contains an invalid signature that was generated from a valid signature by modifying it.", - "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + "ModifiedSignature": { + "bugType": "CAN_OF_WORMS", + "description": "The test vector contains an invalid signature that was generated from a valid signature by modifying it.", + "effect": "Without further analysis it is unclear if the modification can be used to forge signatures." }, - "ModularInverse" : { - "bugType" : "EDGE_CASE", - "description" : "The test vectors contains a signature where computing the modular inverse of s hits an edge case.", - "effect" : "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.", - "cves" : [ + "ModularInverse": { + "bugType": "EDGE_CASE", + "description": "The test vectors contains a signature where computing the modular inverse of s hits an edge case.", + "effect": "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.", + "cves": [ "CVE-2019-0865" ] }, - "PointDuplication" : { - "bugType" : "EDGE_CASE", - "description" : "Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission.", - "cves" : [ + "PointDuplication": { + "bugType": "EDGE_CASE", + "description": "Some implementations of ECDSA do not handle duplication and points at infinity correctly. This is a test vector that has been specially crafted to check for such an omission.", + "cves": [ "2020-12607", "CVE-2015-2730" ] }, - "RangeCheck" : { - "bugType" : "CAN_OF_WORMS", - "description" : "The test vector contains an r and s that has been modified. By adding or subtracting the order of the group (or other values) the test vector checks whether signature verification verifies the range of r and s.", - "effect" : "Without further analysis it is unclear if the modification can be used to forge signatures." + "RangeCheck": { + "bugType": "CAN_OF_WORMS", + "description": "The test vector contains an r and s that has been modified. By adding or subtracting the order of the group (or other values) the test vector checks whether signature verification verifies the range of r and s.", + "effect": "Without further analysis it is unclear if the modification can be used to forge signatures." }, - "SignatureMalleabilityBitcoin" : { - "bugType" : "SIGNATURE_MALLEABILITY", - "description" : "\"BitCoins\"-curves are curves where signature malleability can be a serious issue. An implementation should only accept a signature s where s < n/2. If an implementation is not meant for uses cases that require signature malleability then this implemenation should be tested with another set of test vectors.", - "effect" : "In bitcoin exchanges, it may be used to make a double deposits or double withdrawals", - "links" : [ + "SignatureMalleabilityBitcoin": { + "bugType": "SIGNATURE_MALLEABILITY", + "description": "\"BitCoins\"-curves are curves where signature malleability can be a serious issue. An implementation should only accept a signature s where s < n/2. If an implementation is not meant for uses cases that require signature malleability then this implemenation should be tested with another set of test vectors.", + "effect": "In bitcoin exchanges, it may be used to make a double deposits or double withdrawals", + "links": [ "https://en.bitcoin.it/wiki/Transaction_malleability", "https://en.bitcoinwiki.org/wiki/Transaction_Malleability" ] }, - "SmallRandS" : { - "bugType" : "EDGE_CASE", - "description" : "The test vectors contains a signature where both r and s are small integers. Some libraries cannot verify such signatures.", - "effect" : "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.", - "cves" : [ + "SmallRandS": { + "bugType": "EDGE_CASE", + "description": "The test vectors contains a signature where both r and s are small integers. Some libraries cannot verify such signatures.", + "effect": "While the signature in this test vector is constructed and similar cases are unlikely to occur, it is important to determine if the underlying arithmetic error can be used to forge signatures.", + "cves": [ "2020-13895" ] }, - "SpecialCaseHash" : { - "bugType" : "EDGE_CASE", - "description" : "The test vector contains a signature where the hash of the message is a special case, e.g., contains a long run of 0 or 1 bits." + "SpecialCaseHash": { + "bugType": "EDGE_CASE", + "description": "The test vector contains a signature where the hash of the message is a special case, e.g., contains a long run of 0 or 1 bits." }, - "ValidSignature" : { - "bugType" : "BASIC", - "description" : "The test vector contains a valid signature that was generated pseudorandomly. Such signatures should not fail to verify unless some of the parameters (e.g. curve or hash function) are not supported." + "ValidSignature": { + "bugType": "BASIC", + "description": "The test vector contains a valid signature that was generated pseudorandomly. Such signatures should not fail to verify unless some of the parameters (e.g. curve or hash function) are not supported." } }, - "testGroups" : [ + "testGroups": [ { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9", - "wx" : "00b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6f", - "wy" : "00f0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9", + "wx": "00b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6f", + "wy": "00f0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEuDj/ROW8F3vyEYnQdmCC/J2EMiaIf8l2\nA3EQC37iCm/wyddb+6ezGmvKGXRJbutW3jVwcZVdg8Sxutqgshgy6Q==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004b838ff44e5bc177bf21189d0766082fc9d843226887fc9760371100b7ee20a6ff0c9d75bfba7b31a6bca1974496eeb56de357071955d83c4b1badaa0b21832e9", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEuDj/ROW8F3vyEYnQdmCC/J2EMiaIf8l2\nA3EQC37iCm/wyddb+6ezGmvKGXRJbutW3jVwcZVdg8Sxutqgshgy6Q==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 1, - "comment" : "Signature malleability", - "flags" : [ + "tcId": 1, + "comment": "Signature malleability", + "flags": [ "SignatureMalleabilityBitcoin" ], - "msg" : "313233343030", - "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022100900e75ad233fcc908509dbff5922647db37c21f4afd3203ae8dc4ae7794b0f87", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022100900e75ad233fcc908509dbff5922647db37c21f4afd3203ae8dc4ae7794b0f87", + "result": "invalid" }, { - "tcId" : 2, - "comment" : "valid", - "flags" : [ + "tcId": 2, + "comment": "valid", + "flags": [ "ValidSignature" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "valid" }, { - "tcId" : 3, - "comment" : "length of sequence [r, s] uses long form encoding", - "flags" : [ + "tcId": 3, + "comment": "length of sequence [r, s] uses long form encoding", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "308145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "308145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 4, - "comment" : "length of sequence [r, s] contains a leading 0", - "flags" : [ + "tcId": 4, + "comment": "length of sequence [r, s] contains a leading 0", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "30820045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30820045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 5, - "comment" : "length of sequence [r, s] uses 70 instead of 69", - "flags" : [ + "tcId": 5, + "comment": "length of sequence [r, s] uses 70 instead of 69", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 6, - "comment" : "length of sequence [r, s] uses 68 instead of 69", - "flags" : [ + "tcId": 6, + "comment": "length of sequence [r, s] uses 68 instead of 69", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 7, - "comment" : "uint32 overflow in length of sequence [r, s]", - "flags" : [ + "tcId": 7, + "comment": "uint32 overflow in length of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30850100000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30850100000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 8, - "comment" : "uint64 overflow in length of sequence [r, s]", - "flags" : [ + "tcId": 8, + "comment": "uint64 overflow in length of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3089010000000000000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3089010000000000000045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 9, - "comment" : "length of sequence [r, s] = 2**31 - 1", - "flags" : [ + "tcId": 9, + "comment": "length of sequence [r, s] = 2**31 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30847fffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30847fffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 10, - "comment" : "length of sequence [r, s] = 2**31", - "flags" : [ + "tcId": 10, + "comment": "length of sequence [r, s] = 2**31", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "308480000000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "308480000000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 11, - "comment" : "length of sequence [r, s] = 2**32 - 1", - "flags" : [ + "tcId": 11, + "comment": "length of sequence [r, s] = 2**32 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3084ffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3084ffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 12, - "comment" : "length of sequence [r, s] = 2**40 - 1", - "flags" : [ + "tcId": 12, + "comment": "length of sequence [r, s] = 2**40 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3085ffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3085ffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 13, - "comment" : "length of sequence [r, s] = 2**64 - 1", - "flags" : [ + "tcId": 13, + "comment": "length of sequence [r, s] = 2**64 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3088ffffffffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3088ffffffffffffffff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 14, - "comment" : "incorrect length of sequence [r, s]", - "flags" : [ + "tcId": 14, + "comment": "incorrect length of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30ff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30ff022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 15, - "comment" : "replaced sequence [r, s] by an indefinite length tag without termination", - "flags" : [ + "tcId": 15, + "comment": "replaced sequence [r, s] by an indefinite length tag without termination", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 16, - "comment" : "removing sequence [r, s]", - "flags" : [ + "tcId": 16, + "comment": "removing sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "", - "result" : "invalid" + "msg": "313233343030", + "sig": "", + "result": "invalid" }, { - "tcId" : 17, - "comment" : "lonely sequence tag", - "flags" : [ + "tcId": 17, + "comment": "lonely sequence tag", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30", - "result" : "invalid" + "msg": "313233343030", + "sig": "30", + "result": "invalid" }, { - "tcId" : 18, - "comment" : "appending 0's to sequence [r, s]", - "flags" : [ + "tcId": 18, + "comment": "appending 0's to sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 19, - "comment" : "prepending 0's to sequence [r, s]", - "flags" : [ + "tcId": 19, + "comment": "prepending 0's to sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30470000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30470000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 20, - "comment" : "appending unused 0's to sequence [r, s]", - "flags" : [ + "tcId": 20, + "comment": "appending unused 0's to sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 21, - "comment" : "appending null value to sequence [r, s]", - "flags" : [ + "tcId": 21, + "comment": "appending null value to sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500", + "result": "invalid" }, { - "tcId" : 22, - "comment" : "prepending garbage to sequence [r, s]", - "flags" : [ + "tcId": 22, + "comment": "prepending garbage to sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a4981773045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a4981773045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 23, - "comment" : "prepending garbage to sequence [r, s]", - "flags" : [ + "tcId": 23, + "comment": "prepending garbage to sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304925003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304925003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 24, - "comment" : "appending garbage to sequence [r, s]", - "flags" : [ + "tcId": 24, + "comment": "appending garbage to sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef", - "result" : "invalid" + "msg": "313233343030", + "sig": "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef", + "result": "invalid" }, { - "tcId" : 25, - "comment" : "including undefined tags", - "flags" : [ + "tcId": 25, + "comment": "including undefined tags", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "304daa00bb00cd003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304daa00bb00cd003045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 26, - "comment" : "including undefined tags", - "flags" : [ + "tcId": 26, + "comment": "including undefined tags", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304d2229aa00bb00cd00022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d2229aa00bb00cd00022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 27, - "comment" : "including undefined tags", - "flags" : [ + "tcId": 27, + "comment": "including undefined tags", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652228aa00bb00cd0002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652228aa00bb00cd0002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 28, - "comment" : "truncated length of sequence [r, s]", - "flags" : [ + "tcId": 28, + "comment": "truncated length of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3081", - "result" : "invalid" + "msg": "313233343030", + "sig": "3081", + "result": "invalid" }, { - "tcId" : 29, - "comment" : "including undefined tags to sequence [r, s]", - "flags" : [ + "tcId": 29, + "comment": "including undefined tags to sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "304baa02aabb3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304baa02aabb3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 30, - "comment" : "using composition with indefinite length for sequence [r, s]", - "flags" : [ + "tcId": 30, + "comment": "using composition with indefinite length for sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30803045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30803045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 31, - "comment" : "using composition with wrong tag for sequence [r, s]", - "flags" : [ + "tcId": 31, + "comment": "using composition with wrong tag for sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30803145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30803145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 32, - "comment" : "Replacing sequence [r, s] with NULL", - "flags" : [ + "tcId": 32, + "comment": "Replacing sequence [r, s] with NULL", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "0500", - "result" : "invalid" + "msg": "313233343030", + "sig": "0500", + "result": "invalid" }, { - "tcId" : 33, - "comment" : "changing tag value of sequence [r, s]", - "flags" : [ + "tcId": 33, + "comment": "changing tag value of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "2e45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "2e45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 34, - "comment" : "changing tag value of sequence [r, s]", - "flags" : [ + "tcId": 34, + "comment": "changing tag value of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "2f45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "2f45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 35, - "comment" : "changing tag value of sequence [r, s]", - "flags" : [ + "tcId": 35, + "comment": "changing tag value of sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3145022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 36, - "comment" : "changing tag value of sequence [r, s]", - "flags" : [ + "tcId": 36, + "comment": "changing tag value of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3245022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3245022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 37, - "comment" : "changing tag value of sequence [r, s]", - "flags" : [ + "tcId": 37, + "comment": "changing tag value of sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "ff45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "ff45022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 38, - "comment" : "dropping value of sequence [r, s]", - "flags" : [ + "tcId": 38, + "comment": "dropping value of sequence [r, s]", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3000", + "result": "invalid" }, { - "tcId" : 39, - "comment" : "using composition for sequence [r, s]", - "flags" : [ + "tcId": 39, + "comment": "using composition for sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304930010230442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304930010230442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 40, - "comment" : "truncated sequence [r, s]", - "flags" : [ + "tcId": 40, + "comment": "truncated sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31", + "result": "invalid" }, { - "tcId" : 41, - "comment" : "truncated sequence [r, s]", - "flags" : [ + "tcId": 41, + "comment": "truncated sequence [r, s]", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30442100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 42, - "comment" : "sequence [r, s] of size 4166 to check for overflows", - "flags" : [ + "tcId": 42, + "comment": "sequence [r, s] of size 4166 to check for overflows", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30821046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30821046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "result": "invalid" }, { - "tcId" : 43, - "comment" : "indefinite length", - "flags" : [ + "tcId": 43, + "comment": "indefinite length", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 44, - "comment" : "indefinite length with truncated delimiter", - "flags" : [ + "tcId": 44, + "comment": "indefinite length with truncated delimiter", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba00", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba00", + "result": "invalid" }, { - "tcId" : 45, - "comment" : "indefinite length with additional element", - "flags" : [ + "tcId": 45, + "comment": "indefinite length with additional element", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba05000000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba05000000", + "result": "invalid" }, { - "tcId" : 46, - "comment" : "indefinite length with truncated element", - "flags" : [ + "tcId": 46, + "comment": "indefinite length with truncated element", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba060811220000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba060811220000", + "result": "invalid" }, { - "tcId" : 47, - "comment" : "indefinite length with garbage", - "flags" : [ + "tcId": 47, + "comment": "indefinite length with garbage", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000fe02beef", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000fe02beef", + "result": "invalid" }, { - "tcId" : 48, - "comment" : "indefinite length with nonempty EOC", - "flags" : [ + "tcId": 48, + "comment": "indefinite length with nonempty EOC", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0002beef", - "result" : "invalid" + "msg": "313233343030", + "sig": "3080022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0002beef", + "result": "invalid" }, { - "tcId" : 49, - "comment" : "prepend empty sequence", - "flags" : [ + "tcId": 49, + "comment": "prepend empty sequence", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30473000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30473000022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 50, - "comment" : "append empty sequence", - "flags" : [ + "tcId": 50, + "comment": "append empty sequence", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba3000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba3000", + "result": "invalid" }, { - "tcId" : 51, - "comment" : "append zero", - "flags" : [ + "tcId": 51, + "comment": "append zero", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba020100", + "result": "invalid" }, { - "tcId" : 52, - "comment" : "append garbage with high tag number", - "flags" : [ + "tcId": 52, + "comment": "append garbage with high tag number", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31babf7f00", - "result" : "invalid" + "msg": "313233343030", + "sig": "3048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31babf7f00", + "result": "invalid" }, { - "tcId" : 53, - "comment" : "append null with explicit tag", - "flags" : [ + "tcId": 53, + "comment": "append null with explicit tag", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa0020500", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa0020500", + "result": "invalid" }, { - "tcId" : 54, - "comment" : "append null with implicit tag", - "flags" : [ + "tcId": 54, + "comment": "append null with implicit tag", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31baa000", + "result": "invalid" }, { - "tcId" : 55, - "comment" : "sequence of sequence", - "flags" : [ + "tcId": 55, + "comment": "sequence of sequence", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30473045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 56, - "comment" : "truncated sequence: removed last 1 elements", - "flags" : [ + "tcId": 56, + "comment": "truncated sequence: removed last 1 elements", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3023022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365", - "result" : "invalid" + "msg": "313233343030", + "sig": "3023022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365", + "result": "invalid" }, { - "tcId" : 57, - "comment" : "repeating element in sequence", - "flags" : [ + "tcId": 57, + "comment": "repeating element in sequence", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3067022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3067022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 58, - "comment" : "flipped bit 0 in r", - "flags" : [ + "tcId": 58, + "comment": "flipped bit 0 in r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 59, - "comment" : "flipped bit 32 in r", - "flags" : [ + "tcId": 59, + "comment": "flipped bit 32 in r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccac983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccac983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 60, - "comment" : "flipped bit 48 in r", - "flags" : [ + "tcId": 60, + "comment": "flipped bit 48 in r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5133ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5133ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 61, - "comment" : "flipped bit 64 in r", - "flags" : [ + "tcId": 61, + "comment": "flipped bit 64 in r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc08b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc08b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 62, - "comment" : "length of r uses long form encoding", - "flags" : [ + "tcId": 62, + "comment": "length of r uses long form encoding", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "304602812100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304602812100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 63, - "comment" : "length of r contains a leading 0", - "flags" : [ + "tcId": 63, + "comment": "length of r contains a leading 0", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "30470282002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30470282002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 64, - "comment" : "length of r uses 34 instead of 33", - "flags" : [ + "tcId": 64, + "comment": "length of r uses 34 instead of 33", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 65, - "comment" : "length of r uses 32 instead of 33", - "flags" : [ + "tcId": 65, + "comment": "length of r uses 32 instead of 33", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 66, - "comment" : "uint32 overflow in length of r", - "flags" : [ + "tcId": 66, + "comment": "uint32 overflow in length of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a0285010000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a0285010000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 67, - "comment" : "uint64 overflow in length of r", - "flags" : [ + "tcId": 67, + "comment": "uint64 overflow in length of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304e028901000000000000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304e028901000000000000002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 68, - "comment" : "length of r = 2**31 - 1", - "flags" : [ + "tcId": 68, + "comment": "length of r = 2**31 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304902847fffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304902847fffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 69, - "comment" : "length of r = 2**31", - "flags" : [ + "tcId": 69, + "comment": "length of r = 2**31", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304902848000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304902848000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 70, - "comment" : "length of r = 2**32 - 1", - "flags" : [ + "tcId": 70, + "comment": "length of r = 2**32 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30490284ffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30490284ffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 71, - "comment" : "length of r = 2**40 - 1", - "flags" : [ + "tcId": 71, + "comment": "length of r = 2**40 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a0285ffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a0285ffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 72, - "comment" : "length of r = 2**64 - 1", - "flags" : [ + "tcId": 72, + "comment": "length of r = 2**64 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304d0288ffffffffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d0288ffffffffffffffff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 73, - "comment" : "incorrect length of r", - "flags" : [ + "tcId": 73, + "comment": "incorrect length of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304502ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304502ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 74, - "comment" : "replaced r by an indefinite length tag without termination", - "flags" : [ + "tcId": 74, + "comment": "replaced r by an indefinite length tag without termination", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045028000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045028000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 75, - "comment" : "removing r", - "flags" : [ + "tcId": 75, + "comment": "removing r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "302202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "302202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 76, - "comment" : "lonely integer tag", - "flags" : [ + "tcId": 76, + "comment": "lonely integer tag", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30230202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30230202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 77, - "comment" : "lonely integer tag", - "flags" : [ + "tcId": 77, + "comment": "lonely integer tag", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3024022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502", - "result" : "invalid" + "msg": "313233343030", + "sig": "3024022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502", + "result": "invalid" }, { - "tcId" : 78, - "comment" : "appending 0's to r", - "flags" : [ + "tcId": 78, + "comment": "appending 0's to r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 79, - "comment" : "prepending 0's to r", - "flags" : [ + "tcId": 79, + "comment": "prepending 0's to r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30470223000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30470223000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 80, - "comment" : "appending unused 0's to r", - "flags" : [ + "tcId": 80, + "comment": "appending unused 0's to r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 81, - "comment" : "appending null value to r", - "flags" : [ + "tcId": 81, + "comment": "appending null value to r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022300813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 82, - "comment" : "prepending garbage to r", - "flags" : [ + "tcId": 82, + "comment": "prepending garbage to r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a2226498177022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a2226498177022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 83, - "comment" : "prepending garbage to r", - "flags" : [ + "tcId": 83, + "comment": "prepending garbage to r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304922252500022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304922252500022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 84, - "comment" : "appending garbage to r", - "flags" : [ + "tcId": 84, + "comment": "appending garbage to r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304d2223022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650004deadbeef02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d2223022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650004deadbeef02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 85, - "comment" : "truncated length of r", - "flags" : [ + "tcId": 85, + "comment": "truncated length of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3024028102206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3024028102206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 86, - "comment" : "including undefined tags to r", - "flags" : [ + "tcId": 86, + "comment": "including undefined tags to r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304b2227aa02aabb022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304b2227aa02aabb022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 87, - "comment" : "using composition with indefinite length for r", - "flags" : [ + "tcId": 87, + "comment": "using composition with indefinite length for r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30492280022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30492280022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 88, - "comment" : "using composition with wrong tag for r", - "flags" : [ + "tcId": 88, + "comment": "using composition with wrong tag for r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "30492280032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30492280032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 89, - "comment" : "Replacing r with NULL", - "flags" : [ + "tcId": 89, + "comment": "Replacing r with NULL", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3024050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3024050002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 90, - "comment" : "changing tag value of r", - "flags" : [ + "tcId": 90, + "comment": "changing tag value of r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045002100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 91, - "comment" : "changing tag value of r", - "flags" : [ + "tcId": 91, + "comment": "changing tag value of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045012100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045012100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 92, - "comment" : "changing tag value of r", - "flags" : [ + "tcId": 92, + "comment": "changing tag value of r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045032100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 93, - "comment" : "changing tag value of r", - "flags" : [ + "tcId": 93, + "comment": "changing tag value of r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045042100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045042100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 94, - "comment" : "changing tag value of r", - "flags" : [ + "tcId": 94, + "comment": "changing tag value of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045ff2100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045ff2100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 95, - "comment" : "dropping value of r", - "flags" : [ + "tcId": 95, + "comment": "dropping value of r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3024020002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3024020002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 96, - "comment" : "using composition for r", - "flags" : [ + "tcId": 96, + "comment": "using composition for r", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304922250201000220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304922250201000220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 97, - "comment" : "modifying first byte of r", - "flags" : [ + "tcId": 97, + "comment": "modifying first byte of r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045022102813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022102813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 98, - "comment" : "modifying last byte of r", - "flags" : [ + "tcId": 98, + "comment": "modifying last byte of r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323e502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323e502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 99, - "comment" : "truncated r", - "flags" : [ + "tcId": 99, + "comment": "truncated r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3044022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832302206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832302206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 100, - "comment" : "truncated r", - "flags" : [ + "tcId": 100, + "comment": "truncated r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30440220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30440220813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 101, - "comment" : "r of size 4130 to check for overflows", - "flags" : [ + "tcId": 101, + "comment": "r of size 4130 to check for overflows", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "308210480282102200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "308210480282102200813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 102, - "comment" : "leading ff in r", - "flags" : [ + "tcId": 102, + "comment": "leading ff in r", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30460222ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30460222ff00813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 103, - "comment" : "replaced r by infinity", - "flags" : [ + "tcId": 103, + "comment": "replaced r by infinity", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "302509018002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "302509018002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 104, - "comment" : "replacing r with zero", - "flags" : [ + "tcId": 104, + "comment": "replacing r with zero", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "302502010002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "302502010002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 105, - "comment" : "flipped bit 0 in s", - "flags" : [ + "tcId": 105, + "comment": "flipped bit 0 in s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31bb", - "result" : "invalid" + "msg": "313233343030", + "sig": "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31bb", + "result": "invalid" }, { - "tcId" : 106, - "comment" : "flipped bit 32 in s", - "flags" : [ + "tcId": 106, + "comment": "flipped bit 32 in s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a456eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a456eb31ba", + "result": "invalid" }, { - "tcId" : 107, - "comment" : "flipped bit 48 in s", - "flags" : [ + "tcId": 107, + "comment": "flipped bit 48 in s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f713a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f713a556eb31ba", + "result": "invalid" }, { - "tcId" : 108, - "comment" : "flipped bit 64 in s", - "flags" : [ + "tcId": 108, + "comment": "flipped bit 64 in s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758001d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3043022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323656ff18a52dcc0336f7af62400a6dd9b810732baf1ff758001d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 109, - "comment" : "length of s uses long form encoding", - "flags" : [ + "tcId": 109, + "comment": "length of s uses long form encoding", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 110, - "comment" : "length of s contains a leading 0", - "flags" : [ + "tcId": 110, + "comment": "length of s contains a leading 0", + "flags": [ "BerEncodedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028200206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028200206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 111, - "comment" : "length of s uses 33 instead of 32", - "flags" : [ + "tcId": 111, + "comment": "length of s uses 33 instead of 32", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 112, - "comment" : "length of s uses 31 instead of 32", - "flags" : [ + "tcId": 112, + "comment": "length of s uses 31 instead of 32", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 113, - "comment" : "uint32 overflow in length of s", - "flags" : [ + "tcId": 113, + "comment": "uint32 overflow in length of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028501000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028501000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 114, - "comment" : "uint64 overflow in length of s", - "flags" : [ + "tcId": 114, + "comment": "uint64 overflow in length of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304e022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502890100000000000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304e022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502890100000000000000206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 115, - "comment" : "length of s = 2**31 - 1", - "flags" : [ + "tcId": 115, + "comment": "length of s = 2**31 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502847fffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502847fffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 116, - "comment" : "length of s = 2**31", - "flags" : [ + "tcId": 116, + "comment": "length of s = 2**31", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284800000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284800000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 117, - "comment" : "length of s = 2**32 - 1", - "flags" : [ + "tcId": 117, + "comment": "length of s = 2**32 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284ffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650284ffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 118, - "comment" : "length of s = 2**40 - 1", - "flags" : [ + "tcId": 118, + "comment": "length of s = 2**40 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650285ffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650285ffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 119, - "comment" : "length of s = 2**64 - 1", - "flags" : [ + "tcId": 119, + "comment": "length of s = 2**64 - 1", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650288ffffffffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650288ffffffffffffffff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 120, - "comment" : "incorrect length of s", - "flags" : [ + "tcId": 120, + "comment": "incorrect length of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 121, - "comment" : "replaced s by an indefinite length tag without termination", - "flags" : [ + "tcId": 121, + "comment": "replaced s by an indefinite length tag without termination", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502806ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502806ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 122, - "comment" : "appending 0's to s", - "flags" : [ + "tcId": 122, + "comment": "appending 0's to s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 123, - "comment" : "prepending 0's to s", - "flags" : [ + "tcId": 123, + "comment": "prepending 0's to s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022200006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365022200006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 124, - "comment" : "appending null value to s", - "flags" : [ + "tcId": 124, + "comment": "appending null value to s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500", - "result" : "invalid" + "msg": "313233343030", + "sig": "3047022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502226ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0500", + "result": "invalid" }, { - "tcId" : 125, - "comment" : "prepending garbage to s", - "flags" : [ + "tcId": 125, + "comment": "prepending garbage to s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222549817702206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304a022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222549817702206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 126, - "comment" : "prepending garbage to s", - "flags" : [ + "tcId": 126, + "comment": "prepending garbage to s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652224250002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652224250002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 127, - "comment" : "appending garbage to s", - "flags" : [ + "tcId": 127, + "comment": "appending garbage to s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222202206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0004deadbeef", + "result": "invalid" }, { - "tcId" : 128, - "comment" : "truncated length of s", - "flags" : [ + "tcId": 128, + "comment": "truncated length of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650281", + "result": "invalid" }, { - "tcId" : 129, - "comment" : "including undefined tags to s", - "flags" : [ + "tcId": 129, + "comment": "including undefined tags to s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "304b022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652226aa02aabb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304b022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323652226aa02aabb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 130, - "comment" : "using composition with indefinite length for s", - "flags" : [ + "tcId": 130, + "comment": "using composition with indefinite length for s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228002206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 131, - "comment" : "using composition with wrong tag for s", - "flags" : [ + "tcId": 131, + "comment": "using composition with wrong tag for s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228003206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365228003206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000", + "result": "invalid" }, { - "tcId" : 132, - "comment" : "Replacing s with NULL", - "flags" : [ + "tcId": 132, + "comment": "Replacing s with NULL", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650500", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650500", + "result": "invalid" }, { - "tcId" : 133, - "comment" : "changing tag value of s", - "flags" : [ + "tcId": 133, + "comment": "changing tag value of s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236500206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236500206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 134, - "comment" : "changing tag value of s", - "flags" : [ + "tcId": 134, + "comment": "changing tag value of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236501206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236501206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 135, - "comment" : "changing tag value of s", - "flags" : [ + "tcId": 135, + "comment": "changing tag value of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236503206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236503206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 136, - "comment" : "changing tag value of s", - "flags" : [ + "tcId": 136, + "comment": "changing tag value of s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236504206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236504206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 137, - "comment" : "changing tag value of s", - "flags" : [ + "tcId": 137, + "comment": "changing tag value of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365ff206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365ff206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 138, - "comment" : "dropping value of s", - "flags" : [ + "tcId": 138, + "comment": "dropping value of s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650200", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650200", + "result": "invalid" }, { - "tcId" : 139, - "comment" : "using composition for s", - "flags" : [ + "tcId": 139, + "comment": "using composition for s", + "flags": [ "InvalidEncoding" ], - "msg" : "313233343030", - "sig" : "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222402016f021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3049022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365222402016f021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 140, - "comment" : "modifying first byte of s", - "flags" : [ + "tcId": 140, + "comment": "modifying first byte of s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206df18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206df18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 141, - "comment" : "modifying last byte of s", - "flags" : [ + "tcId": 141, + "comment": "modifying last byte of s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb313a", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb313a", + "result": "invalid" }, { - "tcId" : 142, - "comment" : "truncated s", - "flags" : [ + "tcId": 142, + "comment": "truncated s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021f6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31", + "result": "invalid" }, { - "tcId" : 143, - "comment" : "truncated s", - "flags" : [ + "tcId": 143, + "comment": "truncated s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365021ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 144, - "comment" : "s of size 4129 to check for overflows", - "flags" : [ + "tcId": 144, + "comment": "s of size 4129 to check for overflows", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "30821048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028210216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30821048022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365028210216ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "result": "invalid" }, { - "tcId" : 145, - "comment" : "leading ff in s", - "flags" : [ + "tcId": 145, + "comment": "leading ff in s", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc98323650221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 146, - "comment" : "replaced s by infinity", - "flags" : [ + "tcId": 146, + "comment": "replaced s by infinity", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365090180", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365090180", + "result": "invalid" }, { - "tcId" : 147, - "comment" : "replacing s with zero", - "flags" : [ + "tcId": 147, + "comment": "replacing s with zero", + "flags": [ "ModifiedSignature" ], - "msg" : "313233343030", - "sig" : "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc9832365020100", + "result": "invalid" }, { - "tcId" : 148, - "comment" : "replaced r by r + n", - "flags" : [ + "tcId": 148, + "comment": "replaced r by r + n", + "flags": [ "RangeCheck" ], - "msg" : "313233343030", - "sig" : "3045022101813ef79ccefa9a56f7ba805f0e478583b90deabca4b05c4574e49b5899b964a602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022101813ef79ccefa9a56f7ba805f0e478583b90deabca4b05c4574e49b5899b964a602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 149, - "comment" : "replaced r by r - n", - "flags" : [ + "tcId": 149, + "comment": "replaced r by r - n", + "flags": [ "RangeCheck" ], - "msg" : "313233343030", - "sig" : "30440220813ef79ccefa9a56f7ba805f0e47858643b030ef461f1bcdf53fde3ef94ce22402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30440220813ef79ccefa9a56f7ba805f0e47858643b030ef461f1bcdf53fde3ef94ce22402206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 150, - "comment" : "replaced r by r + 256 * n", - "flags" : [ + "tcId": 150, + "comment": "replaced r by r + 256 * n", + "flags": [ "RangeCheck" ], - "msg" : "313233343030", - "sig" : "304602220100813ef79ccefa9a56f7ba805f0e47843fad3bf4853e07f7c98770c99bffc4646502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304602220100813ef79ccefa9a56f7ba805f0e47843fad3bf4853e07f7c98770c99bffc4646502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 151, - "comment" : "replaced r by -r", - "flags" : [ + "tcId": 151, + "comment": "replaced r by -r", + "flags": [ "ModifiedInteger" ], - "msg" : "313233343030", - "sig" : "30450221ff7ec10863310565a908457fa0f1b87a7b01a0f22a0a9843f64aedc334367cdc9b02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221ff7ec10863310565a908457fa0f1b87a7b01a0f22a0a9843f64aedc334367cdc9b02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 152, - "comment" : "replaced r by n - r", - "flags" : [ + "tcId": 152, + "comment": "replaced r by n - r", + "flags": [ "ModifiedInteger" ], - "msg" : "313233343030", - "sig" : "304402207ec10863310565a908457fa0f1b87a79bc4fcf10b9e0e4320ac021c106b31ddc02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304402207ec10863310565a908457fa0f1b87a79bc4fcf10b9e0e4320ac021c106b31ddc02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 153, - "comment" : "replaced r by -n - r", - "flags" : [ + "tcId": 153, + "comment": "replaced r by -n - r", + "flags": [ "ModifiedInteger" ], - "msg" : "313233343030", - "sig" : "30450221fe7ec10863310565a908457fa0f1b87a7c46f215435b4fa3ba8b1b64a766469b5a02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221fe7ec10863310565a908457fa0f1b87a7c46f215435b4fa3ba8b1b64a766469b5a02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 154, - "comment" : "replaced r by r + 2**256", - "flags" : [ + "tcId": 154, + "comment": "replaced r by r + 2**256", + "flags": [ "IntegerOverflow" ], - "msg" : "313233343030", - "sig" : "3045022101813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022101813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 155, - "comment" : "replaced r by r + 2**320", - "flags" : [ + "tcId": 155, + "comment": "replaced r by r + 2**320", + "flags": [ "IntegerOverflow" ], - "msg" : "313233343030", - "sig" : "304d0229010000000000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d0229010000000000000000813ef79ccefa9a56f7ba805f0e478584fe5f0dd5f567bc09b5123ccbc983236502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 156, - "comment" : "replaced s by s + n", - "flags" : [ + "tcId": 156, + "comment": "replaced s by s + n", + "flags": [ "RangeCheck" ], - "msg" : "313233343030", - "sig" : "30450221016ff18a52dcc0336f7af62400a6dd9b7fc1e197d8aebe203c96c87232272172fb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221016ff18a52dcc0336f7af62400a6dd9b7fc1e197d8aebe203c96c87232272172fb02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 157, - "comment" : "replaced s by s - n", - "flags" : [ + "tcId": 157, + "comment": "replaced s by s - n", + "flags": [ "RangeCheck" ], - "msg" : "313233343030", - "sig" : "30450221ff6ff18a52dcc0336f7af62400a6dd9b824c83de0b502cdfc51723b51886b4f07902206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221ff6ff18a52dcc0336f7af62400a6dd9b824c83de0b502cdfc51723b51886b4f07902206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 158, - "comment" : "replaced s by s + 256 * n", - "flags" : [ + "tcId": 158, + "comment": "replaced s by s + 256 * n", + "flags": [ "RangeCheck" ], - "msg" : "313233343030", - "sig" : "3046022201006ff18a52dcc0336f7af62400a6dd9a3bb60fa1a14815bbc0a954a0758d2c72ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022201006ff18a52dcc0336f7af62400a6dd9a3bb60fa1a14815bbc0a954a0758d2c72ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 159, - "comment" : "replaced s by -s", - "flags" : [ + "tcId": 159, + "comment": "replaced s by -s", + "flags": [ "ModifiedInteger" ], - "msg" : "313233343030", - "sig" : "30440220900e75ad233fcc908509dbff5922647ef8cd450e008a7fff2909ec5aa914ce4602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30440220900e75ad233fcc908509dbff5922647ef8cd450e008a7fff2909ec5aa914ce4602206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 160, - "comment" : "replaced s by -n - s", - "flags" : [ + "tcId": 160, + "comment": "replaced s by -n - s", + "flags": [ "ModifiedInteger" ], - "msg" : "313233343030", - "sig" : "30450221fe900e75ad233fcc908509dbff592264803e1e68275141dfc369378dcdd8de8d0502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221fe900e75ad233fcc908509dbff592264803e1e68275141dfc369378dcdd8de8d0502206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 161, - "comment" : "replaced s by s + 2**256", - "flags" : [ + "tcId": 161, + "comment": "replaced s by s + 2**256", + "flags": [ "IntegerOverflow" ], - "msg" : "313233343030", - "sig" : "30450221016ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221016ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 162, - "comment" : "replaced s by s - 2**256", - "flags" : [ + "tcId": 162, + "comment": "replaced s by s - 2**256", + "flags": [ "IntegerOverflow" ], - "msg" : "313233343030", - "sig" : "30450221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "30450221ff6ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 163, - "comment" : "replaced s by s + 2**320", - "flags" : [ + "tcId": 163, + "comment": "replaced s by s + 2**320", + "flags": [ "IntegerOverflow" ], - "msg" : "313233343030", - "sig" : "304d02290100000000000000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", - "result" : "invalid" + "msg": "313233343030", + "sig": "304d02290100000000000000006ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba02206ff18a52dcc0336f7af62400a6dd9b810732baf1ff758000d6f613a556eb31ba", + "result": "invalid" }, { - "tcId" : 164, - "comment" : "Signature with special case values r=0 and s=0", - "flags" : [ + "tcId": 164, + "comment": "Signature with special case values r=0 and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3006020100020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020100020100", + "result": "invalid" }, { - "tcId" : 165, - "comment" : "Signature with special case values r=0 and s=1", - "flags" : [ + "tcId": 165, + "comment": "Signature with special case values r=0 and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3006020100020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020100020101", + "result": "invalid" }, { - "tcId" : 166, - "comment" : "Signature with special case values r=0 and s=-1", - "flags" : [ + "tcId": 166, + "comment": "Signature with special case values r=0 and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30060201000201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201000201ff", + "result": "invalid" }, { - "tcId" : 167, - "comment" : "Signature with special case values r=0 and s=n", - "flags" : [ + "tcId": 167, + "comment": "Signature with special case values r=0 and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 168, - "comment" : "Signature with special case values r=0 and s=n - 1", - "flags" : [ + "tcId": 168, + "comment": "Signature with special case values r=0 and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 169, - "comment" : "Signature with special case values r=0 and s=n + 1", - "flags" : [ + "tcId": 169, + "comment": "Signature with special case values r=0 and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020100022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 170, - "comment" : "Signature with special case values r=0 and s=p", - "flags" : [ + "tcId": 170, + "comment": "Signature with special case values r=0 and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 171, - "comment" : "Signature with special case values r=0 and s=p + 1", - "flags" : [ + "tcId": 171, + "comment": "Signature with special case values r=0 and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020100022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 172, - "comment" : "Signature with special case values r=1 and s=0", - "flags" : [ + "tcId": 172, + "comment": "Signature with special case values r=1 and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3006020101020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020101020100", + "result": "invalid" }, { - "tcId" : 173, - "comment" : "Signature with special case values r=1 and s=1", - "flags" : [ + "tcId": 173, + "comment": "Signature with special case values r=1 and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3006020101020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020101020101", + "result": "invalid" }, { - "tcId" : 174, - "comment" : "Signature with special case values r=1 and s=-1", - "flags" : [ + "tcId": 174, + "comment": "Signature with special case values r=1 and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30060201010201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201010201ff", + "result": "invalid" }, { - "tcId" : 175, - "comment" : "Signature with special case values r=1 and s=n", - "flags" : [ + "tcId": 175, + "comment": "Signature with special case values r=1 and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 176, - "comment" : "Signature with special case values r=1 and s=n - 1", - "flags" : [ + "tcId": 176, + "comment": "Signature with special case values r=1 and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 177, - "comment" : "Signature with special case values r=1 and s=n + 1", - "flags" : [ + "tcId": 177, + "comment": "Signature with special case values r=1 and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020101022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 178, - "comment" : "Signature with special case values r=1 and s=p", - "flags" : [ + "tcId": 178, + "comment": "Signature with special case values r=1 and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 179, - "comment" : "Signature with special case values r=1 and s=p + 1", - "flags" : [ + "tcId": 179, + "comment": "Signature with special case values r=1 and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026020101022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 180, - "comment" : "Signature with special case values r=-1 and s=0", - "flags" : [ + "tcId": 180, + "comment": "Signature with special case values r=-1 and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff020100", + "result": "invalid" }, { - "tcId" : 181, - "comment" : "Signature with special case values r=-1 and s=1", - "flags" : [ + "tcId": 181, + "comment": "Signature with special case values r=-1 and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff020101", + "result": "invalid" }, { - "tcId" : 182, - "comment" : "Signature with special case values r=-1 and s=-1", - "flags" : [ + "tcId": 182, + "comment": "Signature with special case values r=-1 and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff0201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff0201ff", + "result": "invalid" }, { - "tcId" : 183, - "comment" : "Signature with special case values r=-1 and s=n", - "flags" : [ + "tcId": 183, + "comment": "Signature with special case values r=-1 and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 184, - "comment" : "Signature with special case values r=-1 and s=n - 1", - "flags" : [ + "tcId": 184, + "comment": "Signature with special case values r=-1 and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 185, - "comment" : "Signature with special case values r=-1 and s=n + 1", - "flags" : [ + "tcId": 185, + "comment": "Signature with special case values r=-1 and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "30260201ff022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 186, - "comment" : "Signature with special case values r=-1 and s=p", - "flags" : [ + "tcId": 186, + "comment": "Signature with special case values r=-1 and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 187, - "comment" : "Signature with special case values r=-1 and s=p + 1", - "flags" : [ + "tcId": 187, + "comment": "Signature with special case values r=-1 and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "30260201ff022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 188, - "comment" : "Signature with special case values r=n and s=0", - "flags" : [ + "tcId": 188, + "comment": "Signature with special case values r=n and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020100", + "result": "invalid" }, { - "tcId" : 189, - "comment" : "Signature with special case values r=n and s=1", - "flags" : [ + "tcId": 189, + "comment": "Signature with special case values r=n and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141020101", + "result": "invalid" }, { - "tcId" : 190, - "comment" : "Signature with special case values r=n and s=-1", - "flags" : [ + "tcId": 190, + "comment": "Signature with special case values r=n and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410201ff", + "result": "invalid" }, { - "tcId" : 191, - "comment" : "Signature with special case values r=n and s=n", - "flags" : [ + "tcId": 191, + "comment": "Signature with special case values r=n and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 192, - "comment" : "Signature with special case values r=n and s=n - 1", - "flags" : [ + "tcId": 192, + "comment": "Signature with special case values r=n and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 193, - "comment" : "Signature with special case values r=n and s=n + 1", - "flags" : [ + "tcId": 193, + "comment": "Signature with special case values r=n and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 194, - "comment" : "Signature with special case values r=n and s=p", - "flags" : [ + "tcId": 194, + "comment": "Signature with special case values r=n and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 195, - "comment" : "Signature with special case values r=n and s=p + 1", - "flags" : [ + "tcId": 195, + "comment": "Signature with special case values r=n and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 196, - "comment" : "Signature with special case values r=n - 1 and s=0", - "flags" : [ + "tcId": 196, + "comment": "Signature with special case values r=n - 1 and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020100", + "result": "invalid" }, { - "tcId" : 197, - "comment" : "Signature with special case values r=n - 1 and s=1", - "flags" : [ + "tcId": 197, + "comment": "Signature with special case values r=n - 1 and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140020101", + "result": "invalid" }, { - "tcId" : 198, - "comment" : "Signature with special case values r=n - 1 and s=-1", - "flags" : [ + "tcId": 198, + "comment": "Signature with special case values r=n - 1 and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641400201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641400201ff", + "result": "invalid" }, { - "tcId" : 199, - "comment" : "Signature with special case values r=n - 1 and s=n", - "flags" : [ + "tcId": 199, + "comment": "Signature with special case values r=n - 1 and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 200, - "comment" : "Signature with special case values r=n - 1 and s=n - 1", - "flags" : [ + "tcId": 200, + "comment": "Signature with special case values r=n - 1 and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 201, - "comment" : "Signature with special case values r=n - 1 and s=n + 1", - "flags" : [ + "tcId": 201, + "comment": "Signature with special case values r=n - 1 and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 202, - "comment" : "Signature with special case values r=n - 1 and s=p", - "flags" : [ + "tcId": 202, + "comment": "Signature with special case values r=n - 1 and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 203, - "comment" : "Signature with special case values r=n - 1 and s=p + 1", - "flags" : [ + "tcId": 203, + "comment": "Signature with special case values r=n - 1 and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 204, - "comment" : "Signature with special case values r=n + 1 and s=0", - "flags" : [ + "tcId": 204, + "comment": "Signature with special case values r=n + 1 and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020100", + "result": "invalid" }, { - "tcId" : 205, - "comment" : "Signature with special case values r=n + 1 and s=1", - "flags" : [ + "tcId": 205, + "comment": "Signature with special case values r=n + 1 and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142020101", + "result": "invalid" }, { - "tcId" : 206, - "comment" : "Signature with special case values r=n + 1 and s=-1", - "flags" : [ + "tcId": 206, + "comment": "Signature with special case values r=n + 1 and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641420201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641420201ff", + "result": "invalid" }, { - "tcId" : 207, - "comment" : "Signature with special case values r=n + 1 and s=n", - "flags" : [ + "tcId": 207, + "comment": "Signature with special case values r=n + 1 and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 208, - "comment" : "Signature with special case values r=n + 1 and s=n - 1", - "flags" : [ + "tcId": 208, + "comment": "Signature with special case values r=n + 1 and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 209, - "comment" : "Signature with special case values r=n + 1 and s=n + 1", - "flags" : [ + "tcId": 209, + "comment": "Signature with special case values r=n + 1 and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 210, - "comment" : "Signature with special case values r=n + 1 and s=p", - "flags" : [ + "tcId": 210, + "comment": "Signature with special case values r=n + 1 and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 211, - "comment" : "Signature with special case values r=n + 1 and s=p + 1", - "flags" : [ + "tcId": 211, + "comment": "Signature with special case values r=n + 1 and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 212, - "comment" : "Signature with special case values r=p and s=0", - "flags" : [ + "tcId": 212, + "comment": "Signature with special case values r=p and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020100", + "result": "invalid" }, { - "tcId" : 213, - "comment" : "Signature with special case values r=p and s=1", - "flags" : [ + "tcId": 213, + "comment": "Signature with special case values r=p and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f020101", + "result": "invalid" }, { - "tcId" : 214, - "comment" : "Signature with special case values r=p and s=-1", - "flags" : [ + "tcId": 214, + "comment": "Signature with special case values r=p and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0201ff", + "result": "invalid" }, { - "tcId" : 215, - "comment" : "Signature with special case values r=p and s=n", - "flags" : [ + "tcId": 215, + "comment": "Signature with special case values r=p and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 216, - "comment" : "Signature with special case values r=p and s=n - 1", - "flags" : [ + "tcId": 216, + "comment": "Signature with special case values r=p and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 217, - "comment" : "Signature with special case values r=p and s=n + 1", - "flags" : [ + "tcId": 217, + "comment": "Signature with special case values r=p and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 218, - "comment" : "Signature with special case values r=p and s=p", - "flags" : [ + "tcId": 218, + "comment": "Signature with special case values r=p and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 219, - "comment" : "Signature with special case values r=p and s=p + 1", - "flags" : [ + "tcId": 219, + "comment": "Signature with special case values r=p and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 220, - "comment" : "Signature with special case values r=p + 1 and s=0", - "flags" : [ + "tcId": 220, + "comment": "Signature with special case values r=p + 1 and s=0", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020100", + "result": "invalid" }, { - "tcId" : 221, - "comment" : "Signature with special case values r=p + 1 and s=1", - "flags" : [ + "tcId": 221, + "comment": "Signature with special case values r=p + 1 and s=1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30020101", + "result": "invalid" }, { - "tcId" : 222, - "comment" : "Signature with special case values r=p + 1 and s=-1", - "flags" : [ + "tcId": 222, + "comment": "Signature with special case values r=p + 1 and s=-1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc300201ff", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc300201ff", + "result": "invalid" }, { - "tcId" : 223, - "comment" : "Signature with special case values r=p + 1 and s=n", - "flags" : [ + "tcId": 223, + "comment": "Signature with special case values r=p + 1 and s=n", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", + "result": "invalid" }, { - "tcId" : 224, - "comment" : "Signature with special case values r=p + 1 and s=n - 1", - "flags" : [ + "tcId": 224, + "comment": "Signature with special case values r=p + 1 and s=n - 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", + "result": "invalid" }, { - "tcId" : 225, - "comment" : "Signature with special case values r=p + 1 and s=n + 1", - "flags" : [ + "tcId": 225, + "comment": "Signature with special case values r=p + 1 and s=n + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142", + "result": "invalid" }, { - "tcId" : 226, - "comment" : "Signature with special case values r=p + 1 and s=p", - "flags" : [ + "tcId": 226, + "comment": "Signature with special case values r=p + 1 and s=p", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f", + "result": "invalid" }, { - "tcId" : 227, - "comment" : "Signature with special case values r=p + 1 and s=p + 1", - "flags" : [ + "tcId": 227, + "comment": "Signature with special case values r=p + 1 and s=p + 1", + "flags": [ "InvalidSignature" ], - "msg" : "313233343030", - "sig" : "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", - "result" : "invalid" + "msg": "313233343030", + "sig": "3046022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc30", + "result": "invalid" }, { - "tcId" : 228, - "comment" : "Signature encoding contains incorrect types: r=0, s=0.25", - "flags" : [ + "tcId": 228, + "comment": "Signature encoding contains incorrect types: r=0, s=0.25", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3008020100090380fe01", - "result" : "invalid" + "msg": "313233343030", + "sig": "3008020100090380fe01", + "result": "invalid" }, { - "tcId" : 229, - "comment" : "Signature encoding contains incorrect types: r=0, s=nan", - "flags" : [ + "tcId": 229, + "comment": "Signature encoding contains incorrect types: r=0, s=nan", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006020100090142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020100090142", + "result": "invalid" }, { - "tcId" : 230, - "comment" : "Signature encoding contains incorrect types: r=0, s=True", - "flags" : [ + "tcId": 230, + "comment": "Signature encoding contains incorrect types: r=0, s=True", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006020100010101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020100010101", + "result": "invalid" }, { - "tcId" : 231, - "comment" : "Signature encoding contains incorrect types: r=0, s=False", - "flags" : [ + "tcId": 231, + "comment": "Signature encoding contains incorrect types: r=0, s=False", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006020100010100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020100010100", + "result": "invalid" }, { - "tcId" : 232, - "comment" : "Signature encoding contains incorrect types: r=0, s=Null", - "flags" : [ + "tcId": 232, + "comment": "Signature encoding contains incorrect types: r=0, s=Null", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201000500", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201000500", + "result": "invalid" }, { - "tcId" : 233, - "comment" : "Signature encoding contains incorrect types: r=0, s=empyt UTF-8 string", - "flags" : [ + "tcId": 233, + "comment": "Signature encoding contains incorrect types: r=0, s=empyt UTF-8 string", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201000c00", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201000c00", + "result": "invalid" }, { - "tcId" : 234, - "comment" : "Signature encoding contains incorrect types: r=0, s=\"0\"", - "flags" : [ + "tcId": 234, + "comment": "Signature encoding contains incorrect types: r=0, s=\"0\"", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060201000c0130", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201000c0130", + "result": "invalid" }, { - "tcId" : 235, - "comment" : "Signature encoding contains incorrect types: r=0, s=empty list", - "flags" : [ + "tcId": 235, + "comment": "Signature encoding contains incorrect types: r=0, s=empty list", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201003000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201003000", + "result": "invalid" }, { - "tcId" : 236, - "comment" : "Signature encoding contains incorrect types: r=0, s=list containing 0", - "flags" : [ + "tcId": 236, + "comment": "Signature encoding contains incorrect types: r=0, s=list containing 0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30080201003003020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30080201003003020100", + "result": "invalid" }, { - "tcId" : 237, - "comment" : "Signature encoding contains incorrect types: r=1, s=0.25", - "flags" : [ + "tcId": 237, + "comment": "Signature encoding contains incorrect types: r=1, s=0.25", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3008020101090380fe01", - "result" : "invalid" + "msg": "313233343030", + "sig": "3008020101090380fe01", + "result": "invalid" }, { - "tcId" : 238, - "comment" : "Signature encoding contains incorrect types: r=1, s=nan", - "flags" : [ + "tcId": 238, + "comment": "Signature encoding contains incorrect types: r=1, s=nan", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006020101090142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020101090142", + "result": "invalid" }, { - "tcId" : 239, - "comment" : "Signature encoding contains incorrect types: r=1, s=True", - "flags" : [ + "tcId": 239, + "comment": "Signature encoding contains incorrect types: r=1, s=True", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006020101010101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020101010101", + "result": "invalid" }, { - "tcId" : 240, - "comment" : "Signature encoding contains incorrect types: r=1, s=False", - "flags" : [ + "tcId": 240, + "comment": "Signature encoding contains incorrect types: r=1, s=False", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006020101010100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006020101010100", + "result": "invalid" }, { - "tcId" : 241, - "comment" : "Signature encoding contains incorrect types: r=1, s=Null", - "flags" : [ + "tcId": 241, + "comment": "Signature encoding contains incorrect types: r=1, s=Null", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201010500", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201010500", + "result": "invalid" }, { - "tcId" : 242, - "comment" : "Signature encoding contains incorrect types: r=1, s=empyt UTF-8 string", - "flags" : [ + "tcId": 242, + "comment": "Signature encoding contains incorrect types: r=1, s=empyt UTF-8 string", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201010c00", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201010c00", + "result": "invalid" }, { - "tcId" : 243, - "comment" : "Signature encoding contains incorrect types: r=1, s=\"0\"", - "flags" : [ + "tcId": 243, + "comment": "Signature encoding contains incorrect types: r=1, s=\"0\"", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060201010c0130", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201010c0130", + "result": "invalid" }, { - "tcId" : 244, - "comment" : "Signature encoding contains incorrect types: r=1, s=empty list", - "flags" : [ + "tcId": 244, + "comment": "Signature encoding contains incorrect types: r=1, s=empty list", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201013000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201013000", + "result": "invalid" }, { - "tcId" : 245, - "comment" : "Signature encoding contains incorrect types: r=1, s=list containing 0", - "flags" : [ + "tcId": 245, + "comment": "Signature encoding contains incorrect types: r=1, s=list containing 0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30080201013003020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30080201013003020100", + "result": "invalid" }, { - "tcId" : 246, - "comment" : "Signature encoding contains incorrect types: r=-1, s=0.25", - "flags" : [ + "tcId": 246, + "comment": "Signature encoding contains incorrect types: r=-1, s=0.25", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30080201ff090380fe01", - "result" : "invalid" + "msg": "313233343030", + "sig": "30080201ff090380fe01", + "result": "invalid" }, { - "tcId" : 247, - "comment" : "Signature encoding contains incorrect types: r=-1, s=nan", - "flags" : [ + "tcId": 247, + "comment": "Signature encoding contains incorrect types: r=-1, s=nan", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff090142", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff090142", + "result": "invalid" }, { - "tcId" : 248, - "comment" : "Signature encoding contains incorrect types: r=-1, s=True", - "flags" : [ + "tcId": 248, + "comment": "Signature encoding contains incorrect types: r=-1, s=True", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff010101", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff010101", + "result": "invalid" }, { - "tcId" : 249, - "comment" : "Signature encoding contains incorrect types: r=-1, s=False", - "flags" : [ + "tcId": 249, + "comment": "Signature encoding contains incorrect types: r=-1, s=False", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff010100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff010100", + "result": "invalid" }, { - "tcId" : 250, - "comment" : "Signature encoding contains incorrect types: r=-1, s=Null", - "flags" : [ + "tcId": 250, + "comment": "Signature encoding contains incorrect types: r=-1, s=Null", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201ff0500", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201ff0500", + "result": "invalid" }, { - "tcId" : 251, - "comment" : "Signature encoding contains incorrect types: r=-1, s=empyt UTF-8 string", - "flags" : [ + "tcId": 251, + "comment": "Signature encoding contains incorrect types: r=-1, s=empyt UTF-8 string", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201ff0c00", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201ff0c00", + "result": "invalid" }, { - "tcId" : 252, - "comment" : "Signature encoding contains incorrect types: r=-1, s=\"0\"", - "flags" : [ + "tcId": 252, + "comment": "Signature encoding contains incorrect types: r=-1, s=\"0\"", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060201ff0c0130", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060201ff0c0130", + "result": "invalid" }, { - "tcId" : 253, - "comment" : "Signature encoding contains incorrect types: r=-1, s=empty list", - "flags" : [ + "tcId": 253, + "comment": "Signature encoding contains incorrect types: r=-1, s=empty list", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050201ff3000", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050201ff3000", + "result": "invalid" }, { - "tcId" : 254, - "comment" : "Signature encoding contains incorrect types: r=-1, s=list containing 0", - "flags" : [ + "tcId": 254, + "comment": "Signature encoding contains incorrect types: r=-1, s=list containing 0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30080201ff3003020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30080201ff3003020100", + "result": "invalid" }, { - "tcId" : 255, - "comment" : "Signature encoding contains incorrect types: r=n, s=0.25", - "flags" : [ + "tcId": 255, + "comment": "Signature encoding contains incorrect types: r=n, s=0.25", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090380fe01", - "result" : "invalid" + "msg": "313233343030", + "sig": "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090380fe01", + "result": "invalid" }, { - "tcId" : 256, - "comment" : "Signature encoding contains incorrect types: r=n, s=nan", - "flags" : [ + "tcId": 256, + "comment": "Signature encoding contains incorrect types: r=n, s=nan", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141090142", + "result": "invalid" }, { - "tcId" : 257, - "comment" : "Signature encoding contains incorrect types: r=n, s=True", - "flags" : [ + "tcId": 257, + "comment": "Signature encoding contains incorrect types: r=n, s=True", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010101", + "result": "invalid" }, { - "tcId" : 258, - "comment" : "Signature encoding contains incorrect types: r=n, s=False", - "flags" : [ + "tcId": 258, + "comment": "Signature encoding contains incorrect types: r=n, s=False", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141010100", + "result": "invalid" }, { - "tcId" : 259, - "comment" : "Signature encoding contains incorrect types: r=n, s=Null", - "flags" : [ + "tcId": 259, + "comment": "Signature encoding contains incorrect types: r=n, s=Null", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410500", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410500", + "result": "invalid" }, { - "tcId" : 260, - "comment" : "Signature encoding contains incorrect types: r=n, s=empyt UTF-8 string", - "flags" : [ + "tcId": 260, + "comment": "Signature encoding contains incorrect types: r=n, s=empyt UTF-8 string", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c00", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c00", + "result": "invalid" }, { - "tcId" : 261, - "comment" : "Signature encoding contains incorrect types: r=n, s=\"0\"", - "flags" : [ + "tcId": 261, + "comment": "Signature encoding contains incorrect types: r=n, s=\"0\"", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c0130", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641410c0130", + "result": "invalid" }, { - "tcId" : 262, - "comment" : "Signature encoding contains incorrect types: r=n, s=empty list", - "flags" : [ + "tcId": 262, + "comment": "Signature encoding contains incorrect types: r=n, s=empty list", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413000", + "result": "invalid" }, { - "tcId" : 263, - "comment" : "Signature encoding contains incorrect types: r=n, s=list containing 0", - "flags" : [ + "tcId": 263, + "comment": "Signature encoding contains incorrect types: r=n, s=list containing 0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413003020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3028022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641413003020100", + "result": "invalid" }, { - "tcId" : 264, - "comment" : "Signature encoding contains incorrect types: r=p, s=0.25", - "flags" : [ + "tcId": 264, + "comment": "Signature encoding contains incorrect types: r=p, s=0.25", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090380fe01", - "result" : "invalid" + "msg": "313233343030", + "sig": "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090380fe01", + "result": "invalid" }, { - "tcId" : 265, - "comment" : "Signature encoding contains incorrect types: r=p, s=nan", - "flags" : [ + "tcId": 265, + "comment": "Signature encoding contains incorrect types: r=p, s=nan", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f090142", + "result": "invalid" }, { - "tcId" : 266, - "comment" : "Signature encoding contains incorrect types: r=p, s=True", - "flags" : [ + "tcId": 266, + "comment": "Signature encoding contains incorrect types: r=p, s=True", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010101", + "result": "invalid" }, { - "tcId" : 267, - "comment" : "Signature encoding contains incorrect types: r=p, s=False", - "flags" : [ + "tcId": 267, + "comment": "Signature encoding contains incorrect types: r=p, s=False", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f010100", + "result": "invalid" }, { - "tcId" : 268, - "comment" : "Signature encoding contains incorrect types: r=p, s=Null", - "flags" : [ + "tcId": 268, + "comment": "Signature encoding contains incorrect types: r=p, s=Null", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0500", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0500", + "result": "invalid" }, { - "tcId" : 269, - "comment" : "Signature encoding contains incorrect types: r=p, s=empyt UTF-8 string", - "flags" : [ + "tcId": 269, + "comment": "Signature encoding contains incorrect types: r=p, s=empyt UTF-8 string", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c00", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c00", + "result": "invalid" }, { - "tcId" : 270, - "comment" : "Signature encoding contains incorrect types: r=p, s=\"0\"", - "flags" : [ + "tcId": 270, + "comment": "Signature encoding contains incorrect types: r=p, s=\"0\"", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c0130", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f0c0130", + "result": "invalid" }, { - "tcId" : 271, - "comment" : "Signature encoding contains incorrect types: r=p, s=empty list", - "flags" : [ + "tcId": 271, + "comment": "Signature encoding contains incorrect types: r=p, s=empty list", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3000", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3000", + "result": "invalid" }, { - "tcId" : 272, - "comment" : "Signature encoding contains incorrect types: r=p, s=list containing 0", - "flags" : [ + "tcId": 272, + "comment": "Signature encoding contains incorrect types: r=p, s=list containing 0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3003020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3028022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f3003020100", + "result": "invalid" }, { - "tcId" : 273, - "comment" : "Signature encoding contains incorrect types: r=0.25, s=0.25", - "flags" : [ + "tcId": 273, + "comment": "Signature encoding contains incorrect types: r=0.25, s=0.25", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "300a090380fe01090380fe01", - "result" : "invalid" + "msg": "313233343030", + "sig": "300a090380fe01090380fe01", + "result": "invalid" }, { - "tcId" : 274, - "comment" : "Signature encoding contains incorrect types: r=nan, s=nan", - "flags" : [ + "tcId": 274, + "comment": "Signature encoding contains incorrect types: r=nan, s=nan", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006090142090142", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006090142090142", + "result": "invalid" }, { - "tcId" : 275, - "comment" : "Signature encoding contains incorrect types: r=True, s=True", - "flags" : [ + "tcId": 275, + "comment": "Signature encoding contains incorrect types: r=True, s=True", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006010101010101", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006010101010101", + "result": "invalid" }, { - "tcId" : 276, - "comment" : "Signature encoding contains incorrect types: r=False, s=False", - "flags" : [ + "tcId": 276, + "comment": "Signature encoding contains incorrect types: r=False, s=False", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006010100010100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006010100010100", + "result": "invalid" }, { - "tcId" : 277, - "comment" : "Signature encoding contains incorrect types: r=Null, s=Null", - "flags" : [ + "tcId": 277, + "comment": "Signature encoding contains incorrect types: r=Null, s=Null", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "300405000500", - "result" : "invalid" + "msg": "313233343030", + "sig": "300405000500", + "result": "invalid" }, { - "tcId" : 278, - "comment" : "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=empyt UTF-8 string", - "flags" : [ + "tcId": 278, + "comment": "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=empyt UTF-8 string", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30040c000c00", - "result" : "invalid" + "msg": "313233343030", + "sig": "30040c000c00", + "result": "invalid" }, { - "tcId" : 279, - "comment" : "Signature encoding contains incorrect types: r=\"0\", s=\"0\"", - "flags" : [ + "tcId": 279, + "comment": "Signature encoding contains incorrect types: r=\"0\", s=\"0\"", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060c01300c0130", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060c01300c0130", + "result": "invalid" }, { - "tcId" : 280, - "comment" : "Signature encoding contains incorrect types: r=empty list, s=empty list", - "flags" : [ + "tcId": 280, + "comment": "Signature encoding contains incorrect types: r=empty list, s=empty list", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "300430003000", - "result" : "invalid" + "msg": "313233343030", + "sig": "300430003000", + "result": "invalid" }, { - "tcId" : 281, - "comment" : "Signature encoding contains incorrect types: r=list containing 0, s=list containing 0", - "flags" : [ + "tcId": 281, + "comment": "Signature encoding contains incorrect types: r=list containing 0, s=list containing 0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "300a30030201003003020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "300a30030201003003020100", + "result": "invalid" }, { - "tcId" : 282, - "comment" : "Signature encoding contains incorrect types: r=0.25, s=0", - "flags" : [ + "tcId": 282, + "comment": "Signature encoding contains incorrect types: r=0.25, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3008090380fe01020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3008090380fe01020100", + "result": "invalid" }, { - "tcId" : 283, - "comment" : "Signature encoding contains incorrect types: r=nan, s=0", - "flags" : [ + "tcId": 283, + "comment": "Signature encoding contains incorrect types: r=nan, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006090142020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006090142020100", + "result": "invalid" }, { - "tcId" : 284, - "comment" : "Signature encoding contains incorrect types: r=True, s=0", - "flags" : [ + "tcId": 284, + "comment": "Signature encoding contains incorrect types: r=True, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006010101020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006010101020100", + "result": "invalid" }, { - "tcId" : 285, - "comment" : "Signature encoding contains incorrect types: r=False, s=0", - "flags" : [ + "tcId": 285, + "comment": "Signature encoding contains incorrect types: r=False, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "3006010100020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3006010100020100", + "result": "invalid" }, { - "tcId" : 286, - "comment" : "Signature encoding contains incorrect types: r=Null, s=0", - "flags" : [ + "tcId": 286, + "comment": "Signature encoding contains incorrect types: r=Null, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050500020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050500020100", + "result": "invalid" }, { - "tcId" : 287, - "comment" : "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=0", - "flags" : [ + "tcId": 287, + "comment": "Signature encoding contains incorrect types: r=empyt UTF-8 string, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30050c00020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30050c00020100", + "result": "invalid" }, { - "tcId" : 288, - "comment" : "Signature encoding contains incorrect types: r=\"0\", s=0", - "flags" : [ + "tcId": 288, + "comment": "Signature encoding contains incorrect types: r=\"0\", s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30060c0130020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30060c0130020100", + "result": "invalid" }, { - "tcId" : 289, - "comment" : "Signature encoding contains incorrect types: r=empty list, s=0", - "flags" : [ + "tcId": 289, + "comment": "Signature encoding contains incorrect types: r=empty list, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30053000020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30053000020100", + "result": "invalid" }, { - "tcId" : 290, - "comment" : "Signature encoding contains incorrect types: r=list containing 0, s=0", - "flags" : [ + "tcId": 290, + "comment": "Signature encoding contains incorrect types: r=list containing 0, s=0", + "flags": [ "InvalidTypesInSignature" ], - "msg" : "313233343030", - "sig" : "30083003020100020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "30083003020100020100", + "result": "invalid" }, { - "tcId" : 291, - "comment" : "Edge case for Shamir multiplication", - "flags" : [ + "tcId": 291, + "comment": "Edge case for Shamir multiplication", + "flags": [ "EdgeCaseShamirMultiplication" ], - "msg" : "3235353835", - "sig" : "3045022100dd1b7d09a7bd8218961034a39a87fecf5314f00c4d25eb58a07ac85e85eab516022035138c401ef8d3493d65c9002fe62b43aee568731b744548358996d9cc427e06", - "result" : "valid" + "msg": "3235353835", + "sig": "3045022100dd1b7d09a7bd8218961034a39a87fecf5314f00c4d25eb58a07ac85e85eab516022035138c401ef8d3493d65c9002fe62b43aee568731b744548358996d9cc427e06", + "result": "valid" }, { - "tcId" : 292, - "comment" : "special case hash", - "flags" : [ + "tcId": 292, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "343236343739373234", - "sig" : "304502210095c29267d972a043d955224546222bba343fc1d4db0fec262a33ac61305696ae02206edfe96713aed56f8a28a6653f57e0b829712e5eddc67f34682b24f0676b2640", - "result" : "valid" + "msg": "343236343739373234", + "sig": "304502210095c29267d972a043d955224546222bba343fc1d4db0fec262a33ac61305696ae02206edfe96713aed56f8a28a6653f57e0b829712e5eddc67f34682b24f0676b2640", + "result": "valid" }, { - "tcId" : 293, - "comment" : "special case hash", - "flags" : [ + "tcId": 293, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "37313338363834383931", - "sig" : "3044022028f94a894e92024699e345fe66971e3edcd050023386135ab3939d550898fb25022032963e5bd41fa5911ed8f37deb86dae0a762bb6121c894615083c5d95ea01db3", - "result" : "valid" + "msg": "37313338363834383931", + "sig": "3044022028f94a894e92024699e345fe66971e3edcd050023386135ab3939d550898fb25022032963e5bd41fa5911ed8f37deb86dae0a762bb6121c894615083c5d95ea01db3", + "result": "valid" }, { - "tcId" : 294, - "comment" : "special case hash", - "flags" : [ + "tcId": 294, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3130333539333331363638", - "sig" : "3045022100be26b18f9549f89f411a9b52536b15aa270b84548d0e859a1952a27af1a77ac6022070c1d4fa9cd03cc8eaa8d506edb97eed7b8358b453c88aefbb880a3f0e8d472f", - "result" : "valid" + "msg": "3130333539333331363638", + "sig": "3045022100be26b18f9549f89f411a9b52536b15aa270b84548d0e859a1952a27af1a77ac6022070c1d4fa9cd03cc8eaa8d506edb97eed7b8358b453c88aefbb880a3f0e8d472f", + "result": "valid" }, { - "tcId" : 295, - "comment" : "special case hash", - "flags" : [ + "tcId": 295, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33393439343031323135", - "sig" : "3045022100b1a4b1478e65cc3eafdf225d1298b43f2da19e4bcff7eacc0a2e98cd4b74b1140220179aa31e304cc142cf5073171751b28f3f5e0fa88c994e7c55f1bc07b8d56c16", - "result" : "valid" + "msg": "33393439343031323135", + "sig": "3045022100b1a4b1478e65cc3eafdf225d1298b43f2da19e4bcff7eacc0a2e98cd4b74b1140220179aa31e304cc142cf5073171751b28f3f5e0fa88c994e7c55f1bc07b8d56c16", + "result": "valid" }, { - "tcId" : 296, - "comment" : "special case hash", - "flags" : [ + "tcId": 296, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31333434323933303739", - "sig" : "30440220325332021261f1bd18f2712aa1e2252da23796da8a4b1ff6ea18cafec7e171f2022040b4f5e287ee61fc3c804186982360891eaa35c75f05a43ecd48b35d984a6648", - "result" : "valid" + "msg": "31333434323933303739", + "sig": "30440220325332021261f1bd18f2712aa1e2252da23796da8a4b1ff6ea18cafec7e171f2022040b4f5e287ee61fc3c804186982360891eaa35c75f05a43ecd48b35d984a6648", + "result": "valid" }, { - "tcId" : 297, - "comment" : "special case hash", - "flags" : [ + "tcId": 297, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33373036323131373132", - "sig" : "3045022100a23ad18d8fc66d81af0903890cbd453a554cb04cdc1a8ca7f7f78e5367ed88a0022023e3eb2ce1c04ea748c389bd97374aa9413b9268851c04dcd9f88e78813fee56", - "result" : "valid" + "msg": "33373036323131373132", + "sig": "3045022100a23ad18d8fc66d81af0903890cbd453a554cb04cdc1a8ca7f7f78e5367ed88a0022023e3eb2ce1c04ea748c389bd97374aa9413b9268851c04dcd9f88e78813fee56", + "result": "valid" }, { - "tcId" : 298, - "comment" : "special case hash", - "flags" : [ + "tcId": 298, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "333433363838373132", - "sig" : "304402202bdea41cda63a2d14bf47353bd20880a690901de7cd6e3cc6d8ed5ba0cdb109102203cea66bccfc9f9bf8c7ca4e1c1457cc9145e13e936d90b3d9c7786b8b26cf4c7", - "result" : "valid" + "msg": "333433363838373132", + "sig": "304402202bdea41cda63a2d14bf47353bd20880a690901de7cd6e3cc6d8ed5ba0cdb109102203cea66bccfc9f9bf8c7ca4e1c1457cc9145e13e936d90b3d9c7786b8b26cf4c7", + "result": "valid" }, { - "tcId" : 299, - "comment" : "special case hash", - "flags" : [ + "tcId": 299, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31333531353330333730", - "sig" : "3045022100d7cd76ec01c1b1079eba9e2aa2a397243c4758c98a1ba0b7404a340b9b00ced602203575001e19d922e6de8b3d6c84ea43b5c3338106cf29990134e7669a826f78e6", - "result" : "valid" + "msg": "31333531353330333730", + "sig": "3045022100d7cd76ec01c1b1079eba9e2aa2a397243c4758c98a1ba0b7404a340b9b00ced602203575001e19d922e6de8b3d6c84ea43b5c3338106cf29990134e7669a826f78e6", + "result": "valid" }, { - "tcId" : 300, - "comment" : "special case hash", - "flags" : [ + "tcId": 300, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "36353533323033313236", - "sig" : "3045022100a872c744d936db21a10c361dd5c9063355f84902219652f6fc56dc95a7139d960220400df7575d9756210e9ccc77162c6b593c7746cfb48ac263c42750b421ef4bb9", - "result" : "valid" + "msg": "36353533323033313236", + "sig": "3045022100a872c744d936db21a10c361dd5c9063355f84902219652f6fc56dc95a7139d960220400df7575d9756210e9ccc77162c6b593c7746cfb48ac263c42750b421ef4bb9", + "result": "valid" }, { - "tcId" : 301, - "comment" : "special case hash", - "flags" : [ + "tcId": 301, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31353634333436363033", - "sig" : "30450221009fa9afe07752da10b36d3afcd0fe44bfc40244d75203599cf8f5047fa3453854022050e0a7c013bfbf51819736972d44b4b56bc2a2b2c180df6ec672df171410d77a", - "result" : "valid" + "msg": "31353634333436363033", + "sig": "30450221009fa9afe07752da10b36d3afcd0fe44bfc40244d75203599cf8f5047fa3453854022050e0a7c013bfbf51819736972d44b4b56bc2a2b2c180df6ec672df171410d77a", + "result": "valid" }, { - "tcId" : 302, - "comment" : "special case hash", - "flags" : [ + "tcId": 302, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "34343239353339313137", - "sig" : "3045022100885640384d0d910efb177b46be6c3dc5cac81f0b88c3190bb6b5f99c2641f2050220738ed9bff116306d9caa0f8fc608be243e0b567779d8dab03e8e19d553f1dc8e", - "result" : "valid" + "msg": "34343239353339313137", + "sig": "3045022100885640384d0d910efb177b46be6c3dc5cac81f0b88c3190bb6b5f99c2641f2050220738ed9bff116306d9caa0f8fc608be243e0b567779d8dab03e8e19d553f1dc8e", + "result": "valid" }, { - "tcId" : 303, - "comment" : "special case hash", - "flags" : [ + "tcId": 303, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3130393533323631333531", - "sig" : "304402202d051f91c5a9d440c5676985710483bc4f1a6c611b10c95a2ff0363d90c2a45802206ddf94e6fba5be586833d0c53cf216ad3948f37953c26c1cf4968e9a9e8243dc", - "result" : "valid" + "msg": "3130393533323631333531", + "sig": "304402202d051f91c5a9d440c5676985710483bc4f1a6c611b10c95a2ff0363d90c2a45802206ddf94e6fba5be586833d0c53cf216ad3948f37953c26c1cf4968e9a9e8243dc", + "result": "valid" }, { - "tcId" : 304, - "comment" : "special case hash", - "flags" : [ + "tcId": 304, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "35393837333530303431", - "sig" : "3045022100f3ac2523967482f53d508522712d583f4379cd824101ff635ea0935117baa54f022027f10812227397e02cea96fb0e680761636dab2b080d1fc5d11685cbe8500cfe", - "result" : "valid" + "msg": "35393837333530303431", + "sig": "3045022100f3ac2523967482f53d508522712d583f4379cd824101ff635ea0935117baa54f022027f10812227397e02cea96fb0e680761636dab2b080d1fc5d11685cbe8500cfe", + "result": "valid" }, { - "tcId" : 305, - "comment" : "special case hash", - "flags" : [ + "tcId": 305, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33343633303036383738", - "sig" : "304502210096447cf68c3ab7266ed7447de3ac52fed7cc08cbdfea391c18a9b8ab370bc91302200f5e7874d3ac0e918f01c885a1639177c923f8660d1ceba1ca1f301bc675cdbc", - "result" : "valid" + "msg": "33343633303036383738", + "sig": "304502210096447cf68c3ab7266ed7447de3ac52fed7cc08cbdfea391c18a9b8ab370bc91302200f5e7874d3ac0e918f01c885a1639177c923f8660d1ceba1ca1f301bc675cdbc", + "result": "valid" }, { - "tcId" : 306, - "comment" : "special case hash", - "flags" : [ + "tcId": 306, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "39383137333230323837", - "sig" : "30440220530a0832b691da0b5619a0b11de6877f3c0971baaa68ed122758c29caaf46b7202206c89e44f5eb33060ea4b46318c39138eaedec72de42ba576579a6a4690e339f3", - "result" : "valid" + "msg": "39383137333230323837", + "sig": "30440220530a0832b691da0b5619a0b11de6877f3c0971baaa68ed122758c29caaf46b7202206c89e44f5eb33060ea4b46318c39138eaedec72de42ba576579a6a4690e339f3", + "result": "valid" }, { - "tcId" : 307, - "comment" : "special case hash", - "flags" : [ + "tcId": 307, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33323232303431303436", - "sig" : "30450221009c54c25500bde0b92d72d6ec483dc2482f3654294ca74de796b681255ed58a770220677453c6b56f527631c9f67b3f3eb621fd88582b4aff156d2f1567d6211a2a33", - "result" : "valid" + "msg": "33323232303431303436", + "sig": "30450221009c54c25500bde0b92d72d6ec483dc2482f3654294ca74de796b681255ed58a770220677453c6b56f527631c9f67b3f3eb621fd88582b4aff156d2f1567d6211a2a33", + "result": "valid" }, { - "tcId" : 308, - "comment" : "special case hash", - "flags" : [ + "tcId": 308, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "36363636333037313034", - "sig" : "3045022100e7909d41439e2f6af29136c7348ca2641a2b070d5b64f91ea9da7070c7a2618b022042d782f132fa1d36c2c88ba27c3d678d80184a5d1eccac7501f0b47e3d205008", - "result" : "valid" + "msg": "36363636333037313034", + "sig": "3045022100e7909d41439e2f6af29136c7348ca2641a2b070d5b64f91ea9da7070c7a2618b022042d782f132fa1d36c2c88ba27c3d678d80184a5d1eccac7501f0b47e3d205008", + "result": "valid" }, { - "tcId" : 309, - "comment" : "special case hash", - "flags" : [ + "tcId": 309, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31303335393531383938", - "sig" : "304402205924873209593135a4c3da7bb381227f8a4b6aa9f34fe5bb7f8fbc131a039ffe02201f1bb11b441c8feaa40f44213d9a405ed792d59fb49d5bcdd9a4285ae5693022", - "result" : "valid" + "msg": "31303335393531383938", + "sig": "304402205924873209593135a4c3da7bb381227f8a4b6aa9f34fe5bb7f8fbc131a039ffe02201f1bb11b441c8feaa40f44213d9a405ed792d59fb49d5bcdd9a4285ae5693022", + "result": "valid" }, { - "tcId" : 310, - "comment" : "special case hash", - "flags" : [ + "tcId": 310, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31383436353937313935", - "sig" : "3045022100eeb692c9b262969b231c38b5a7f60649e0c875cd64df88f33aa571fa3d29ab0e0220218b3a1eb06379c2c18cf51b06430786d1c64cd2d24c9b232b23e5bac7989acd", - "result" : "valid" + "msg": "31383436353937313935", + "sig": "3045022100eeb692c9b262969b231c38b5a7f60649e0c875cd64df88f33aa571fa3d29ab0e0220218b3a1eb06379c2c18cf51b06430786d1c64cd2d24c9b232b23e5bac7989acd", + "result": "valid" }, { - "tcId" : 311, - "comment" : "special case hash", - "flags" : [ + "tcId": 311, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33313336303436313839", - "sig" : "3045022100a40034177f36091c2b653684a0e3eb5d4bff18e4d09f664c2800e7cafda1daf802203a3ec29853704e52031c58927a800a968353adc3d973beba9172cbbeab4dd149", - "result" : "valid" + "msg": "33313336303436313839", + "sig": "3045022100a40034177f36091c2b653684a0e3eb5d4bff18e4d09f664c2800e7cafda1daf802203a3ec29853704e52031c58927a800a968353adc3d973beba9172cbbeab4dd149", + "result": "valid" }, { - "tcId" : 312, - "comment" : "special case hash", - "flags" : [ + "tcId": 312, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "32363633373834323534", - "sig" : "3045022100b5d795cc75cea5c434fa4185180cd6bd21223f3d5a86da6670d71d95680dadbf022054e4d8810a001ecbb9f7ca1c2ebfdb9d009e9031a431aca3c20ab4e0d1374ec1", - "result" : "valid" + "msg": "32363633373834323534", + "sig": "3045022100b5d795cc75cea5c434fa4185180cd6bd21223f3d5a86da6670d71d95680dadbf022054e4d8810a001ecbb9f7ca1c2ebfdb9d009e9031a431aca3c20ab4e0d1374ec1", + "result": "valid" }, { - "tcId" : 313, - "comment" : "special case hash", - "flags" : [ + "tcId": 313, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31363532313030353234", - "sig" : "3044022007dc2478d43c1232a4595608c64426c35510051a631ae6a5a6eb1161e57e42e102204a59ea0fdb72d12165cea3bf1ca86ba97517bd188db3dbd21a5a157850021984", - "result" : "valid" + "msg": "31363532313030353234", + "sig": "3044022007dc2478d43c1232a4595608c64426c35510051a631ae6a5a6eb1161e57e42e102204a59ea0fdb72d12165cea3bf1ca86ba97517bd188db3dbd21a5a157850021984", + "result": "valid" }, { - "tcId" : 314, - "comment" : "special case hash", - "flags" : [ + "tcId": 314, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "35373438303831363936", - "sig" : "3045022100ddd20c4a05596ca868b558839fce9f6511ddd83d1ccb53f82e5269d559a0155202205b91734729d93093ff22123c4a25819d7feb66a250663fc780cb66fc7b6e6d17", - "result" : "valid" + "msg": "35373438303831363936", + "sig": "3045022100ddd20c4a05596ca868b558839fce9f6511ddd83d1ccb53f82e5269d559a0155202205b91734729d93093ff22123c4a25819d7feb66a250663fc780cb66fc7b6e6d17", + "result": "valid" }, { - "tcId" : 315, - "comment" : "special case hash", - "flags" : [ + "tcId": 315, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "36333433393133343638", - "sig" : "30450221009cde6e0ede0a003f02fda0a01b59facfe5dec063318f279ce2de7a9b1062f7b702202886a5b8c679bdf8224c66f908fd6205492cb70b0068d46ae4f33a4149b12a52", - "result" : "valid" + "msg": "36333433393133343638", + "sig": "30450221009cde6e0ede0a003f02fda0a01b59facfe5dec063318f279ce2de7a9b1062f7b702202886a5b8c679bdf8224c66f908fd6205492cb70b0068d46ae4f33a4149b12a52", + "result": "valid" }, { - "tcId" : 316, - "comment" : "special case hash", - "flags" : [ + "tcId": 316, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31353431313033353938", - "sig" : "3045022100c5771016d0dd6357143c89f684cd740423502554c0c59aa8c99584f1ff38f609022054b405f4477546686e464c5463b4fd4190572e58d0f7e7357f6e61947d20715c", - "result" : "valid" + "msg": "31353431313033353938", + "sig": "3045022100c5771016d0dd6357143c89f684cd740423502554c0c59aa8c99584f1ff38f609022054b405f4477546686e464c5463b4fd4190572e58d0f7e7357f6e61947d20715c", + "result": "valid" }, { - "tcId" : 317, - "comment" : "special case hash", - "flags" : [ + "tcId": 317, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3130343738353830313238", - "sig" : "3045022100a24ebc0ec224bd67ae397cbe6fa37b3125adbd34891abe2d7c7356921916dfe6022034f6eb6374731bbbafc4924fb8b0bdcdda49456d724cdae6178d87014cb53d8c", - "result" : "valid" + "msg": "3130343738353830313238", + "sig": "3045022100a24ebc0ec224bd67ae397cbe6fa37b3125adbd34891abe2d7c7356921916dfe6022034f6eb6374731bbbafc4924fb8b0bdcdda49456d724cdae6178d87014cb53d8c", + "result": "valid" }, { - "tcId" : 318, - "comment" : "special case hash", - "flags" : [ + "tcId": 318, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3130353336323835353638", - "sig" : "304402202557d64a7aee2e0931c012e4fea1cd3a2c334edae68cdeb7158caf21b68e5a2402207f06cdbb6a90023a973882ed97b080fe6b05af3ec93db6f1a4399a69edf7670d", - "result" : "valid" + "msg": "3130353336323835353638", + "sig": "304402202557d64a7aee2e0931c012e4fea1cd3a2c334edae68cdeb7158caf21b68e5a2402207f06cdbb6a90023a973882ed97b080fe6b05af3ec93db6f1a4399a69edf7670d", + "result": "valid" }, { - "tcId" : 319, - "comment" : "special case hash", - "flags" : [ + "tcId": 319, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "393533393034313035", - "sig" : "3045022100c4f2eccbb6a24350c8466450b9d61b207ee359e037b3dcedb42a3f2e6dd6aeb502203263c6b59a2f55cdd1c6e14894d5e5963b28bc3e2469ac9ba1197991ca7ff9c7", - "result" : "valid" + "msg": "393533393034313035", + "sig": "3045022100c4f2eccbb6a24350c8466450b9d61b207ee359e037b3dcedb42a3f2e6dd6aeb502203263c6b59a2f55cdd1c6e14894d5e5963b28bc3e2469ac9ba1197991ca7ff9c7", + "result": "valid" }, { - "tcId" : 320, - "comment" : "special case hash", - "flags" : [ + "tcId": 320, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "393738383438303339", - "sig" : "3045022100eff04781c9cbcd162d0a25a6e2ebcca43506c523385cb515d49ea38a1b12fcad022015acd73194c91a95478534f23015b672ebed213e45424dd2c8e26ac8b3eb34a5", - "result" : "valid" + "msg": "393738383438303339", + "sig": "3045022100eff04781c9cbcd162d0a25a6e2ebcca43506c523385cb515d49ea38a1b12fcad022015acd73194c91a95478534f23015b672ebed213e45424dd2c8e26ac8b3eb34a5", + "result": "valid" }, { - "tcId" : 321, - "comment" : "special case hash", - "flags" : [ + "tcId": 321, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33363130363732343432", - "sig" : "3045022100f58b4e3110a64bf1b5db97639ee0e5a9c8dfa49dc59b679891f520fdf0584c8702202cd8fe51888aee9db3e075440fd4db73b5c732fb87b510e97093d66415f62af7", - "result" : "valid" + "msg": "33363130363732343432", + "sig": "3045022100f58b4e3110a64bf1b5db97639ee0e5a9c8dfa49dc59b679891f520fdf0584c8702202cd8fe51888aee9db3e075440fd4db73b5c732fb87b510e97093d66415f62af7", + "result": "valid" }, { - "tcId" : 322, - "comment" : "special case hash", - "flags" : [ + "tcId": 322, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31303534323430373035", - "sig" : "3045022100f8abecaa4f0c502de4bf5903d48417f786bf92e8ad72fec0bd7fcb7800c0bbe302204c7f9e231076a30b7ae36b0cebe69ccef1cd194f7cce93a5588fd6814f437c0e", - "result" : "valid" + "msg": "31303534323430373035", + "sig": "3045022100f8abecaa4f0c502de4bf5903d48417f786bf92e8ad72fec0bd7fcb7800c0bbe302204c7f9e231076a30b7ae36b0cebe69ccef1cd194f7cce93a5588fd6814f437c0e", + "result": "valid" }, { - "tcId" : 323, - "comment" : "special case hash", - "flags" : [ + "tcId": 323, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "35313734343438313937", - "sig" : "304402205d5b38bd37ad498b2227a633268a8cca879a5c7c94a4e416bd0a614d09e606d2022012b8d664ea9991062ecbb834e58400e25c46007af84f6007d7f1685443269afe", - "result" : "valid" + "msg": "35313734343438313937", + "sig": "304402205d5b38bd37ad498b2227a633268a8cca879a5c7c94a4e416bd0a614d09e606d2022012b8d664ea9991062ecbb834e58400e25c46007af84f6007d7f1685443269afe", + "result": "valid" }, { - "tcId" : 324, - "comment" : "special case hash", - "flags" : [ + "tcId": 324, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31393637353631323531", - "sig" : "304402200c1cd9fe4034f086a2b52d65b9d3834d72aebe7f33dfe8f976da82648177d8e3022013105782e3d0cfe85c2778dec1a848b27ac0ae071aa6da341a9553a946b41e59", - "result" : "valid" + "msg": "31393637353631323531", + "sig": "304402200c1cd9fe4034f086a2b52d65b9d3834d72aebe7f33dfe8f976da82648177d8e3022013105782e3d0cfe85c2778dec1a848b27ac0ae071aa6da341a9553a946b41e59", + "result": "valid" }, { - "tcId" : 325, - "comment" : "special case hash", - "flags" : [ + "tcId": 325, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33343437323533333433", - "sig" : "3045022100ae7935fb96ff246b7b5d5662870d1ba587b03d6e1360baf47988b5c02ccc1a5b02205f00c323272083782d4a59f2dfd65e49de0693627016900ef7e61428056664b3", - "result" : "valid" + "msg": "33343437323533333433", + "sig": "3045022100ae7935fb96ff246b7b5d5662870d1ba587b03d6e1360baf47988b5c02ccc1a5b02205f00c323272083782d4a59f2dfd65e49de0693627016900ef7e61428056664b3", + "result": "valid" }, { - "tcId" : 326, - "comment" : "special case hash", - "flags" : [ + "tcId": 326, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "333638323634333138", - "sig" : "3044022000a134b5c6ccbcefd4c882b945baeb4933444172795fa6796aae1490675470980220566e46105d24d890151e3eea3ebf88f5b92b3f5ec93a217765a6dcbd94f2c55b", - "result" : "valid" + "msg": "333638323634333138", + "sig": "3044022000a134b5c6ccbcefd4c882b945baeb4933444172795fa6796aae1490675470980220566e46105d24d890151e3eea3ebf88f5b92b3f5ec93a217765a6dcbd94f2c55b", + "result": "valid" }, { - "tcId" : 327, - "comment" : "special case hash", - "flags" : [ + "tcId": 327, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33323631313938363038", - "sig" : "304402202e4721363ad3992c139e5a1c26395d2c2d777824aa24fde075e0d7381171309d0220740f7c494418e1300dd4512f782a58800bff6a7abdfdd20fbbd4f05515ca1a4f", - "result" : "valid" + "msg": "33323631313938363038", + "sig": "304402202e4721363ad3992c139e5a1c26395d2c2d777824aa24fde075e0d7381171309d0220740f7c494418e1300dd4512f782a58800bff6a7abdfdd20fbbd4f05515ca1a4f", + "result": "valid" }, { - "tcId" : 328, - "comment" : "special case hash", - "flags" : [ + "tcId": 328, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "39363738373831303934", - "sig" : "304402206852e9d3cd9fe373c2d504877967d365ab1456707b6817a042864694e1960ccf0220064b27ea142b30887b84c86adccb2fa39a6911ad21fc7e819f593be52bc4f3bd", - "result" : "valid" + "msg": "39363738373831303934", + "sig": "304402206852e9d3cd9fe373c2d504877967d365ab1456707b6817a042864694e1960ccf0220064b27ea142b30887b84c86adccb2fa39a6911ad21fc7e819f593be52bc4f3bd", + "result": "valid" }, { - "tcId" : 329, - "comment" : "special case hash", - "flags" : [ + "tcId": 329, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "34393538383233383233", - "sig" : "30440220188a8c5648dc79eace158cf886c62b5468f05fd95f03a7635c5b4c31f09af4c5022036361a0b571a00c6cd5e686ccbfcfa703c4f97e48938346d0c103fdc76dc5867", - "result" : "valid" + "msg": "34393538383233383233", + "sig": "30440220188a8c5648dc79eace158cf886c62b5468f05fd95f03a7635c5b4c31f09af4c5022036361a0b571a00c6cd5e686ccbfcfa703c4f97e48938346d0c103fdc76dc5867", + "result": "valid" }, { - "tcId" : 330, - "comment" : "special case hash", - "flags" : [ + "tcId": 330, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "383234363337383337", - "sig" : "3045022100a74f1fb9a8263f62fc4416a5b7d584f4206f3996bb91f6fc8e73b9e92bad0e1302206815032e8c7d76c3ab06a86f33249ce9940148cb36d1f417c2e992e801afa3fa", - "result" : "valid" + "msg": "383234363337383337", + "sig": "3045022100a74f1fb9a8263f62fc4416a5b7d584f4206f3996bb91f6fc8e73b9e92bad0e1302206815032e8c7d76c3ab06a86f33249ce9940148cb36d1f417c2e992e801afa3fa", + "result": "valid" }, { - "tcId" : 331, - "comment" : "special case hash", - "flags" : [ + "tcId": 331, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3131303230383333373736", - "sig" : "3044022007244865b72ff37e62e3146f0dc14682badd7197799135f0b00ade7671742bfe02200d80c2238edb4e4a7a86a8c57ca9af1711f406f7f5da0299aa04e2932d960754", - "result" : "valid" + "msg": "3131303230383333373736", + "sig": "3044022007244865b72ff37e62e3146f0dc14682badd7197799135f0b00ade7671742bfe02200d80c2238edb4e4a7a86a8c57ca9af1711f406f7f5da0299aa04e2932d960754", + "result": "valid" }, { - "tcId" : 332, - "comment" : "special case hash", - "flags" : [ + "tcId": 332, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "313333383731363438", - "sig" : "3045022100da7fdd05b5badabd619d805c4ee7d9a84f84ddd5cf9c5bf4d4338140d689ef08022028f1cf4fa1c3c5862cfa149c0013cf5fe6cf5076cae000511063e7de25bb38e5", - "result" : "valid" + "msg": "313333383731363438", + "sig": "3045022100da7fdd05b5badabd619d805c4ee7d9a84f84ddd5cf9c5bf4d4338140d689ef08022028f1cf4fa1c3c5862cfa149c0013cf5fe6cf5076cae000511063e7de25bb38e5", + "result": "valid" }, { - "tcId" : 333, - "comment" : "special case hash", - "flags" : [ + "tcId": 333, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "333232313434313632", - "sig" : "3045022100d3027c656f6d4fdfd8ede22093e3c303b0133c340d615e7756f6253aea927238022009aef060c8e4cef972974011558df144fed25ca69ae8d0b2eaf1a8feefbec417", - "result" : "valid" + "msg": "333232313434313632", + "sig": "3045022100d3027c656f6d4fdfd8ede22093e3c303b0133c340d615e7756f6253aea927238022009aef060c8e4cef972974011558df144fed25ca69ae8d0b2eaf1a8feefbec417", + "result": "valid" }, { - "tcId" : 334, - "comment" : "special case hash", - "flags" : [ + "tcId": 334, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3130363836363535353436", - "sig" : "304402200bf6c0188dc9571cd0e21eecac5fbb19d2434988e9cc10244593ef3a98099f6902204864a562661f9221ec88e3dd0bc2f6e27ac128c30cc1a80f79ec670a22b042ee", - "result" : "valid" + "msg": "3130363836363535353436", + "sig": "304402200bf6c0188dc9571cd0e21eecac5fbb19d2434988e9cc10244593ef3a98099f6902204864a562661f9221ec88e3dd0bc2f6e27ac128c30cc1a80f79ec670a22b042ee", + "result": "valid" }, { - "tcId" : 335, - "comment" : "special case hash", - "flags" : [ + "tcId": 335, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "3632313535323436", - "sig" : "3045022100ae459640d5d1179be47a47fa538e16d94ddea5585e7a244804a51742c686443a02206c8e30e530a634fae80b3ceb062978b39edbe19777e0a24553b68886181fd897", - "result" : "valid" + "msg": "3632313535323436", + "sig": "3045022100ae459640d5d1179be47a47fa538e16d94ddea5585e7a244804a51742c686443a02206c8e30e530a634fae80b3ceb062978b39edbe19777e0a24553b68886181fd897", + "result": "valid" }, { - "tcId" : 336, - "comment" : "special case hash", - "flags" : [ + "tcId": 336, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "37303330383138373734", - "sig" : "304402201cf3517ba3bf2ab8b9ead4ebb6e866cb88a1deacb6a785d3b63b483ca02ac4950220249a798b73606f55f5f1c70de67cb1a0cff95d7dc50b3a617df861bad3c6b1c9", - "result" : "valid" + "msg": "37303330383138373734", + "sig": "304402201cf3517ba3bf2ab8b9ead4ebb6e866cb88a1deacb6a785d3b63b483ca02ac4950220249a798b73606f55f5f1c70de67cb1a0cff95d7dc50b3a617df861bad3c6b1c9", + "result": "valid" }, { - "tcId" : 337, - "comment" : "special case hash", - "flags" : [ + "tcId": 337, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "35393234353233373434", - "sig" : "3045022100e69b5238265ea35d77e4dd172288d8cea19810a10292617d5976519dc5757cb802204b03c5bc47e826bdb27328abd38d3056d77476b2130f3df6ec4891af08ba1e29", - "result" : "valid" + "msg": "35393234353233373434", + "sig": "3045022100e69b5238265ea35d77e4dd172288d8cea19810a10292617d5976519dc5757cb802204b03c5bc47e826bdb27328abd38d3056d77476b2130f3df6ec4891af08ba1e29", + "result": "valid" }, { - "tcId" : 338, - "comment" : "special case hash", - "flags" : [ + "tcId": 338, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31343935353836363231", - "sig" : "304402205f9d7d7c870d085fc1d49fff69e4a275812800d2cf8973e7325866cb40fa2b6f02206d1f5491d9f717a597a15fd540406486d76a44697b3f0d9d6dcef6669f8a0a56", - "result" : "valid" + "msg": "31343935353836363231", + "sig": "304402205f9d7d7c870d085fc1d49fff69e4a275812800d2cf8973e7325866cb40fa2b6f02206d1f5491d9f717a597a15fd540406486d76a44697b3f0d9d6dcef6669f8a0a56", + "result": "valid" }, { - "tcId" : 339, - "comment" : "special case hash", - "flags" : [ + "tcId": 339, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "34303035333134343036", - "sig" : "304402200a7d5b1959f71df9f817146ee49bd5c89b431e7993e2fdecab6858957da685ae02200f8aad2d254690bdc13f34a4fec44a02fd745a422df05ccbb54635a8b86b9609", - "result" : "valid" + "msg": "34303035333134343036", + "sig": "304402200a7d5b1959f71df9f817146ee49bd5c89b431e7993e2fdecab6858957da685ae02200f8aad2d254690bdc13f34a4fec44a02fd745a422df05ccbb54635a8b86b9609", + "result": "valid" }, { - "tcId" : 340, - "comment" : "special case hash", - "flags" : [ + "tcId": 340, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "33303936343537353132", - "sig" : "3044022079e88bf576b74bc07ca142395fda28f03d3d5e640b0b4ff0752c6d94cd553408022032cea05bd2d706c8f6036a507e2ab7766004f0904e2e5c5862749c0073245d6a", - "result" : "valid" + "msg": "33303936343537353132", + "sig": "3044022079e88bf576b74bc07ca142395fda28f03d3d5e640b0b4ff0752c6d94cd553408022032cea05bd2d706c8f6036a507e2ab7766004f0904e2e5c5862749c0073245d6a", + "result": "valid" }, { - "tcId" : 341, - "comment" : "special case hash", - "flags" : [ + "tcId": 341, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "32373834303235363230", - "sig" : "30450221009d54e037a00212b377bc8874798b8da080564bbdf7e07591b861285809d01488022018b4e557667a82bd95965f0706f81a29243fbdd86968a7ebeb43069db3b18c7f", - "result" : "valid" + "msg": "32373834303235363230", + "sig": "30450221009d54e037a00212b377bc8874798b8da080564bbdf7e07591b861285809d01488022018b4e557667a82bd95965f0706f81a29243fbdd86968a7ebeb43069db3b18c7f", + "result": "valid" }, { - "tcId" : 342, - "comment" : "special case hash", - "flags" : [ + "tcId": 342, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "32363138373837343138", - "sig" : "304402202664f1ffa982fedbcc7cab1b8bc6e2cb420218d2a6077ad08e591ba9feab33bd022049f5c7cb515e83872a3d41b4cdb85f242ad9d61a5bfc01debfbb52c6c84ba728", - "result" : "valid" + "msg": "32363138373837343138", + "sig": "304402202664f1ffa982fedbcc7cab1b8bc6e2cb420218d2a6077ad08e591ba9feab33bd022049f5c7cb515e83872a3d41b4cdb85f242ad9d61a5bfc01debfbb52c6c84ba728", + "result": "valid" }, { - "tcId" : 343, - "comment" : "special case hash", - "flags" : [ + "tcId": 343, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "31363432363235323632", - "sig" : "304402205827518344844fd6a7de73cbb0a6befdea7b13d2dee4475317f0f18ffc81524b02204f5ccb4e0b488b5a5d760aacddb2d791970fe43da61eb30e2e90208a817e46db", - "result" : "valid" + "msg": "31363432363235323632", + "sig": "304402205827518344844fd6a7de73cbb0a6befdea7b13d2dee4475317f0f18ffc81524b02204f5ccb4e0b488b5a5d760aacddb2d791970fe43da61eb30e2e90208a817e46db", + "result": "valid" }, { - "tcId" : 344, - "comment" : "special case hash", - "flags" : [ + "tcId": 344, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "36383234313839343336", - "sig" : "304502210097ab19bd139cac319325869218b1bce111875d63fb12098a04b0cd59b6fdd3a30220431d9cea3a243847303cebda56476431d034339f31d785ee8852db4f040d4921", - "result" : "valid" + "msg": "36383234313839343336", + "sig": "304502210097ab19bd139cac319325869218b1bce111875d63fb12098a04b0cd59b6fdd3a30220431d9cea3a243847303cebda56476431d034339f31d785ee8852db4f040d4921", + "result": "valid" }, { - "tcId" : 345, - "comment" : "special case hash", - "flags" : [ + "tcId": 345, + "comment": "special case hash", + "flags": [ "SpecialCaseHash" ], - "msg" : "343834323435343235", - "sig" : "3044022052c683144e44119ae2013749d4964ef67509278f6d38ba869adcfa69970e123d02203479910167408f45bda420a626ec9c4ec711c1274be092198b4187c018b562ca", - "result" : "valid" + "msg": "343834323435343235", + "sig": "3044022052c683144e44119ae2013749d4964ef67509278f6d38ba869adcfa69970e123d02203479910167408f45bda420a626ec9c4ec711c1274be092198b4187c018b562ca", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0", - "wx" : "07310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc362", - "wy" : "26a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0", + "wx": "07310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc362", + "wy": "26a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEBzEPkKnq4UmghAL1QZSg97SsQnv42b1s\ndoEHHcR9w2ImptN6xG1h/WAMC/G/+HaJ7RF92msOWTGK4BChl6JsoA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000407310f90a9eae149a08402f54194a0f7b4ac427bf8d9bd6c7681071dc47dc36226a6d37ac46d61fd600c0bf1bff87689ed117dda6b0e59318ae010a197a26ca0", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEBzEPkKnq4UmghAL1QZSg97SsQnv42b1s\ndoEHHcR9w2ImptN6xG1h/WAMC/G/+HaJ7RF92msOWTGK4BChl6JsoA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 346, - "comment" : "k*G has a large x-coordinate", - "flags" : [ + "tcId": 346, + "comment": "k*G has a large x-coordinate", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "30160211014551231950b75fc4402da1722fc9baeb020103", - "result" : "valid" + "msg": "313233343030", + "sig": "30160211014551231950b75fc4402da1722fc9baeb020103", + "result": "valid" }, { - "tcId" : 347, - "comment" : "r too large", - "flags" : [ + "tcId": 347, + "comment": "r too large", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2c020103", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2c020103", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5", - "wx" : "00bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22", - "wy" : "705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5", + "wx": "00bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22", + "wy": "705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvJfnWF7srUjhZoO8QJFwjhqTDGg/xHAB\n1LODWU8sTiJwWYnPadrq3U5OS4FR7YiN/sIPsBco2J1Ws/OPKunIxQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004bc97e7585eecad48e16683bc4091708e1a930c683fc47001d4b383594f2c4e22705989cf69daeadd4e4e4b8151ed888dfec20fb01728d89d56b3f38f2ae9c8c5", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvJfnWF7srUjhZoO8QJFwjhqTDGg/xHAB\n1LODWU8sTiJwWYnPadrq3U5OS4FR7YiN/sIPsBco2J1Ws/OPKunIxQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 348, - "comment" : "r,s are large", - "flags" : [ + "tcId": 348, + "comment": "r,s are large", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f020103", - "result" : "valid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f020103", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463", - "wx" : "44ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252", - "wy" : "00b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463", + "wx": "44ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252", + "wy": "00b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERK0zmvvCHpq/e2AqXKU16jeBNbbRDYEx\nC92Ck9HfMlK2P/fQd0dw+P4dFyL6g6zQL0NOT8EQoMyPbd3TfVbEYw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000444ad339afbc21e9abf7b602a5ca535ea378135b6d10d81310bdd8293d1df3252b63ff7d0774770f8fe1d1722fa83acd02f434e4fc110a0cc8f6dddd37d56c463", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERK0zmvvCHpq/e2AqXKU16jeBNbbRDYEx\nC92Ck9HfMlK2P/fQd0dw+P4dFyL6g6zQL0NOT8EQoMyPbd3TfVbEYw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 349, - "comment" : "r and s^-1 have a large Hamming weight", - "flags" : [ + "tcId": 349, + "comment": "r and s^-1 have a large Hamming weight", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e9a7582886089c62fb840cf3b83061cd1cff3ae4341808bb5bdee6191174177", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e9a7582886089c62fb840cf3b83061cd1cff3ae4341808bb5bdee6191174177", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0", - "wx" : "1260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c", - "wy" : "5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0", + "wx": "1260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c", + "wy": "5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEmDCEiyeJE4a9RUb7eDDriO1TXxZaIHT\n7rrSHzfdh4xcmgwamt52c3qIEb1qf5KHyXjuOWqonBHkcinSzLVS8A==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200041260c2122c9e244e1af5151bede0c3ae23b54d7c596881d3eebad21f37dd878c5c9a0c1a9ade76737a8811bd6a7f9287c978ee396aa89c11e47229d2ccb552f0", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEmDCEiyeJE4a9RUb7eDDriO1TXxZaIHT\n7rrSHzfdh4xcmgwamt52c3qIEb1qf5KHyXjuOWqonBHkcinSzLVS8A==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 350, - "comment" : "r and s^-1 have a large Hamming weight", - "flags" : [ + "tcId": 350, + "comment": "r and s^-1 have a large Hamming weight", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022024238e70b431b1a64efdf9032669939d4b77f249503fc6905feb7540dea3e6d2", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022024238e70b431b1a64efdf9032669939d4b77f249503fc6905feb7540dea3e6d2", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159", - "wx" : "1877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce", - "wy" : "00821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159", + "wx": "1877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce", + "wy": "00821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGHcEW+JdNKHQYA+dXADQZFoqVDebbO76\n0ua/XCozUs6CGlMswXUe4dNtQcPWq06bFD5E7EbXNHjqanmlwOVBWQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200041877045be25d34a1d0600f9d5c00d0645a2a54379b6ceefad2e6bf5c2a3352ce821a532cc1751ee1d36d41c3d6ab4e9b143e44ec46d73478ea6a79a5c0e54159", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGHcEW+JdNKHQYA+dXADQZFoqVDebbO76\n0ua/XCozUs6CGlMswXUe4dNtQcPWq06bFD5E7EbXNHjqanmlwOVBWQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 351, - "comment" : "small r and s", - "flags" : [ + "tcId": 351, + "comment": "small r and s", + "flags": [ "SmallRandS", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3006020101020101", - "result" : "valid" + "msg": "313233343030", + "sig": "3006020101020101", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77", - "wx" : "455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50", - "wy" : "00aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77", + "wx": "455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50", + "wy": "00aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERVQ5/MPS3uzt3q7OYOe9FzBPNuu2Aq31\noi4Ljx20alCuw4+yuvIh6ajRiHx79iIt0YNGNOdyYzFa9tI2CdBPdw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004455439fcc3d2deeceddeaece60e7bd17304f36ebb602adf5a22e0b8f1db46a50aec38fb2baf221e9a8d1887c7bf6222dd1834634e77263315af6d23609d04f77", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERVQ5/MPS3uzt3q7OYOe9FzBPNuu2Aq31\noi4Ljx20alCuw4+yuvIh6ajRiHx79iIt0YNGNOdyYzFa9tI2CdBPdw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 352, - "comment" : "small r and s", - "flags" : [ + "tcId": 352, + "comment": "small r and s", + "flags": [ "SmallRandS", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3006020101020102", - "result" : "valid" + "msg": "313233343030", + "sig": "3006020101020102", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d", - "wx" : "2e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece718", - "wy" : "0449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d", + "wx": "2e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece718", + "wy": "0449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELh9GawJMDDrOJDfeCRJ/7QS3BvlLGaIb\nscKs81zs5xgESa41I9clNOlklyz9OzivC93ZYZ5a8iPk0aQPNM+fHQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200042e1f466b024c0c3ace2437de09127fed04b706f94b19a21bb1c2acf35cece7180449ae3523d72534e964972cfd3b38af0bddd9619e5af223e4d1a40f34cf9f1d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELh9GawJMDDrOJDfeCRJ/7QS3BvlLGaIb\nscKs81zs5xgESa41I9clNOlklyz9OzivC93ZYZ5a8iPk0aQPNM+fHQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 353, - "comment" : "small r and s", - "flags" : [ + "tcId": 353, + "comment": "small r and s", + "flags": [ "SmallRandS", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3006020101020103", - "result" : "valid" + "msg": "313233343030", + "sig": "3006020101020103", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3", - "wx" : "008e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a23373", - "wy" : "26ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3", + "wx": "008e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a23373", + "wy": "26ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjnq9u9GN50UjdMGHmhw7AdEyYefUVxw7\nR6HHbFWiM3Mm7Yl81Rek9TSduAl4D20vK59imdi1qJB38RGacY/Xsw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200048e7abdbbd18de7452374c1879a1c3b01d13261e7d4571c3b47a1c76c55a2337326ed897cd517a4f5349db809780f6d2f2b9f6299d8b5a89077f1119a718fd7b3", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjnq9u9GN50UjdMGHmhw7AdEyYefUVxw7\nR6HHbFWiM3Mm7Yl81Rek9TSduAl4D20vK59imdi1qJB38RGacY/Xsw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 354, - "comment" : "small r and s", - "flags" : [ + "tcId": 354, + "comment": "small r and s", + "flags": [ "SmallRandS", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3006020102020101", - "result" : "valid" + "msg": "313233343030", + "sig": "3006020102020101", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b", - "wx" : "7b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af19", - "wy" : "42117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b", + "wx": "7b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af19", + "wy": "42117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEezM9Q0DT1xjdPmr/fee7+Lcr/WFshCAF\nYFKEI3a5rxlCEXxa/qx1XW83b8Yymn12BRuHEjpKXQvEpTk4DwPeew==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200047b333d4340d3d718dd3e6aff7de7bbf8b72bfd616c8420056052842376b9af1942117c5afeac755d6f376fc6329a7d76051b87123a4a5d0bc4a539380f03de7b", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEezM9Q0DT1xjdPmr/fee7+Lcr/WFshCAF\nYFKEI3a5rxlCEXxa/qx1XW83b8Yymn12BRuHEjpKXQvEpTk4DwPeew==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 355, - "comment" : "small r and s", - "flags" : [ + "tcId": 355, + "comment": "small r and s", + "flags": [ "SmallRandS", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3006020102020102", - "result" : "valid" + "msg": "313233343030", + "sig": "3006020102020102", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff", - "wx" : "00d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e5", - "wy" : "03a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff", + "wx": "00d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e5", + "wy": "03a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0wykoN22YWyFHTDO1oLED4PGJ1ih8nWZ\niNZ2OojxwOUDqA1UFWUNQSOXhOji+xI16f6ZHREuu4EYbL8Not46/w==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004d30ca4a0ddb6616c851d30ced682c40f83c62758a1f2759988d6763a88f1c0e503a80d5415650d41239784e8e2fb1235e9fe991d112ebb81186cbf0da2de3aff", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0wykoN22YWyFHTDO1oLED4PGJ1ih8nWZ\niNZ2OojxwOUDqA1UFWUNQSOXhOji+xI16f6ZHREuu4EYbL8Not46/w==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 356, - "comment" : "small r and s", - "flags" : [ + "tcId": 356, + "comment": "small r and s", + "flags": [ "SmallRandS", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3006020102020103", - "result" : "valid" + "msg": "313233343030", + "sig": "3006020102020103", + "result": "valid" }, { - "tcId" : 357, - "comment" : "r is larger than n", - "flags" : [ + "tcId": 357, + "comment": "r is larger than n", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143020103", - "result" : "invalid" + "msg": "313233343030", + "sig": "3026022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364143020103", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec", - "wx" : "48969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24", - "wy" : "00b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec", + "wx": "48969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24", + "wy": "00b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAESJabOZkSl7MyplLT7m4B6QmzmQTnH6I1\nSngwx3ULryS0AS0bgw0ZnMsfyXKzK/3tVfCc1i0lfl6ETiflehWU7A==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000448969b39991297b332a652d3ee6e01e909b39904e71fa2354a7830c7750baf24b4012d1b830d199ccb1fc972b32bfded55f09cd62d257e5e844e27e57a1594ec", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAESJabOZkSl7MyplLT7m4B6QmzmQTnH6I1\nSngwx3ULryS0AS0bgw0ZnMsfyXKzK/3tVfCc1i0lfl6ETiflehWU7A==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 358, - "comment" : "s is larger than n", - "flags" : [ + "tcId": 358, + "comment": "s is larger than n", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "30080201020203ed2979", - "result" : "invalid" + "msg": "313233343030", + "sig": "30080201020203ed2979", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866", - "wx" : "02ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee77", - "wy" : "7eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866", + "wx": "02ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee77", + "wy": "7eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAu9NbWz9WpTx13hCJuPipsCkNsVYOWGf\nOPtEcrX57nd+tKzU7r2lzXKHX/0qLyYinC3GtGUAkZpDLIZznzroZg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000402ef4d6d6cfd5a94f1d7784226e3e2a6c0a436c55839619f38fb4472b5f9ee777eb4acd4eebda5cd72875ffd2a2f26229c2dc6b46500919a432c86739f3ae866", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAu9NbWz9WpTx13hCJuPipsCkNsVYOWGf\nOPtEcrX57nd+tKzU7r2lzXKHX/0qLyYinC3GtGUAkZpDLIZznzroZg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 359, - "comment" : "small r and s^-1", - "flags" : [ + "tcId": 359, + "comment": "small r and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "30260202010102203a74e9d3a74e9d3a74e9d3a74e9d3a749f8ab3732a0a89604a09bce5b2916da4", - "result" : "valid" + "msg": "313233343030", + "sig": "30260202010102203a74e9d3a74e9d3a74e9d3a74e9d3a749f8ab3732a0a89604a09bce5b2916da4", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08", - "wx" : "464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584", - "wy" : "00b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08", + "wx": "464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584", + "wy": "00b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERk9P9xVynK5Qcso72AHTGVtnrsZemwGq\n0gopQ9y8tYSxr9KdMaOaEdVwqhWXQ5s7LRlxvy8avxVDLQIHsQ0dCA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004464f4ff715729cae5072ca3bd801d3195b67aec65e9b01aad20a2943dcbcb584b1afd29d31a39a11d570aa1597439b3b2d1971bf2f1abf15432d0207b10d1d08", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERk9P9xVynK5Qcso72AHTGVtnrsZemwGq\n0gopQ9y8tYSxr9KdMaOaEdVwqhWXQ5s7LRlxvy8avxVDLQIHsQ0dCA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 360, - "comment" : "smallish r and s^-1", - "flags" : [ + "tcId": 360, + "comment": "smallish r and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "302b02072d9b4d347952cc02200343aefc2f25d98b882e86eb9e30d55a6eb508b516510b34024ae4b6362330b3", - "result" : "valid" + "msg": "313233343030", + "sig": "302b02072d9b4d347952cc02200343aefc2f25d98b882e86eb9e30d55a6eb508b516510b34024ae4b6362330b3", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f", - "wx" : "157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4c", - "wy" : "00deadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f", + "wx": "157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4c", + "wy": "00deadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFX+P3fNz619Jz88Q2LhTz5HLzX1mXDUi\nun3XON23mkzerfGlxEjqPJ9BkaiZmr/MdXrG1kVn7wcsR/7GE0Q7jw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004157f8fddf373eb5f49cfcf10d8b853cf91cbcd7d665c3522ba7dd738ddb79a4cdeadf1a5c448ea3c9f4191a8999abfcc757ac6d64567ef072c47fec613443b8f", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEFX+P3fNz619Jz88Q2LhTz5HLzX1mXDUi\nun3XON23mkzerfGlxEjqPJ9BkaiZmr/MdXrG1kVn7wcsR/7GE0Q7jw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 361, - "comment" : "100-bit r and small s^-1", - "flags" : [ + "tcId": 361, + "comment": "100-bit r and small s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3031020d1033e67e37b32b445580bf4efc02206f906f906f906f906f906f906f906f8fe1cab5eefdb214061dce3b22789f1d6f", - "result" : "valid" + "msg": "313233343030", + "sig": "3031020d1033e67e37b32b445580bf4efc02206f906f906f906f906f906f906f906f8fe1cab5eefdb214061dce3b22789f1d6f", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa", - "wx" : "0934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0", - "wy" : "00d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa", + "wx": "0934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0", + "wy": "00d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECTSlN0ZsB0MOLEj+uZC7Gft4zsyc7kJO\npNEwKRqiN/DU+S0jtGKAS1toxSVYwByZltv3J/zKu+7bliGkAFNa+g==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200040934a537466c07430e2c48feb990bb19fb78cecc9cee424ea4d130291aa237f0d4f92d23b462804b5b68c52558c01c9996dbf727fccabbeedb9621a400535afa", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAECTSlN0ZsB0MOLEj+uZC7Gft4zsyc7kJO\npNEwKRqiN/DU+S0jtGKAS1toxSVYwByZltv3J/zKu+7bliGkAFNa+g==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 362, - "comment" : "small r and 100 bit s^-1", - "flags" : [ + "tcId": 362, + "comment": "small r and 100 bit s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3026020201010220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57", - "result" : "valid" + "msg": "313233343030", + "sig": "3026020201010220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265", - "wx" : "00d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c65", - "wy" : "4a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265", + "wx": "00d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c65", + "wy": "4a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1u8gvmbIk/dBqb+Q2bdGddHCoxKWOXrL\nPvF0/QswDGVKDJVHjKADmRYtfw8tyJ79wrKKMPur4oWFcpWksMTiZQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004d6ef20be66c893f741a9bf90d9b74675d1c2a31296397acb3ef174fd0b300c654a0c95478ca00399162d7f0f2dc89efdc2b28a30fbabe285857295a4b0c4e265", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1u8gvmbIk/dBqb+Q2bdGddHCoxKWOXrL\nPvF0/QswDGVKDJVHjKADmRYtfw8tyJ79wrKKMPur4oWFcpWksMTiZQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 363, - "comment" : "100-bit r and s^-1", - "flags" : [ + "tcId": 363, + "comment": "100-bit r and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3031020d062522bbd3ecbe7c39e93e7c260220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57", - "result" : "valid" + "msg": "313233343030", + "sig": "3031020d062522bbd3ecbe7c39e93e7c260220783266e90f43dafe5cd9b3b0be86de22f9de83677d0f50713a468ec72fcf5d57", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829", - "wx" : "00b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee06", - "wy" : "29c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829", + "wx": "00b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee06", + "wy": "29c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtykdFATgwMB9q5NyGJ9L1Y0s6qjRXt5U\nTZUUVFup7gYpyaY9XjCHacww7CdqQQ5kZKJ+6v2eWZ2xDwU6T+SoKQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004b7291d1404e0c0c07dab9372189f4bd58d2ceaa8d15ede544d9514545ba9ee0629c9a63d5e308769cc30ec276a410e6464a27eeafd9e599db10f053a4fe4a829", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtykdFATgwMB9q5NyGJ9L1Y0s6qjRXt5U\nTZUUVFup7gYpyaY9XjCHacww7CdqQQ5kZKJ+6v2eWZ2xDwU6T+SoKQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 364, - "comment" : "r and s^-1 are close to n", - "flags" : [ + "tcId": 364, + "comment": "r and s^-1 are close to n", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03640c1022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03640c1022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6", - "wx" : "6e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8", - "wy" : "186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6", + "wx": "6e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8", + "wy": "186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbigwMwXWQsy5I7ci6oayoLyONzXssm6E\nmxnJ92sv27gYboDWTYyrFk9SOPUxhGG/idTZbuZUTIFsdWaUd3Tg9g==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200046e28303305d642ccb923b722ea86b2a0bc8e3735ecb26e849b19c9f76b2fdbb8186e80d64d8cab164f5238f5318461bf89d4d96ee6544c816c7566947774e0f6", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbigwMwXWQsy5I7ci6oayoLyONzXssm6E\nmxnJ92sv27gYboDWTYyrFk9SOPUxhGG/idTZbuZUTIFsdWaUd3Tg9g==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 365, - "comment" : "r and s are 64-bit integer", - "flags" : [ + "tcId": 365, + "comment": "r and s are 64-bit integer", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "30160209009c44febf31c3594d020900839ed28247c2b06b", - "result" : "valid" + "msg": "313233343030", + "sig": "30160209009c44febf31c3594d020900839ed28247c2b06b", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd", - "wx" : "375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9", - "wy" : "00a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd", + "wx": "375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9", + "wy": "00a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEN1vak/avkvtfj0sbXwU047r6s0y3rZ+5\n0Lci5KXDAqmgC584elo5YJeqIWL8W7z0pSYzcvaByU2lHpeZEgmQ/Q==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004375bda93f6af92fb5f8f4b1b5f0534e3bafab34cb7ad9fb9d0b722e4a5c302a9a00b9f387a5a396097aa2162fc5bbcf4a5263372f681c94da51e9799120990fd", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEN1vak/avkvtfj0sbXwU047r6s0y3rZ+5\n0Lci5KXDAqmgC584elo5YJeqIWL8W7z0pSYzcvaByU2lHpeZEgmQ/Q==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 366, - "comment" : "r and s are 100-bit integer", - "flags" : [ + "tcId": 366, + "comment": "r and s are 100-bit integer", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "301e020d09df8b682430beef6f5fd7c7cf020d0fd0a62e13778f4222a0d61c8a", - "result" : "valid" + "msg": "313233343030", + "sig": "301e020d09df8b682430beef6f5fd7c7cf020d0fd0a62e13778f4222a0d61c8a", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44", - "wx" : "00d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197", - "wy" : "00da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44", + "wx": "00d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197", + "wy": "00da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE11toIWur4DriV+lLTjvxxS9E498mbRUk\n/4xepp2nMZfaS/+e0cU/RJF6Z9e5eFmOid81nj1ZE+rqJPOuJZq8RA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004d75b68216babe03ae257e94b4e3bf1c52f44e3df266d1524ff8c5ea69da73197da4bff9ed1c53f44917a67d7b978598e89df359e3d5913eaea24f3ae259abc44", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE11toIWur4DriV+lLTjvxxS9E498mbRUk\n/4xepp2nMZfaS/+e0cU/RJF6Z9e5eFmOid81nj1ZE+rqJPOuJZq8RA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 367, - "comment" : "r and s are 128-bit integer", - "flags" : [ + "tcId": 367, + "comment": "r and s are 128-bit integer", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "30260211008a598e563a89f526c32ebec8de26367a02110084f633e2042630e99dd0f1e16f7a04bf", - "result" : "valid" + "msg": "313233343030", + "sig": "30260211008a598e563a89f526c32ebec8de26367a02110084f633e2042630e99dd0f1e16f7a04bf", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e", - "wx" : "78bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653", - "wy" : "118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e", + "wx": "78bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653", + "wy": "118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeLzaFArtI9QwyyPD3A0B9CPbE07pSjqM\ntIPy3qwqxlMRgRT28zBF1OntkQcIUAe/vd+PWP56GiRF1mqZAEVHbg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000478bcda140aed23d430cb23c3dc0d01f423db134ee94a3a8cb483f2deac2ac653118114f6f33045d4e9ed9107085007bfbddf8f58fe7a1a2445d66a990045476e", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeLzaFArtI9QwyyPD3A0B9CPbE07pSjqM\ntIPy3qwqxlMRgRT28zBF1OntkQcIUAe/vd+PWP56GiRF1mqZAEVHbg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 368, - "comment" : "r and s are 160-bit integer", - "flags" : [ + "tcId": 368, + "comment": "r and s are 160-bit integer", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "302e021500aa6eeb5823f7fa31b466bb473797f0d0314c0bdf021500e2977c479e6d25703cebbc6bd561938cc9d1bfb9", - "result" : "valid" + "msg": "313233343030", + "sig": "302e021500aa6eeb5823f7fa31b466bb473797f0d0314c0bdf021500e2977c479e6d25703cebbc6bd561938cc9d1bfb9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677", - "wx" : "00bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c", - "wy" : "1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677", + "wx": "00bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c", + "wy": "1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEu3n2GFf3Q7+htucRHOQJQ3claWnk4VFZ\nEj2VSKzDvmwfnZ+IYNz/0+s23Wwx/y5yJsIAnEyU2NfStWhr96vWdw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004bb79f61857f743bfa1b6e7111ce4094377256969e4e15159123d9548acc3be6c1f9d9f8860dcffd3eb36dd6c31ff2e7226c2009c4c94d8d7d2b5686bf7abd677", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEu3n2GFf3Q7+htucRHOQJQ3claWnk4VFZ\nEj2VSKzDvmwfnZ+IYNz/0+s23Wwx/y5yJsIAnEyU2NfStWhr96vWdw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 369, - "comment" : "s == 1", - "flags" : [ + "tcId": 369, + "comment": "s == 1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020101", - "result" : "valid" + "msg": "313233343030", + "sig": "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020101", + "result": "valid" }, { - "tcId" : 370, - "comment" : "s == 0", - "flags" : [ + "tcId": 370, + "comment": "s == 0", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020100", - "result" : "invalid" + "msg": "313233343030", + "sig": "3025022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1020100", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518", - "wx" : "0093591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36", - "wy" : "073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518", + "wx": "0093591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36", + "wy": "073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEk1kYJ9nmcTtOn66mLHKyjf76aODAUWC1\n1qroj9LjbDYHP1VFrVr0EK8mr/9oZUz3LUXkk0iTESAyRzR6iQ9FGA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000493591827d9e6713b4e9faea62c72b28dfefa68e0c05160b5d6aae88fd2e36c36073f5545ad5af410af26afff68654cf72d45e493489311203247347a890f4518", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEk1kYJ9nmcTtOn66mLHKyjf76aODAUWC1\n1qroj9LjbDYHP1VFrVr0EK8mr/9oZUz3LUXkk0iTESAyRzR6iQ9FGA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 371, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 371, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220419d981c515af8cc82545aac0c85e9e308fbb2eab6acd7ed497e0b4145a18fd9", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220419d981c515af8cc82545aac0c85e9e308fbb2eab6acd7ed497e0b4145a18fd9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f", - "wx" : "31ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0da", - "wy" : "00da01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f", + "wx": "31ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0da", + "wy": "00da01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMe0wga7+AB62QCBp7izMGGKTe4WZUUTb\nqVA5Q1h78NraAbjMTfNPWrOxo1lhUgiUbl7jX5jud1uMzs2GzMFlDw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000431ed3081aefe001eb6402069ee2ccc1862937b85995144dba9503943587bf0dada01b8cc4df34f5ab3b1a359615208946e5ee35f98ee775b8ccecd86ccc1650f", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMe0wga7+AB62QCBp7izMGGKTe4WZUUTb\nqVA5Q1h78NraAbjMTfNPWrOxo1lhUgiUbl7jX5jud1uMzs2GzMFlDw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 372, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 372, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102201b21717ad71d23bbac60a9ad0baf75b063c9fdf52a00ebf99d022172910993c9", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102201b21717ad71d23bbac60a9ad0baf75b063c9fdf52a00ebf99d022172910993c9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4", - "wx" : "7dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea8", - "wy" : "54c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4", + "wx": "7dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea8", + "wy": "54c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEff9m+phQn/Pi5RBF9DkFI9zNpDo7wohe\nWMJICQmQ7qhUx2wrmt62u1cYI+B/18ZchjnPnZBSYAZMjnZ1zm2YtA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200047dff66fa98509ff3e2e51045f4390523dccda43a3bc2885e58c248090990eea854c76c2b9adeb6bb571823e07fd7c65c8639cf9d905260064c8e7675ce6d98b4", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEff9m+phQn/Pi5RBF9DkFI9zNpDo7wohe\nWMJICQmQ7qhUx2wrmt62u1cYI+B/18ZchjnPnZBSYAZMjnZ1zm2YtA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 373, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 373, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202f588f66018f3dd14db3e28e77996487e32486b521ed8e5a20f06591951777e9", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202f588f66018f3dd14db3e28e77996487e32486b521ed8e5a20f06591951777e9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1", - "wx" : "4280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a", - "wy" : "2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1", + "wx": "4280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a", + "wy": "2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEQoBQmqtk7fwLSiln5MvOhJy1ROSncxPI\n5uzlefvXQgouif5cwZJ9VU5qO7FAM+p8kizXXLosdBX9q1LyCxhg8Q==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200044280509aab64edfc0b4a2967e4cbce849cb544e4a77313c8e6ece579fbd7420a2e89fe5cc1927d554e6a3bb14033ea7c922cd75cba2c7415fdab52f20b1860f1", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEQoBQmqtk7fwLSiln5MvOhJy1ROSncxPI\n5uzlefvXQgouif5cwZJ9VU5qO7FAM+p8kizXXLosdBX9q1LyCxhg8Q==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 374, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 374, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220091a08870ff4daf9123b30c20e8c4fc8505758dcf4074fcaff2170c9bfcf74f4", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220091a08870ff4daf9123b30c20e8c4fc8505758dcf4074fcaff2170c9bfcf74f4", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db", - "wx" : "4f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb", - "wy" : "2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db", + "wx": "4f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb", + "wy": "2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAET43xRRlOPE/D7qJtQ851tALWsXRy3cuy\nVLinmwvz2csqog2ChEyyZjROccp48q0np1oJ5bwPpX5O/Z1GWgiI2w==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200044f8df145194e3c4fc3eea26d43ce75b402d6b17472ddcbb254b8a79b0bf3d9cb2aa20d82844cb266344e71ca78f2ad27a75a09e5bc0fa57e4efd9d465a0888db", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAET43xRRlOPE/D7qJtQ851tALWsXRy3cuy\nVLinmwvz2csqog2ChEyyZjROccp48q0np1oJ5bwPpX5O/Z1GWgiI2w==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 375, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 375, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207c370dc0ce8c59a8b273cba44a7c1191fc3186dc03cab96b0567312df0d0b250", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207c370dc0ce8c59a8b273cba44a7c1191fc3186dc03cab96b0567312df0d0b250", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207", - "wx" : "009598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14", - "wy" : "122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207", + "wx": "009598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14", + "wy": "122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElZilfdZ+w+FrWHoziqOhCjo5E7QaOvMu\nPtP/ATWMaxQSKBnt+AdLvFIffUzc6C/velFnBq/7odk9neqcyuGiBw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200049598a57dd67ec3e16b587a338aa3a10a3a3913b41a3af32e3ed3ff01358c6b14122819edf8074bbc521f7d4cdce82fef7a516706affba1d93d9dea9ccae1a207", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElZilfdZ+w+FrWHoziqOhCjo5E7QaOvMu\nPtP/ATWMaxQSKBnt+AdLvFIffUzc6C/velFnBq/7odk9neqcyuGiBw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 376, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 376, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022070b59a7d1ee77a2f9e0491c2a7cfcd0ed04df4a35192f6132dcc668c79a6160e", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022070b59a7d1ee77a2f9e0491c2a7cfcd0ed04df4a35192f6132dcc668c79a6160e", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330", - "wx" : "009171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e", - "wy" : "634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330", + "wx": "009171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e", + "wy": "634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkXH+w8oggGvAhPEvB2CRG2CZC9gOWypx\nygOgSLIPg35jT9F4Y3YbKVjSvk4Un409ervcGL4D9FGrbBf6Ch+DMA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200049171fec3ca20806bc084f12f0760911b60990bd80e5b2a71ca03a048b20f837e634fd17863761b2958d2be4e149f8d3d7abbdc18be03f451ab6c17fa0a1f8330", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkXH+w8oggGvAhPEvB2CRG2CZC9gOWypx\nygOgSLIPg35jT9F4Y3YbKVjSvk4Un409ervcGL4D9FGrbBf6Ch+DMA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 377, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 377, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202736d76e412246e097148e2bf62915614eb7c428913a58eb5e9cd4674a9423de", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102202736d76e412246e097148e2bf62915614eb7c428913a58eb5e9cd4674a9423de", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d", - "wx" : "777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9", - "wy" : "00ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d", + "wx": "777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9", + "wy": "00ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd3yJMLbh0nEQD+aM6T8WP6N2EsX/9n9K\nYvw7r689F6ntc9hvYKUbXtkTU6OwVO3AqpLJ68vQt10Yj9yIJ5HWjQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004777c8930b6e1d271100fe68ce93f163fa37612c5fff67f4a62fc3bafaf3d17a9ed73d86f60a51b5ed91353a3b054edc0aa92c9ebcbd0b75d188fdc882791d68d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEd3yJMLbh0nEQD+aM6T8WP6N2EsX/9n9K\nYvw7r689F6ntc9hvYKUbXtkTU6OwVO3AqpLJ68vQt10Yj9yIJ5HWjQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 378, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 378, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204a1e12831fbe93627b02d6e7f24bccdd6ef4b2d0f46739eaf3b1eaf0ca117770", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204a1e12831fbe93627b02d6e7f24bccdd6ef4b2d0f46739eaf3b1eaf0ca117770", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000", - "wx" : "00eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf470", - "wy" : "0603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000", + "wx": "00eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf470", + "wy": "0603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE6rwkj2JuCmPh64HEPUYaOaHbqIHrbuIV\nKwfDLXG89HAGA8qoudM9sTr0TG777IoZjtYSSsnrF+qv0oJKVF7AAA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004eabc248f626e0a63e1eb81c43d461a39a1dba881eb6ee2152b07c32d71bcf4700603caa8b9d33db13af44c6efbec8a198ed6124ac9eb17eaafd2824a545ec000", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE6rwkj2JuCmPh64HEPUYaOaHbqIHrbuIV\nKwfDLXG89HAGA8qoudM9sTr0TG777IoZjtYSSsnrF+qv0oJKVF7AAA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 379, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 379, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022006c778d4dfff7dee06ed88bc4e0ed34fc553aad67caf796f2a1c6487c1b2e877", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022006c778d4dfff7dee06ed88bc4e0ed34fc553aad67caf796f2a1c6487c1b2e877", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73", - "wx" : "009f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001", - "wy" : "00f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73", + "wx": "009f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001", + "wy": "00f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEn3oTraFYpV+d3xpF8ETwc9m4ADDv3Pyf\nn1hBj7zq8AH4raAXUJD4DUcifWcTtnQPmgCR2IqDfQoc13tYqPKNcw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200049f7a13ada158a55f9ddf1a45f044f073d9b80030efdcfc9f9f58418fbceaf001f8ada0175090f80d47227d6713b6740f9a0091d88a837d0a1cd77b58a8f28d73", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEn3oTraFYpV+d3xpF8ETwc9m4ADDv3Pyf\nn1hBj7zq8AH4raAXUJD4DUcifWcTtnQPmgCR2IqDfQoc13tYqPKNcw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 380, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 380, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204de459ef9159afa057feb3ec40fef01c45b809f4ab296ea48c206d4249a2b451", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102204de459ef9159afa057feb3ec40fef01c45b809f4ab296ea48c206d4249a2b451", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb", - "wx" : "11c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4db", - "wy" : "00bbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb", + "wx": "11c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4db", + "wy": "00bbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEcTz5GHNAZtcBuoM6kxAkMPMPjxdnzxt\nZbQ2gm2ptNu763p35Mv9ogcJfENCNwX3LIBHbaPaxApIOwqw8urRyw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000411c4f3e461cd019b5c06ea0cea4c4090c3cc3e3c5d9f3c6d65b436826da9b4dbbbeb7a77e4cbfda207097c43423705f72c80476da3dac40a483b0ab0f2ead1cb", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEEcTz5GHNAZtcBuoM6kxAkMPMPjxdnzxt\nZbQ2gm2ptNu763p35Mv9ogcJfENCNwX3LIBHbaPaxApIOwqw8urRyw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 381, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 381, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220745d294978007302033502e1acc48b63ae6500be43adbea1b258d6b423dbb416", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c10220745d294978007302033502e1acc48b63ae6500be43adbea1b258d6b423dbb416", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb", - "wx" : "00e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4", - "wy" : "161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb", + "wx": "00e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4", + "wy": "161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE4uGGgtUxI6oBpsXQCwxiPWcbRi6oC93W\nUif9UQWYiqQWGQez/SUESpSepByOLqhFncbxZUhWuLYbMVQ7sbRb2w==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004e2e18682d53123aa01a6c5d00b0c623d671b462ea80bddd65227fd5105988aa4161907b3fd25044a949ea41c8e2ea8459dc6f1654856b8b61b31543bb1b45bdb", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE4uGGgtUxI6oBpsXQCwxiPWcbRi6oC93W\nUif9UQWYiqQWGQez/SUESpSepByOLqhFncbxZUhWuLYbMVQ7sbRb2w==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 382, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 382, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207b2a785e3896f59b2d69da57648e80ad3c133a750a2847fd2098ccd902042b6c", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102207b2a785e3896f59b2d69da57648e80ad3c133a750a2847fd2098ccd902042b6c", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d", - "wx" : "0090f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197da", - "wy" : "00fadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d", + "wx": "0090f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197da", + "wy": "00fadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkPjUynPeCKZWSq8AUke28P/peFBNzlJg\nX0a3w+Vhl9r62+Uo63DZ7n6g5wcC21T3IVFMe4YErCyyFPHey344PQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000490f8d4ca73de08a6564aaf005247b6f0ffe978504dce52605f46b7c3e56197dafadbe528eb70d9ee7ea0e70702db54f721514c7b8604ac2cb214f1decb7e383d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkPjUynPeCKZWSq8AUke28P/peFBNzlJg\nX0a3w+Vhl9r62+Uo63DZ7n6g5wcC21T3IVFMe4YErCyyFPHey344PQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 383, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 383, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022071ae94a72ca896875e7aa4a4c3d29afdb4b35b6996273e63c47ac519256c5eb1", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c1022071ae94a72ca896875e7aa4a4c3d29afdb4b35b6996273e63c47ac519256c5eb1", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc", - "wx" : "00824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e", - "wy" : "3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc", + "wx": "00824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e", + "wy": "3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEgkwZXHPP/fA40QG84Wh7XDthRvOVyIWX\nb3dTsjdrlI483vpvw0fRPk3LxjoLA6FlGAzSvhQxoM90zh6iUILSvA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004824c195c73cffdf038d101bce1687b5c3b6146f395c885976f7753b2376b948e3cdefa6fc347d13e4dcbc63a0b03a165180cd2be1431a0cf74ce1ea25082d2bc", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEgkwZXHPP/fA40QG84Wh7XDthRvOVyIWX\nb3dTsjdrlI483vpvw0fRPk3LxjoLA6FlGAzSvhQxoM90zh6iUILSvA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 384, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 384, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102200fa527fa7343c0bc9ec35a6278bfbff4d83301b154fc4bd14aee7eb93445b5f9", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102200fa527fa7343c0bc9ec35a6278bfbff4d83301b154fc4bd14aee7eb93445b5f9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f", - "wx" : "2788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f", - "wy" : "30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f", + "wx": "2788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f", + "wy": "30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJ4ilLweOs/ICxPpz4NM4b6899r6FYANj\nb1mZItT1Jo8wtPIHyRm7315nqL5CZagXR1Szq6jxbldbd/9NWn62Tw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200042788a52f078eb3f202c4fa73e0d3386faf3df6be856003636f599922d4f5268f30b4f207c919bbdf5e67a8be4265a8174754b3aba8f16e575b77ff4d5a7eb64f", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJ4ilLweOs/ICxPpz4NM4b6899r6FYANj\nb1mZItT1Jo8wtPIHyRm7315nqL5CZagXR1Szq6jxbldbd/9NWn62Tw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 385, - "comment" : "edge case modular inverse", - "flags" : [ + "tcId": 385, + "comment": "edge case modular inverse", + "flags": [ "ModularInverse", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102206539c0adadd0525ff42622164ce9314348bd0863b4c80e936b23ca0414264671", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c102206539c0adadd0525ff42622164ce9314348bd0863b4c80e936b23ca0414264671", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4", - "wx" : "00d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b4150874", - "wy" : "01b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4", + "wx": "00d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b4150874", + "wy": "01b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1TO3iaSviQ+nqCofrljEBPmmKlC0mtr6\ns0nFE7QVCHQBtBcbgD52s0qYYeEPe8KJoGb9Ab0p+EyYehCl+xjC1A==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004d533b789a4af890fa7a82a1fae58c404f9a62a50b49adafab349c513b415087401b4171b803e76b34a9861e10f7bc289a066fd01bd29f84c987a10a5fb18c2d4", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE1TO3iaSviQ+nqCofrljEBPmmKlC0mtr6\ns0nFE7QVCHQBtBcbgD52s0qYYeEPe8KJoGb9Ab0p+EyYehCl+xjC1A==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 386, - "comment" : "point at infinity during verify", - "flags" : [ + "tcId": 386, + "comment": "point at infinity during verify", + "flags": [ "PointDuplication", "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", - "result" : "invalid" + "msg": "313233343030", + "sig": "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a", - "wx" : "3a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4", - "wy" : "221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a", + "wx": "3a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4", + "wy": "221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOjFQeYyK9p0ebpgfOkVAK6HXMvS+gzDF\nFk9J4Q7FVbQiG9hCvF5Nl+/zcWX2DjmYpCTXKkUM+V6kd8eCh9A0Og==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200043a3150798c8af69d1e6e981f3a45402ba1d732f4be8330c5164f49e10ec555b4221bd842bc5e4d97eff37165f60e3998a424d72a450cf95ea477c78287d0343a", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOjFQeYyK9p0ebpgfOkVAK6HXMvS+gzDF\nFk9J4Q7FVbQiG9hCvF5Nl+/zcWX2DjmYpCTXKkUM+V6kd8eCh9A0Og==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 387, - "comment" : "edge case for signature malleability", - "flags" : [ + "tcId": 387, + "comment": "edge case for signature malleability", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026", - "wx" : "3b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e80", - "wy" : "0de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026", + "wx": "3b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e80", + "wy": "0de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOzffX7NHxpoPF9hcDHyoNzaIOoJeExQ9\nD8/IEB6FHoAN48CQtsohulQ1FzMMBLEvlIxrrfFKY6v/3074x1NwJg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200043b37df5fb347c69a0f17d85c0c7ca83736883a825e13143d0fcfc8101e851e800de3c090b6ca21ba543517330c04b12f948c6badf14a63abffdf4ef8c7537026", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOzffX7NHxpoPF9hcDHyoNzaIOoJeExQ9\nD8/IEB6FHoAN48CQtsohulQ1FzMMBLEvlIxrrfFKY6v/3074x1NwJg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 388, - "comment" : "edge case for signature malleability", - "flags" : [ + "tcId": 388, + "comment": "edge case for signature malleability", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", - "result" : "invalid" + "msg": "313233343030", + "sig": "304402207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a002207fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e", - "wx" : "00feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82c", - "wy" : "00e87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e", + "wx": "00feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82c", + "wy": "00e87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/rUWOw7OMP8+A8fVXEOA+i+oHuLANUlC\n/28IyZ0M2CzofeBe4b2gidPk4kj6D3IRAqz//fUOZUvigUM5md+Jfg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004feb5163b0ece30ff3e03c7d55c4380fa2fa81ee2c0354942ff6f08c99d0cd82ce87de05ee1bda089d3e4e248fa0f721102acfffdf50e654be281433999df897e", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/rUWOw7OMP8+A8fVXEOA+i+oHuLANUlC\n/28IyZ0M2CzofeBe4b2gidPk4kj6D3IRAqz//fUOZUvigUM5md+Jfg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 389, - "comment" : "u1 == 1", - "flags" : [ + "tcId": 389, + "comment": "u1 == 1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2", - "wx" : "238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd4149228976", - "wy" : "40683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2", + "wx": "238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd4149228976", + "wy": "40683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEI4ztABzyK4hT4C7cicvspQULp+BCp6d/\nk4LNQUkiiXZAaD0wlGQ4QPKViQqkwYqjm0HXfdD7O7JwDk+ewoT/wg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004238ced001cf22b8853e02edc89cbeca5050ba7e042a7a77f9382cd414922897640683d3094643840f295890aa4c18aa39b41d77dd0fb3bb2700e4f9ec284ffc2", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEI4ztABzyK4hT4C7cicvspQULp+BCp6d/\nk4LNQUkiiXZAaD0wlGQ4QPKViQqkwYqjm0HXfdD7O7JwDk+ewoT/wg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 390, - "comment" : "u1 == n - 1", - "flags" : [ + "tcId": 390, + "comment": "u1 == n - 1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf", - "wx" : "00961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35e", - "wy" : "00d2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf", + "wx": "00961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35e", + "wy": "00d2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElhz2SBfAbA5Rs8JzbJIv3hi9jEkG/Nf1\n72bEZ4UI817SxdGBaM++cPLxI710GSMruS3WkRPilBBhiJSBxaAnvw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004961cf64817c06c0e51b3c2736c922fde18bd8c4906fcd7f5ef66c4678508f35ed2c5d18168cfbe70f2f123bd7419232bb92dd69113e2941061889481c5a027bf", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAElhz2SBfAbA5Rs8JzbJIv3hi9jEkG/Nf1\n72bEZ4UI817SxdGBaM++cPLxI710GSMruS3WkRPilBBhiJSBxaAnvw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 391, - "comment" : "u2 == 1", - "flags" : [ + "tcId": 391, + "comment": "u2 == 1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384", - "wx" : "13681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b10288", - "wy" : "16528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384", + "wx": "13681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b10288", + "wy": "16528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE2gerhaM1Op88uKkXQUnQtEKn2TnloZ9\nvcuCn+CxAogWUodg0Xc3bAnfed45VXwynMF1NRes/+j6LsKYAmuDhA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000413681eae168cd4ea7cf2e2a45d052742d10a9f64e796867dbdcb829fe0b1028816528760d177376c09df79de39557c329cc1753517acffe8fa2ec298026b8384", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEE2gerhaM1Op88uKkXQUnQtEKn2TnloZ9\nvcuCn+CxAogWUodg0Xc3bAnfed45VXwynMF1NRes/+j6LsKYAmuDhA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 392, - "comment" : "u2 == n - 1", - "flags" : [ + "tcId": 392, + "comment": "u2 == n - 1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215b8", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b", - "wx" : "5aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c2", - "wy" : "0091c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b", + "wx": "5aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c2", + "wy": "0091c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWqer/ba0CG1UMyXl15xulc5C+GbSu4SQ\nljOgS7GqMcKRyACIeUkF4dozM22HTi+RzPRcxZGFvt5d1vP3rKrhiw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200045aa7abfdb6b4086d543325e5d79c6e95ce42f866d2bb84909633a04bb1aa31c291c80088794905e1da33336d874e2f91ccf45cc59185bede5dd6f3f7acaae18b", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWqer/ba0CG1UMyXl15xulc5C+GbSu4SQ\nljOgS7GqMcKRyACIeUkF4dozM22HTi+RzPRcxZGFvt5d1vP3rKrhiw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 393, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 393, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41", - "wx" : "277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e4", - "wy" : "64108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41", + "wx": "277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e4", + "wy": "64108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEACd3kbMFpFsrOVkLLwXTOSpsgYLO9OtU\nASDg9cIGw+RkEIIz+wuMOsiS15744Pv5LtEzrdtFVCcBMlhNxS7vQQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000400277791b305a45b2b39590b2f05d3392a6c8182cef4eb540120e0f5c206c3e464108233fb0b8c3ac892d79ef8e0fbf92ed133addb4554270132584dc52eef41", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEACd3kbMFpFsrOVkLLwXTOSpsgYLO9OtU\nASDg9cIGw+RkEIIz+wuMOsiS15744Pv5LtEzrdtFVCcBMlhNxS7vQQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 394, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 394, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02201c940f313f92647be257eccd7ed08b0baef3f0478f25871b53635302c5f6314a", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02201c940f313f92647be257eccd7ed08b0baef3f0478f25871b53635302c5f6314a", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49", - "wx" : "6efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1a", - "wy" : "00c75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49", + "wx": "6efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1a", + "wy": "00c75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbvoJK2jelGDwvMkZAFpfboDhnemJaL48\n0sdwqZSb+xrHXm5Qh9ZVDV+b6x555QKTB7wlUjXi1dyZJBrDq4hsSQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200046efa092b68de9460f0bcc919005a5f6e80e19de98968be3cd2c770a9949bfb1ac75e6e5087d6550d5f9beb1e79e5029307bc255235e2d5dc99241ac3ab886c49", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbvoJK2jelGDwvMkZAFpfboDhnemJaL48\n0sdwqZSb+xrHXm5Qh9ZVDV+b6x555QKTB7wlUjXi1dyZJBrDq4hsSQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 395, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 395, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022015d94a85077b493f91cb7101ec63e1b01be58b594e855f45050a8c14062d689b", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022015d94a85077b493f91cb7101ec63e1b01be58b594e855f45050a8c14062d689b", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942", - "wx" : "72d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058", - "wy" : "00e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942", + "wx": "72d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058", + "wy": "00e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEctShnE+dLPWEjqQERbcNRpa18C1jLAxl\nTMfX7rDG0FjoxM2ZQ+RZF0x6wB+nQhmOR+bBmmvbDE9sI3gxwbP5Qg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000472d4a19c4f9d2cf5848ea40445b70d4696b5f02d632c0c654cc7d7eeb0c6d058e8c4cd9943e459174c7ac01fa742198e47e6c19a6bdb0c4f6c237831c1b3f942", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEctShnE+dLPWEjqQERbcNRpa18C1jLAxl\nTMfX7rDG0FjoxM2ZQ+RZF0x6wB+nQhmOR+bBmmvbDE9sI3gxwbP5Qg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 396, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 396, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b1d27a7694c146244a5ad0bd0636d9d9ef3b9fb58385418d9c982105077d1b7", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b1d27a7694c146244a5ad0bd0636d9d9ef3b9fb58385418d9c982105077d1b7", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec", - "wx" : "2a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e7402", - "wy" : "58f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec", + "wx": "2a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e7402", + "wy": "58f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKo6i9Q3M7QwhdXW9+nzUfRxvEABB7A41\nUSeUwb5+dAJY+MFxIu0wP9pxQ+tYvt5wKVtlMmYBOwsOvT8FMTf27A==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200042a8ea2f50dcced0c217575bdfa7cd47d1c6f100041ec0e35512794c1be7e740258f8c17122ed303fda7143eb58bede70295b653266013b0b0ebd3f053137f6ec", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEKo6i9Q3M7QwhdXW9+nzUfRxvEABB7A41\nUSeUwb5+dAJY+MFxIu0wP9pxQ+tYvt5wKVtlMmYBOwsOvT8FMTf27A==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 397, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 397, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202d85896b3eb9dbb5a52f42f9c9261ed3fc46644ec65f06ade3fd78f257e43432", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202d85896b3eb9dbb5a52f42f9c9261ed3fc46644ec65f06ade3fd78f257e43432", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946", - "wx" : "0088de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b8", - "wy" : "0c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946", + "wx": "0088de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b8", + "wy": "0c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiN5onOmvHpS+aiCJyKixJT/9u2yOnIYk\nm6IgABpK07gMSZjlSEL0E7ntsYJay7YzXoHk0YSysByL69yF0fKJRg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000488de689ce9af1e94be6a2089c8a8b1253ffdbb6c8e9c86249ba220001a4ad3b80c4998e54842f413b9edb1825acbb6335e81e4d184b2b01c8bebdc85d1f28946", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiN5onOmvHpS+aiCJyKixJT/9u2yOnIYk\nm6IgABpK07gMSZjlSEL0E7ntsYJay7YzXoHk0YSysByL69yF0fKJRg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 398, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 398, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b0b12d67d73b76b4a5e85f3924c3da7f88cc89d8cbe0d5bc7faf1e4afc86864", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205b0b12d67d73b76b4a5e85f3924c3da7f88cc89d8cbe0d5bc7faf1e4afc86864", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9", - "wx" : "00fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7", - "wy" : "00b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9", + "wx": "00fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7", + "wy": "00b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/qLTH3D5DV+z4A4YasQqs8FhXO5xTgtO\nETGz1NgiW/ewN6GN8qwVND8w90Bn3fKegX1fd/jc4FcU2lnAlPDNqQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004fea2d31f70f90d5fb3e00e186ac42ab3c1615cee714e0b4e1131b3d4d8225bf7b037a18df2ac15343f30f74067ddf29e817d5f77f8dce05714da59c094f0cda9", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE/qLTH3D5DV+z4A4YasQqs8FhXO5xTgtO\nETGz1NgiW/ewN6GN8qwVND8w90Bn3fKegX1fd/jc4FcU2lnAlPDNqQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 399, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 399, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220694c146244a5ad0bd0636d9e12bc9e09e60e68b90d0b5e6c5dddd0cb694d8799", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220694c146244a5ad0bd0636d9e12bc9e09e60e68b90d0b5e6c5dddd0cb694d8799", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0", - "wx" : "7258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db", - "wy" : "17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0", + "wx": "7258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db", + "wy": "17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEcliRHj1CM0kWZHnb4Lg0Gvf70D0KfhDt\nzLNrbO6lo9sXrCuJknkRKPo7ltwvvUyjv6eC7ygy/GZWlD2xjnNGsA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200047258911e3d423349166479dbe0b8341af7fbd03d0a7e10edccb36b6ceea5a3db17ac2b8992791128fa3b96dc2fbd4ca3bfa782ef2832fc6656943db18e7346b0", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEcliRHj1CM0kWZHnb4Lg0Gvf70D0KfhDt\nzLNrbO6lo9sXrCuJknkRKPo7ltwvvUyjv6eC7ygy/GZWlD2xjnNGsA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 400, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 400, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203d7f487c07bfc5f30846938a3dcef696444707cf9677254a92b06c63ab867d22", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203d7f487c07bfc5f30846938a3dcef696444707cf9677254a92b06c63ab867d22", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470", - "wx" : "4f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914", - "wy" : "00c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470", + "wx": "4f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914", + "wy": "00c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAETyhGHepkR01rs00Umcl9N7npVjPfHO7q\nrNRQFsmLORTIgYgQuMwG3bQOihJhxSj6pYlFXVpt+Tt3vF4OSTx0cA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200044f28461dea64474d6bb34d1499c97d37b9e95633df1ceeeaacd45016c98b3914c8818810b8cc06ddb40e8a1261c528faa589455d5a6df93b77bc5e0e493c7470", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAETyhGHepkR01rs00Umcl9N7npVjPfHO7q\nrNRQFsmLORTIgYgQuMwG3bQOihJhxSj6pYlFXVpt+Tt3vF4OSTx0cA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 401, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 401, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206c7648fc0fbf8a06adb8b839f97b4ff7a800f11b1e37c593b261394599792ba4", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206c7648fc0fbf8a06adb8b839f97b4ff7a800f11b1e37c593b261394599792ba4", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b", - "wx" : "74f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66", - "wy" : "00eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b", + "wx": "74f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66", + "wy": "00eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEdPKoFPtdjsqRppteYHEnMrOTfeMoKb6X\nTte2jFwvXWbv8PB8VvmHplf0IZYgX1iMDx2W/YpjpfI4tI9Hh4j+Ow==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000474f2a814fb5d8eca91a69b5e60712732b3937de32829be974ed7b68c5c2f5d66eff0f07c56f987a657f42196205f588c0f1d96fd8a63a5f238b48f478788fe3b", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEdPKoFPtdjsqRppteYHEnMrOTfeMoKb6X\nTte2jFwvXWbv8PB8VvmHplf0IZYgX1iMDx2W/YpjpfI4tI9Hh4j+Ow==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 402, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 402, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220641c9c5d790dc09cdd3dfabb62cdf453e69747a7e3d7aa1a714189ef53171a99", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220641c9c5d790dc09cdd3dfabb62cdf453e69747a7e3d7aa1a714189ef53171a99", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad", - "wx" : "195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6a", - "wy" : "00b2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad", + "wx": "195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6a", + "wy": "00b2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGVtRp8xKIbgnSnCpDed5gUw8jKNYMoII\nwJop8za4LWqyQWt8kv/9wpw7EoLdKnek0E3390UgRzk9hJmJxc7prQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004195b51a7cc4a21b8274a70a90de779814c3c8ca358328208c09a29f336b82d6ab2416b7c92fffdc29c3b1282dd2a77a4d04df7f7452047393d849989c5cee9ad", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGVtRp8xKIbgnSnCpDed5gUw8jKNYMoII\nwJop8za4LWqyQWt8kv/9wpw7EoLdKnek0E3390UgRzk9hJmJxc7prQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 403, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 403, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022029798c5c45bdf58b4a7b2fdc2c46ab4af1218c7eeb9f0f27a88f1267674de3b0", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022029798c5c45bdf58b4a7b2fdc2c46ab4af1218c7eeb9f0f27a88f1267674de3b0", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0", - "wx" : "622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa", - "wy" : "736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0", + "wx": "622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa", + "wy": "736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYi/HRzIDS+wt3zvBbTSz0fejJ90qjBm6\ntLtP46JLWKpzay8vrnb0367MkJYzOwEyjVHrP9qckifpDQtEmYPE8A==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004622fc74732034bec2ddf3bc16d34b3d1f7a327dd2a8c19bab4bb4fe3a24b58aa736b2f2fae76f4dfaecc9096333b01328d51eb3fda9c9227e90d0b449983c4f0", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYi/HRzIDS+wt3zvBbTSz0fejJ90qjBm6\ntLtP46JLWKpzay8vrnb0367MkJYzOwEyjVHrP9qckifpDQtEmYPE8A==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 404, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 404, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02200b70f22ca2bb3cefadca1a5711fa3a59f4695385eb5aedf3495d0b6d00f8fd85", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02200b70f22ca2bb3cefadca1a5711fa3a59f4695385eb5aedf3495d0b6d00f8fd85", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93", - "wx" : "1f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c7", - "wy" : "0827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93", + "wx": "1f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c7", + "wy": "0827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH3+FyvLXVQ56+bZQI+u03ONFAxFpIwnb\nJplpuDS2EccIJ/RbeAIOy7r0hP3Vv6rmhw8RhMIVgbr274K9e1MPkw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200041f7f85caf2d7550e7af9b65023ebb4dce3450311692309db269969b834b611c70827f45b78020ecbbaf484fdd5bfaae6870f1184c21581baf6ef82bd7b530f93", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH3+FyvLXVQ56+bZQI+u03ONFAxFpIwnb\nJplpuDS2EccIJ/RbeAIOy7r0hP3Vv6rmhw8RhMIVgbr274K9e1MPkw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 405, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 405, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022016e1e459457679df5b9434ae23f474b3e8d2a70bd6b5dbe692ba16da01f1fb0a", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d", - "wx" : "49c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377a", - "wy" : "00efc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d", + "wx": "49c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377a", + "wy": "00efc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEScGX3ICtHaR6Q0K5OJPo4fsLuU/DOoPn\ng8ALJMeBN3rvwg2pK6x2KVH3JHS+zHNNTMIrqBuJXigv2sTfevDzfQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000449c197dc80ad1da47a4342b93893e8e1fb0bb94fc33a83e783c00b24c781377aefc20da92bac762951f72474becc734d4cc22ba81b895e282fdac4df7af0f37d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEScGX3ICtHaR6Q0K5OJPo4fsLuU/DOoPn\ng8ALJMeBN3rvwg2pK6x2KVH3JHS+zHNNTMIrqBuJXigv2sTfevDzfQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 406, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 406, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202252d685e831b6cf095e4f0535eeaf0ddd3bfa91c210c9d9dc17224702eaf88f", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202252d685e831b6cf095e4f0535eeaf0ddd3bfa91c210c9d9dc17224702eaf88f", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c", - "wx" : "00d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe", - "wy" : "7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c", + "wx": "00d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe", + "wy": "7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2MtoUXthalZACqOGhjXlS29plZii9hZ3\nV2VJgLr2rL5+yM9EnISaoDRhow762kFFPFfG5vvJO7xvpJrabcBVXA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004d8cb68517b616a56400aa3868635e54b6f699598a2f6167757654980baf6acbe7ec8cf449c849aa03461a30efada41453c57c6e6fbc93bbc6fa49ada6dc0555c", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2MtoUXthalZACqOGhjXlS29plZii9hZ3\nV2VJgLr2rL5+yM9EnISaoDRhow762kFFPFfG5vvJO7xvpJrabcBVXA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 407, - "comment" : "edge case for u1", - "flags" : [ + "tcId": 407, + "comment": "edge case for u1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022075135abd7c425b60371a477f09ce0f274f64a8c6b061a07b5d63e93c65046c53", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022075135abd7c425b60371a477f09ce0f274f64a8c6b061a07b5d63e93c65046c53", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750", - "wx" : "030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3", - "wy" : "00b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750", + "wx": "030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3", + "wy": "00b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAwcT+2Pyqm/iyt8bIO/CWcd0Rdr6h9rD\nmLhAZco0ffOyJ4GN4aObWJywcdg+UxfMzcIzjlHjEv4x2Nw0pIAXUA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004030713fb63f2aa6fe2cadf1b20efc259c77445dafa87dac398b84065ca347df3b227818de1a39b589cb071d83e5317cccdc2338e51e312fe31d8dc34a4801750", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAwcT+2Pyqm/iyt8bIO/CWcd0Rdr6h9rD\nmLhAZco0ffOyJ4GN4aObWJywcdg+UxfMzcIzjlHjEv4x2Nw0pIAXUA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 408, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 408, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950", - "wx" : "00babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7", - "wy" : "252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950", + "wx": "00babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7", + "wy": "252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEurs2d7CVWALY6SmkE1VkDq8eoTU/incT\nMcSUbjSAr6clLxlsh+09KlnTsbVZE3/tABP+zvwZ+1qSaCubylG5UA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004babb3677b0955802d8e929a41355640eaf1ea1353f8a771331c4946e3480afa7252f196c87ed3d2a59d3b1b559137fed0013fecefc19fb5a92682b9bca51b950", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEurs2d7CVWALY6SmkE1VkDq8eoTU/incT\nMcSUbjSAr6clLxlsh+09KlnTsbVZE3/tABP+zvwZ+1qSaCubylG5UA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 409, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 409, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e888377ac6c71ac9dec3fdb9b56c9feaf0cfaca9f827fc5eb65fc3eac811210", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203e888377ac6c71ac9dec3fdb9b56c9feaf0cfaca9f827fc5eb65fc3eac811210", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9", - "wx" : "1aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60", - "wy" : "00bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9", + "wx": "1aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60", + "wy": "00bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGqsgGHk0cREaig6bFD/eAvyVkgeW06Y9\n4ym0JDlvumC75BMHBRdHkkQbMY06ox3+hXeCHptEbsVz0nLgNsTr6Q==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200041aab2018793471111a8a0e9b143fde02fc95920796d3a63de329b424396fba60bbe4130705174792441b318d3aa31dfe8577821e9b446ec573d272e036c4ebe9", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEGqsgGHk0cREaig6bFD/eAvyVkgeW06Y9\n4ym0JDlvumC75BMHBRdHkkQbMY06ox3+hXeCHptEbsVz0nLgNsTr6Q==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 410, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 410, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022030bbb794db588363b40679f6c182a50d3ce9679acdd3ffbe36d7813dacbdc818", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022030bbb794db588363b40679f6c182a50d3ce9679acdd3ffbe36d7813dacbdc818", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75", - "wx" : "008cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff", - "wy" : "47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75", + "wx": "008cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff", + "wy": "47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjLC5CUmcg+qAbNiFsd1GegEZ8GqIoCdu\nsM/aJ0U1qP9HtUKIM7w/LIv52QQRWM8zcYpplhzQFym8ABHR5YardQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200048cb0b909499c83ea806cd885b1dd467a0119f06a88a0276eb0cfda274535a8ff47b5428833bc3f2c8bf9d9041158cf33718a69961cd01729bc0011d1e586ab75", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjLC5CUmcg+qAbNiFsd1GegEZ8GqIoCdu\nsM/aJ0U1qP9HtUKIM7w/LIv52QQRWM8zcYpplhzQFym8ABHR5YardQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 411, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 411, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202c37fd995622c4fb7fffffffffffffffc7cee745110cb45ab558ed7c90c15a2f", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202c37fd995622c4fb7fffffffffffffffc7cee745110cb45ab558ed7c90c15a2f", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0", - "wx" : "008f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d", - "wy" : "3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0", + "wx": "008f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d", + "wy": "3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjwPPGkInK7FTJyMJP3Lm/urIXhcA6fvp\npqLdZC10v107iacYna2M91/CL28ViqJ/nCygDaynhb4zWPK9o4YsoA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200048f03cf1a42272bb1532723093f72e6feeac85e1700e9fbe9a6a2dd642d74bf5d3b89a7189dad8cf75fc22f6f158aa27f9c2ca00daca785be3358f2bda3862ca0", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjwPPGkInK7FTJyMJP3Lm/urIXhcA6fvp\npqLdZC10v107iacYna2M91/CL28ViqJ/nCygDaynhb4zWPK9o4YsoA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 412, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 412, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02207fd995622c4fb7ffffffffffffffffff5d883ffab5b32652ccdcaa290fccb97d", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02207fd995622c4fb7ffffffffffffffffff5d883ffab5b32652ccdcaa290fccb97d", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12", - "wx" : "44de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8ace", - "wy" : "00a2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12", + "wx": "44de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8ace", + "wy": "00a2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERN47nHpXqMnoIJUnU0IefZh7s9efcfAT\ngFyJfgGPis6iRgdYyPmNP9zhIalDZZ43LDJv/y5fwq5/o/edquE8Eg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000444de3b9c7a57a8c9e820952753421e7d987bb3d79f71f013805c897e018f8acea2460758c8f98d3fdce121a943659e372c326fff2e5fc2ae7fa3f79daae13c12", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAERN47nHpXqMnoIJUnU0IefZh7s9efcfAT\ngFyJfgGPis6iRgdYyPmNP9zhIalDZZ43LDJv/y5fwq5/o/edquE8Eg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 413, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 413, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304302207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc021f4cd53ba7608fffffffffffffffffffff9e5cf143e2539626190a3ab09cce47", - "result" : "valid" + "msg": "313233343030", + "sig": "304302207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc021f4cd53ba7608fffffffffffffffffffff9e5cf143e2539626190a3ab09cce47", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204", - "wx" : "6fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a", - "wy" : "0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204", + "wx": "6fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a", + "wy": "0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEb7iytI4zAxJorWpRdITciDnqkPZmnqDH\nrDIz4qwxOUoKyLvn9zwv9N+ZeHJ6wd/C/VhkfSDzH5kQUxa2RnHyBA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200046fb8b2b48e33031268ad6a517484dc8839ea90f6669ea0c7ac3233e2ac31394a0ac8bbe7f73c2ff4df9978727ac1dfc2fd58647d20f31f99105316b64671f204", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEb7iytI4zAxJorWpRdITciDnqkPZmnqDH\nrDIz4qwxOUoKyLvn9zwv9N+ZeHJ6wd/C/VhkfSDzH5kQUxa2RnHyBA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 414, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 414, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205622c4fb7fffffffffffffffffffffff928a8f1c7ac7bec1808b9f61c01ec327", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02205622c4fb7fffffffffffffffffffffff928a8f1c7ac7bec1808b9f61c01ec327", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c", - "wx" : "00bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6", - "wy" : "00f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c", + "wx": "00bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6", + "wy": "00f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvqcRIqBIaT6QX/YCs8+d0Yr2m5/J2EMd\nKx3Sa5Qsleb0PHuLletiCCwS2529p/445Fy+SkiGkH+4G9sMXqkkbA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004bea71122a048693e905ff602b3cf9dd18af69b9fc9d8431d2b1dd26b942c95e6f43c7b8b95eb62082c12db9dbda7fe38e45cbe4a4886907fb81bdb0c5ea9246c", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEvqcRIqBIaT6QX/YCs8+d0Yr2m5/J2EMd\nKx3Sa5Qsleb0PHuLletiCCwS2529p/445Fy+SkiGkH+4G9sMXqkkbA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 415, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 415, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022044104104104104104104104104104103b87853fd3b7d3f8e175125b4382f25ed", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc022044104104104104104104104104104103b87853fd3b7d3f8e175125b4382f25ed", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391", - "wx" : "00da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156", - "wy" : "00e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391", + "wx": "00da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156", + "wy": "00e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2pGMcxugaiDLlO8zt3jpgaQEowXxlB/j\nNma0WwM1MVbiuyaU9XW0UYO+eOXJtSEL879Ij9TIKUUW2JVyyk9TkQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004da918c731ba06a20cb94ef33b778e981a404a305f1941fe33666b45b03353156e2bb2694f575b45183be78e5c9b5210bf3bf488fd4c8294516d89572ca4f5391", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE2pGMcxugaiDLlO8zt3jpgaQEowXxlB/j\nNma0WwM1MVbiuyaU9XW0UYO+eOXJtSEL879Ij9TIKUUW2JVyyk9TkQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 416, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 416, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202739ce739ce739ce739ce739ce739ce705560298d1f2f08dc419ac273a5b54d9", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202739ce739ce739ce739ce739ce739ce705560298d1f2f08dc419ac273a5b54d9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5", - "wx" : "3007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d", - "wy" : "5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5", + "wx": "3007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d", + "wy": "5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMAfpLDk32t55ZN+jWw7/Ax9+sCrtCgMU\nQREGzetw/j1adUb8BVKZeyDj1vQT514stm4RYyJpcRS3m6xzS/xNxQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200043007e92c3937dade7964dfa35b0eff031f7eb02aed0a0314411106cdeb70fe3d5a7546fc0552997b20e3d6f413e75e2cb66e116322697114b79bac734bfc4dc5", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEMAfpLDk32t55ZN+jWw7/Ax9+sCrtCgMU\nQREGzetw/j1adUb8BVKZeyDj1vQT514stm4RYyJpcRS3m6xzS/xNxQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 417, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 417, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02204888888888888888888888888888888831c83ae82ebe0898776b4c69d11f88de", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02204888888888888888888888888888888831c83ae82ebe0898776b4c69d11f88de", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567", - "wx" : "60e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9b", - "wy" : "00d2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567", + "wx": "60e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9b", + "wy": "00d2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYOc071Yk08vw3dN1ARvWY9bWrrxkTrWZ\n/fmNvc0YzpvS2Qs6wx8TmvgyzM9sy7ssbqEfqXNw3JkG2kdNfYp1Zw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000460e734ef5624d3cbf0ddd375011bd663d6d6aebc644eb599fdf98dbdcd18ce9bd2d90b3ac31f139af832cccf6ccbbb2c6ea11fa97370dc9906da474d7d8a7567", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYOc071Yk08vw3dN1ARvWY9bWrrxkTrWZ\n/fmNvc0YzpvS2Qs6wx8TmvgyzM9sy7ssbqEfqXNw3JkG2kdNfYp1Zw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 418, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 418, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206492492492492492492492492492492406dd3a19b8d5fb875235963c593bd2d3", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206492492492492492492492492492492406dd3a19b8d5fb875235963c593bd2d3", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c", - "wx" : "0085a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba337", - "wy" : "69744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c", + "wx": "0085a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba337", + "wy": "69744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEhakA6XhY9pPAt9+iYeOA2tbqBG0fZd3u\n7dX32K8LozdpdE0VrdT2wLw7DaKuyTs0y4xl+TQN33TnsACe7szOPA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000485a900e97858f693c0b7dfa261e380dad6ea046d1f65ddeeedd5f7d8af0ba33769744d15add4f6c0bc3b0da2aec93b34cb8c65f9340ddf74e7b0009eeeccce3c", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEhakA6XhY9pPAt9+iYeOA2tbqBG0fZd3u\n7dX32K8LozdpdE0VrdT2wLw7DaKuyTs0y4xl+TQN33TnsACe7szOPA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 419, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 419, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b15", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02206aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b15", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed", - "wx" : "38066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046", - "wy" : "00a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed", + "wx": "38066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046", + "wy": "00a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOAZvddiO/EyT3jb0ngN7I0zBix3lYIdQ\npiyrA0VAEEaj6EvtjPy4Ge9NVQRE8s5LZRdmtp4uKQH4iDb/kANP7Q==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000438066f75d88efc4c93de36f49e037b234cc18b1de5608750a62cab0345401046a3e84bed8cfcb819ef4d550444f2ce4b651766b69e2e2901f88836ff90034fed", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOAZvddiO/EyT3jb0ngN7I0zBix3lYIdQ\npiyrA0VAEEaj6EvtjPy4Ge9NVQRE8s5LZRdmtp4uKQH4iDb/kANP7Q==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 420, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 420, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02202aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3e3a49a23a6d8abe95461f8445676b17", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89", - "wx" : "0098f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabf", - "wy" : "00a33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89", + "wx": "0098f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabf", + "wy": "00a33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmPaBd9yVwbTL+lJFSIylI6fVYpRw0DXW\nIaRDxy85qr+jPSlUb6HGSPLH1cz3DPHOSrebXbGsBZ2+zQaNvf8biQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000498f68177dc95c1b4cbfa5245488ca523a7d5629470d035d621a443c72f39aabfa33d29546fa1c648f2c7d5ccf70cf1ce4ab79b5db1ac059dbecd068dbdff1b89", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmPaBd9yVwbTL+lJFSIylI6fVYpRw0DXW\nIaRDxy85qr+jPSlUb6HGSPLH1cz3DPHOSrebXbGsBZ2+zQaNvf8biQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 421, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 421, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc02203ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191", - "wx" : "5c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277", - "wy" : "00e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191", + "wx": "5c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277", + "wy": "00e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXCu/ojybmtB/A4qom0kwvyZ9lAHkJV3p\n6NoKUHjsgnfj6IKjHV5qN54Hk5g8ze05uVxDU6sv8B6lNpukewwxkQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200045c2bbfa23c9b9ad07f038aa89b4930bf267d9401e4255de9e8da0a5078ec8277e3e882a31d5e6a379e0793983ccded39b95c4353ab2ff01ea5369ba47b0c3191", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEXCu/ojybmtB/A4qom0kwvyZ9lAHkJV3p\n6NoKUHjsgnfj6IKjHV5qN54Hk5g8ze05uVxDU6sv8B6lNpukewwxkQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 422, - "comment" : "edge case for u2", - "flags" : [ + "tcId": 422, + "comment": "edge case for u2", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220185ddbca6dac41b1da033cfb60c152869e74b3cd66e9ffdf1b6bc09ed65ee40c", - "result" : "valid" + "msg": "313233343030", + "sig": "304402207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0220185ddbca6dac41b1da033cfb60c152869e74b3cd66e9ffdf1b6bc09ed65ee40c", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc", - "wx" : "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385", - "wy" : "3547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc", + "wx": "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385", + "wy": "3547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4U1R4CCmESO215wGt6EzV+xrJVnul6Ptoprkz7EtcyEzA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a3853547808298448edb5e701ade84cd5fb1ac9567ba5e8fb68a6b933ec4b5cc84cc", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4U1R4CCmESO215wGt6EzV+xrJVnul6Ptoprkz7EtcyEzA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 423, - "comment" : "point duplication during verification", - "flags" : [ + "tcId": 423, + "comment": "point duplication during verification", + "flags": [ "PointDuplication" ], - "msg" : "313233343030", - "sig" : "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763", - "wx" : "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385", - "wy" : "00cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763", + "wx": "2ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385", + "wy": "00cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4XKuH99Z7txJKGP5SF7MqBOU2qYRaFwSXWUbME6SjN3Yw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200042ea7133432339c69d27f9b267281bd2ddd5f19d6338d400a05cd3647b157a385cab87f7d67bb7124a18fe5217b32a04e536a9845a1704975946cc13a4a337763", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAELqcTNDIznGnSf5smcoG9Ld1fGdYzjUAK\nBc02R7FXo4XKuH99Z7txJKGP5SF7MqBOU2qYRaFwSXWUbME6SjN3Yw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 424, - "comment" : "duplication bug", - "flags" : [ + "tcId": 424, + "comment": "duplication bug", + "flags": [ "PointDuplication" ], - "msg" : "313233343030", - "sig" : "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022032b0d10d8d0e04bc8d4d064d270699e87cffc9b49c5c20730e1c26f6105ddcda022029ed3d67b3d505be95580d77d5b792b436881179b2b6b2e04c5fe592d38d82d9", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff", - "wx" : "008aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e", - "wy" : "1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff", + "wx": "008aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e", + "wy": "1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiqLGT6nGQ3Vjq/vL0AsgSNSMGMFSoqb0\nkDbedkfr6C4c5kOHmVxooGD6O8A5mwXMBu7H1Zj3UEGkkX5pK39R/w==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200048aa2c64fa9c6437563abfbcbd00b2048d48c18c152a2a6f49036de7647ebe82e1ce64387995c68a060fa3bc0399b05cc06eec7d598f75041a4917e692b7f51ff", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEiqLGT6nGQ3Vjq/vL0AsgSNSMGMFSoqb0\nkDbedkfr6C4c5kOHmVxooGD6O8A5mwXMBu7H1Zj3UEGkkX5pK39R/w==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 425, - "comment" : "comparison with point at infinity ", - "flags" : [ + "tcId": 425, + "comment": "comparison with point at infinity ", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0022033333333333333333333333333333332f222f8faefdb533f265d461c29a47373", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0022033333333333333333333333333333332f222f8faefdb533f265d461c29a47373", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd", - "wx" : "391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71f", - "wy" : "00dd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd", + "wx": "391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71f", + "wy": "00dd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEORQn/37ngBPBSux9lqigYiCSmKeDg16U\n/WVJ1QL/9x/dZiTsNDrZ/PTZhyGB5Z+EL5ukzMrgmmwJcvtqxrTGvQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004391427ff7ee78013c14aec7d96a8a062209298a783835e94fd6549d502fff71fdd6624ec343ad9fcf4d9872181e59f842f9ba4cccae09a6c0972fb6ac6b4c6bd", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEORQn/37ngBPBSux9lqigYiCSmKeDg16U\n/WVJ1QL/9x/dZiTsNDrZ/PTZhyGB5Z+EL5ukzMrgmmwJcvtqxrTGvQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 426, - "comment" : "extreme value for k and edgecase s", - "flags" : [ + "tcId": 426, + "comment": "extreme value for k and edgecase s", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e", - "wx" : "00e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138e", - "wy" : "00c1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e", + "wx": "00e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138e", + "wy": "00c1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE52K4ohm08YAhnMepBZJF5JYb0ZHAOJl4\nnHo0uJ6ME47BUz7wQZu3N24L/ekxnRCgaWh5HZ6g7tnBzmNFrtl1ng==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004e762b8a219b4f180219cc7a9059245e4961bd191c03899789c7a34b89e8c138ec1533ef0419bb7376e0bfde9319d10a06968791d9ea0eed9c1ce6345aed9759e", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE52K4ohm08YAhnMepBZJF5JYb0ZHAOJl4\nnHo0uJ6ME47BUz7wQZu3N24L/ekxnRCgaWh5HZ6g7tnBzmNFrtl1ng==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 427, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 427, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175", - "wx" : "009aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952", - "wy" : "00fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175", + "wx": "009aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952", + "wy": "00fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmu2w0oHbFk4TAADFaX+uDzBe+Ei+b/+0\nOsWT+7lQ6VL6b2MzWb3NgrVrC5+WWwN3idRrmoFBt5GyrvpxP5bBdQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200049aedb0d281db164e130000c5697fae0f305ef848be6fffb43ac593fbb950e952fa6f633359bdcd82b56b0b9f965b037789d46b9a8141b791b2aefa713f96c175", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEmu2w0oHbFk4TAADFaX+uDzBe+Ei+b/+0\nOsWT+7lQ6VL6b2MzWb3NgrVrC5+WWwN3idRrmoFBt5GyrvpxP5bBdQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 428, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 428, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd", - "wx" : "008ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee", - "wy" : "1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd", + "wx": "008ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee", + "wy": "1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEitRF22KBYmDk5of9GITki5/AY20DFUfW\nMxXnkuGb+u4d5k+Z1fHNi27Jyw94emVK6GmTuj2xAI70PP8GhMsivQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200048ad445db62816260e4e687fd1884e48b9fc0636d031547d63315e792e19bfaee1de64f99d5f1cd8b6ec9cb0f787a654ae86993ba3db1008ef43cff0684cb22bd", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEitRF22KBYmDk5of9GITki5/AY20DFUfW\nMxXnkuGb+u4d5k+Z1fHNi27Jyw94emVK6GmTuj2xAI70PP8GhMsivQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 429, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 429, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566", - "wx" : "1f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32", - "wy" : "00e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566", + "wx": "1f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32", + "wy": "00e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH1eZyVvokGOyTybkDLkowahop2+wCUYH\n6AQ9tAnJHDLnVyToE6QZHjqDkAfwji6Jc4iwbUoA3m3mDlNtkfq1Zg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200041f5799c95be89063b24f26e40cb928c1a868a76fb0094607e8043db409c91c32e75724e813a4191e3a839007f08e2e897388b06d4a00de6de60e536d91fab566", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEH1eZyVvokGOyTybkDLkowahop2+wCUYH\n6AQ9tAnJHDLnVyToE6QZHjqDkAfwji6Jc4iwbUoA3m3mDlNtkfq1Zg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 430, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 430, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d", - "wx" : "00a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc", - "wy" : "28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d", + "wx": "00a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc", + "wy": "28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEozMaThtCI+wsAn7dSCySihTtNY2T8dQh\nfTmr9p/LXMwo1oTSqqvNY4N3XKpiOd4m1MaTe7YD7LQZYIL0z/1QnQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004a3331a4e1b4223ec2c027edd482c928a14ed358d93f1d4217d39abf69fcb5ccc28d684d2aaabcd6383775caa6239de26d4c6937bb603ecb4196082f4cffd509d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEozMaThtCI+wsAn7dSCySihTtNY2T8dQh\nfTmr9p/LXMwo1oTSqqvNY4N3XKpiOd4m1MaTe7YD7LQZYIL0z/1QnQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 431, - "comment" : "extreme value for k", - "flags" : [ + "tcId": 431, + "comment": "extreme value for k", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee502200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee502200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d", - "wx" : "3f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb24818", - "wy" : "5ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d", + "wx": "3f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb24818", + "wy": "5ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEPzlSGZd0x885s4tmyxBCpiYNhoCAOEXk\n1DOtujuySBhepJW2jLx+1Bc+5jyQQtxQJiXH634h+wLKmpEU4KOhjQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200043f3952199774c7cf39b38b66cb1042a6260d8680803845e4d433adba3bb248185ea495b68cbc7ed4173ee63c9042dc502625c7eb7e21fb02ca9a9114e0a3a18d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEPzlSGZd0x885s4tmyxBCpiYNhoCAOEXk\n1DOtujuySBhepJW2jLx+1Bc+5jyQQtxQJiXH634h+wLKmpEU4KOhjQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 432, - "comment" : "extreme value for k and edgecase s", - "flags" : [ + "tcId": 432, + "comment": "extreme value for k and edgecase s", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022055555555555555555555555555555554e8e4f44ce51835693ff0ca2ef01215c0", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698", - "wx" : "00cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e", - "wy" : "054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698", + "wx": "00cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e", + "wy": "054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzfuMD0IuFE4TfCQSyGwXH1/j+j9bu1RO\nkHYojzzteG4FT9ByG3fBHHm+rLPJQhGwoZvaCGUu/q+SUTo7ChY2mA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004cdfb8c0f422e144e137c2412c86c171f5fe3fa3f5bbb544e9076288f3ced786e054fd0721b77c11c79beacb3c94211b0a19bda08652efeaf92513a3b0a163698", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEzfuMD0IuFE4TfCQSyGwXH1/j+j9bu1RO\nkHYojzzteG4FT9ByG3fBHHm+rLPJQhGwoZvaCGUu/q+SUTo7ChY2mA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 433, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 433, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d", - "wx" : "73598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3", - "wy" : "00cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d", + "wx": "73598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3", + "wy": "00cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEc1mKahxoJ4+mv9DOQGTmgjW8HA9rIKko\nEIvjNnMPh+PLrmElGbUDLsyFrtgRJxqV/nk51dNGAUC6MY9NFKujHQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000473598a6a1c68278fa6bfd0ce4064e68235bc1c0f6b20a928108be336730f87e3cbae612519b5032ecc85aed811271a95fe7939d5d3460140ba318f4d14aba31d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEc1mKahxoJ4+mv9DOQGTmgjW8HA9rIKko\nEIvjNnMPh+PLrmElGbUDLsyFrtgRJxqV/nk51dNGAUC6MY9NFKujHQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 434, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 434, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d", - "wx" : "58debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a1", - "wy" : "6773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d", + "wx": "58debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a1", + "wy": "6773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWN69mn7iydWRMkeKVECuTV1+1Dcwg2n5\nLqhsghg/EKFnc+dvXtv02g5PG9/6wPVyV+HfpGWEKTEwmiQkX9pqXQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000458debd9a7ee2c9d59132478a5440ae4d5d7ed437308369f92ea86c82183f10a16773e76f5edbf4da0e4f1bdffac0f57257e1dfa465842931309a24245fda6a5d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEWN69mn7iydWRMkeKVECuTV1+1Dcwg2n5\nLqhsghg/EKFnc+dvXtv02g5PG9/6wPVyV+HfpGWEKTEwmiQkX9pqXQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 435, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 435, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022066666666666666666666666666666665e445f1f5dfb6a67e4cba8c385348e6e7", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f", - "wx" : "008b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b", - "wy" : "00950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f", + "wx": "008b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b", + "wy": "00950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEi5BN5HlnNAxfjDVypyCSTvdXhjf+qxlJ\nrLJBpaasP1uVCQRJb5gksdY/MxO64huJ+uia/fyBG17OA/1aowGGTw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200048b904de47967340c5f8c3572a720924ef7578637feab1949acb241a5a6ac3f5b950904496f9824b1d63f3313bae21b89fae89afdfc811b5ece03fd5aa301864f", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEi5BN5HlnNAxfjDVypyCSTvdXhjf+qxlJ\nrLJBpaasP1uVCQRJb5gksdY/MxO64huJ+uia/fyBG17OA/1aowGGTw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 436, - "comment" : "extreme value for k and s^-1", - "flags" : [ + "tcId": 436, + "comment": "extreme value for k and s^-1", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798022049249249249249249249249249249248c79facd43214c011123c1b03a93412a5", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b", - "wx" : "00f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a", - "wy" : "346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b", + "wx": "00f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a", + "wy": "346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE9IkrbVJcdx4DXyolJwjzeE5II4YEtPlN\nxW6qHlRtlBo0axqgvOaLHFDltS9Qn7VSLlwl4Ci8j4Y0Au23vK2LGw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004f4892b6d525c771e035f2a252708f3784e48238604b4f94dc56eaa1e546d941a346b1aa0bce68b1c50e5b52f509fb5522e5c25e028bc8f863402edb7bcad8b1b", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE9IkrbVJcdx4DXyolJwjzeE5II4YEtPlN\nxW6qHlRtlBo0axqgvOaLHFDltS9Qn7VSLlwl4Ci8j4Y0Au23vK2LGw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 437, - "comment" : "extreme value for k", - "flags" : [ + "tcId": 437, + "comment": "extreme value for k", + "flags": [ "ArithmeticError" ], - "msg" : "313233343030", - "sig" : "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b", - "result" : "valid" + "msg": "313233343030", + "sig": "3044022079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802200eb10e5ab95f2f275348d82ad2e4d7949c8193800d8c9c75df58e343f0ebba7b", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", - "wx" : "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", - "wy" : "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "wx": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "wy": "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuA==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuA==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 438, - "comment" : "public key shares x-coordinate with generator", - "flags" : [ + "tcId": 438, + "comment": "public key shares x-coordinate with generator", + "flags": [ "PointDuplication" ], - "msg" : "313233343030", - "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result": "invalid" }, { - "tcId" : 439, - "comment" : "public key shares x-coordinate with generator", - "flags" : [ + "tcId": 439, + "comment": "public key shares x-coordinate with generator", + "flags": [ "PointDuplication" ], - "msg" : "313233343030", - "sig" : "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", - "wx" : "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", - "wy" : "00b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", + "wx": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", + "wy": "00b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5i3xSWI2Vw7mqJbBAPx7vdXAuhLt1l6q+ZjuC9vBO8ndw==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798b7c52588d95c3b9aa25b0403f1eef75702e84bb7597aabe663b82f6f04ef2777", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeb5mfvncu6xVoGKVzocLBwKb/NstzijZ\nWfKBWxb4F5i3xSWI2Vw7mqJbBAPx7vdXAuhLt1l6q+ZjuC9vBO8ndw==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 440, - "comment" : "public key shares x-coordinate with generator", - "flags" : [ + "tcId": 440, + "comment": "public key shares x-coordinate with generator", + "flags": [ "PointDuplication" ], - "msg" : "313233343030", - "sig" : "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", - "result" : "invalid" + "msg": "313233343030", + "sig": "3045022100bb5a52f42f9c9261ed4361f59422a1e30036e7c32b270c8807a419feca60502302202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result": "invalid" }, { - "tcId" : 441, - "comment" : "public key shares x-coordinate with generator", - "flags" : [ + "tcId": 441, + "comment": "public key shares x-coordinate with generator", + "flags": [ "PointDuplication" ], - "msg" : "313233343030", - "sig" : "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", - "result" : "invalid" + "msg": "313233343030", + "sig": "3044022044a5ad0bd0636d9e12bc9e0a6bdd5e1bba77f523842193b3b82e448e05d5f11e02202492492492492492492492492492492463cfd66a190a6008891e0d81d49a0952", + "result": "invalid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152", - "wx" : "782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963", - "wy" : "00af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152", + "wx": "782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963", + "wy": "00af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeCyO0X47Kng7VGTzOwllKnHGeOBexR6E\n4rz8Zjo96WOvmstCgLjH98QvTvmrpiRewewXEv04oPqWQY2M1qphUg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004782c8ed17e3b2a783b5464f33b09652a71c678e05ec51e84e2bcfc663a3de963af9acb4280b8c7f7c42f4ef9aba6245ec1ec1712fd38a0fa96418d8cd6aa6152", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEeCyO0X47Kng7VGTzOwllKnHGeOBexR6E\n4rz8Zjo96WOvmstCgLjH98QvTvmrpiRewewXEv04oPqWQY2M1qphUg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 442, - "comment" : "pseudorandom signature", - "flags" : [ + "tcId": 442, + "comment": "pseudorandom signature", + "flags": [ "ValidSignature" ], - "msg" : "", - "sig" : "3045022100f80ae4f96cdbc9d853f83d47aae225bf407d51c56b7776cd67d0dc195d99a9dc02204cfc1d941e08cb9aceadde0f4ccead76b30d332fc442115d50e673e28686b70b", - "result" : "valid" + "msg": "", + "sig": "3045022100f80ae4f96cdbc9d853f83d47aae225bf407d51c56b7776cd67d0dc195d99a9dc02204cfc1d941e08cb9aceadde0f4ccead76b30d332fc442115d50e673e28686b70b", + "result": "valid" }, { - "tcId" : 443, - "comment" : "pseudorandom signature", - "flags" : [ + "tcId": 443, + "comment": "pseudorandom signature", + "flags": [ "ValidSignature" ], - "msg" : "4d7367", - "sig" : "30440220109cd8ae0374358984a8249c0a843628f2835ffad1df1a9a69aa2fe72355545c02205390ff250ac4274e1cb25cd6ca6491f6b91281e32f5b264d87977aed4a94e77b", - "result" : "valid" + "msg": "4d7367", + "sig": "30440220109cd8ae0374358984a8249c0a843628f2835ffad1df1a9a69aa2fe72355545c02205390ff250ac4274e1cb25cd6ca6491f6b91281e32f5b264d87977aed4a94e77b", + "result": "valid" }, { - "tcId" : 444, - "comment" : "pseudorandom signature", - "flags" : [ + "tcId": 444, + "comment": "pseudorandom signature", + "flags": [ "ValidSignature" ], - "msg" : "313233343030", - "sig" : "3045022100d035ee1f17fdb0b2681b163e33c359932659990af77dca632012b30b27a057b302201939d9f3b2858bc13e3474cb50e6a82be44faa71940f876c1cba4c3e989202b6", - "result" : "valid" + "msg": "313233343030", + "sig": "3045022100d035ee1f17fdb0b2681b163e33c359932659990af77dca632012b30b27a057b302201939d9f3b2858bc13e3474cb50e6a82be44faa71940f876c1cba4c3e989202b6", + "result": "valid" }, { - "tcId" : 445, - "comment" : "pseudorandom signature", - "flags" : [ + "tcId": 445, + "comment": "pseudorandom signature", + "flags": [ "ValidSignature" ], - "msg" : "0000000000000000000000000000000000000000", - "sig" : "304402204f053f563ad34b74fd8c9934ce59e79c2eb8e6eca0fef5b323ca67d5ac7ed23802204d4b05daa0719e773d8617dce5631c5fd6f59c9bdc748e4b55c970040af01be5", - "result" : "valid" + "msg": "0000000000000000000000000000000000000000", + "sig": "304402204f053f563ad34b74fd8c9934ce59e79c2eb8e6eca0fef5b323ca67d5ac7ed23802204d4b05daa0719e773d8617dce5631c5fd6f59c9bdc748e4b55c970040af01be5", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1", - "wx" : "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff", - "wy" : "01060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1", + "wx": "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff", + "wy": "01060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv8AAAABBgSS1aVnPg8l2NUPt+WMSdhtRtQhaVXgqj1A4Q==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff00000001060492d5a5673e0f25d8d50fb7e58c49d86d46d4216955e0aa3d40e1", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv8AAAABBgSS1aVnPg8l2NUPt+WMSdhtRtQhaVXgqj1A4Q==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 446, - "comment" : "y-coordinate of the public key is small", - "flags" : [ + "tcId": 446, + "comment": "y-coordinate of the public key is small", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "304402206d6a4f556ccce154e7fb9f19e76c3deca13d59cc2aeb4ecad968aab2ded45965022053b9fa74803ede0fc4441bf683d56c564d3e274e09ccf47390badd1471c05fb7", - "result" : "valid" + "msg": "4d657373616765", + "sig": "304402206d6a4f556ccce154e7fb9f19e76c3deca13d59cc2aeb4ecad968aab2ded45965022053b9fa74803ede0fc4441bf683d56c564d3e274e09ccf47390badd1471c05fb7", + "result": "valid" }, { - "tcId" : 447, - "comment" : "y-coordinate of the public key is small", - "flags" : [ + "tcId": 447, + "comment": "y-coordinate of the public key is small", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3044022100aad503de9b9fd66b948e9acf596f0a0e65e700b28b26ec56e6e45e846489b3c4021f0ddc3a2f89abb817bb85c062ce02f823c63fc26b269e0bc9b84d81a5aa123d", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3044022100aad503de9b9fd66b948e9acf596f0a0e65e700b28b26ec56e6e45e846489b3c4021f0ddc3a2f89abb817bb85c062ce02f823c63fc26b269e0bc9b84d81a5aa123d", + "result": "valid" }, { - "tcId" : 448, - "comment" : "y-coordinate of the public key is small", - "flags" : [ + "tcId": 448, + "comment": "y-coordinate of the public key is small", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "30450221009182cebd3bb8ab572e167174397209ef4b1d439af3b200cdf003620089e43225022054477c982ea019d2e1000497fc25fcee1bccae55f2ac27530ae53b29c4b356a4", - "result" : "valid" + "msg": "4d657373616765", + "sig": "30450221009182cebd3bb8ab572e167174397209ef4b1d439af3b200cdf003620089e43225022054477c982ea019d2e1000497fc25fcee1bccae55f2ac27530ae53b29c4b356a4", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e", - "wx" : "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff", - "wy" : "00fffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e", + "wx": "6e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40caff", + "wy": "00fffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv/////++fttKlqYwfDaJyrwSBpztieSuSvelqoeVcK7Tg==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200046e823555452914099182c6b2c1d6f0b5d28d50ccd005af2ce1bba541aa40cafffffffffef9fb6d2a5a98c1f0da272af0481a73b62792b92bde96aa1e55c2bb4e", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEboI1VUUpFAmRgsaywdbwtdKNUMzQBa8s\n4bulQapAyv/////++fttKlqYwfDaJyrwSBpztieSuSvelqoeVcK7Tg==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 449, - "comment" : "y-coordinate of the public key is large", - "flags" : [ + "tcId": 449, + "comment": "y-coordinate of the public key is large", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "304402203854a3998aebdf2dbc28adac4181462ccac7873907ab7f212c42db0e69b56ed802203ed3f6b8a388d02f3e4df9f2ae9c1bd2c3916a686460dffcd42909cd7f82058e", - "result" : "valid" + "msg": "4d657373616765", + "sig": "304402203854a3998aebdf2dbc28adac4181462ccac7873907ab7f212c42db0e69b56ed802203ed3f6b8a388d02f3e4df9f2ae9c1bd2c3916a686460dffcd42909cd7f82058e", + "result": "valid" }, { - "tcId" : 450, - "comment" : "y-coordinate of the public key is large", - "flags" : [ + "tcId": 450, + "comment": "y-coordinate of the public key is large", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100e94dbdc38795fe5c904d8f16d969d3b587f0a25d2de90b6d8c5c53ff887e360702207a947369c164972521bb8af406813b2d9f94d2aeaa53d4c215aaa0a2578a2c5d", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100e94dbdc38795fe5c904d8f16d969d3b587f0a25d2de90b6d8c5c53ff887e360702207a947369c164972521bb8af406813b2d9f94d2aeaa53d4c215aaa0a2578a2c5d", + "result": "valid" }, { - "tcId" : 451, - "comment" : "y-coordinate of the public key is large", - "flags" : [ + "tcId": 451, + "comment": "y-coordinate of the public key is large", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3044022049fc102a08ca47b60e0858cd0284d22cddd7233f94aaffbb2db1dd2cf08425e102205b16fca5a12cdb39701697ad8e39ffd6bdec0024298afaa2326aea09200b14d6", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3044022049fc102a08ca47b60e0858cd0284d22cddd7233f94aaffbb2db1dd2cf08425e102205b16fca5a12cdb39701697ad8e39ffd6bdec0024298afaa2326aea09200b14d6", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d", - "wx" : "013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0", - "wy" : "00f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d", + "wx": "013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0", + "wy": "00f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAAAAAT/SIkjWTZX3PCm0irSGMYUL5QP9\nAPhGi18PcOD27nqkO8LG/SWx2CaSQcvdnbsNrJbcliMfQwcF+DhxfQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004000000013fd22248d64d95f73c29b48ab48631850be503fd00f8468b5f0f70e0f6ee7aa43bc2c6fd25b1d8269241cbdd9dbb0dac96dc96231f430705f838717d", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEAAAAAT/SIkjWTZX3PCm0irSGMYUL5QP9\nAPhGi18PcOD27nqkO8LG/SWx2CaSQcvdnbsNrJbcliMfQwcF+DhxfQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 452, - "comment" : "x-coordinate of the public key is small", - "flags" : [ + "tcId": 452, + "comment": "x-coordinate of the public key is small", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3044022041efa7d3f05a0010675fcb918a45c693da4b348df21a59d6f9cd73e0d831d67a02204454ada693e5e26b7bd693236d340f80545c834577b6f73d378c7bcc534244da", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3044022041efa7d3f05a0010675fcb918a45c693da4b348df21a59d6f9cd73e0d831d67a02204454ada693e5e26b7bd693236d340f80545c834577b6f73d378c7bcc534244da", + "result": "valid" }, { - "tcId" : 453, - "comment" : "x-coordinate of the public key is small", - "flags" : [ + "tcId": 453, + "comment": "x-coordinate of the public key is small", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100b615698c358b35920dd883eca625a6c5f7563970cdfc378f8fe0cee17092144c022025f47b326b5be1fb610b885153ea84d41eb4716be66a994e8779989df1c863d4", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100b615698c358b35920dd883eca625a6c5f7563970cdfc378f8fe0cee17092144c022025f47b326b5be1fb610b885153ea84d41eb4716be66a994e8779989df1c863d4", + "result": "valid" }, { - "tcId" : 454, - "comment" : "x-coordinate of the public key is small", - "flags" : [ + "tcId": 454, + "comment": "x-coordinate of the public key is small", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "304502210087cf8c0eb82d44f69c60a2ff5457d3aaa322e7ec61ae5aecfd678ae1c1932b0e02203add3b115815047d6eb340a3e008989eaa0f8708d1794814729094d08d2460d3", - "result" : "valid" + "msg": "4d657373616765", + "sig": "304502210087cf8c0eb82d44f69c60a2ff5457d3aaa322e7ec61ae5aecfd678ae1c1932b0e02203add3b115815047d6eb340a3e008989eaa0f8708d1794814729094d08d2460d3", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "0425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35", - "wx" : "25afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dffffffff", - "wy" : "00fa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "0425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35", + "wx": "25afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dffffffff", + "wy": "00fa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a0342000425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJa/WiayrrtZ8Hylt5ZQG+MVQ9XFGoLTs\nLJeHbf/////6RqduUgMi37xJHsTwzBl0IPxOpYg9j23VPDVLxPZ8NQ==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a0342000425afd689acabaed67c1f296de59406f8c550f57146a0b4ec2c97876dfffffffffa46a76e520322dfbc491ec4f0cc197420fc4ea5883d8f6dd53c354bc4f67c35", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEJa/WiayrrtZ8Hylt5ZQG+MVQ9XFGoLTs\nLJeHbf/////6RqduUgMi37xJHsTwzBl0IPxOpYg9j23VPDVLxPZ8NQ==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 455, - "comment" : "x-coordinate of the public key has many trailing 1's", - "flags" : [ + "tcId": 455, + "comment": "x-coordinate of the public key has many trailing 1's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3044022062f48ef71ace27bf5a01834de1f7e3f948b9dce1ca1e911d5e13d3b104471d8202205ea8f33f0c778972c4582080deda9b341857dd64514f0849a05f6964c2e34022", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3044022062f48ef71ace27bf5a01834de1f7e3f948b9dce1ca1e911d5e13d3b104471d8202205ea8f33f0c778972c4582080deda9b341857dd64514f0849a05f6964c2e34022", + "result": "valid" }, { - "tcId" : 456, - "comment" : "x-coordinate of the public key has many trailing 1's", - "flags" : [ + "tcId": 456, + "comment": "x-coordinate of the public key has many trailing 1's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100f6b0e2f6fe020cf7c0c20137434344ed7add6c4be51861e2d14cbda472a6ffb402206416c8dd3e5c5282b306e8dc8ff34ab64cc99549232d678d714402eb6ca7aa0f", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100f6b0e2f6fe020cf7c0c20137434344ed7add6c4be51861e2d14cbda472a6ffb402206416c8dd3e5c5282b306e8dc8ff34ab64cc99549232d678d714402eb6ca7aa0f", + "result": "valid" }, { - "tcId" : 457, - "comment" : "x-coordinate of the public key has many trailing 1's", - "flags" : [ + "tcId": 457, + "comment": "x-coordinate of the public key has many trailing 1's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100db09d8460f05eff23bc7e436b67da563fa4b4edb58ac24ce201fa8a358125057022046da116754602940c8999c8d665f786c50f5772c0a3cdbda075e77eabc64df16", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100db09d8460f05eff23bc7e436b67da563fa4b4edb58ac24ce201fa8a358125057022046da116754602940c8999c8d665f786c50f5772c0a3cdbda075e77eabc64df16", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "04d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff", - "wx" : "00d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb9", - "wy" : "3f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "04d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff", + "wx": "00d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb9", + "wy": "3f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a03420004d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0S5sZrZ3NMPITSYBz1013Al+J2N/CspK\nT9t0tqrdO7k/W9/4i9VzbfiY5pkAbtdQ8RzwfFhmzXrXDHEh/////w==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a03420004d12e6c66b67734c3c84d2601cf5d35dc097e27637f0aca4a4fdb74b6aadd3bb93f5bdff88bd5736df898e699006ed750f11cf07c5866cd7ad70c7121ffffffff", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0S5sZrZ3NMPITSYBz1013Al+J2N/CspK\nT9t0tqrdO7k/W9/4i9VzbfiY5pkAbtdQ8RzwfFhmzXrXDHEh/////w==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 458, - "comment" : "y-coordinate of the public key has many trailing 1's", - "flags" : [ + "tcId": 458, + "comment": "y-coordinate of the public key has many trailing 1's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "30440220592c41e16517f12fcabd98267674f974b588e9f35d35406c1a7bb2ed1d19b7b802203e65a06bd9f83caaeb7b00f2368d7e0dece6b12221269a9b5b765198f840a3a1", - "result" : "valid" + "msg": "4d657373616765", + "sig": "30440220592c41e16517f12fcabd98267674f974b588e9f35d35406c1a7bb2ed1d19b7b802203e65a06bd9f83caaeb7b00f2368d7e0dece6b12221269a9b5b765198f840a3a1", + "result": "valid" }, { - "tcId" : 459, - "comment" : "y-coordinate of the public key has many trailing 1's", - "flags" : [ + "tcId": 459, + "comment": "y-coordinate of the public key has many trailing 1's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100be0d70887d5e40821a61b68047de4ea03debfdf51cdf4d4b195558b959a032b202207d994b2d8f1dbbeb13534eb3f6e5dccd85f5c4133c27d9e64271b1826ce1f67d", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100be0d70887d5e40821a61b68047de4ea03debfdf51cdf4d4b195558b959a032b202207d994b2d8f1dbbeb13534eb3f6e5dccd85f5c4133c27d9e64271b1826ce1f67d", + "result": "valid" }, { - "tcId" : 460, - "comment" : "y-coordinate of the public key has many trailing 1's", - "flags" : [ + "tcId": 460, + "comment": "y-coordinate of the public key has many trailing 1's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100fae92dfcb2ee392d270af3a5739faa26d4f97bfd39ed3cbee4d29e26af3b206a02206c9ba37f9faa6a1fd3f65f23b4e853d4692a7274240a12db7ba3884830630d16", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100fae92dfcb2ee392d270af3a5739faa26d4f97bfd39ed3cbee4d29e26af3b206a02206c9ba37f9faa6a1fd3f65f23b4e853d4692a7274240a12db7ba3884830630d16", + "result": "valid" } ] }, { - "type" : "EcdsaBitcoinVerify", - "publicKey" : { - "type" : "EcPublicKey", - "curve" : "secp256k1", - "keySize" : 256, - "uncompressed" : "046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb", - "wx" : "6d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000", - "wy" : "00e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb" + "type": "EcdsaBitcoinVerify", + "publicKey": { + "type": "EcPublicKey", + "curve": "secp256k1", + "keySize": 256, + "uncompressed": "046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb", + "wx": "6d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000", + "wy": "00e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb" }, - "publicKeyDer" : "3056301006072a8648ce3d020106052b8104000a034200046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb", - "publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbUp/YNR3Sk8KqLve25U8fup5CUB+MWR1\nVmS8KAAAAADmWdNOTfONnoyeqt+6NmEsdpGVvobHeqw/NueLU4aA+w==\n-----END PUBLIC KEY-----\n", - "sha" : "SHA-256", - "tests" : [ + "publicKeyDer": "3056301006072a8648ce3d020106052b8104000a034200046d4a7f60d4774a4f0aa8bbdedb953c7eea7909407e3164755664bc2800000000e659d34e4df38d9e8c9eaadfba36612c769195be86c77aac3f36e78b538680fb", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEbUp/YNR3Sk8KqLve25U8fup5CUB+MWR1\nVmS8KAAAAADmWdNOTfONnoyeqt+6NmEsdpGVvobHeqw/NueLU4aA+w==\n-----END PUBLIC KEY-----\n", + "sha": "SHA-256", + "tests": [ { - "tcId" : 461, - "comment" : "x-coordinate of the public key has many trailing 0's", - "flags" : [ + "tcId": 461, + "comment": "x-coordinate of the public key has many trailing 0's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "30440220176a2557566ffa518b11226694eb9802ed2098bfe278e5570fe1d5d7af18a94302201291df6a0ed5fc0d15098e70bcf13a009284dfd0689d3bb4be6ceeb9be1487c4", - "result" : "valid" + "msg": "4d657373616765", + "sig": "30440220176a2557566ffa518b11226694eb9802ed2098bfe278e5570fe1d5d7af18a94302201291df6a0ed5fc0d15098e70bcf13a009284dfd0689d3bb4be6ceeb9be1487c4", + "result": "valid" }, { - "tcId" : 462, - "comment" : "x-coordinate of the public key has many trailing 0's", - "flags" : [ + "tcId": 462, + "comment": "x-coordinate of the public key has many trailing 0's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3044022060be20c3dbc162dd34d26780621c104bbe5dace630171b2daef0d826409ee5c20220427f7e4d889d549170bda6a9409fb1cb8b0e763d13eea7bd97f64cf41dc6e497", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3044022060be20c3dbc162dd34d26780621c104bbe5dace630171b2daef0d826409ee5c20220427f7e4d889d549170bda6a9409fb1cb8b0e763d13eea7bd97f64cf41dc6e497", + "result": "valid" }, { - "tcId" : 463, - "comment" : "x-coordinate of the public key has many trailing 0's", - "flags" : [ + "tcId": 463, + "comment": "x-coordinate of the public key has many trailing 0's", + "flags": [ "EdgeCasePublicKey" ], - "msg" : "4d657373616765", - "sig" : "3045022100edf03cf63f658883289a1a593d1007895b9f236d27c9c1f1313089aaed6b16ae02201a4dd6fc0814dc523d1fefa81c64fbf5e618e651e7096fccadbb94cd48e5e0cd", - "result" : "valid" + "msg": "4d657373616765", + "sig": "3045022100edf03cf63f658883289a1a593d1007895b9f236d27c9c1f1313089aaed6b16ae02201a4dd6fc0814dc523d1fefa81c64fbf5e618e651e7096fccadbb94cd48e5e0cd", + "result": "valid" } ] } diff --git a/include/xrpl/basics/README.md b/include/xrpl/basics/README.md index 544bc8aece..290bb7ad0c 100644 --- a/include/xrpl/basics/README.md +++ b/include/xrpl/basics/README.md @@ -4,37 +4,34 @@ Utility functions and classes. ripple/basic should contain no dependencies on other modules. +# Choosing a rippled container. -Choosing a rippled container. -============================= +- `std::vector` + - For ordered containers with most insertions or erases at the end. -* `std::vector` - * For ordered containers with most insertions or erases at the end. +- `std::deque` + - For ordered containers with most insertions or erases at the start or end. -* `std::deque` - * For ordered containers with most insertions or erases at the start or end. - -* `std::list` - * For ordered containers with inserts and erases to the middle. - * For containers with iterators stable over insert and erase. - * Generally slower and bigger than `std::vector` or `std::deque` except for +- `std::list` + - For ordered containers with inserts and erases to the middle. + - For containers with iterators stable over insert and erase. + - Generally slower and bigger than `std::vector` or `std::deque` except for those cases. -* `std::set` - * For sorted containers. +- `std::set` + - For sorted containers. -* `ripple::hash_set` - * Where inserts and contains need to be O(1). - * For "small" sets, `std::set` might be faster and smaller. +- `ripple::hash_set` + - Where inserts and contains need to be O(1). + - For "small" sets, `std::set` might be faster and smaller. -* `ripple::hardened_hash_set` - * For data sets where the key could be manipulated by an attacker - in an attempt to mount an algorithmic complexity attack: see +- `ripple::hardened_hash_set` + - For data sets where the key could be manipulated by an attacker + in an attempt to mount an algorithmic complexity attack: see http://en.wikipedia.org/wiki/Algorithmic_complexity_attack - The following container is deprecated -* `std::unordered_set` - * Use `ripple::hash_set` instead, which uses a better hashing algorithm. - * Or use `ripple::hardened_hash_set` to prevent algorithmic complexity attacks. +- `std::unordered_set` +- Use `ripple::hash_set` instead, which uses a better hashing algorithm. +- Or use `ripple::hardened_hash_set` to prevent algorithmic complexity attacks. diff --git a/include/xrpl/proto/org/xrpl/rpc/v1/README.md b/include/xrpl/proto/org/xrpl/rpc/v1/README.md index 9268439847..e9b9b55841 100644 --- a/include/xrpl/proto/org/xrpl/rpc/v1/README.md +++ b/include/xrpl/proto/org/xrpl/rpc/v1/README.md @@ -79,4 +79,3 @@ mirror the JSON test as much as possible. Refer to the Protocol Buffers [language guide](https://developers.google.com/protocol-buffers/docs/proto3) for more detailed information about Protocol Buffers. - diff --git a/include/xrpl/protocol/README.md b/include/xrpl/protocol/README.md index 9864b700ef..a6e8d24982 100644 --- a/include/xrpl/protocol/README.md +++ b/include/xrpl/protocol/README.md @@ -23,9 +23,9 @@ optional fields easier to read: if it exists, or nothing if it doesn't." This usage of the tilde/bitwise NOT operator is not standard outside of the `rippled` codebase. - - As a consequence of this, `x[~sfFoo] = y[~sfFoo]` - assigns the value of Foo from y to x, including omitting - Foo from x if it doesn't exist in y. + - As a consequence of this, `x[~sfFoo] = y[~sfFoo]` + assigns the value of Foo from y to x, including omitting + Foo from x if it doesn't exist in y. Typically, for things that are guaranteed to exist, you use `x[sfFoo]` and avoid having to deal with a container that may diff --git a/include/xrpl/resource/README.md b/include/xrpl/resource/README.md index 8fed985bfd..253e3c7625 100644 --- a/include/xrpl/resource/README.md +++ b/include/xrpl/resource/README.md @@ -1,4 +1,4 @@ -# Resource::Manager # +# Resource::Manager The ResourceManager module has these responsibilities: @@ -7,7 +7,7 @@ The ResourceManager module has these responsibilities: - Provide an interface to share load information in a cluster. - Warn and/or disconnect endpoints for imposing load. -## Description ## +## Description To prevent monopolization of server resources or attacks on servers, resource consumption is monitored at each endpoint. When consumption @@ -33,44 +33,44 @@ Although RPC connections consume resources, they are transient and cannot be rate limited. It is advised not to expose RPC interfaces to the general public. -## Consumer Types ## +## Consumer Types Consumers are placed into three classifications (as identified by the Resource::Kind enumeration): - - InBound, - - OutBound, and - - Admin +- InBound, +- OutBound, and +- Admin - Each caller determines for itself the classification of the Consumer it is - creating. +Each caller determines for itself the classification of the Consumer it is +creating. -## Resource Loading ## +## Resource Loading It is expected that a client will impose a higher load on the server when it first connects: the client may need to catch up on transactions -it has missed, or get trust lines, or transfer fees. The Manager must +it has missed, or get trust lines, or transfer fees. The Manager must expect this initial peak load, but not allow that high load to continue because over the long term that would unduly stress the server. If a client places a sustained high load on the server, that client -is initially given a warning message. If that high load continues +is initially given a warning message. If that high load continues the Manager may tell the heavily loaded server to drop the connection entirely and not allow re-connection for some amount of time. Each load is monitored by capturing peaks and then decaying those peak values over time: this is implemented by the DecayingSample class. -## Gossip ## +## Gossip Each server in a cluster creates a list of IP addresses of end points -that are imposing a significant load. This list is called Gossip, which -is passed to other nodes in that cluster. Gossip helps individual +that are imposing a significant load. This list is called Gossip, which +is passed to other nodes in that cluster. Gossip helps individual servers in the cluster identify IP addreses that might be unduly loading -the entire cluster. Again the recourse of the individual servers is to +the entire cluster. Again the recourse of the individual servers is to drop connections to those IP addresses that occur commonly in the gossip. -## Access ## +## Access In rippled, the Application holds a unique instance of Resource::Manager, which may be retrieved by calling the method diff --git a/src/test/README.md b/src/test/README.md index 7d342f24bf..b012607f58 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -1,4 +1,3 @@ - # Unit Tests ## Running Tests @@ -12,13 +11,13 @@ just `NoRippleCheckLimits`). More than one suite or group of suites can be specified as a comma separated list via the argument. For example, `--unittest=beast,OversizeMeta` will run all suites in the `beast` library (root identifier) as well as the test suite -named `OversizeMeta`). All name matches are case sensitive. +named `OversizeMeta`). All name matches are case sensitive. Tests can be executed in parallel using several child processes by specifying the `--unittest-jobs=N` parameter. The default behavior is to execute serially using a single process. -The order that suites are executed is determined by the suite priority that +The order that suites are executed is determined by the suite priority that is optionally specified when the suite is declared in the code with one of the `BEAST_DEFINE_TESTSUITE` macros. By default, suites have a priority of 0, and other suites can choose to declare an integer priority value to make themselves diff --git a/src/test/csf/README.md b/src/test/csf/README.md index a4b69abab5..30d5abb042 100644 --- a/src/test/csf/README.md +++ b/src/test/csf/README.md @@ -26,7 +26,7 @@ collect when running the simulation. The specification includes: - A collection of [`Peer`s](./Peer.h) that represent the participants in the network, with each independently running the consensus algorithm. - The `Peer` trust relationships as a `TrustGraph`. This is a directed graph - whose edges define what other `Peer`s a given `Peer` trusts. In other words, + whose edges define what other `Peer`s a given `Peer` trusts. In other words, the set of out edges for a `Peer` in the graph correspond to the UNL of that `Peer`. - The network communication layer as a `BasicNetwork`. This models the overlay @@ -45,6 +45,7 @@ eventually fully validating the consensus history of accepted transactions. Each the registered `Collector`s. ## Example Simulation + Below is a basic simulation we can walk through to get an understanding of the framework. This simulation is for a set of 5 validators that aren't directly connected but rely on a single hub node for communication. @@ -98,12 +99,12 @@ center[0]->runAsValidator = false; The simulation code starts by creating a single instance of the [`Sim` class](./Sim.h). This class is used to manage the overall simulation and internally owns most other components, including the `Peer`s, `Scheduler`, -`BasicNetwork` and `TrustGraph`. The next two lines create two differ +`BasicNetwork` and `TrustGraph`. The next two lines create two differ `PeerGroup`s of size 5 and 1 . A [`PeerGroup`](./PeerGroup.h) is a convenient way for configuring a set of related peers together and internally has a vector of pointers to the `Peer`s which are owned by the `Sim`. `PeerGroup`s can be combined using `+/-` operators to configure more complex relationships of nodes -as shown by `PeerGroup network`. Note that each call to `createGroup` adds that +as shown by `PeerGroup network`. Note that each call to `createGroup` adds that many new `Peer`s to the simulation, but does not specify any trust or network relationships for the new `Peer`s. @@ -125,14 +126,14 @@ validators.connect(center, delay); Although the `sim` object has accessible instances of [TrustGraph](./TrustGraph.h) and [BasicNetwork](./BasicNetwork.h), it is more -convenient to manage the graphs via the `PeerGroup`s. The first two lines -create a trust topology in which all `Peer`s trust the 5 validating `Peer`s. Or +convenient to manage the graphs via the `PeerGroup`s. The first two lines +create a trust topology in which all `Peer`s trust the 5 validating `Peer`s. Or in the UNL perspective, all `Peer`s are configured with the same UNL listing the 5 validating `Peer`s. The two lines could've been rewritten as `network.trust(validators)`. The next lines create the network communication topology. Each of the validating -`Peer`s connects to the central hub `Peer` with a fixed delay of 200ms. Note +`Peer`s connects to the central hub `Peer` with a fixed delay of 200ms. Note that the network connections are really undirected, but are represented internally in a directed graph using edge pairs of inbound and outbound connections. @@ -143,11 +144,11 @@ SimDurationCollector simDur; sim.collectors.add(simDur); ``` -The next lines add a single collector to the simulation. The +The next lines add a single collector to the simulation. The `SimDurationCollector` is a simple example collector which tracks the total -duration of the simulation. More generally, a collector is any class that +duration of the simulation. More generally, a collector is any class that implements `void on(NodeID, SimTime, Event)` for all [Events](./events.h) -emitted by a Peer. Events are arbitrary types used to indicate some action or +emitted by a Peer. Events are arbitrary types used to indicate some action or change of state of a `Peer`. Other [existing collectors](./collectors.h) measure latencies of transaction submission to validation or the rate of ledger closing and monitor any jumps in ledger history. @@ -176,9 +177,9 @@ to send transactions in at fixed or random intervals to fixed or random `Peer`s. ## Run -The example has two calls to `sim.run(1)`. This call runs the simulation until -each `Peer` has closed one additional ledger. After closing the additional -ledger, the `Peer` stops participating in consensus. The first call is used to +The example has two calls to `sim.run(1)`. This call runs the simulation until +each `Peer` has closed one additional ledger. After closing the additional +ledger, the `Peer` stops participating in consensus. The first call is used to ensure a more useful prior state of all `Peer`s. After the transaction submission, the second call to `run` results in one additional ledger that accepts those transactions. @@ -188,4 +189,4 @@ Alternatively, you can specify a duration to run the simulation, e.g. scheduler has elapsed 10 additional seconds. The `sim.scheduler.in` or `sim.scheduler.at` methods can schedule arbitrary code to execute at a later time in the simulation, for example removing a network connection or modifying -the trust graph. \ No newline at end of file +the trust graph. diff --git a/src/tests/README.md b/src/tests/README.md index 8065316580..7c4cc5edf8 100644 --- a/src/tests/README.md +++ b/src/tests/README.md @@ -1,4 +1,5 @@ # Unit tests + This directory contains unit tests for the project. The difference from existing `src/test` folder is that we switch to 3rd party testing framework (doctest). We intend to gradually move existing tests from our own framework to doctest and such tests will be moved to this new folder. diff --git a/src/xrpld/app/consensus/README.md b/src/xrpld/app/consensus/README.md index 0050273138..bdf5afe87c 100644 --- a/src/xrpld/app/consensus/README.md +++ b/src/xrpld/app/consensus/README.md @@ -1,13 +1,12 @@ -# RCL Consensus +# RCL Consensus This directory holds the types and classes needed to connect the generic consensus algorithm to the rippled-specific instance of consensus. - * `RCLCxTx` adapts a `SHAMapItem` transaction. - * `RCLCxTxSet` adapts a `SHAMap` to represent a set of transactions. - * `RCLCxLedger` adapts a `Ledger`. - * `RCLConsensus` is implements the requirements of the generic - `Consensus` class by connecting to the rest of the `rippled` - application. - +- `RCLCxTx` adapts a `SHAMapItem` transaction. +- `RCLCxTxSet` adapts a `SHAMap` to represent a set of transactions. +- `RCLCxLedger` adapts a `Ledger`. +- `RCLConsensus` is implements the requirements of the generic + `Consensus` class by connecting to the rest of the `rippled` + application. diff --git a/src/xrpld/app/ledger/README.md b/src/xrpld/app/ledger/README.md index cf7844856b..d2afe01e71 100644 --- a/src/xrpld/app/ledger/README.md +++ b/src/xrpld/app/ledger/README.md @@ -1,9 +1,8 @@ +# Ledger Process -# Ledger Process # +## Introduction -## Introduction ## - -## Life Cycle ## +## Life Cycle Every server always has an open ledger. All received new transactions are applied to the open ledger. The open ledger can't close until we reach @@ -37,10 +36,11 @@ round. This is a "rebase": now that we know the real history, the current open ledger is rebased against the last closed ledger. The purpose of the open ledger is as follows: + - Forms the basis of the initial proposal during consensus - Used to decide if we can reject the transaction without relaying it -## Byzantine Failures ## +## Byzantine Failures Byzantine failures are resolved as follows. If there is a supermajority ledger, then a minority of validators will discover that the consensus round is @@ -52,167 +52,169 @@ If there is no majority ledger, then starting on the next consensus round there will not be a consensus on the last closed ledger. Another avalanche process is started. -## Validators ## +## Validators The only meaningful difference between a validator and a 'regular' server is that the validator sends its proposals and validations to the network. --- -# The Ledger Stream # +# The Ledger Stream -## Ledger Priorities ## +## Ledger Priorities There are two ledgers that are the most important for a rippled server to have: - - The consensus ledger and - - The last validated ledger. +- The consensus ledger and +- The last validated ledger. If we need either of those two ledgers they are fetched with the highest -priority. Also, when they arrive, they replace their earlier counterparts +priority. Also, when they arrive, they replace their earlier counterparts (if they exist). The `LedgerMaster` object tracks - - the last published ledger, - - the last validated ledger, and - - ledger history. -So the `LedgerMaster` is at the center of fetching historical ledger data. + +- the last published ledger, +- the last validated ledger, and +- ledger history. + So the `LedgerMaster` is at the center of fetching historical ledger data. In specific, the `LedgerMaster::doAdvance()` method triggers the code that fetches historical data and controls the state machine for ledger acquisition. The server tries to publish an on-going stream of consecutive ledgers to its -clients. After the server has started and caught up with network +clients. After the server has started and caught up with network activity, say when ledger 500 is being settled, then the server puts its best effort into publishing validated ledger 500 followed by validated ledger 501 -and then 502. This effort continues until the server is shut down. +and then 502. This effort continues until the server is shut down. But loading or network connectivity may sometimes interfere with that ledger -stream. So suppose the server publishes validated ledger 600 and then -receives validated ledger 603. Then the server wants to back fill its ledger +stream. So suppose the server publishes validated ledger 600 and then +receives validated ledger 603. Then the server wants to back fill its ledger history with ledgers 601 and 602. -The server prioritizes keeping up with current ledgers. But if it is caught +The server prioritizes keeping up with current ledgers. But if it is caught up on the current ledger, and there are no higher priority demands on the -server, then it will attempt to back fill its historical ledgers. It fills +server, then it will attempt to back fill its historical ledgers. It fills in the historical ledger data first by attempting to retrieve it from the -local database. If the local database does not have all of the necessary data +local database. If the local database does not have all of the necessary data then the server requests the remaining information from network peers. -Suppose the server is missing multiple historical ledgers. Take the previous -example where we have ledgers 603 and 600, but we're missing 601 and 602. In +Suppose the server is missing multiple historical ledgers. Take the previous +example where we have ledgers 603 and 600, but we're missing 601 and 602. In that case the server requests information for ledger 602 first, before -back-filling ledger 601. We want to expand the contiguous range of -most-recent ledgers that the server has locally. There's also a limit to -how much historical ledger data is useful. So if we're on ledger 603, but +back-filling ledger 601. We want to expand the contiguous range of +most-recent ledgers that the server has locally. There's also a limit to +how much historical ledger data is useful. So if we're on ledger 603, but we're missing ledger 4 we may not bother asking for ledger 4. -## Assembling a Ledger ## +## Assembling a Ledger When data for a ledger arrives from a peer, it may take a while before the -server can apply that data. So when ledger data arrives we schedule a job -thread to apply that data. If more data arrives before the job starts we add -that data to the job. We defer requesting more ledger data until all of the -data we have for that ledger has been processed. Once all of that data is +server can apply that data. So when ledger data arrives we schedule a job +thread to apply that data. If more data arrives before the job starts we add +that data to the job. We defer requesting more ledger data until all of the +data we have for that ledger has been processed. Once all of that data is processed we can intelligently request only the additional data that we need -to fill in the ledger. This reduces network traffic and minimizes the load +to fill in the ledger. This reduces network traffic and minimizes the load on peers supplying the data. If we receive data for a ledger that is not currently under construction, -we don't just throw the data away. In particular the AccountStateNodes -may be useful, since they can be re-used across ledgers. This data is +we don't just throw the data away. In particular the AccountStateNodes +may be useful, since they can be re-used across ledgers. This data is stashed in memory (not the database) where the acquire process can find it. Peers deliver ledger data in the order in which the data can be validated. Data arrives in the following order: - 1. The hash of the ledger header - 2. The ledger header - 3. The root nodes of the transaction tree and state tree - 4. The lower (non-root) nodes of the state tree - 5. The lower (non-root) nodes of the transaction tree +1. The hash of the ledger header +2. The ledger header +3. The root nodes of the transaction tree and state tree +4. The lower (non-root) nodes of the state tree +5. The lower (non-root) nodes of the transaction tree -Inner-most nodes are supplied before outer nodes. This allows the +Inner-most nodes are supplied before outer nodes. This allows the requesting server to hook things up (and validate) in the order in which data arrives. If this process fails, then a server can also ask for ledger data by hash, -rather than by asking for specific nodes in a ledger. Asking for information +rather than by asking for specific nodes in a ledger. Asking for information by hash is less efficient, but it allows a peer to return the information -even if the information is not assembled into a tree. All the peer needs is +even if the information is not assembled into a tree. All the peer needs is the raw data. -## Which Peer To Ask ## +## Which Peer To Ask Peers go though state transitions as the network goes through its state -transitions. Peer's provide their state to their directly connected peers. +transitions. Peer's provide their state to their directly connected peers. By monitoring the state of each connected peer a server can tell which of its peers has the information that it needs. Therefore if a server suffers a byzantine failure the server can tell which -of its peers did not suffer that same failure. So the server knows which +of its peers did not suffer that same failure. So the server knows which peer(s) to ask for the missing information. -Peers also report their contiguous range of ledgers. This is another way that +Peers also report their contiguous range of ledgers. This is another way that a server can determine which peer to ask for a particular ledger or piece of a ledger. -There are also indirect peer queries. If there have been timeouts while -acquiring ledger data then a server may issue indirect queries. In that +There are also indirect peer queries. If there have been timeouts while +acquiring ledger data then a server may issue indirect queries. In that case the server receiving the indirect query passes the query along to any -of its peers that may have the requested data. This is important if the -network has a byzantine failure. It also helps protect the validation -network. A validator may need to get a peer set from one of the other +of its peers that may have the requested data. This is important if the +network has a byzantine failure. It also helps protect the validation +network. A validator may need to get a peer set from one of the other validators, and indirect queries improve the likelihood of success with that. -## Kinds of Fetch Packs ## +## Kinds of Fetch Packs A FetchPack is the way that peers send partial ledger data to other peers so the receiving peer can reconstruct a ledger. -A 'normal' FetchPack is a bucket of nodes indexed by hash. The server +A 'normal' FetchPack is a bucket of nodes indexed by hash. The server building the FetchPack puts information into the FetchPack that the -destination server is likely to need. Normally they contain all of the +destination server is likely to need. Normally they contain all of the missing nodes needed to fill in a ledger. A 'compact' FetchPack, on the other hand, contains only leaf nodes, no -inner nodes. Because there are no inner nodes, the ledger information that -it contains cannot be validated as the ledger is assembled. We have to, +inner nodes. Because there are no inner nodes, the ledger information that +it contains cannot be validated as the ledger is assembled. We have to, initially, take the accuracy of the FetchPack for granted and assemble the -ledger. Once the entire ledger is assembled the entire ledger can be -validated. But if the ledger does not validate then there's nothing to be +ledger. Once the entire ledger is assembled the entire ledger can be +validated. But if the ledger does not validate then there's nothing to be done but throw the entire FetchPack away; there's no way to save a portion of the FetchPack. -The FetchPacks just described could be termed 'reverse FetchPacks.' They -only provide historical data. There may be a use for what could be called a -'forward FetchPack.' A forward FetchPack would contain the information that +The FetchPacks just described could be termed 'reverse FetchPacks.' They +only provide historical data. There may be a use for what could be called a +'forward FetchPack.' A forward FetchPack would contain the information that is needed to build a new ledger out of the preceding ledger. A forward compact FetchPack would need to contain: - - The header for the new ledger, - - The leaf nodes of the transaction tree (if there is one), - - The index of deleted nodes in the state tree, - - The index and data for new nodes in the state tree, and - - The index and new data of modified nodes in the state tree. + +- The header for the new ledger, +- The leaf nodes of the transaction tree (if there is one), +- The index of deleted nodes in the state tree, +- The index and data for new nodes in the state tree, and +- The index and new data of modified nodes in the state tree. --- -# Definitions # +# Definitions -## Open Ledger ## +## Open Ledger The open ledger is the ledger that the server applies all new incoming transactions to. -## Last Validated Ledger ## +## Last Validated Ledger The most recent ledger that the server is certain will always remain part of the permanent, public history. -## Last Closed Ledger ## +## Last Closed Ledger The most recent ledger that the server believes the network reached consensus on. Different servers can arrive at a different conclusion about the last @@ -220,29 +222,29 @@ closed ledger. This is a consequence of Byzantanine failure. The purpose of validations is to resolve the differences between servers and come to a common conclusion about which last closed ledger is authoritative. -## Consensus ## +## Consensus A distributed agreement protocol. Ripple uses the consensus process to solve the problem of double-spending. -## Validation ## +## Validation A signed statement indicating that it built a particular ledger as a result of the consensus process. -## Proposal ## +## Proposal A signed statement of which transactions it believes should be included in the next consensus ledger. -## Ledger Header ## +## Ledger Header The "ledger header" is the chunk of data that hashes to the ledger's hash. It contains the sequence number, parent hash, hash of the previous ledger, hash of the root node of the state tree, and so on. -## Ledger Base ## +## Ledger Base The term "ledger base" refers to a particular type of query and response used in the ledger fetch process that includes @@ -251,9 +253,9 @@ such as the root node of the state tree. --- -# Ledger Structures # +# Ledger Structures -## Account Root ## +## Account Root **Account:** A 160-bit account ID. @@ -264,8 +266,8 @@ such as the root node of the state tree. **LedgerEntryType:** "AccountRoot" **OwnerCount:** The number of items the account owns that are charged to the -account. Offers are charged to the account. Trust lines may be charged to -the account (but not necessarily). The OwnerCount determines the reserve on +account. Offers are charged to the account. Trust lines may be charged to +the account (but not necessarily). The OwnerCount determines the reserve on the account. **PreviousTxnID:** 256-bit index of the previous transaction on this account. @@ -274,43 +276,45 @@ the account. transaction on this account. **Sequence:** Must be a value of 1 for the account to process a valid -transaction. The value initially matches the sequence number of the state -tree of the account that signed the transaction. The process of executing -the transaction increments the sequence number. This is how ripple prevents +transaction. The value initially matches the sequence number of the state +tree of the account that signed the transaction. The process of executing +the transaction increments the sequence number. This is how ripple prevents a transaction from executing more than once. **index:** 256-bit hash of this AccountRoot. - -## Trust Line ## +## Trust Line The trust line acts as an edge connecting two accounts: the accounts -represented by the HighNode and the LowNode. Which account is "high" and -"low" is determined by the values of the two 160-bit account IDs. The -account with the smaller 160-bit ID is always the low account. This +represented by the HighNode and the LowNode. Which account is "high" and +"low" is determined by the values of the two 160-bit account IDs. The +account with the smaller 160-bit ID is always the low account. This ordering makes the hash of a trust line between accounts A and B have the same value as a trust line between accounts B and A. **Balance:** - - **currency:** String identifying a valid currency, e.g., "BTC". - - **issuer:** There is no issuer, really, this entry is "NoAccount". - - **value:** + +- **currency:** String identifying a valid currency, e.g., "BTC". +- **issuer:** There is no issuer, really, this entry is "NoAccount". +- **value:** **Flags:** ??? **HighLimit:** - - **currency:** Same as for Balance. - - **issuer:** A 160-bit account ID. - - **value:** The largest amount this issuer will accept of the currency. + +- **currency:** Same as for Balance. +- **issuer:** A 160-bit account ID. +- **value:** The largest amount this issuer will accept of the currency. **HighNode:** A deletion hint. **LedgerEntryType:** "RippleState". **LowLimit:** - - **currency:** Same as for Balance. - - **issuer:** A 160-bit account ID. - - **value:** The largest amount of the currency this issuer will accept. + +- **currency:** Same as for Balance. +- **issuer:** A 160-bit account ID. +- **value:** The largest amount of the currency this issuer will accept. **LowNode:** A deletion hint @@ -321,8 +325,7 @@ transaction on this account. **index:** 256-bit hash of this RippleState. - -## Ledger Hashes ## +## Ledger Hashes **Flags:** ??? @@ -334,8 +337,7 @@ transaction on this account. **index:** 256-bit hash of this LedgerHashes. - -## Owner Directory ## +## Owner Directory Lists all of the offers and trust lines that are associated with an account. @@ -351,8 +353,7 @@ Lists all of the offers and trust lines that are associated with an account. **index:** A hash of the owner account. - -## Book Directory ## +## Book Directory Lists one or more offers that have the same quality. @@ -360,18 +361,18 @@ If a pair of Currency and Issuer fields are all zeros, then that pair is dealing in XRP. The code, at the moment, does not recognize that the Currency and Issuer -fields are currencies and issuers. So those values are presented in hex, -rather than as accounts and currencies. That's a bug and should be fixed +fields are currencies and issuers. So those values are presented in hex, +rather than as accounts and currencies. That's a bug and should be fixed at some point. -**ExchangeRate:** A 64-bit value. The first 8-bits is the exponent and the -remaining bits are the mantissa. The format is such that a bigger 64-bit +**ExchangeRate:** A 64-bit value. The first 8-bits is the exponent and the +remaining bits are the mantissa. The format is such that a bigger 64-bit value always represents a higher exchange rate. -Each type can compute its own hash. The hash of a book directory contains, -as its lowest 64 bits, the exchange rate. This means that if there are -multiple *almost* identical book directories, but with different exchange -rates, then these book directories will sit together in the ledger. The best +Each type can compute its own hash. The hash of a book directory contains, +as its lowest 64 bits, the exchange rate. This means that if there are +multiple _almost_ identical book directories, but with different exchange +rates, then these book directories will sit together in the ledger. The best exchange rate will be the first in the sequence of Book Directories. **Flags:** ??? @@ -392,14 +393,14 @@ currencies described by this BookDirectory. **TakerPaysIssuer:** Issuer of the PaysCurrency. **index:** A 256-bit hash computed using the TakerGetsCurrency, TakerGetsIssuer, -TakerPaysCurrency, and TakerPaysIssuer in the top 192 bits. The lower 64-bits +TakerPaysCurrency, and TakerPaysIssuer in the top 192 bits. The lower 64-bits are occupied by the exchange rate. --- -# Ledger Publication # +# Ledger Publication -## Overview ## +## Overview The Ripple server permits clients to subscribe to a continuous stream of fully-validated ledgers. The publication code maintains this stream. @@ -408,7 +409,7 @@ The server attempts to maintain this continuous stream unless it falls too far behind, in which case it jumps to the current fully-validated ledger and then attempts to resume a continuous stream. -## Implementation ## +## Implementation `LedgerMaster::doAdvance` is invoked when work may need to be done to publish ledgers to clients. This code loops until it cannot make further @@ -430,17 +431,17 @@ the list of resident ledgers. --- -# The Ledger Cleaner # +# The Ledger Cleaner -## Overview ## +## Overview The ledger cleaner checks and, if necessary, repairs the SQLite ledger and -transaction databases. It can also check for pieces of a ledger that should -be in the node back end but are missing. If it detects this case, it -triggers a fetch of the ledger. The ledger cleaner only operates by manual +transaction databases. It can also check for pieces of a ledger that should +be in the node back end but are missing. If it detects this case, it +triggers a fetch of the ledger. The ledger cleaner only operates by manual request. It is never started automatically. -## Operations ## +## Operations The ledger cleaner can operate on a single ledger or a range of ledgers. It always validates the ledger chain itself, ensuring that the SQLite database @@ -448,7 +449,7 @@ contains a consistent chain of ledgers from the last validated ledger as far back as the database goes. If requested, it can additionally repair the SQLite entries for transactions -in each checked ledger. This was primarily intended to repair incorrect +in each checked ledger. This was primarily intended to repair incorrect entries created by a bug (since fixed) that could cause transasctions from a ledger other than the fully-validated ledger to appear in the SQLite databases in addition to the transactions from the correct ledger. @@ -460,7 +461,7 @@ To prevent the ledger cleaner from saturating the available I/O bandwidth and excessively polluting caches with ancient information, the ledger cleaner paces itself and does not attempt to get its work done quickly. -## Commands ## +## Commands The ledger cleaner can be controlled and monitored with the **ledger_cleaner** RPC command. With no parameters, this command reports on the status of the @@ -486,4 +487,4 @@ ledger(s) for missing nodes in the back end node store --- -# References # +# References diff --git a/src/xrpld/app/misc/FeeEscalation.md b/src/xrpld/app/misc/FeeEscalation.md index b86f8dab94..468ab2b528 100644 --- a/src/xrpld/app/misc/FeeEscalation.md +++ b/src/xrpld/app/misc/FeeEscalation.md @@ -17,15 +17,16 @@ transactions into the open ledger, even during unfavorable conditions. How fees escalate: 1. There is a base [fee level](#fee-level) of 256, -which is the minimum that a typical transaction -is required to pay. For a [reference -transaction](#reference-transaction), that corresponds to the -network base fee, which is currently 10 drops. + which is the minimum that a typical transaction + is required to pay. For a [reference + transaction](#reference-transaction), that corresponds to the + network base fee, which is currently 10 drops. 2. However, there is a limit on the number of transactions that -can get into an open ledger for that base fee level. The limit -will vary based on the [health](#consensus-health) of the -consensus process, but will be at least [5](#other-constants). - * If consensus stays [healthy](#consensus-health), the limit will + can get into an open ledger for that base fee level. The limit + will vary based on the [health](#consensus-health) of the + consensus process, but will be at least [5](#other-constants). + +- If consensus stays [healthy](#consensus-health), the limit will be the max of the number of transactions in the validated ledger plus [20%](#other-constants) or the current limit until it gets to [50](#other-constants), at which point, the limit will be the @@ -35,50 +36,56 @@ consensus process, but will be at least [5](#other-constants). decreases (i.e. a large ledger is no longer recent), the limit will decrease to the new largest value by 10% each time the ledger has more than 50 transactions. - * If consensus does not stay [healthy](#consensus-health), +- If consensus does not stay [healthy](#consensus-health), the limit will clamp down to the smaller of the number of transactions in the validated ledger minus [50%](#other-constants) or the previous limit minus [50%](#other-constants). - * The intended effect of these mechanisms is to allow as many base fee +- The intended effect of these mechanisms is to allow as many base fee level transactions to get into the ledger as possible while the network is [healthy](#consensus-health), but to respond quickly to any condition that makes it [unhealthy](#consensus-health), including, but not limited to, malicious attacks. + 3. Once there are more transactions in the open ledger than indicated -by the limit, the required fee level jumps drastically. - * The formula is `( lastLedgerMedianFeeLevel * - TransactionsInOpenLedger^2 / limit^2 )`, + by the limit, the required fee level jumps drastically. + +- The formula is `( lastLedgerMedianFeeLevel * +TransactionsInOpenLedger^2 / limit^2 )`, and returns a [fee level](#fee-level). + 4. That may still be pretty small, but as more transactions get -into the ledger, the fee level increases exponentially. - * For example, if the limit is 6, and the median fee is minimal, + into the ledger, the fee level increases exponentially. + +- For example, if the limit is 6, and the median fee is minimal, and assuming all [reference transactions](#reference-transaction), the 8th transaction only requires a [level](#fee-level) of about 174,000 or about 6800 drops, but the 20th transaction requires a [level](#fee-level) of about 1,283,000 or about 50,000 drops. + 5. Finally, as each ledger closes, the median fee level of that ledger is -computed and used as `lastLedgerMedianFeeLevel` (with a -[minimum value of 128,000](#other-constants)) -in the fee escalation formula for the next open ledger. - * Continuing the example above, if ledger consensus completes with + computed and used as `lastLedgerMedianFeeLevel` (with a + [minimum value of 128,000](#other-constants)) + in the fee escalation formula for the next open ledger. + +- Continuing the example above, if ledger consensus completes with only those 20 transactions, and all of those transactions paid the minimum required fee at each step, the limit will be adjusted from 6 to 24, and the `lastLedgerMedianFeeLevel` will be about 322,000, which is 12,600 drops for a [reference transaction](#reference-transaction). - * This will only require 10 drops for the first 25 transactions, +- This will only require 10 drops for the first 25 transactions, but the 26th transaction will require a level of about 349,150 or about 13,649 drops. -* This example assumes a cold-start scenario, with a single, possibly -malicious, user willing to pay arbitrary amounts to get transactions -into the open ledger. It ignores the effects of the [Transaction -Queue](#transaction-queue). Any lower fee level transactions submitted -by other users at the same time as this user's transactions will go into -the transaction queue, and will have the first opportunity to be applied -to the _next_ open ledger. The next section describes how that works in -more detail. +- This example assumes a cold-start scenario, with a single, possibly + malicious, user willing to pay arbitrary amounts to get transactions + into the open ledger. It ignores the effects of the [Transaction + Queue](#transaction-queue). Any lower fee level transactions submitted + by other users at the same time as this user's transactions will go into + the transaction queue, and will have the first opportunity to be applied + to the _next_ open ledger. The next section describes how that works in + more detail. ## Transaction Queue @@ -92,33 +99,34 @@ traffic periods, and give those transactions a much better chance to succeed. 1. If an incoming transaction meets both the base [fee -level](#fee-level) and the [load fee](#load-fee) minimum, but does not have a high -enough [fee level](#fee-level) to immediately go into the open ledger, -it is instead put into the queue and broadcast to peers. Each peer will -then make an independent decision about whether to put the transaction -into its open ledger or the queue. In principle, peers with identical -open ledgers will come to identical decisions. Any discrepancies will be -resolved as usual during consensus. + level](#fee-level) and the [load fee](#load-fee) minimum, but does not have a high + enough [fee level](#fee-level) to immediately go into the open ledger, + it is instead put into the queue and broadcast to peers. Each peer will + then make an independent decision about whether to put the transaction + into its open ledger or the queue. In principle, peers with identical + open ledgers will come to identical decisions. Any discrepancies will be + resolved as usual during consensus. 2. When consensus completes, the open ledger limit is adjusted, and -the required [fee level](#fee-level) drops back to the base -[fee level](#fee-level). Before the ledger is made available to -external transactions, transactions are applied from the queue to the -ledger from highest [fee level](#fee-level) to lowest. These transactions -count against the open ledger limit, so the required [fee level](#fee-level) -may start rising during this process. + the required [fee level](#fee-level) drops back to the base + [fee level](#fee-level). Before the ledger is made available to + external transactions, transactions are applied from the queue to the + ledger from highest [fee level](#fee-level) to lowest. These transactions + count against the open ledger limit, so the required [fee level](#fee-level) + may start rising during this process. 3. Once the queue is empty, or the required [fee level](#fee-level) -rises too high for the remaining transactions in the queue, the ledger -is opened up for normal transaction processing. + rises too high for the remaining transactions in the queue, the ledger + is opened up for normal transaction processing. 4. A transaction in the queue can stay there indefinitely in principle, -but in practice, either - * it will eventually get applied to the ledger, - * it will attempt to apply to the ledger and fail, - * it will attempt to apply to the ledger and retry [10 + but in practice, either + +- it will eventually get applied to the ledger, +- it will attempt to apply to the ledger and fail, +- it will attempt to apply to the ledger and retry [10 times](#other-constants), - * its last ledger sequence number will expire, - * the user will replace it by submitting another transaction with the same +- its last ledger sequence number will expire, +- the user will replace it by submitting another transaction with the same sequence number and at least a [25% higher fee](#other-constants), or - * it will get dropped when the queue fills up with more valuable transactions. +- it will get dropped when the queue fills up with more valuable transactions. The size limit is computed dynamically, and can hold transactions for the next [20 ledgers](#other-constants) (restricted to a minimum of [2000 transactions](#other-constants)). The lower the transaction's @@ -128,14 +136,15 @@ If a transaction is submitted for an account with one or more transactions already in the queue, and a sequence number that is sequential with the other transactions in the queue for that account, it will be considered for the queue if it meets these additional criteria: - * the account has fewer than [10](#other-constants) transactions + +- the account has fewer than [10](#other-constants) transactions already in the queue. - * all other queued transactions for that account, in the case where +- all other queued transactions for that account, in the case where they spend the maximum possible XRP, leave enough XRP balance to pay the fee, - * the total fees for the other queued transactions are less than both +- the total fees for the other queued transactions are less than both the network's minimum reserve and the account's XRP balance, and - * none of the prior queued transactions affect the ability of subsequent +- none of the prior queued transactions affect the ability of subsequent transactions to claim a fee. Currently, there is an additional restriction that the queue cannot work with @@ -148,7 +157,7 @@ development will make the queue aware of `sfAccountTxnID` mechanisms. ### Fee Level "Fee level" is used to allow the cost of different types of transactions -to be compared directly. For a [reference +to be compared directly. For a [reference transaction](#reference-transaction), the base fee level is 256. If a transaction is submitted with a higher `Fee` field, the fee level is scaled appropriately. @@ -157,16 +166,16 @@ Examples, assuming a [reference transaction](#reference-transaction) base fee of 10 drops: 1. A single-signed [reference transaction](#reference-transaction) -with `Fee=20` will have a fee level of -`20 drop fee * 256 fee level / 10 drop base fee = 512 fee level`. + with `Fee=20` will have a fee level of + `20 drop fee * 256 fee level / 10 drop base fee = 512 fee level`. 2. A multi-signed [reference transaction](#reference-transaction) with -3 signatures (base fee = 40 drops) and `Fee=60` will have a fee level of -`60 drop fee * 256 fee level / ((1tx + 3sigs) * 10 drop base fee) = 384 + 3 signatures (base fee = 40 drops) and `Fee=60` will have a fee level of + `60 drop fee * 256 fee level / ((1tx + 3sigs) * 10 drop base fee) = 384 fee level`. 3. A hypothetical future non-reference transaction with a base -fee of 15 drops multi-signed with 5 signatures and `Fee=90` will -have a fee level of -`90 drop fee * 256 fee level / ((1tx + 5sigs) * 15 drop base fee) = 256 + fee of 15 drops multi-signed with 5 signatures and `Fee=90` will + have a fee level of + `90 drop fee * 256 fee level / ((1tx + 5sigs) * 15 drop base fee) = 256 fee level`. This demonstrates that a simpler transaction paying less XRP can be more @@ -194,7 +203,7 @@ For consensus to be considered healthy, the peers on the network should largely remain in sync with one another. It is particularly important for the validators to remain in sync, because that is required for participation in consensus. However, the network tolerates some -validators being out of sync. Fundamentally, network health is a +validators being out of sync. Fundamentally, network health is a function of validators reaching consensus on sets of recently submitted transactions. @@ -214,61 +223,61 @@ often coincides with new ledgers with zero transactions. ### Other Constants -* *Base fee transaction limit per ledger*. The minimum value of 5 was -chosen to ensure the limit never gets so small that the ledger becomes -unusable. The "target" value of 50 was chosen so the limit never gets large -enough to invite abuse, but keeps up if the network stays healthy and -active. These exact values were chosen experimentally, and can easily -change in the future. -* *Expected ledger size growth and reduction percentages*. The growth -value of 20% was chosen to allow the limit to grow quickly as load -increases, but not so quickly as to allow bad actors to run unrestricted. -The reduction value of 50% was chosen to cause the limit to drop -significantly, but not so drastically that the limit cannot quickly -recover if the problem is temporary. These exact values were chosen -experimentally, and can easily change in the future. -* *Minimum `lastLedgerMedianFeeLevel`*. The value of 500 was chosen to -ensure that the first escalated fee was more significant and noticable -than what the default would allow. This exact value was chosen -experimentally, and can easily change in the future. -* *Transaction queue size limit*. The limit is computed based on the -base fee transaction limit per ledger, so that the queue can grow -automatically as the network's performance improves, allowing -more transactions per second, and thus more transactions per ledger -to process successfully. The limit of 20 ledgers was used to provide -a balance between resource (specifically memory) usage, and giving -transactions a realistic chance to be processed. The minimum size of -2000 transactions was chosen to allow a decent functional backlog during -network congestion conditions. These exact values were -chosen experimentally, and can easily change in the future. -* *Maximum retries*. A transaction in the queue can attempt to apply -to the open ledger, but get a retry (`ter`) code up to 10 times, at -which point, it will be removed from the queue and dropped. The -value was chosen to be large enough to allow temporary failures to clear -up, but small enough that the queue doesn't fill up with stale -transactions which prevent lower fee level, but more likely to succeed, -transactions from queuing. -* *Maximum transactions per account*. A single account can have up to 10 -transactions in the queue at any given time. This is primarily to -mitigate the lost cost of broadcasting multiple transactions if one of -the earlier ones fails or is otherwise removed from the queue without -being applied to the open ledger. The value was chosen arbitrarily, and -can easily change in the future. -* *Minimum last ledger sequence buffer*. If a transaction has a -`LastLedgerSequence` value, and cannot be processed into the open -ledger, that `LastLedgerSequence` must be at least 2 more than the -sequence number of the open ledger to be considered for the queue. The -value was chosen to provide a balance between letting the user control -the lifespan of the transaction, and giving a queued transaction a -chance to get processed out of the queue before getting discarded, -particularly since it may have dependent transactions also in the queue, -which will never succeed if this one is discarded. -* *Replaced transaction fee increase*. Any transaction in the queue can be -replaced by another transaction with the same sequence number and at -least a 25% higher fee level. The 25% increase is intended to cover the -resource cost incurred by broadcasting the original transaction to the -network. This value was chosen experimentally, and can easily change in -the future. +- _Base fee transaction limit per ledger_. The minimum value of 5 was + chosen to ensure the limit never gets so small that the ledger becomes + unusable. The "target" value of 50 was chosen so the limit never gets large + enough to invite abuse, but keeps up if the network stays healthy and + active. These exact values were chosen experimentally, and can easily + change in the future. +- _Expected ledger size growth and reduction percentages_. The growth + value of 20% was chosen to allow the limit to grow quickly as load + increases, but not so quickly as to allow bad actors to run unrestricted. + The reduction value of 50% was chosen to cause the limit to drop + significantly, but not so drastically that the limit cannot quickly + recover if the problem is temporary. These exact values were chosen + experimentally, and can easily change in the future. +- _Minimum `lastLedgerMedianFeeLevel`_. The value of 500 was chosen to + ensure that the first escalated fee was more significant and noticable + than what the default would allow. This exact value was chosen + experimentally, and can easily change in the future. +- _Transaction queue size limit_. The limit is computed based on the + base fee transaction limit per ledger, so that the queue can grow + automatically as the network's performance improves, allowing + more transactions per second, and thus more transactions per ledger + to process successfully. The limit of 20 ledgers was used to provide + a balance between resource (specifically memory) usage, and giving + transactions a realistic chance to be processed. The minimum size of + 2000 transactions was chosen to allow a decent functional backlog during + network congestion conditions. These exact values were + chosen experimentally, and can easily change in the future. +- _Maximum retries_. A transaction in the queue can attempt to apply + to the open ledger, but get a retry (`ter`) code up to 10 times, at + which point, it will be removed from the queue and dropped. The + value was chosen to be large enough to allow temporary failures to clear + up, but small enough that the queue doesn't fill up with stale + transactions which prevent lower fee level, but more likely to succeed, + transactions from queuing. +- _Maximum transactions per account_. A single account can have up to 10 + transactions in the queue at any given time. This is primarily to + mitigate the lost cost of broadcasting multiple transactions if one of + the earlier ones fails or is otherwise removed from the queue without + being applied to the open ledger. The value was chosen arbitrarily, and + can easily change in the future. +- _Minimum last ledger sequence buffer_. If a transaction has a + `LastLedgerSequence` value, and cannot be processed into the open + ledger, that `LastLedgerSequence` must be at least 2 more than the + sequence number of the open ledger to be considered for the queue. The + value was chosen to provide a balance between letting the user control + the lifespan of the transaction, and giving a queued transaction a + chance to get processed out of the queue before getting discarded, + particularly since it may have dependent transactions also in the queue, + which will never succeed if this one is discarded. +- _Replaced transaction fee increase_. Any transaction in the queue can be + replaced by another transaction with the same sequence number and at + least a 25% higher fee level. The 25% increase is intended to cover the + resource cost incurred by broadcasting the original transaction to the + network. This value was chosen experimentally, and can easily change in + the future. ### `fee` command @@ -287,6 +296,7 @@ ledger. It includes the sequence number of the current open ledger, but may not make sense if rippled is not synced to the network. Result format: + ``` { "result" : { @@ -319,13 +329,13 @@ without warning.** Up to two fields in `server_info` output are related to fee escalation. 1. `load_factor_fee_escalation`: The factor on base transaction cost -that a transaction must pay to get into the open ledger. This value can -change quickly as transactions are processed from the network and -ledgers are closed. If not escalated, the value is 1, so will not be -returned. + that a transaction must pay to get into the open ledger. This value can + change quickly as transactions are processed from the network and + ledgers are closed. If not escalated, the value is 1, so will not be + returned. 2. `load_factor_fee_queue`: If the queue is full, this is the factor on -base transaction cost that a transaction must pay to get into the queue. -If not full, the value is 1, so will not be returned. + base transaction cost that a transaction must pay to get into the queue. + If not full, the value is 1, so will not be returned. In all cases, the transaction fee must be high enough to overcome both `load_factor_fee_queue` and `load_factor` to be considered. It does not @@ -341,22 +351,21 @@ without warning.** Three fields in `server_state` output are related to fee escalation. 1. `load_factor_fee_escalation`: The factor on base transaction cost -that a transaction must pay to get into the open ledger. This value can -change quickly as transactions are processed from the network and -ledgers are closed. The ratio between this value and -`load_factor_fee_reference` determines the multiplier for transaction -fees to get into the current open ledger. + that a transaction must pay to get into the open ledger. This value can + change quickly as transactions are processed from the network and + ledgers are closed. The ratio between this value and + `load_factor_fee_reference` determines the multiplier for transaction + fees to get into the current open ledger. 2. `load_factor_fee_queue`: This is the factor on base transaction cost -that a transaction must pay to get into the queue. The ratio between -this value and `load_factor_fee_reference` determines the multiplier for -transaction fees to get into the transaction queue to be considered for -a later ledger. + that a transaction must pay to get into the queue. The ratio between + this value and `load_factor_fee_reference` determines the multiplier for + transaction fees to get into the transaction queue to be considered for + a later ledger. 3. `load_factor_fee_reference`: Like `load_base`, this is the baseline -that is used to scale fee escalation computations. + that is used to scale fee escalation computations. In all cases, the transaction fee must be high enough to overcome both `load_factor_fee_queue` and `load_factor` to be considered. It does not need to overcome `load_factor_fee_escalation`, though if it does not, it is more likely to be queued than immediately processed into the open ledger. - diff --git a/src/xrpld/app/misc/README.md b/src/xrpld/app/misc/README.md index 52e6e14934..2f9fff0ca3 100644 --- a/src/xrpld/app/misc/README.md +++ b/src/xrpld/app/misc/README.md @@ -71,18 +71,18 @@ Amendment must receive at least an 80% approval rate from validating nodes for a period of two weeks before being accepted. The following example outlines the process of an Amendment from its conception to approval and usage. -* A community member proposes to change transaction processing in some way. +- A community member proposes to change transaction processing in some way. The proposal is discussed amongst the community and receives its support creating a community or human consensus. -* Some members contribute their time and work to develop the Amendment. +- Some members contribute their time and work to develop the Amendment. -* A pull request is created and the new code is folded into a rippled build +- A pull request is created and the new code is folded into a rippled build and made available for use. -* The consensus process begins with the validating nodes. +- The consensus process begins with the validating nodes. -* If the Amendment holds an 80% majority for a two week period, nodes will begin +- If the Amendment holds an 80% majority for a two week period, nodes will begin including the transaction to enable it in their initial sets. Nodes may veto Amendments they consider undesirable by never announcing their @@ -112,7 +112,7 @@ enabled. Optional online deletion happens through the SHAMapStore. Records are deleted from disk based on ledger sequence number. These records reside in the -key-value database as well as in the SQLite ledger and transaction databases. +key-value database as well as in the SQLite ledger and transaction databases. Without online deletion storage usage grows without bounds. It can only be pruned by stopping, manually deleting data, and restarting the server. Online deletion requires less operator intervention to manage the server. @@ -142,14 +142,14 @@ server restarts. Configuration: -* In the [node_db] configuration section, an optional online_delete parameter is -set. If not set or if set to 0, online delete is disabled. Otherwise, the -setting defines number of ledgers between deletion cycles. -* Another optional parameter in [node_db] is that for advisory_delete. It is -disabled by default. If set to non-zero, requires an RPC call to activate the -deletion routine. -* online_delete must not be greater than the [ledger_history] parameter. -* [fetch_depth] will be silently set to equal the online_delete setting if -online_delete is greater than fetch_depth. -* In the [node_db] section, there is a performance tuning option, delete_batch, -which sets the maximum size in ledgers for each SQL DELETE query. +- In the [node_db] configuration section, an optional online_delete parameter is + set. If not set or if set to 0, online delete is disabled. Otherwise, the + setting defines number of ledgers between deletion cycles. +- Another optional parameter in [node_db] is that for advisory_delete. It is + disabled by default. If set to non-zero, requires an RPC call to activate the + deletion routine. +- online_delete must not be greater than the [ledger_history] parameter. +- [fetch_depth] will be silently set to equal the online_delete setting if + online_delete is greater than fetch_depth. +- In the [node_db] section, there is a performance tuning option, delete_batch, + which sets the maximum size in ledgers for each SQL DELETE query. diff --git a/src/xrpld/app/rdb/README.md b/src/xrpld/app/rdb/README.md index 81aaa32f2c..a50bb395c1 100644 --- a/src/xrpld/app/rdb/README.md +++ b/src/xrpld/app/rdb/README.md @@ -2,8 +2,8 @@ The guiding principles of the Relational Database Interface are summarized below: -* All hard-coded SQL statements should be stored in the [files](#source-files) under the `xrpld/app/rdb` directory. With the exception of test modules, no hard-coded SQL should be added to any other file in rippled. -* The base class `RelationalDatabase` is inherited by derived classes that each provide an interface for operating on distinct relational database systems. +- All hard-coded SQL statements should be stored in the [files](#source-files) under the `xrpld/app/rdb` directory. With the exception of test modules, no hard-coded SQL should be added to any other file in rippled. +- The base class `RelationalDatabase` is inherited by derived classes that each provide an interface for operating on distinct relational database systems. ## Overview @@ -45,36 +45,34 @@ src/xrpld/app/rdb/ ``` ### File Contents -| File | Contents | -| ----------- | ----------- | -| `Node.[h\|cpp]` | Defines/Implements methods used by `SQLiteDatabase` for interacting with SQLite node databases| -|`SQLiteDatabase.[h\|cpp]`| Defines/Implements the class `SQLiteDatabase`/`SQLiteDatabaseImp` which inherits from `RelationalDatabase` and is used to operate on the main stores | -| `PeerFinder.[h\|cpp]` | Defines/Implements methods for interacting with the PeerFinder SQLite database | -|`RelationalDatabase.cpp`| Implements the static method `RelationalDatabase::init` which is used to initialize an instance of `RelationalDatabase` | -| `RelationalDatabase.h` | Defines the abstract class `RelationalDatabase`, the primary class of the Relational Database Interface | -| `State.[h\|cpp]` | Defines/Implements methods for interacting with the State SQLite database which concerns ledger deletion and database rotation | -| `Vacuum.[h\|cpp]` | Defines/Implements a method for performing the `VACUUM` operation on SQLite databases | -| `Wallet.[h\|cpp]` | Defines/Implements methods for interacting with Wallet SQLite databases | + +| File | Contents | +| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Node.[h\|cpp]` | Defines/Implements methods used by `SQLiteDatabase` for interacting with SQLite node databases | +| `SQLiteDatabase.[h\|cpp]` | Defines/Implements the class `SQLiteDatabase`/`SQLiteDatabaseImp` which inherits from `RelationalDatabase` and is used to operate on the main stores | +| `PeerFinder.[h\|cpp]` | Defines/Implements methods for interacting with the PeerFinder SQLite database | +| `RelationalDatabase.cpp` | Implements the static method `RelationalDatabase::init` which is used to initialize an instance of `RelationalDatabase` | +| `RelationalDatabase.h` | Defines the abstract class `RelationalDatabase`, the primary class of the Relational Database Interface | +| `State.[h\|cpp]` | Defines/Implements methods for interacting with the State SQLite database which concerns ledger deletion and database rotation | +| `Vacuum.[h\|cpp]` | Defines/Implements a method for performing the `VACUUM` operation on SQLite databases | +| `Wallet.[h\|cpp]` | Defines/Implements methods for interacting with Wallet SQLite databases | ## Classes -The abstract class `RelationalDatabase` is the primary class of the Relational Database Interface and is defined in the eponymous header file. This class provides a static method `init()` which, when invoked, creates a concrete instance of a derived class whose type is specified by the system configuration. All other methods in the class are virtual. Presently there exist two classes that derive from `RelationalDatabase`, namely `SQLiteDatabase` and `PostgresDatabase`. +The abstract class `RelationalDatabase` is the primary class of the Relational Database Interface and is defined in the eponymous header file. This class provides a static method `init()` which, when invoked, creates a concrete instance of a derived class whose type is specified by the system configuration. All other methods in the class are virtual. Presently there exist two classes that derive from `RelationalDatabase`, namely `SQLiteDatabase` and `PostgresDatabase`. ## Database Methods The Relational Database Interface provides three categories of methods for interacting with databases: -* Free functions for interacting with SQLite databases used by various components of the software. These methods feature a `soci::session` parameter which facilitates connecting to SQLite databases, and are defined and implemented in the following files: +- Free functions for interacting with SQLite databases used by various components of the software. These methods feature a `soci::session` parameter which facilitates connecting to SQLite databases, and are defined and implemented in the following files: - * `PeerFinder.[h\|cpp]` - * `State.[h\|cpp]` - * `Vacuum.[h\|cpp]` - * `Wallet.[h\|cpp]` +- `PeerFinder.[h\|cpp]` +- `State.[h\|cpp]` +- `Vacuum.[h\|cpp]` +- `Wallet.[h\|cpp]` +- Free functions used exclusively by `SQLiteDatabaseImp` for interacting with SQLite databases owned by the node store. Unlike the free functions in the files listed above, these are not intended to be invoked directly by clients. Rather, these methods are invoked by derived instances of `RelationalDatabase`. These methods are defined in the following files: + - `Node.[h|cpp]` -* Free functions used exclusively by `SQLiteDatabaseImp` for interacting with SQLite databases owned by the node store. Unlike the free functions in the files listed above, these are not intended to be invoked directly by clients. Rather, these methods are invoked by derived instances of `RelationalDatabase`. These methods are defined in the following files: - - * `Node.[h|cpp]` - - -* Member functions of `RelationalDatabase`, `SQLiteDatabase`, and `PostgresDatabase` which are used to access the node store. +- Member functions of `RelationalDatabase`, `SQLiteDatabase`, and `PostgresDatabase` which are used to access the node store. diff --git a/src/xrpld/consensus/README.md b/src/xrpld/consensus/README.md index c8850a2a51..3cc1294c4f 100644 --- a/src/xrpld/consensus/README.md +++ b/src/xrpld/consensus/README.md @@ -1,9 +1,8 @@ # Consensus This directory contains the implementation of a -generic consensus algorithm. The implementation +generic consensus algorithm. The implementation follows a CRTP design, requiring client code to implement specific functions and types to use consensus in their -application. The interface is undergoing refactoring and +application. The interface is undergoing refactoring and is not yet finalized. - diff --git a/src/xrpld/nodestore/README.md b/src/xrpld/nodestore/README.md index 1549c1ef96..a5d1128d17 100644 --- a/src/xrpld/nodestore/README.md +++ b/src/xrpld/nodestore/README.md @@ -1,6 +1,7 @@ # Database Documentation -* [NodeStore](#nodestore) -* [Benchmarks](#benchmarks) + +- [NodeStore](#nodestore) +- [Benchmarks](#benchmarks) # NodeStore @@ -12,41 +13,43 @@ identified by the hash, which is a 256 bit hash of the blob. The blob is a variable length block of serialized data. The type identifies what the blob contains. The fields are as follows: -* `mType` +- `mType` - An enumeration that determines what the blob holds. There are four - different types of objects stored. +An enumeration that determines what the blob holds. There are four +different types of objects stored. - * **ledger** +- **ledger** - A ledger header. + A ledger header. - * **transaction** +- **transaction** - A signed transaction. + A signed transaction. - * **account node** +- **account node** - A node in a ledger's account state tree. + A node in a ledger's account state tree. - * **transaction node** +- **transaction node** - A node in a ledger's transaction tree. + A node in a ledger's transaction tree. -* `mHash` +- `mHash` - A 256-bit hash of the blob. +A 256-bit hash of the blob. -* `mData` +- `mData` - A blob containing the payload. Stored in the following format. +A blob containing the payload. Stored in the following format. + +| Byte | | | +| :------ | :----- | :------------------------- | +| 0...7 | unused | | +| 8 | type | NodeObjectType enumeration | +| 9...end | data | body of the object data | -|Byte | | | -|:------|:--------------------|:-------------------------| -|0...7 |unused | | -|8 |type |NodeObjectType enumeration| -|9...end|data |body of the object data | --- + The `NodeStore` provides an interface that stores, in a persistent database, a collection of NodeObjects that rippled uses as its primary representation of ledger entries. All ledger entries are stored as NodeObjects and as such, need @@ -64,41 +67,42 @@ the configuration file [node_db] section as follows. One or more lines of key / value pairs Example: + ``` type=RocksDB path=rocksdb compression=1 ``` + Choices for 'type' (not case-sensitive) -* **HyperLevelDB** +- **HyperLevelDB** - An improved version of LevelDB (preferred). +An improved version of LevelDB (preferred). -* **LevelDB** +- **LevelDB** - Google's LevelDB database (deprecated). +Google's LevelDB database (deprecated). -* **none** +- **none** - Use no backend. +Use no backend. -* **RocksDB** +- **RocksDB** - Facebook's RocksDB database, builds on LevelDB. +Facebook's RocksDB database, builds on LevelDB. -* **SQLite** +- **SQLite** - Use SQLite. +Use SQLite. 'path' speficies where the backend will store its data files. Choices for 'compression' -* **0** off - -* **1** on (default) +- **0** off +- **1** on (default) # Benchmarks @@ -129,48 +133,48 @@ RocksDBQuickFactory is intended to provide a testbed for comparing potential rocksdb performance with the existing recommended configuration in rippled.cfg. Through various executions and profiling some conclusions are presented below. -* If the write ahead log is enabled, insert speed soon clogs up under load. The -BatchWriter class intends to stop this from blocking the main threads by queuing -up writes and running them in a separate thread. However, rocksdb already has -separate threads dedicated to flushing the memtable to disk and the memtable is -itself an in-memory queue. The result is two queues with a guarantee of -durability in between. However if the memtable was used as the sole queue and -the rocksdb::Flush() call was manually triggered at opportune moments, possibly -just after ledger close, then that would provide similar, but more predictable -guarantees. It would also remove an unneeded thread and unnecessary memory -usage. An alternative point of view is that because there will always be many -other rippled instances running there is no need for such guarantees. The nodes -will always be available from another peer. +- If the write ahead log is enabled, insert speed soon clogs up under load. The + BatchWriter class intends to stop this from blocking the main threads by queuing + up writes and running them in a separate thread. However, rocksdb already has + separate threads dedicated to flushing the memtable to disk and the memtable is + itself an in-memory queue. The result is two queues with a guarantee of + durability in between. However if the memtable was used as the sole queue and + the rocksdb::Flush() call was manually triggered at opportune moments, possibly + just after ledger close, then that would provide similar, but more predictable + guarantees. It would also remove an unneeded thread and unnecessary memory + usage. An alternative point of view is that because there will always be many + other rippled instances running there is no need for such guarantees. The nodes + will always be available from another peer. -* Lookup in a block was previously using binary search. With rippled's use case -it is highly unlikely that two adjacent key/values will ever be requested one -after the other. Therefore hash indexing of blocks makes much more sense. -Rocksdb has a number of options for hash indexing both memtables and blocks and -these need more testing to find the best choice. +- Lookup in a block was previously using binary search. With rippled's use case + it is highly unlikely that two adjacent key/values will ever be requested one + after the other. Therefore hash indexing of blocks makes much more sense. + Rocksdb has a number of options for hash indexing both memtables and blocks and + these need more testing to find the best choice. -* The current Database implementation has two forms of caching, so the LRU cache -of blocks at Factory level does not make any sense. However, if the hash -indexing and potentially the new [bloom -filter](http://rocksdb.org/blog/1427/new-bloom-filter-format/) can provide -faster lookup for non-existent keys, then potentially the caching could exist at -Factory level. +- The current Database implementation has two forms of caching, so the LRU cache + of blocks at Factory level does not make any sense. However, if the hash + indexing and potentially the new [bloom + filter](http://rocksdb.org/blog/1427/new-bloom-filter-format/) can provide + faster lookup for non-existent keys, then potentially the caching could exist at + Factory level. -* Multiple runs of the benchmarks can yield surprisingly different results. This -can perhaps be attributed to the asynchronous nature of rocksdb's compaction -process. The benchmarks are artifical and create highly unlikely write load to -create the dataset to measure different read access patterns. Therefore multiple -runs of the benchmarks are required to get a feel for the effectiveness of the -changes. This contrasts sharply with the keyvadb benchmarking were highly -repeatable timings were discovered. Also realistically sized datasets are -required to get a correct insight. The number of 2,000,000 key/values (actually -4,000,000 after the two insert benchmarks complete) is too low to get a full -picture. +- Multiple runs of the benchmarks can yield surprisingly different results. This + can perhaps be attributed to the asynchronous nature of rocksdb's compaction + process. The benchmarks are artifical and create highly unlikely write load to + create the dataset to measure different read access patterns. Therefore multiple + runs of the benchmarks are required to get a feel for the effectiveness of the + changes. This contrasts sharply with the keyvadb benchmarking were highly + repeatable timings were discovered. Also realistically sized datasets are + required to get a correct insight. The number of 2,000,000 key/values (actually + 4,000,000 after the two insert benchmarks complete) is too low to get a full + picture. -* An interesting side effect of running the benchmarks in a profiler was that a -clear pattern of what RocksDB does under the hood was observable. This led to -the decision to trial hash indexing and also the discovery of the native CRC32 -instruction not being used. +- An interesting side effect of running the benchmarks in a profiler was that a + clear pattern of what RocksDB does under the hood was observable. This led to + the decision to trial hash indexing and also the discovery of the native CRC32 + instruction not being used. -* Important point to note that is if this factory is tested with an existing set -of sst files none of the old sst files will benefit from indexing changes until -they are compacted at a future point in time. +- Important point to note that is if this factory is tested with an existing set + of sst files none of the old sst files will benefit from indexing changes until + they are compacted at a future point in time. diff --git a/src/xrpld/overlay/README.md b/src/xrpld/overlay/README.md index 6525e5edf8..cd00488915 100644 --- a/src/xrpld/overlay/README.md +++ b/src/xrpld/overlay/README.md @@ -39,10 +39,10 @@ The HTTP [request](https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html) must: - Use HTTP version 1.1. - Specify a request URI consisting of a single forward slash character ("/") -indicating the server root. Requests using different URIs are reserved for -future protocol implementations. + indicating the server root. Requests using different URIs are reserved for + future protocol implementations. - Use the [_HTTP/1.1 Upgrade_][upgrade_header] mechanism with additional custom -fields to communicate protocol specific information related to the upgrade. + fields to communicate protocol specific information related to the upgrade. HTTP requests which do not conform to this requirements must generate an appropriate HTTP error and result in the connection being closed. @@ -72,7 +72,6 @@ Previous-Ledger: q4aKbP7sd5wv+EXArwCmQiWZhq9AwBl2p/hCtpGJNsc= ##### Example HTTP Upgrade Response (Success) - ``` HTTP/1.1 101 Switching Protocols Connection: Upgrade @@ -102,9 +101,9 @@ Content-Type: application/json #### Standard Fields -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `User-Agent` | :heavy_check_mark: | | +| Field Name | Request | Response | +| ------------ | :----------------: | :------: | +| `User-Agent` | :heavy_check_mark: | | The `User-Agent` field indicates the version of the software that the peer that is making the HTTP request is using. No semantic meaning is @@ -113,9 +112,9 @@ specify the version of the software that is used. See [RFC2616 §14.43](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43). -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Server` | | :heavy_check_mark: | +| Field Name | Request | Response | +| ---------- | :-----: | :----------------: | +| `Server` | | :heavy_check_mark: | The `Server` field indicates the version of the software that the peer that is processing the HTTP request is using. No semantic meaning is @@ -124,18 +123,18 @@ specify the version of the software that is used. See [RFC2616 §14.38](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.38). -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Connection` | :heavy_check_mark: | :heavy_check_mark: | +| Field Name | Request | Response | +| ------------ | :----------------: | :----------------: | +| `Connection` | :heavy_check_mark: | :heavy_check_mark: | The `Connection` field should have a value of `Upgrade` to indicate that a request to upgrade the connection is being performed. See [RFC2616 §14.10](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.10). -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Upgrade` | :heavy_check_mark: | :heavy_check_mark: | +| Field Name | Request | Response | +| ---------- | :----------------: | :----------------: | +| `Upgrade` | :heavy_check_mark: | :heavy_check_mark: | The `Upgrade` field is part of the standard connection upgrade mechanism and must be present in both requests and responses. It is used to negotiate the @@ -156,12 +155,11 @@ equal to 2 and the minor is greater than or equal to 0. See [RFC 2616 §14.42](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.42) - #### Custom Fields -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Connect-As` | :heavy_check_mark: | :heavy_check_mark: | +| Field Name | Request | Response | +| ------------ | :----------------: | :----------------: | +| `Connect-As` | :heavy_check_mark: | :heavy_check_mark: | The mandatory `Connect-As` field is used to specify that type of connection that is being requested. @@ -175,10 +173,9 @@ elements specified in the request. If a server processing a request does not recognize any of the connection types, the request should fail with an appropriate HTTP error code (e.g. by sending an HTTP 400 "Bad Request" response). - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Remote-IP` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| ----------- | :----------------: | :----------------: | +| `Remote-IP` | :white_check_mark: | :white_check_mark: | The optional `Remote-IP` field contains the string representation of the IP address of the remote end of the connection as seen from the peer that is @@ -187,10 +184,9 @@ sending the field. By observing values of this field from a sufficient number of different servers, a peer making outgoing connections can deduce its own IP address. - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Local-IP` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| ---------- | :----------------: | :----------------: | +| `Local-IP` | :white_check_mark: | :white_check_mark: | The optional `Local-IP` field contains the string representation of the IP address that the peer sending the field believes to be its own. @@ -198,10 +194,9 @@ address that the peer sending the field believes to be its own. Servers receiving this field can detect IP address mismatches, which may indicate a potential man-in-the-middle attack. - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Network-ID` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| ------------ | :----------------: | :----------------: | +| `Network-ID` | :white_check_mark: | :white_check_mark: | The optional `Network-ID` can be used to identify to which of several [parallel networks](https://xrpl.org/parallel-networks.html) the server @@ -217,10 +212,9 @@ If a server configured to join one network receives a connection request from a server configured to join another network, the request should fail with an appropriate HTTP error code (e.g. by sending an HTTP 400 "Bad Request" response). - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Network-Time` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| -------------- | :----------------: | :----------------: | +| `Network-Time` | :white_check_mark: | :white_check_mark: | The optional `Network-Time` field reports the current [time](https://xrpl.org/basic-data-types.html#specifying-time) according to sender's internal clock. @@ -232,20 +226,18 @@ each other with an appropriate HTTP error code (e.g. by sending an HTTP 400 It is highly recommended that servers synchronize their clocks using time synchronization software. For more on this topic, please visit [ntp.org](http://www.ntp.org/). - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Public-Key` | :heavy_check_mark: | :heavy_check_mark: | +| Field Name | Request | Response | +| ------------ | :----------------: | :----------------: | +| `Public-Key` | :heavy_check_mark: | :heavy_check_mark: | The mandatory `Public-Key` field identifies the sending server's public key, encoded in base58 using the standard encoding for node public keys. See: https://xrpl.org/base58-encodings.html - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Server-Domain` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| --------------- | :----------------: | :----------------: | +| `Server-Domain` | :white_check_mark: | :white_check_mark: | The optional `Server-Domain` field allows a server to report the domain that it is operating under. The value is configured by the server administrator in @@ -259,10 +251,9 @@ under the specified domain and locating the public key of this server under the Sending a malformed domain will prevent a connection from being established. - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Session-Signature` | :heavy_check_mark: | :heavy_check_mark: | +| Field Name | Request | Response | +| ------------------- | :----------------: | :----------------: | +| `Session-Signature` | :heavy_check_mark: | :heavy_check_mark: | The `Session-Signature` field is mandatory and is used to secure the peer link against certain types of attack. For more details see "Session Signature" below. @@ -272,36 +263,35 @@ should support both **Base64** and **HEX** encoding for this value. For more details on this field, please see **Session Signature** below. - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Crawl` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| ---------- | :----------------: | :----------------: | +| `Crawl` | :white_check_mark: | :white_check_mark: | The optional `Crawl` field can be used by a server to indicate whether peers should include it in crawl reports. The field can take two values: + - **`Public`**: The server's IP address and port should be included in crawl -reports. + reports. - **`Private`**: The server's IP address and port should not be included in -crawl reports. _This is the default, if the field is omitted._ + crawl reports. _This is the default, if the field is omitted._ For more on the Peer Crawler, please visit https://xrpl.org/peer-crawler.html. - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Closed-Ledger` | :white_check_mark: | :white_check_mark: | +| Field Name | Request | Response | +| --------------- | :----------------: | :----------------: | +| `Closed-Ledger` | :white_check_mark: | :white_check_mark: | If present, identifies the hash of the last ledger that the sending server considers to be closed. The value is encoded as **HEX**, but implementations should support both **Base64** and **HEX** encoding for this value for legacy purposes. - -| Field Name | Request | Response | -|--------------------- |:-----------------: |:-----------------: | -| `Previous-Ledger` | :white_check_mark: | :white_check_mark: | + +| Field Name | Request | Response | +| ----------------- | :----------------: | :----------------: | +| `Previous-Ledger` | :white_check_mark: | :white_check_mark: | If present, identifies the hash of the parent ledger that the sending server considers to be closed. @@ -317,7 +307,6 @@ and values in both requests and responses. Implementations should not reject requests because of the presence of fields that they do not understand. - ### Session Signature Even for SSL/TLS encrypted connections, it is possible for an attacker to mount @@ -365,8 +354,7 @@ transferred between A and B and will not be able to intelligently tamper with th message stream between Alice and Bob, although she may be still be able to inject delays or terminate the link. - -# Ripple Clustering # +# Ripple Clustering A cluster consists of more than one Ripple server under common administration that share load information, distribute cryptography @@ -374,19 +362,19 @@ operations, and provide greater response consistency. Cluster nodes are identified by their public node keys. Cluster nodes exchange information about endpoints that are imposing load upon them. -Cluster nodes share information about their internal load status. Cluster +Cluster nodes share information about their internal load status. Cluster nodes do not have to verify the cryptographic signatures on messages received from other cluster nodes. -## Configuration ## +## Configuration A server's public key can be determined from the output of the `server_info` -command. The key is in the `pubkey_node` value, and is a text string -beginning with the letter `n`. The key is maintained across runs in a +command. The key is in the `pubkey_node` value, and is a text string +beginning with the letter `n`. The key is maintained across runs in a database. Cluster members are configured in the `rippled.cfg` file under -`[cluster_nodes]`. Each member should be configured on a line beginning +`[cluster_nodes]`. Each member should be configured on a line beginning with the node public key, followed optionally by a space and a friendly name. @@ -404,23 +392,23 @@ New spokes can be added as follows: - Restart each hub, one by one - Restart the spoke -## Transaction Behavior ## +## Transaction Behavior When a transaction is received from a cluster member, several normal checks are bypassed: Signature checking is bypassed because we trust that a cluster member would -not relay a transaction with an incorrect signature. Validators may wish to +not relay a transaction with an incorrect signature. Validators may wish to disable this feature, preferring the additional load to get the additional security of having validators check each transaction. Local checks for transaction checking are also bypassed. For example, a server will not reject a transaction from a cluster peer because the fee -does not meet its current relay fee. It is preferable to keep the cluster +does not meet its current relay fee. It is preferable to keep the cluster in agreement and permit confirmation from one cluster member to more reliably indicate the transaction's acceptance by the cluster. -## Server Load Information ## +## Server Load Information Cluster members exchange information on their server's load level. The load level is essentially the amount by which the normal fee levels are multiplied @@ -431,22 +419,22 @@ fee, is the highest of its local load level, the network load level, and the cluster load level. The cluster load level is the median load level reported by a cluster member. -## Gossip ## +## Gossip Gossip is the mechanism by which cluster members share information about endpoints (typically IPv4 addresses) that are imposing unusually high load -on them. The endpoint load manager takes into account gossip to reduce the +on them. The endpoint load manager takes into account gossip to reduce the amount of load the endpoint is permitted to impose on the local server before it is warned, disconnected, or banned. Suppose, for example, that an attacker controls a large number of IP addresses, and with these, he can send sufficient requests to overload a -server. Without gossip, he could use these same addresses to overload all -the servers in a cluster. With gossip, if he chooses to use the same IP +server. Without gossip, he could use these same addresses to overload all +the servers in a cluster. With gossip, if he chooses to use the same IP address to impose load on more than one server, he will find that the amount of load he can impose before getting disconnected is much lower. -## Monitoring ## +## Monitoring The `peers` command will report on the status of the cluster. The `cluster` object will contain one entry for each member of the cluster (either configured diff --git a/src/xrpld/peerfinder/README.md b/src/xrpld/peerfinder/README.md index ab1ac4491a..a3f89fd446 100644 --- a/src/xrpld/peerfinder/README.md +++ b/src/xrpld/peerfinder/README.md @@ -1,4 +1,3 @@ - # PeerFinder ## Introduction @@ -31,23 +30,23 @@ slots_. PeerFinder has these responsibilities -* Maintain a persistent set of endpoint addresses suitable for bootstrapping +- Maintain a persistent set of endpoint addresses suitable for bootstrapping into the peer to peer overlay, ranked by relative locally observed utility. -* Send and receive protocol messages for discovery of endpoint addresses. +- Send and receive protocol messages for discovery of endpoint addresses. -* Provide endpoint addresses to new peers that need them. +- Provide endpoint addresses to new peers that need them. -* Maintain connections to a configured set of fixed peers. +- Maintain connections to a configured set of fixed peers. -* Impose limits on the various slots consumed by peer connections. +- Impose limits on the various slots consumed by peer connections. -* Initiate outgoing connection attempts to endpoint addresses to maintain the +- Initiate outgoing connection attempts to endpoint addresses to maintain the overlay connectivity and fixed peer policies. -* Verify the connectivity of neighbors who advertise inbound connection slots. +- Verify the connectivity of neighbors who advertise inbound connection slots. -* Prevent duplicate connections and connections to self. +- Prevent duplicate connections and connections to self. --- @@ -79,28 +78,28 @@ The `Config` structure defines the operational parameters of the PeerFinder. Some values come from the configuration file while others are calculated via tuned heuristics. The fields are as follows: -* `autoConnect` - +- `autoConnect` + A flag indicating whether or not the Autoconnect feature is enabled. -* `wantIncoming` +- `wantIncoming` A flag indicating whether or not the peer desires inbound connections. When this flag is turned off, a peer will not advertise itself in Endpoint messages. -* `listeningPort` +- `listeningPort` The port number to use when creating the listening socket for peer connections. -* `maxPeers` +- `maxPeers` The largest number of active peer connections to allow. This includes inbound and outbound connections, but excludes fixed and cluster peers. There is an implementation defined floor on this value. -* `outPeers` +- `outPeers` The number of automatic outbound connections that PeerFinder will maintain when the Autoconnect feature is enabled. The value is computed with fractional @@ -161,8 +160,8 @@ Endpoint messages are received from the overlay over time. The `Bootcache` stores IP addresses useful for gaining initial connections. Each address is associated with the following metadata: - -* **Valence** + +- **Valence** A signed integer which represents the number of successful consecutive connection attempts when positive, and the number of @@ -202,30 +201,30 @@ a slot. Slots have properties and state associated with them: The slot state represents the current stage of the connection as it passes through the business logic for establishing peer connections. -* `accept` +- `accept` The accept state is an initial state resulting from accepting an incoming connection request on a listening socket. The remote IP address and port are known, and a handshake is expected next. -* `connect` +- `connect` The connect state is an initial state used when actively establishing outbound connection attempts. The desired remote IP address and port are known. -* `connected` +- `connected` When an outbound connection attempt succeeds, it moves to the connected state. The handshake is initiated but not completed. -* `active` +- `active` The state becomes Active when a connection in either the Accepted or Connected state completes the handshake process, and a slot is available based on the properties. If no slot is available when the handshake completes, the socket is gracefully closed. -* `closing` +- `closing` The Closing state represents a connected socket in the process of being gracefully closed. @@ -234,13 +233,13 @@ through the business logic for establishing peer connections. Slot properties may be combined and are not mutually exclusive. -* **Inbound** +- **Inbound** An inbound slot is the condition of a socket which has accepted an incoming connection request. A connection which is not inbound is by definition outbound. -* **Fixed** +- **Fixed** A fixed slot is a desired connection to a known peer identified by IP address, usually entered manually in the configuration file. For the purpose of @@ -248,14 +247,14 @@ Slot properties may be combined and are not mutually exclusive. although only the IP address is checked to determine if the fixed peer is already connected. Fixed slots do not count towards connection limits. -* **Cluster** +- **Cluster** A cluster slot is a connection which has completed the handshake stage, whose public key matches a known public key usually entered manually in the configuration file or learned through overlay messages from other trusted peers. Cluster slots do not count towards connection limits. -* **Superpeer** (forthcoming) +- **Superpeer** (forthcoming) A superpeer slot is a connection to a peer which can accept incoming connections, meets certain resource availaibility requirements (such as @@ -279,7 +278,7 @@ Cluster slots are identified by the public key and set up during the initialization of the manager or discovered upon receipt of messages in the overlay from trusted connections. --------------------------------------------------------------------------------- +--- # Algorithms @@ -295,8 +294,8 @@ This stage is invoked when the number of active fixed connections is below the number of fixed connections specified in the configuration, and one of the following is true: -* There are eligible fixed addresses to try -* Any outbound connection attempts are in progress +- There are eligible fixed addresses to try +- Any outbound connection attempts are in progress Each fixed address is associated with a retry timer. On a fixed connection failure, the timer is reset so that the address is not tried for some amount @@ -317,8 +316,8 @@ The Livecache is invoked when Stage 1 is not active, autoconnect is enabled, and the number of active outbound connections is below the number desired. The stage remains active while: -* The Livecache has addresses to try -* Any outbound connection attempts are in progress +- The Livecache has addresses to try +- Any outbound connection attempts are in progress PeerFinder makes its best effort to exhaust addresses in the Livecache before moving on to the Bootcache, because Livecache addresses are highly likely @@ -333,7 +332,7 @@ The Bootcache is invoked when Stage 1 and Stage 2 are not active, autoconnect is enabled, and the number of active outbound connections is below the number desired. The stage remains active while: -* There are addresses in the cache that have not been tried recently. +- There are addresses in the cache that have not been tried recently. Entries in the Bootcache are ranked, with highly connectible addresses preferred over others. Connection attempts to Bootcache addresses are very likely to @@ -342,7 +341,7 @@ not have open slots. Before the remote peer closes the connection it will send a handful of addresses from its Livecache to help the new peer coming online obtain connections. --------------------------------------------------------------------------------- +--- # References @@ -352,10 +351,11 @@ Much of the work in PeerFinder was inspired by earlier work in Gnutella: _By Christopher Rohrs and Vincent Falco_ [Gnutella 0.6 Protocol:](http://rfc-gnutella.sourceforge.net/src/rfc-0_6-draft.html) Sections: -* 2.2.2 Ping (0x00) -* 2.2.3 Pong (0x01) -* 2.2.4 Use of Ping and Pong messages -* 2.2.4.1 A simple pong caching scheme -* 2.2.4.2 Other pong caching schemes + +- 2.2.2 Ping (0x00) +- 2.2.3 Pong (0x01) +- 2.2.4 Use of Ping and Pong messages +- 2.2.4.1 A simple pong caching scheme +- 2.2.4.2 Other pong caching schemes [overlay_network]: http://en.wikipedia.org/wiki/Overlay_network diff --git a/src/xrpld/rpc/README.md b/src/xrpld/rpc/README.md index cece30a3b2..5bb9655a76 100644 --- a/src/xrpld/rpc/README.md +++ b/src/xrpld/rpc/README.md @@ -2,15 +2,16 @@ ## Introduction. -By default, an RPC handler runs as an uninterrupted task on the JobQueue. This +By default, an RPC handler runs as an uninterrupted task on the JobQueue. This is fine for commands that are fast to compute but might not be acceptable for tasks that require multiple parts or are large, like a full ledger. -For this purpose, the rippled RPC handler allows *suspension with continuation* +For this purpose, the rippled RPC handler allows _suspension with continuation_ + - a request to suspend execution of the RPC response and to continue it after -some function or job has been executed. A default continuation is supplied -which simply reschedules the job on the JobQueue, or the programmer can supply -their own. + some function or job has been executed. A default continuation is supplied + which simply reschedules the job on the JobQueue, or the programmer can supply + their own. ## The classes. @@ -28,16 +29,16 @@ would prevent any other task from making forward progress when you call a `Callback`. A `Continuation` is a function that is given a `Callback` and promises to call -it later. A `Continuation` guarantees to call the `Callback` exactly once at +it later. A `Continuation` guarantees to call the `Callback` exactly once at some point in the future, but it does not have to be immediately or even in the current thread. -A `Suspend` is a function belonging to a `Coroutine`. A `Suspend` runs a +A `Suspend` is a function belonging to a `Coroutine`. A `Suspend` runs a `Continuation`, passing it a `Callback` that continues execution of the `Coroutine`. And finally, a `Coroutine` is a `std::function` which is given a -`Suspend`. This is what the RPC handler gives to the coroutine manager, +`Suspend`. This is what the RPC handler gives to the coroutine manager, expecting to get called back with a `Suspend` and to be able to start execution. ## The flow of control. diff --git a/src/xrpld/shamap/README.md b/src/xrpld/shamap/README.md index ef2d22024b..3bff74e67b 100644 --- a/src/xrpld/shamap/README.md +++ b/src/xrpld/shamap/README.md @@ -1,4 +1,4 @@ -# SHAMap Introduction # +# SHAMap Introduction March 2020 @@ -30,20 +30,20 @@ The root node is always a SHAMapInnerNode. A given `SHAMap` always stores only one of three kinds of data: - * Transactions with metadata - * Transactions without metadata, or - * Account states. +- Transactions with metadata +- Transactions without metadata, or +- Account states. So all of the leaf nodes of a particular `SHAMap` will always have a uniform type. The inner nodes carry no data other than the hash of the nodes beneath them. All nodes are owned by shared_ptrs resident in either other nodes, or in case of -the root node, a shared_ptr in the `SHAMap` itself. The use of shared_ptrs -permits more than one `SHAMap` at a time to share ownership of a node. This +the root node, a shared_ptr in the `SHAMap` itself. The use of shared_ptrs +permits more than one `SHAMap` at a time to share ownership of a node. This occurs (for example), when a copy of a `SHAMap` is made. Copies are made with the `snapShot` function as opposed to the `SHAMap` copy -constructor. See the section on `SHAMap` creation for more details about +constructor. See the section on `SHAMap` creation for more details about `snapShot`. Sequence numbers are used to further customize the node ownership strategy. See @@ -51,62 +51,62 @@ the section on sequence numbers for details on sequence numbers. ![node diagram](https://user-images.githubusercontent.com/46455409/77350005-1ef12c80-6cf9-11ea-9c8d-56410f442859.png) -## Mutability ## +## Mutability There are two different ways of building and using a `SHAMap`: - 1. A mutable `SHAMap` and - 2. An immutable `SHAMap` +1. A mutable `SHAMap` and +2. An immutable `SHAMap` The distinction here is not of the classic C++ immutable-means-unchanging sense. - An immutable `SHAMap` contains *nodes* that are immutable. Also, once a node has +An immutable `SHAMap` contains _nodes_ that are immutable. Also, once a node has been located in an immutable `SHAMap`, that node is guaranteed to persist in that `SHAMap` for the lifetime of the `SHAMap`. So, somewhat counter-intuitively, an immutable `SHAMap` may grow as new nodes are -introduced. But an immutable `SHAMap` will never get smaller (until it entirely -evaporates when it is destroyed). Nodes, once introduced to the immutable -`SHAMap`, also never change their location in memory. So nodes in an immutable +introduced. But an immutable `SHAMap` will never get smaller (until it entirely +evaporates when it is destroyed). Nodes, once introduced to the immutable +`SHAMap`, also never change their location in memory. So nodes in an immutable `SHAMap` can be handled using raw pointers (if you're careful). One consequence of this design is that an immutable `SHAMap` can never be -"trimmed". There is no way to identify unnecessary nodes in an immutable `SHAMap` -that could be removed. Once a node has been brought into the in-memory `SHAMap`, +"trimmed". There is no way to identify unnecessary nodes in an immutable `SHAMap` +that could be removed. Once a node has been brought into the in-memory `SHAMap`, that node stays in memory for the life of the `SHAMap`. Most `SHAMap`s are immutable, in the sense that they don't modify or remove their contained nodes. An example where a mutable `SHAMap` is required is when we want to apply -transactions to the last closed ledger. To do so we'd make a mutable snapshot +transactions to the last closed ledger. To do so we'd make a mutable snapshot of the state trie and then start applying transactions to it. Because the snapshot is mutable, changes to nodes in the snapshot will not affect nodes in other `SHAMap`s. An example using a immutable ledger would be when there's an open ledger and -some piece of code wishes to query the state of the ledger. In this case we +some piece of code wishes to query the state of the ledger. In this case we don't wish to change the state of the `SHAMap`, so we'd use an immutable snapshot. -## Sequence numbers ## +## Sequence numbers -Both `SHAMap`s and their nodes carry a sequence number. This is simply an +Both `SHAMap`s and their nodes carry a sequence number. This is simply an unsigned number that indicates ownership or membership, or a non-membership. -`SHAMap`s sequence numbers normally start out as 1. However when a snap-shot of +`SHAMap`s sequence numbers normally start out as 1. However when a snap-shot of a `SHAMap` is made, the copy's sequence number is 1 greater than the original. -The nodes of a `SHAMap` have their own copy of a sequence number. If the `SHAMap` +The nodes of a `SHAMap` have their own copy of a sequence number. If the `SHAMap` is mutable, meaning it can change, then all of its nodes must have the -same sequence number as the `SHAMap` itself. This enforces an invariant that none +same sequence number as the `SHAMap` itself. This enforces an invariant that none of the nodes are shared with other `SHAMap`s. When a `SHAMap` needs to have a private copy of a node, not shared by any other `SHAMap`, it first clones it and then sets the new copy to have a sequence number -equal to the `SHAMap` sequence number. The `unshareNode` is a private utility +equal to the `SHAMap` sequence number. The `unshareNode` is a private utility which automates the task of first checking if the node is already sharable, and -if so, cloning it and giving it the proper sequence number. An example case +if so, cloning it and giving it the proper sequence number. An example case where a private copy is needed is when an inner node needs to have a child -pointer altered. Any modification to a node will require a non-shared node. +pointer altered. Any modification to a node will require a non-shared node. When a `SHAMap` decides that it is safe to share a node of its own, it sets the node's sequence number to 0 (a `SHAMap` never has a sequence number of 0). This @@ -116,40 +116,40 @@ Note that other objects in rippled also have sequence numbers (e.g. ledgers). The `SHAMap` and node sequence numbers should not be confused with these other sequence numbers (no relation). -## SHAMap Creation ## +## SHAMap Creation -A `SHAMap` is usually not created from vacuum. Once an initial `SHAMap` is +A `SHAMap` is usually not created from vacuum. Once an initial `SHAMap` is constructed, later `SHAMap`s are usually created by calling snapShot(bool -isMutable) on the original `SHAMap`. The returned `SHAMap` has the expected +isMutable) on the original `SHAMap`. The returned `SHAMap` has the expected characteristics (mutable or immutable) based on the passed in flag. It is cheaper to make an immutable snapshot of a `SHAMap` than to make a mutable -snapshot. If the `SHAMap` snapshot is mutable then sharable nodes must be +snapshot. If the `SHAMap` snapshot is mutable then sharable nodes must be copied before they are placed in the mutable map. -A new `SHAMap` is created with each new ledger round. Transactions not executed +A new `SHAMap` is created with each new ledger round. Transactions not executed in the previous ledger populate the `SHAMap` for the new ledger. -## Storing SHAMap data in the database ## +## Storing SHAMap data in the database -When consensus is reached, the ledger is closed. As part of this process, the +When consensus is reached, the ledger is closed. As part of this process, the `SHAMap` is stored to the database by calling `SHAMap::flushDirty`. Both `unshare()` and `flushDirty` walk the `SHAMap` by calling -`SHAMap::walkSubTree`. As `unshare()` walks the trie, nodes are not written to +`SHAMap::walkSubTree`. As `unshare()` walks the trie, nodes are not written to the database, and as `flushDirty` walks the trie nodes are written to the database. `walkSubTree` visits every node in the trie. This process must ensure that each node is only owned by this trie, and so "unshares" as it walks each -node (from the root down). This is done in the `preFlushNode` function by -ensuring that the node has a sequence number equal to that of the `SHAMap`. If +node (from the root down). This is done in the `preFlushNode` function by +ensuring that the node has a sequence number equal to that of the `SHAMap`. If the node doesn't, it is cloned. For each inner node encountered (starting with the root node), each of the -children are inspected (from 1 to 16). For each child, if it has a non-zero -sequence number (unshareable), the child is first copied. Then if the child is -an inner node, we recurse down to that node's children. Otherwise we've found a -leaf node and that node is written to the database. A count of each leaf node -that is visited is kept. The hash of the data in the leaf node is computed at +children are inspected (from 1 to 16). For each child, if it has a non-zero +sequence number (unshareable), the child is first copied. Then if the child is +an inner node, we recurse down to that node's children. Otherwise we've found a +leaf node and that node is written to the database. A count of each leaf node +that is visited is kept. The hash of the data in the leaf node is computed at this time, and the child is reassigned back into the parent inner node just in case the COW operation created a new pointer to this leaf node. @@ -157,22 +157,22 @@ After processing each node, the node is then marked as sharable again by setting its sequence number to 0. After all of an inner node's children are processed, then its hash is updated -and the inner node is written to the database. Then this inner node is assigned +and the inner node is written to the database. Then this inner node is assigned back into it's parent node, again in case the COW operation created a new pointer to it. -## Walking a SHAMap ## +## Walking a SHAMap -The private function `SHAMap::walkTowardsKey` is a good example of *how* to walk +The private function `SHAMap::walkTowardsKey` is a good example of _how_ to walk a `SHAMap`, and the various functions that call `walkTowardsKey` are good examples -of *why* one would want to walk a `SHAMap` (e.g. `SHAMap::findKey`). +of _why_ one would want to walk a `SHAMap` (e.g. `SHAMap::findKey`). `walkTowardsKey` always starts at the root of the `SHAMap` and traverses down through the inner nodes, looking for a leaf node along a path in the trie designated by a `uint256`. -As one walks the trie, one can *optionally* keep a stack of nodes that one has -passed through. This isn't necessary for walking the trie, but many clients -will use the stack after finding the desired node. For example if one is +As one walks the trie, one can _optionally_ keep a stack of nodes that one has +passed through. This isn't necessary for walking the trie, but many clients +will use the stack after finding the desired node. For example if one is deleting a node from the trie, the stack is handy for repairing invariants in the trie after the deletion. @@ -189,10 +189,10 @@ how we use a `SHAMapNodeID` to select a "branch" (child) by indexing into a path at a given depth. While the current node is an inner node, traversing down the trie from the root -continues, unless the path indicates a child that does not exist. And in this +continues, unless the path indicates a child that does not exist. And in this case, `nullptr` is returned to indicate no leaf node along the given path -exists. Otherwise a leaf node is found and a (non-owning) pointer to it is -returned. At each step, if a stack is requested, a +exists. Otherwise a leaf node is found and a (non-owning) pointer to it is +returned. At each step, if a stack is requested, a `pair, SHAMapNodeID>` is pushed onto the stack. When a child node is found by `selectBranch`, the traversal to that node @@ -210,35 +210,35 @@ The first step consists of several attempts to find the node in various places: If the node is not found in the trie, then it is installed into the trie as part of the traversal process. -## Late-arriving Nodes ## +## Late-arriving Nodes -As we noted earlier, `SHAMap`s (even immutable ones) may grow. If a `SHAMap` is +As we noted earlier, `SHAMap`s (even immutable ones) may grow. If a `SHAMap` is searching for a node and runs into an empty spot in the trie, then the `SHAMap` -looks to see if the node exists but has not yet been made part of the map. This -operation is performed in the `SHAMap::fetchNodeNT()` method. The *NT* +looks to see if the node exists but has not yet been made part of the map. This +operation is performed in the `SHAMap::fetchNodeNT()` method. The _NT_ is this case stands for 'No Throw'. The `fetchNodeNT()` method goes through three phases: - 1. By calling `cacheLookup()` we attempt to locate the missing node in the - TreeNodeCache. The TreeNodeCache is a cache of immutable SHAMapTreeNodes +1. By calling `cacheLookup()` we attempt to locate the missing node in the + TreeNodeCache. The TreeNodeCache is a cache of immutable SHAMapTreeNodes that are shared across all `SHAMap`s. Any SHAMapLeafNode that is immutable has a sequence number of zero (sharable). When a mutable `SHAMap` is created then its SHAMapTreeNodes are - given non-zero sequence numbers (unsharable). But all nodes in the + given non-zero sequence numbers (unsharable). But all nodes in the TreeNodeCache are immutable, so if one is found here, its sequence number will be 0. - 2. If the node is not in the TreeNodeCache, we attempt to locate the node - in the historic data stored by the data base. The call to to +2. If the node is not in the TreeNodeCache, we attempt to locate the node + in the historic data stored by the data base. The call to to `fetchNodeFromDB(hash)` does that work for us. - 3. Finally if a filter exists, we check if it can supply the node. This is +3. Finally if a filter exists, we check if it can supply the node. This is typically the LedgerMaster which tracks the current ledger and ledgers in the process of closing. -## Canonicalize ## +## Canonicalize `canonicalize()` is called every time a node is introduced into the `SHAMap`. @@ -251,51 +251,50 @@ by favoring the copy already in the `TreeNodeCache`. By using `canonicalize()` we manage a thread race condition where two different threads might both recognize the lack of a SHAMapLeafNode at the same time -(during a fetch). If they both attempt to insert the node into the `SHAMap`, then +(during a fetch). If they both attempt to insert the node into the `SHAMap`, then `canonicalize` makes sure that the first node in wins and the slower thread -receives back a pointer to the node inserted by the faster thread. Recall +receives back a pointer to the node inserted by the faster thread. Recall that these two `SHAMap`s will share the same `TreeNodeCache`. -## `TreeNodeCache` ## +## `TreeNodeCache` The `TreeNodeCache` is a `std::unordered_map` keyed on the hash of the -`SHAMap` node. The stored type consists of `shared_ptr`, +`SHAMap` node. The stored type consists of `shared_ptr`, `weak_ptr`, and a time point indicating the most recent -access of this node in the cache. The time point is based on +access of this node in the cache. The time point is based on `std::chrono::steady_clock`. The container uses a cryptographically secure hash that is randomly seeded. The `TreeNodeCache` also carries with it various data used for statistics -and logging, and a target age for the contained nodes. When the target age +and logging, and a target age for the contained nodes. When the target age for a node is exceeded, and there are no more references to the node, the node is removed from the `TreeNodeCache`. -## `FullBelowCache` ## +## `FullBelowCache` This cache remembers which trie keys have all of their children resident in a -`SHAMap`. This optimizes the process of acquiring a complete trie. This is used -when creating the missing nodes list. Missing nodes are those nodes that a +`SHAMap`. This optimizes the process of acquiring a complete trie. This is used +when creating the missing nodes list. Missing nodes are those nodes that a `SHAMap` refers to but that are not stored in the local database. As a depth-first walk of a `SHAMap` is performed, if an inner node answers true to `isFullBelow()` then it is known that none of this node's children are missing -nodes, and thus that subtree does not need to be walked. These nodes are stored -in the FullBelowCache. Subsequent walks check the FullBelowCache first when +nodes, and thus that subtree does not need to be walked. These nodes are stored +in the FullBelowCache. Subsequent walks check the FullBelowCache first when encountering a node, and ignore that subtree if found. -## `SHAMapTreeNode` ## +## `SHAMapTreeNode` -This is an abstract base class for the concrete node types. It holds the +This is an abstract base class for the concrete node types. It holds the following common data: 1. A hash 2. An identifier used to perform copy-on-write operations +### `SHAMapInnerNode` -### `SHAMapInnerNode` ### - -`SHAMapInnerNode` publicly inherits directly from `SHAMapTreeNode`. It holds +`SHAMapInnerNode` publicly inherits directly from `SHAMapTreeNode`. It holds the following data: 1. Up to 16 child nodes, each held with a shared_ptr. @@ -304,36 +303,34 @@ the following data: 4. An identifier used to determine whether the map below this node is fully populated -### `SHAMapLeafNode` ### +### `SHAMapLeafNode` `SHAMapLeafNode` is an abstract class which publicly inherits directly from -`SHAMapTreeNode`. It isIt holds the +`SHAMapTreeNode`. It isIt holds the following data: 1. A shared_ptr to a const SHAMapItem. -#### `SHAMapAccountStateLeafNode` #### +#### `SHAMapAccountStateLeafNode` `SHAMapAccountStateLeafNode` is a class which publicly inherits directly from `SHAMapLeafNode`. It is used to represent entries (i.e. account objects, escrow objects, trust lines, etc.) in a state map. -#### `SHAMapTxLeafNode` #### +#### `SHAMapTxLeafNode` `SHAMapTxLeafNode` is a class which publicly inherits directly from `SHAMapLeafNode`. It is used to represent transactions in a state map. -#### `SHAMapTxPlusMetaLeafNode` #### +#### `SHAMapTxPlusMetaLeafNode` `SHAMapTxPlusMetaLeafNode` is a class which publicly inherits directly from `SHAMapLeafNode`. It is used to represent transactions along with metadata associated with this transaction in a state map. -## SHAMapItem ## +## SHAMapItem This holds the following data: -1. uint256. The hash of the data. -2. vector. The data (transactions, account info). - - +1. uint256. The hash of the data. +2. vector. The data (transactions, account info). diff --git a/tests/README.md b/tests/README.md index 0306915b3b..c4a96005e7 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,4 +1,5 @@ # Integration tests + This directory contains integration tests for the project. These tests are run against the `libxrpl` library or `rippled` binary to verify they are working as expected. From b7ed99426b078ba1f256eeba4f36feb640cfe113 Mon Sep 17 00:00:00 2001 From: Oleksandr Hrabar <40630611+Afformativ@users.noreply.github.com> Date: Mon, 11 Aug 2025 14:12:36 -0400 Subject: [PATCH 05/16] fix: Make test suite names match the directory name (#5597) This change fixes the suite names all around the test files, to make them match to the folder name in which this test files are located. Also, the RCL test files are relocated to the consensus folder, because they are testing consensus functionality. --- src/test/app/Check_test.cpp | 2 +- src/test/app/CrossingLimits_test.cpp | 2 +- src/test/app/DNS_test.cpp | 2 +- src/test/app/FeeVote_test.cpp | 2 +- src/test/app/FixNFTokenPageLinks_test.cpp | 2 +- src/test/{ledger => app}/Invariants_test.cpp | 2 +- src/test/app/LoadFeeTrack_test.cpp | 2 +- src/test/app/MPToken_test.cpp | 2 +- src/test/app/NFTokenAuth_test.cpp | 2 +- src/test/app/NFTokenBurn_test.cpp | 10 +++++----- src/test/app/NFTokenDir_test.cpp | 2 +- src/test/app/NFToken_test.cpp | 16 ++++++++-------- src/test/app/OfferStream_test.cpp | 2 +- src/test/app/Offer_test.cpp | 14 +++++++------- src/test/app/OversizeMeta_test.cpp | 8 ++++---- src/test/app/ReducedOffer_test.cpp | 2 +- src/test/app/SetAuth_test.cpp | 2 +- src/test/app/Ticket_test.cpp | 2 +- src/test/app/Vault_test.cpp | 2 +- src/test/app/tx/apply_test.cpp | 2 +- src/test/basics/Buffer_test.cpp | 2 +- src/test/basics/DetectCrash_test.cpp | 2 +- src/test/basics/Expected_test.cpp | 2 +- src/test/basics/FeeUnits_test.cpp | 2 +- src/test/basics/FileUtilities_test.cpp | 2 +- src/test/basics/IOUAmount_test.cpp | 2 +- src/test/basics/IntrusiveShared_test.cpp | 2 +- src/test/basics/KeyCache_test.cpp | 2 +- src/test/basics/Number_test.cpp | 2 +- src/test/basics/StringUtilities_test.cpp | 2 +- src/test/basics/TaggedCache_test.cpp | 2 +- src/test/basics/XRPAmount_test.cpp | 2 +- src/test/basics/base58_test.cpp | 2 +- src/test/basics/base_uint_test.cpp | 2 +- src/test/basics/join_test.cpp | 2 +- src/test/beast/IPEndpoint_test.cpp | 2 +- src/test/beast/LexicalCast_test.cpp | 2 +- src/test/beast/SemanticVersion_test.cpp | 2 +- .../beast/aged_associative_container_test.cpp | 16 ++++++++-------- src/test/beast/beast_CurrentThreadName_test.cpp | 2 +- src/test/beast/beast_Journal_test.cpp | 2 +- src/test/beast/beast_PropertyStream_test.cpp | 2 +- src/test/beast/beast_Zero_test.cpp | 2 +- src/test/beast/beast_abstract_clock_test.cpp | 2 +- .../beast/beast_basic_seconds_clock_test.cpp | 2 +- src/test/beast/beast_io_latency_probe_test.cpp | 2 +- src/test/beast/define_print.cpp | 2 +- src/test/consensus/NegativeUNL_test.cpp | 4 ++-- .../RCLCensorshipDetector_test.cpp | 2 +- src/test/csf/BasicNetwork_test.cpp | 2 +- src/test/csf/Digraph_test.cpp | 2 +- src/test/csf/Histogram_test.cpp | 2 +- src/test/csf/Scheduler_test.cpp | 2 +- src/test/json/Object_test.cpp | 2 +- src/test/json/Output_test.cpp | 2 +- src/test/json/Writer_test.cpp | 2 +- src/test/jtx/Env_test.cpp | 2 +- src/test/jtx/WSClient_test.cpp | 2 +- src/test/nodestore/Backend_test.cpp | 2 +- src/test/nodestore/Basics_test.cpp | 2 +- src/test/nodestore/Database_test.cpp | 2 +- src/test/nodestore/Timing_test.cpp | 2 +- src/test/nodestore/import_test.cpp | 2 +- src/test/nodestore/varint_test.cpp | 2 +- src/test/overlay/compression_test.cpp | 2 +- src/test/overlay/handshake_test.cpp | 2 +- src/test/overlay/reduce_relay_test.cpp | 4 ++-- src/test/overlay/tx_reduce_relay_test.cpp | 2 +- src/test/peerfinder/PeerFinder_test.cpp | 2 +- src/test/protocol/InnerObjectFormats_test.cpp | 2 +- src/test/protocol/Memo_test.cpp | 2 +- src/test/protocol/STAmount_test.cpp | 2 +- src/test/protocol/STIssue_test.cpp | 2 +- src/test/protocol/STTx_test.cpp | 4 ++-- src/test/rpc/AMMInfo_test.cpp | 2 +- src/test/rpc/AccountSet_test.cpp | 2 +- src/test/rpc/AmendmentBlocked_test.cpp | 2 +- src/test/rpc/BookChanges_test.cpp | 2 +- src/test/rpc/Book_test.cpp | 2 +- src/test/rpc/DeliveredAmount_test.cpp | 2 +- src/test/rpc/DepositAuthorized_test.cpp | 2 +- src/test/rpc/GatewayBalances_test.cpp | 2 +- src/test/rpc/GetAggregatePrice_test.cpp | 2 +- src/test/rpc/Handler_test.cpp | 2 +- src/test/rpc/JSONRPC_test.cpp | 2 +- src/test/rpc/KeyGeneration_test.cpp | 2 +- src/test/rpc/LedgerClosed_test.cpp | 2 +- src/test/rpc/LedgerData_test.cpp | 2 +- src/test/rpc/LedgerEntry_test.cpp | 4 ++-- src/test/rpc/LedgerRPC_test.cpp | 2 +- src/test/rpc/LedgerRequestRPC_test.cpp | 2 +- src/test/rpc/NoRipple_test.cpp | 2 +- src/test/rpc/OwnerInfo_test.cpp | 2 +- src/test/rpc/RPCCall_test.cpp | 2 +- src/test/rpc/RPCHelpers_test.cpp | 2 +- src/test/rpc/RPCOverload_test.cpp | 2 +- src/test/rpc/RobustTransaction_test.cpp | 2 +- src/test/rpc/Roles_test.cpp | 2 +- src/test/rpc/ServerInfo_test.cpp | 2 +- src/test/rpc/Status_test.cpp | 4 ++-- src/test/rpc/Subscribe_test.cpp | 2 +- src/test/rpc/ValidatorRPC_test.cpp | 2 +- src/test/server/Server_test.cpp | 2 +- src/test/shamap/SHAMap_test.cpp | 4 ++-- 104 files changed, 137 insertions(+), 137 deletions(-) rename src/test/{ledger => app}/Invariants_test.cpp (99%) rename src/test/{app => consensus}/RCLCensorshipDetector_test.cpp (98%) diff --git a/src/test/app/Check_test.cpp b/src/test/app/Check_test.cpp index be38b22313..e724b83535 100644 --- a/src/test/app/Check_test.cpp +++ b/src/test/app/Check_test.cpp @@ -2729,6 +2729,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Check, tx, ripple); +BEAST_DEFINE_TESTSUITE(Check, app, ripple); } // namespace ripple diff --git a/src/test/app/CrossingLimits_test.cpp b/src/test/app/CrossingLimits_test.cpp index 6e76936199..18fc21078c 100644 --- a/src/test/app/CrossingLimits_test.cpp +++ b/src/test/app/CrossingLimits_test.cpp @@ -530,7 +530,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(CrossingLimits, tx, ripple, 10); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(CrossingLimits, app, ripple, 10); } // namespace test } // namespace ripple diff --git a/src/test/app/DNS_test.cpp b/src/test/app/DNS_test.cpp index 7e209deb1c..28a143e93d 100644 --- a/src/test/app/DNS_test.cpp +++ b/src/test/app/DNS_test.cpp @@ -128,7 +128,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(DNS, ripple_data, ripple, 20); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(DNS, app, ripple, 20); } // namespace test } // namespace ripple diff --git a/src/test/app/FeeVote_test.cpp b/src/test/app/FeeVote_test.cpp index 1cf2e67f83..ba3d379219 100644 --- a/src/test/app/FeeVote_test.cpp +++ b/src/test/app/FeeVote_test.cpp @@ -100,7 +100,7 @@ class FeeVote_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(FeeVote, server, ripple); +BEAST_DEFINE_TESTSUITE(FeeVote, app, ripple); } // namespace test } // namespace ripple diff --git a/src/test/app/FixNFTokenPageLinks_test.cpp b/src/test/app/FixNFTokenPageLinks_test.cpp index a54e889960..4acd650a08 100644 --- a/src/test/app/FixNFTokenPageLinks_test.cpp +++ b/src/test/app/FixNFTokenPageLinks_test.cpp @@ -663,6 +663,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(FixNFTokenPageLinks, tx, ripple); +BEAST_DEFINE_TESTSUITE(FixNFTokenPageLinks, app, ripple); } // namespace ripple diff --git a/src/test/ledger/Invariants_test.cpp b/src/test/app/Invariants_test.cpp similarity index 99% rename from src/test/ledger/Invariants_test.cpp rename to src/test/app/Invariants_test.cpp index fadd9c0eae..ae2a1c45df 100644 --- a/src/test/ledger/Invariants_test.cpp +++ b/src/test/app/Invariants_test.cpp @@ -1626,6 +1626,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Invariants, ledger, ripple); +BEAST_DEFINE_TESTSUITE(Invariants, app, ripple); } // namespace ripple diff --git a/src/test/app/LoadFeeTrack_test.cpp b/src/test/app/LoadFeeTrack_test.cpp index 9b0cf2fa2d..8a88e0273f 100644 --- a/src/test/app/LoadFeeTrack_test.cpp +++ b/src/test/app/LoadFeeTrack_test.cpp @@ -87,6 +87,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(LoadFeeTrack, ripple_core, ripple); +BEAST_DEFINE_TESTSUITE(LoadFeeTrack, app, ripple); } // namespace ripple diff --git a/src/test/app/MPToken_test.cpp b/src/test/app/MPToken_test.cpp index 2cb47780ba..6470962f2f 100644 --- a/src/test/app/MPToken_test.cpp +++ b/src/test/app/MPToken_test.cpp @@ -2797,7 +2797,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(MPToken, tx, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(MPToken, app, ripple, 2); } // namespace test } // namespace ripple diff --git a/src/test/app/NFTokenAuth_test.cpp b/src/test/app/NFTokenAuth_test.cpp index 1a59dc579a..f5eedfce77 100644 --- a/src/test/app/NFTokenAuth_test.cpp +++ b/src/test/app/NFTokenAuth_test.cpp @@ -619,6 +619,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenAuth, tx, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenAuth, app, ripple, 2); } // namespace ripple \ No newline at end of file diff --git a/src/test/app/NFTokenBurn_test.cpp b/src/test/app/NFTokenBurn_test.cpp index 21b0a1ffd8..44c55f2b8c 100644 --- a/src/test/app/NFTokenBurn_test.cpp +++ b/src/test/app/NFTokenBurn_test.cpp @@ -1454,10 +1454,10 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnBaseUtil, tx, ripple, 3); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnWOfixFungTokens, tx, ripple, 3); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnWOFixTokenRemint, tx, ripple, 3); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnWOFixNFTPageLinks, tx, ripple, 3); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnAllFeatures, tx, ripple, 3); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnBaseUtil, app, ripple, 3); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnWOfixFungTokens, app, ripple, 3); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnWOFixTokenRemint, app, ripple, 3); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnWOFixNFTPageLinks, app, ripple, 3); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBurnAllFeatures, app, ripple, 3); } // namespace ripple diff --git a/src/test/app/NFTokenDir_test.cpp b/src/test/app/NFTokenDir_test.cpp index df40781590..a63653d8dc 100644 --- a/src/test/app/NFTokenDir_test.cpp +++ b/src/test/app/NFTokenDir_test.cpp @@ -1110,7 +1110,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenDir, tx, ripple, 1); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenDir, app, ripple, 1); } // namespace ripple diff --git a/src/test/app/NFToken_test.cpp b/src/test/app/NFToken_test.cpp index b79ebf3c40..1c4314643c 100644 --- a/src/test/app/NFToken_test.cpp +++ b/src/test/app/NFToken_test.cpp @@ -8171,13 +8171,13 @@ class NFTokenAllFeatures_test : public NFTokenBaseUtil_test } }; -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBaseUtil, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenDisallowIncoming, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOfixV1, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOTokenRemint, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOTokenReserve, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOMintOffer, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOModify, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(NFTokenAllFeatures, tx, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenBaseUtil, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenDisallowIncoming, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOfixV1, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOTokenRemint, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOTokenReserve, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOMintOffer, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenWOModify, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(NFTokenAllFeatures, app, ripple, 2); } // namespace ripple diff --git a/src/test/app/OfferStream_test.cpp b/src/test/app/OfferStream_test.cpp index 691d327cd8..35f38da29a 100644 --- a/src/test/app/OfferStream_test.cpp +++ b/src/test/app/OfferStream_test.cpp @@ -39,6 +39,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(OfferStream, tx, ripple); +BEAST_DEFINE_TESTSUITE(OfferStream, app, ripple); } // namespace ripple diff --git a/src/test/app/Offer_test.cpp b/src/test/app/Offer_test.cpp index 96f68fb2ad..aa647925fa 100644 --- a/src/test/app/Offer_test.cpp +++ b/src/test/app/Offer_test.cpp @@ -5466,13 +5466,13 @@ class Offer_manual_test : public OfferBaseUtil_test } }; -BEAST_DEFINE_TESTSUITE_PRIO(OfferBaseUtil, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(OfferWTakerDryOffer, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(OfferWOSmallQOffers, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(OfferWOFillOrKill, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(OfferWOPermDEX, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_PRIO(OfferAllFeatures, tx, ripple, 2); -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Offer_manual, tx, ripple, 20); +BEAST_DEFINE_TESTSUITE_PRIO(OfferBaseUtil, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(OfferWTakerDryOffer, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(OfferWOSmallQOffers, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(OfferWOFillOrKill, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(OfferWOPermDEX, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(OfferAllFeatures, app, ripple, 2); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Offer_manual, app, ripple, 20); } // namespace test } // namespace ripple diff --git a/src/test/app/OversizeMeta_test.cpp b/src/test/app/OversizeMeta_test.cpp index f6e4466bab..fb6faa3ec3 100644 --- a/src/test/app/OversizeMeta_test.cpp +++ b/src/test/app/OversizeMeta_test.cpp @@ -61,7 +61,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(PlumpBook, tx, ripple, 5); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(PlumpBook, app, ripple, 5); //------------------------------------------------------------------------------ @@ -76,7 +76,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(ThinBook, tx, ripple); +BEAST_DEFINE_TESTSUITE(ThinBook, app, ripple); //------------------------------------------------------------------------------ @@ -119,7 +119,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(OversizeMeta, tx, ripple, 3); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(OversizeMeta, app, ripple, 3); //------------------------------------------------------------------------------ @@ -185,7 +185,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(FindOversizeCross, tx, ripple, 50); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(FindOversizeCross, app, ripple, 50); } // namespace test } // namespace ripple diff --git a/src/test/app/ReducedOffer_test.cpp b/src/test/app/ReducedOffer_test.cpp index 5142aaab0e..fa2be451fa 100644 --- a/src/test/app/ReducedOffer_test.cpp +++ b/src/test/app/ReducedOffer_test.cpp @@ -800,7 +800,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(ReducedOffer, tx, ripple, 2); +BEAST_DEFINE_TESTSUITE_PRIO(ReducedOffer, app, ripple, 2); } // namespace test } // namespace ripple diff --git a/src/test/app/SetAuth_test.cpp b/src/test/app/SetAuth_test.cpp index 4c63560770..dfa831a72e 100644 --- a/src/test/app/SetAuth_test.cpp +++ b/src/test/app/SetAuth_test.cpp @@ -80,7 +80,7 @@ struct SetAuth_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(SetAuth, test, ripple); +BEAST_DEFINE_TESTSUITE(SetAuth, app, ripple); } // namespace test } // namespace ripple diff --git a/src/test/app/Ticket_test.cpp b/src/test/app/Ticket_test.cpp index f8ac64679e..70a5a48adf 100644 --- a/src/test/app/Ticket_test.cpp +++ b/src/test/app/Ticket_test.cpp @@ -1000,6 +1000,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Ticket, tx, ripple); +BEAST_DEFINE_TESTSUITE(Ticket, app, ripple); } // namespace ripple diff --git a/src/test/app/Vault_test.cpp b/src/test/app/Vault_test.cpp index f9036719cd..7ea38db2b1 100644 --- a/src/test/app/Vault_test.cpp +++ b/src/test/app/Vault_test.cpp @@ -3342,6 +3342,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(Vault, tx, ripple, 1); +BEAST_DEFINE_TESTSUITE_PRIO(Vault, app, ripple, 1); } // namespace ripple diff --git a/src/test/app/tx/apply_test.cpp b/src/test/app/tx/apply_test.cpp index 0f5ccf5a55..a754866c7f 100644 --- a/src/test/app/tx/apply_test.cpp +++ b/src/test/app/tx/apply_test.cpp @@ -87,6 +87,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Apply, app, ripple); +BEAST_DEFINE_TESTSUITE(Apply, tx, ripple); } // namespace ripple diff --git a/src/test/basics/Buffer_test.cpp b/src/test/basics/Buffer_test.cpp index c59805f569..065c33c12f 100644 --- a/src/test/basics/Buffer_test.cpp +++ b/src/test/basics/Buffer_test.cpp @@ -280,7 +280,7 @@ struct Buffer_test : beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(Buffer, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(Buffer, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/basics/DetectCrash_test.cpp b/src/test/basics/DetectCrash_test.cpp index 1ae761f34a..5489ae5b26 100644 --- a/src/test/basics/DetectCrash_test.cpp +++ b/src/test/basics/DetectCrash_test.cpp @@ -41,7 +41,7 @@ struct DetectCrash_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE_MANUAL(DetectCrash, unit_test, beast); +BEAST_DEFINE_TESTSUITE_MANUAL(DetectCrash, basics, beast); } // namespace test } // namespace ripple diff --git a/src/test/basics/Expected_test.cpp b/src/test/basics/Expected_test.cpp index d022d07461..faa6b98764 100644 --- a/src/test/basics/Expected_test.cpp +++ b/src/test/basics/Expected_test.cpp @@ -243,7 +243,7 @@ struct Expected_test : beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(Expected, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(Expected, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/basics/FeeUnits_test.cpp b/src/test/basics/FeeUnits_test.cpp index 6266288896..f9be632644 100644 --- a/src/test/basics/FeeUnits_test.cpp +++ b/src/test/basics/FeeUnits_test.cpp @@ -371,7 +371,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(feeunits, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(feeunits, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/basics/FileUtilities_test.cpp b/src/test/basics/FileUtilities_test.cpp index 4b4cbe70c8..9071ac7231 100644 --- a/src/test/basics/FileUtilities_test.cpp +++ b/src/test/basics/FileUtilities_test.cpp @@ -79,6 +79,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(FileUtilities, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(FileUtilities, basics, ripple); } // namespace ripple diff --git a/src/test/basics/IOUAmount_test.cpp b/src/test/basics/IOUAmount_test.cpp index 6ba1cfd6f1..dfc48c9be7 100644 --- a/src/test/basics/IOUAmount_test.cpp +++ b/src/test/basics/IOUAmount_test.cpp @@ -274,6 +274,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(IOUAmount, protocol, ripple); +BEAST_DEFINE_TESTSUITE(IOUAmount, basics, ripple); } // namespace ripple diff --git a/src/test/basics/IntrusiveShared_test.cpp b/src/test/basics/IntrusiveShared_test.cpp index 736cc47345..a3acc54d45 100644 --- a/src/test/basics/IntrusiveShared_test.cpp +++ b/src/test/basics/IntrusiveShared_test.cpp @@ -887,6 +887,6 @@ public: } }; // namespace tests -BEAST_DEFINE_TESTSUITE(IntrusiveShared, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(IntrusiveShared, basics, ripple); } // namespace tests } // namespace ripple diff --git a/src/test/basics/KeyCache_test.cpp b/src/test/basics/KeyCache_test.cpp index d12dd59af0..e1d57fb3e4 100644 --- a/src/test/basics/KeyCache_test.cpp +++ b/src/test/basics/KeyCache_test.cpp @@ -93,6 +93,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(KeyCache, common, ripple); +BEAST_DEFINE_TESTSUITE(KeyCache, basics, ripple); } // namespace ripple diff --git a/src/test/basics/Number_test.cpp b/src/test/basics/Number_test.cpp index 13d8b259d1..964cfe9614 100644 --- a/src/test/basics/Number_test.cpp +++ b/src/test/basics/Number_test.cpp @@ -743,6 +743,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Number, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(Number, basics, ripple); } // namespace ripple diff --git a/src/test/basics/StringUtilities_test.cpp b/src/test/basics/StringUtilities_test.cpp index cf916c6265..b3fac22b42 100644 --- a/src/test/basics/StringUtilities_test.cpp +++ b/src/test/basics/StringUtilities_test.cpp @@ -322,6 +322,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(StringUtilities, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(StringUtilities, basics, ripple); } // namespace ripple diff --git a/src/test/basics/TaggedCache_test.cpp b/src/test/basics/TaggedCache_test.cpp index ce33455110..ec450e46dd 100644 --- a/src/test/basics/TaggedCache_test.cpp +++ b/src/test/basics/TaggedCache_test.cpp @@ -151,6 +151,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(TaggedCache, common, ripple); +BEAST_DEFINE_TESTSUITE(TaggedCache, basics, ripple); } // namespace ripple diff --git a/src/test/basics/XRPAmount_test.cpp b/src/test/basics/XRPAmount_test.cpp index 08745b61e3..452ab80dda 100644 --- a/src/test/basics/XRPAmount_test.cpp +++ b/src/test/basics/XRPAmount_test.cpp @@ -344,6 +344,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(XRPAmount, protocol, ripple); +BEAST_DEFINE_TESTSUITE(XRPAmount, basics, ripple); } // namespace ripple diff --git a/src/test/basics/base58_test.cpp b/src/test/basics/base58_test.cpp index 799f6537dc..590f19a44e 100644 --- a/src/test/basics/base58_test.cpp +++ b/src/test/basics/base58_test.cpp @@ -470,7 +470,7 @@ class base58_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(base58, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(base58, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/basics/base_uint_test.cpp b/src/test/basics/base_uint_test.cpp index 8058e0d6f0..6ee9f0901a 100644 --- a/src/test/basics/base_uint_test.cpp +++ b/src/test/basics/base_uint_test.cpp @@ -366,7 +366,7 @@ struct base_uint_test : beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(base_uint, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(base_uint, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/basics/join_test.cpp b/src/test/basics/join_test.cpp index 1b09482824..e533635bcb 100644 --- a/src/test/basics/join_test.cpp +++ b/src/test/basics/join_test.cpp @@ -99,7 +99,7 @@ struct join_test : beast::unit_test::suite } }; // namespace test -BEAST_DEFINE_TESTSUITE(join, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(join, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/beast/IPEndpoint_test.cpp b/src/test/beast/IPEndpoint_test.cpp index 7b3eba55f1..aed6d715d4 100644 --- a/src/test/beast/IPEndpoint_test.cpp +++ b/src/test/beast/IPEndpoint_test.cpp @@ -478,7 +478,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(IPEndpoint, net, beast); +BEAST_DEFINE_TESTSUITE(IPEndpoint, beast, beast); } // namespace IP } // namespace beast diff --git a/src/test/beast/LexicalCast_test.cpp b/src/test/beast/LexicalCast_test.cpp index 22638f27e6..686546a475 100644 --- a/src/test/beast/LexicalCast_test.cpp +++ b/src/test/beast/LexicalCast_test.cpp @@ -289,6 +289,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(LexicalCast, beast_core, beast); +BEAST_DEFINE_TESTSUITE(LexicalCast, beast, beast); } // namespace beast diff --git a/src/test/beast/SemanticVersion_test.cpp b/src/test/beast/SemanticVersion_test.cpp index fb7a3e3e4f..af9d2808fb 100644 --- a/src/test/beast/SemanticVersion_test.cpp +++ b/src/test/beast/SemanticVersion_test.cpp @@ -280,5 +280,5 @@ public: } }; -BEAST_DEFINE_TESTSUITE(SemanticVersion, beast_core, beast); +BEAST_DEFINE_TESTSUITE(SemanticVersion, beast, beast); } // namespace beast diff --git a/src/test/beast/aged_associative_container_test.cpp b/src/test/beast/aged_associative_container_test.cpp index 586f486872..017181df22 100644 --- a/src/test/beast/aged_associative_container_test.cpp +++ b/src/test/beast/aged_associative_container_test.cpp @@ -1936,13 +1936,13 @@ public: } }; -BEAST_DEFINE_TESTSUITE(aged_set, container, beast); -BEAST_DEFINE_TESTSUITE(aged_map, container, beast); -BEAST_DEFINE_TESTSUITE(aged_multiset, container, beast); -BEAST_DEFINE_TESTSUITE(aged_multimap, container, beast); -BEAST_DEFINE_TESTSUITE(aged_unordered_set, container, beast); -BEAST_DEFINE_TESTSUITE(aged_unordered_map, container, beast); -BEAST_DEFINE_TESTSUITE(aged_unordered_multiset, container, beast); -BEAST_DEFINE_TESTSUITE(aged_unordered_multimap, container, beast); +BEAST_DEFINE_TESTSUITE(aged_set, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_map, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_multiset, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_multimap, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_unordered_set, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_unordered_map, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_unordered_multiset, beast, beast); +BEAST_DEFINE_TESTSUITE(aged_unordered_multimap, beast, beast); } // namespace beast diff --git a/src/test/beast/beast_CurrentThreadName_test.cpp b/src/test/beast/beast_CurrentThreadName_test.cpp index 839aaaef0a..e1de5d9ae9 100644 --- a/src/test/beast/beast_CurrentThreadName_test.cpp +++ b/src/test/beast/beast_CurrentThreadName_test.cpp @@ -86,7 +86,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(CurrentThreadName, core, beast); +BEAST_DEFINE_TESTSUITE(CurrentThreadName, beast, beast); } // namespace test } // namespace ripple diff --git a/src/test/beast/beast_Journal_test.cpp b/src/test/beast/beast_Journal_test.cpp index 99badc0fc4..13e2726c89 100644 --- a/src/test/beast/beast_Journal_test.cpp +++ b/src/test/beast/beast_Journal_test.cpp @@ -103,6 +103,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Journal, utility, beast); +BEAST_DEFINE_TESTSUITE(Journal, beast, beast); } // namespace beast diff --git a/src/test/beast/beast_PropertyStream_test.cpp b/src/test/beast/beast_PropertyStream_test.cpp index bbbc2fc0e0..585c7cfe6b 100644 --- a/src/test/beast/beast_PropertyStream_test.cpp +++ b/src/test/beast/beast_PropertyStream_test.cpp @@ -238,5 +238,5 @@ public: } }; -BEAST_DEFINE_TESTSUITE(PropertyStream, utility, beast); +BEAST_DEFINE_TESTSUITE(PropertyStream, beast, beast); } // namespace beast diff --git a/src/test/beast/beast_Zero_test.cpp b/src/test/beast/beast_Zero_test.cpp index 9a645334ab..64239fbe85 100644 --- a/src/test/beast/beast_Zero_test.cpp +++ b/src/test/beast/beast_Zero_test.cpp @@ -129,6 +129,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Zero, types, beast); +BEAST_DEFINE_TESTSUITE(Zero, beast, beast); } // namespace beast diff --git a/src/test/beast/beast_abstract_clock_test.cpp b/src/test/beast/beast_abstract_clock_test.cpp index b86afdb139..74ab833e9d 100644 --- a/src/test/beast/beast_abstract_clock_test.cpp +++ b/src/test/beast/beast_abstract_clock_test.cpp @@ -84,6 +84,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL(abstract_clock, chrono, beast); +BEAST_DEFINE_TESTSUITE_MANUAL(abstract_clock, beast, beast); } // namespace beast diff --git a/src/test/beast/beast_basic_seconds_clock_test.cpp b/src/test/beast/beast_basic_seconds_clock_test.cpp index c769cde07a..10e5e466f3 100644 --- a/src/test/beast/beast_basic_seconds_clock_test.cpp +++ b/src/test/beast/beast_basic_seconds_clock_test.cpp @@ -33,6 +33,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(basic_seconds_clock, chrono, beast); +BEAST_DEFINE_TESTSUITE(basic_seconds_clock, beast, beast); } // namespace beast diff --git a/src/test/beast/beast_io_latency_probe_test.cpp b/src/test/beast/beast_io_latency_probe_test.cpp index de3c5d1d20..c72336bf27 100644 --- a/src/test/beast/beast_io_latency_probe_test.cpp +++ b/src/test/beast/beast_io_latency_probe_test.cpp @@ -238,4 +238,4 @@ public: } }; -BEAST_DEFINE_TESTSUITE(io_latency_probe, asio, beast); +BEAST_DEFINE_TESTSUITE(io_latency_probe, beast, beast); diff --git a/src/test/beast/define_print.cpp b/src/test/beast/define_print.cpp index ec86d5d7d7..eca6a70c90 100644 --- a/src/test/beast/define_print.cpp +++ b/src/test/beast/define_print.cpp @@ -46,7 +46,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL(print, unit_test, beast); +BEAST_DEFINE_TESTSUITE_MANUAL(print, beast, beast); } // namespace unit_test } // namespace beast diff --git a/src/test/consensus/NegativeUNL_test.cpp b/src/test/consensus/NegativeUNL_test.cpp index 56558f525f..b56b834726 100644 --- a/src/test/consensus/NegativeUNL_test.cpp +++ b/src/test/consensus/NegativeUNL_test.cpp @@ -1885,8 +1885,8 @@ class NegativeUNLVoteFilterValidations_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(NegativeUNL, ledger, ripple); -BEAST_DEFINE_TESTSUITE(NegativeUNLNoAmendment, ledger, ripple); +BEAST_DEFINE_TESTSUITE(NegativeUNL, consensus, ripple); +BEAST_DEFINE_TESTSUITE(NegativeUNLNoAmendment, consensus, ripple); BEAST_DEFINE_TESTSUITE(NegativeUNLVoteInternal, consensus, ripple); BEAST_DEFINE_TESTSUITE_MANUAL(NegativeUNLVoteScoreTable, consensus, ripple); diff --git a/src/test/app/RCLCensorshipDetector_test.cpp b/src/test/consensus/RCLCensorshipDetector_test.cpp similarity index 98% rename from src/test/app/RCLCensorshipDetector_test.cpp rename to src/test/consensus/RCLCensorshipDetector_test.cpp index 85ba0ab78d..1581dc81c4 100644 --- a/src/test/app/RCLCensorshipDetector_test.cpp +++ b/src/test/consensus/RCLCensorshipDetector_test.cpp @@ -98,6 +98,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(RCLCensorshipDetector, app, ripple); +BEAST_DEFINE_TESTSUITE(RCLCensorshipDetector, consensus, ripple); } // namespace test } // namespace ripple diff --git a/src/test/csf/BasicNetwork_test.cpp b/src/test/csf/BasicNetwork_test.cpp index 4173db6502..4580dab468 100644 --- a/src/test/csf/BasicNetwork_test.cpp +++ b/src/test/csf/BasicNetwork_test.cpp @@ -146,7 +146,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(BasicNetwork, test, ripple); +BEAST_DEFINE_TESTSUITE(BasicNetwork, csf, ripple); } // namespace test } // namespace ripple diff --git a/src/test/csf/Digraph_test.cpp b/src/test/csf/Digraph_test.cpp index 0cc4be1976..df78a10733 100644 --- a/src/test/csf/Digraph_test.cpp +++ b/src/test/csf/Digraph_test.cpp @@ -92,7 +92,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Digraph, test, ripple); +BEAST_DEFINE_TESTSUITE(Digraph, csf, ripple); } // namespace test } // namespace ripple diff --git a/src/test/csf/Histogram_test.cpp b/src/test/csf/Histogram_test.cpp index 40274c9046..60f12e9a66 100644 --- a/src/test/csf/Histogram_test.cpp +++ b/src/test/csf/Histogram_test.cpp @@ -81,7 +81,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Histogram, test, ripple); +BEAST_DEFINE_TESTSUITE(Histogram, csf, ripple); } // namespace test } // namespace ripple diff --git a/src/test/csf/Scheduler_test.cpp b/src/test/csf/Scheduler_test.cpp index 1935e40236..c31b881b03 100644 --- a/src/test/csf/Scheduler_test.cpp +++ b/src/test/csf/Scheduler_test.cpp @@ -83,7 +83,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Scheduler, test, ripple); +BEAST_DEFINE_TESTSUITE(Scheduler, csf, ripple); } // namespace test } // namespace ripple diff --git a/src/test/json/Object_test.cpp b/src/test/json/Object_test.cpp index 94a9e96cf6..0ad5f76307 100644 --- a/src/test/json/Object_test.cpp +++ b/src/test/json/Object_test.cpp @@ -253,6 +253,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(JsonObject, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(JsonObject, json, ripple); } // namespace Json diff --git a/src/test/json/Output_test.cpp b/src/test/json/Output_test.cpp index 2343843fe3..6421682b01 100644 --- a/src/test/json/Output_test.cpp +++ b/src/test/json/Output_test.cpp @@ -61,6 +61,6 @@ struct Output_test : ripple::test::TestOutputSuite } }; -BEAST_DEFINE_TESTSUITE(Output, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(Output, json, ripple); } // namespace Json diff --git a/src/test/json/Writer_test.cpp b/src/test/json/Writer_test.cpp index c5305876ff..3739af07e1 100644 --- a/src/test/json/Writer_test.cpp +++ b/src/test/json/Writer_test.cpp @@ -212,6 +212,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(JsonWriter, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(JsonWriter, json, ripple); } // namespace Json diff --git a/src/test/jtx/Env_test.cpp b/src/test/jtx/Env_test.cpp index 2be20d6e33..34d9f6c0e8 100644 --- a/src/test/jtx/Env_test.cpp +++ b/src/test/jtx/Env_test.cpp @@ -944,7 +944,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Env, app, ripple); +BEAST_DEFINE_TESTSUITE(Env, jtx, ripple); } // namespace test } // namespace ripple diff --git a/src/test/jtx/WSClient_test.cpp b/src/test/jtx/WSClient_test.cpp index 471e6ff31b..431c57558a 100644 --- a/src/test/jtx/WSClient_test.cpp +++ b/src/test/jtx/WSClient_test.cpp @@ -46,7 +46,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(WSClient, test, ripple); +BEAST_DEFINE_TESTSUITE(WSClient, jtx, ripple); } // namespace test } // namespace ripple diff --git a/src/test/nodestore/Backend_test.cpp b/src/test/nodestore/Backend_test.cpp index 488370fbe9..f161f7a0c0 100644 --- a/src/test/nodestore/Backend_test.cpp +++ b/src/test/nodestore/Backend_test.cpp @@ -121,7 +121,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Backend, ripple_core, ripple); +BEAST_DEFINE_TESTSUITE(Backend, nodestore, ripple); } // namespace NodeStore } // namespace ripple diff --git a/src/test/nodestore/Basics_test.cpp b/src/test/nodestore/Basics_test.cpp index 62a66c9dce..d781bb0c78 100644 --- a/src/test/nodestore/Basics_test.cpp +++ b/src/test/nodestore/Basics_test.cpp @@ -85,7 +85,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(NodeStoreBasic, ripple_core, ripple); +BEAST_DEFINE_TESTSUITE(NodeStoreBasic, nodestore, ripple); } // namespace NodeStore } // namespace ripple diff --git a/src/test/nodestore/Database_test.cpp b/src/test/nodestore/Database_test.cpp index bbf6381ee5..5ecb5b94e8 100644 --- a/src/test/nodestore/Database_test.cpp +++ b/src/test/nodestore/Database_test.cpp @@ -765,7 +765,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Database, NodeStore, ripple); +BEAST_DEFINE_TESTSUITE(Database, nodestore, ripple); } // namespace NodeStore } // namespace ripple diff --git a/src/test/nodestore/Timing_test.cpp b/src/test/nodestore/Timing_test.cpp index 3df18eee66..1ba5903cbe 100644 --- a/src/test/nodestore/Timing_test.cpp +++ b/src/test/nodestore/Timing_test.cpp @@ -779,7 +779,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Timing, NodeStore, ripple, 1); +BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(Timing, nodestore, ripple, 1); } // namespace NodeStore } // namespace ripple diff --git a/src/test/nodestore/import_test.cpp b/src/test/nodestore/import_test.cpp index d7865a20fc..11009ec5be 100644 --- a/src/test/nodestore/import_test.cpp +++ b/src/test/nodestore/import_test.cpp @@ -549,7 +549,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL(import, NodeStore, ripple); +BEAST_DEFINE_TESTSUITE_MANUAL(import, nodestore, ripple); #endif diff --git a/src/test/nodestore/varint_test.cpp b/src/test/nodestore/varint_test.cpp index 4f6d3c141c..f047616d79 100644 --- a/src/test/nodestore/varint_test.cpp +++ b/src/test/nodestore/varint_test.cpp @@ -72,7 +72,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(varint, NodeStore, ripple); +BEAST_DEFINE_TESTSUITE(varint, nodestore, ripple); } // namespace tests } // namespace NodeStore diff --git a/src/test/overlay/compression_test.cpp b/src/test/overlay/compression_test.cpp index 4ecbe7f232..01be43d58b 100644 --- a/src/test/overlay/compression_test.cpp +++ b/src/test/overlay/compression_test.cpp @@ -537,7 +537,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL(compression, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE_MANUAL(compression, overlay, ripple); } // namespace test } // namespace ripple diff --git a/src/test/overlay/handshake_test.cpp b/src/test/overlay/handshake_test.cpp index 2d5155aaee..936b6e5fff 100644 --- a/src/test/overlay/handshake_test.cpp +++ b/src/test/overlay/handshake_test.cpp @@ -59,7 +59,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(handshake, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE(handshake, overlay, ripple); } // namespace test } // namespace ripple diff --git a/src/test/overlay/reduce_relay_test.cpp b/src/test/overlay/reduce_relay_test.cpp index a8aafcfa06..0047454cf9 100644 --- a/src/test/overlay/reduce_relay_test.cpp +++ b/src/test/overlay/reduce_relay_test.cpp @@ -1748,8 +1748,8 @@ class reduce_relay_simulate_test : public reduce_relay_test } }; -BEAST_DEFINE_TESTSUITE(reduce_relay, ripple_data, ripple); -BEAST_DEFINE_TESTSUITE_MANUAL(reduce_relay_simulate, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE(reduce_relay, overlay, ripple); +BEAST_DEFINE_TESTSUITE_MANUAL(reduce_relay_simulate, overlay, ripple); } // namespace test diff --git a/src/test/overlay/tx_reduce_relay_test.cpp b/src/test/overlay/tx_reduce_relay_test.cpp index 7a6b36ecd2..0024f2b98e 100644 --- a/src/test/overlay/tx_reduce_relay_test.cpp +++ b/src/test/overlay/tx_reduce_relay_test.cpp @@ -284,6 +284,6 @@ private: } }; -BEAST_DEFINE_TESTSUITE(tx_reduce_relay, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE(tx_reduce_relay, overlay, ripple); } // namespace test } // namespace ripple diff --git a/src/test/peerfinder/PeerFinder_test.cpp b/src/test/peerfinder/PeerFinder_test.cpp index 9006b8c1c7..f35cbbdaae 100644 --- a/src/test/peerfinder/PeerFinder_test.cpp +++ b/src/test/peerfinder/PeerFinder_test.cpp @@ -367,7 +367,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(PeerFinder, PeerFinder, ripple); +BEAST_DEFINE_TESTSUITE(PeerFinder, peerfinder, ripple); } // namespace PeerFinder } // namespace ripple diff --git a/src/test/protocol/InnerObjectFormats_test.cpp b/src/test/protocol/InnerObjectFormats_test.cpp index f4d9722392..daf9548b8b 100644 --- a/src/test/protocol/InnerObjectFormats_test.cpp +++ b/src/test/protocol/InnerObjectFormats_test.cpp @@ -201,6 +201,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(InnerObjectFormatsParsedJSON, ripple_app, ripple); +BEAST_DEFINE_TESTSUITE(InnerObjectFormatsParsedJSON, protocol, ripple); } // namespace ripple diff --git a/src/test/protocol/Memo_test.cpp b/src/test/protocol/Memo_test.cpp index a7fa846a4d..3b36cfc368 100644 --- a/src/test/protocol/Memo_test.cpp +++ b/src/test/protocol/Memo_test.cpp @@ -135,6 +135,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Memo, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE(Memo, protocol, ripple); } // namespace ripple diff --git a/src/test/protocol/STAmount_test.cpp b/src/test/protocol/STAmount_test.cpp index d62241f2f4..5d3fdfb28a 100644 --- a/src/test/protocol/STAmount_test.cpp +++ b/src/test/protocol/STAmount_test.cpp @@ -1052,6 +1052,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(STAmount, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE(STAmount, protocol, ripple); } // namespace ripple diff --git a/src/test/protocol/STIssue_test.cpp b/src/test/protocol/STIssue_test.cpp index 6e8d37331b..6ef80cd379 100644 --- a/src/test/protocol/STIssue_test.cpp +++ b/src/test/protocol/STIssue_test.cpp @@ -159,7 +159,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(STIssue, ripple_data, ripple); +BEAST_DEFINE_TESTSUITE(STIssue, protocol, ripple); } // namespace test } // namespace ripple diff --git a/src/test/protocol/STTx_test.cpp b/src/test/protocol/STTx_test.cpp index f48bea11aa..eaa7a15212 100644 --- a/src/test/protocol/STTx_test.cpp +++ b/src/test/protocol/STTx_test.cpp @@ -1857,7 +1857,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(STTx, ripple_app, ripple); -BEAST_DEFINE_TESTSUITE(InnerObjectFormatsSerializer, ripple_app, ripple); +BEAST_DEFINE_TESTSUITE(STTx, protocol, ripple); +BEAST_DEFINE_TESTSUITE(InnerObjectFormatsSerializer, protocol, ripple); } // namespace ripple diff --git a/src/test/rpc/AMMInfo_test.cpp b/src/test/rpc/AMMInfo_test.cpp index a6e866b1c8..d5bfc8e83d 100644 --- a/src/test/rpc/AMMInfo_test.cpp +++ b/src/test/rpc/AMMInfo_test.cpp @@ -369,7 +369,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(AMMInfo, app, ripple); +BEAST_DEFINE_TESTSUITE(AMMInfo, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/AccountSet_test.cpp b/src/test/rpc/AccountSet_test.cpp index 5c0ca89305..3615a715cd 100644 --- a/src/test/rpc/AccountSet_test.cpp +++ b/src/test/rpc/AccountSet_test.cpp @@ -597,6 +597,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(AccountSet, app, ripple, 1); +BEAST_DEFINE_TESTSUITE_PRIO(AccountSet, rpc, ripple, 1); } // namespace ripple diff --git a/src/test/rpc/AmendmentBlocked_test.cpp b/src/test/rpc/AmendmentBlocked_test.cpp index bea9cdf57d..4708a873f6 100644 --- a/src/test/rpc/AmendmentBlocked_test.cpp +++ b/src/test/rpc/AmendmentBlocked_test.cpp @@ -255,6 +255,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(AmendmentBlocked, app, ripple); +BEAST_DEFINE_TESTSUITE(AmendmentBlocked, rpc, ripple); } // namespace ripple diff --git a/src/test/rpc/BookChanges_test.cpp b/src/test/rpc/BookChanges_test.cpp index 1f7b6775f2..41b26415af 100644 --- a/src/test/rpc/BookChanges_test.cpp +++ b/src/test/rpc/BookChanges_test.cpp @@ -143,7 +143,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(BookChanges, app, ripple); +BEAST_DEFINE_TESTSUITE(BookChanges, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/Book_test.cpp b/src/test/rpc/Book_test.cpp index e885762644..7177ab847c 100644 --- a/src/test/rpc/Book_test.cpp +++ b/src/test/rpc/Book_test.cpp @@ -2019,7 +2019,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(Book, app, ripple, 1); +BEAST_DEFINE_TESTSUITE_PRIO(Book, rpc, ripple, 1); } // namespace test } // namespace ripple diff --git a/src/test/rpc/DeliveredAmount_test.cpp b/src/test/rpc/DeliveredAmount_test.cpp index d084f92f25..c1aa77695d 100644 --- a/src/test/rpc/DeliveredAmount_test.cpp +++ b/src/test/rpc/DeliveredAmount_test.cpp @@ -422,7 +422,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(DeliveredAmount, app, ripple); +BEAST_DEFINE_TESTSUITE(DeliveredAmount, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/DepositAuthorized_test.cpp b/src/test/rpc/DepositAuthorized_test.cpp index 647f9e25ed..326766221a 100644 --- a/src/test/rpc/DepositAuthorized_test.cpp +++ b/src/test/rpc/DepositAuthorized_test.cpp @@ -638,7 +638,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(DepositAuthorized, app, ripple); +BEAST_DEFINE_TESTSUITE(DepositAuthorized, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/GatewayBalances_test.cpp b/src/test/rpc/GatewayBalances_test.cpp index 691f32317e..a13e5bc20c 100644 --- a/src/test/rpc/GatewayBalances_test.cpp +++ b/src/test/rpc/GatewayBalances_test.cpp @@ -262,7 +262,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(GatewayBalances, app, ripple); +BEAST_DEFINE_TESTSUITE(GatewayBalances, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/GetAggregatePrice_test.cpp b/src/test/rpc/GetAggregatePrice_test.cpp index 4e9b950690..9d007f7f52 100644 --- a/src/test/rpc/GetAggregatePrice_test.cpp +++ b/src/test/rpc/GetAggregatePrice_test.cpp @@ -346,7 +346,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(GetAggregatePrice, app, ripple); +BEAST_DEFINE_TESTSUITE(GetAggregatePrice, rpc, ripple); } // namespace oracle } // namespace jtx diff --git a/src/test/rpc/Handler_test.cpp b/src/test/rpc/Handler_test.cpp index 8eb0c8d01d..c58d29252b 100644 --- a/src/test/rpc/Handler_test.cpp +++ b/src/test/rpc/Handler_test.cpp @@ -128,6 +128,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE_MANUAL(Handler, test, ripple); +BEAST_DEFINE_TESTSUITE_MANUAL(Handler, rpc, ripple); } // namespace ripple::test diff --git a/src/test/rpc/JSONRPC_test.cpp b/src/test/rpc/JSONRPC_test.cpp index 1612d1b455..31bdacfb9c 100644 --- a/src/test/rpc/JSONRPC_test.cpp +++ b/src/test/rpc/JSONRPC_test.cpp @@ -2936,7 +2936,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(JSONRPC, ripple_app, ripple); +BEAST_DEFINE_TESTSUITE(JSONRPC, rpc, ripple); } // namespace RPC } // namespace ripple diff --git a/src/test/rpc/KeyGeneration_test.cpp b/src/test/rpc/KeyGeneration_test.cpp index 07ebd93dd3..3ea6a07e94 100644 --- a/src/test/rpc/KeyGeneration_test.cpp +++ b/src/test/rpc/KeyGeneration_test.cpp @@ -894,7 +894,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(WalletPropose, ripple_basics, ripple); +BEAST_DEFINE_TESTSUITE(WalletPropose, rpc, ripple); } // namespace RPC } // namespace ripple diff --git a/src/test/rpc/LedgerClosed_test.cpp b/src/test/rpc/LedgerClosed_test.cpp index fc7b3a7dac..37d6b1e393 100644 --- a/src/test/rpc/LedgerClosed_test.cpp +++ b/src/test/rpc/LedgerClosed_test.cpp @@ -68,6 +68,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(LedgerClosed, app, ripple); +BEAST_DEFINE_TESTSUITE(LedgerClosed, rpc, ripple); } // namespace ripple diff --git a/src/test/rpc/LedgerData_test.cpp b/src/test/rpc/LedgerData_test.cpp index 54f51255d1..d57b33013a 100644 --- a/src/test/rpc/LedgerData_test.cpp +++ b/src/test/rpc/LedgerData_test.cpp @@ -523,6 +523,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE_PRIO(LedgerData, app, ripple, 1); +BEAST_DEFINE_TESTSUITE_PRIO(LedgerData, rpc, ripple, 1); } // namespace ripple diff --git a/src/test/rpc/LedgerEntry_test.cpp b/src/test/rpc/LedgerEntry_test.cpp index b5cab9d13c..89cb7b72eb 100644 --- a/src/test/rpc/LedgerEntry_test.cpp +++ b/src/test/rpc/LedgerEntry_test.cpp @@ -2711,8 +2711,8 @@ public: } }; -BEAST_DEFINE_TESTSUITE(LedgerEntry, app, ripple); -BEAST_DEFINE_TESTSUITE(LedgerEntry_XChain, app, ripple); +BEAST_DEFINE_TESTSUITE(LedgerEntry, rpc, ripple); +BEAST_DEFINE_TESTSUITE(LedgerEntry_XChain, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index 9ba9c9a655..9309fbdd6c 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -785,7 +785,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(LedgerRPC, app, ripple); +BEAST_DEFINE_TESTSUITE(LedgerRPC, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/LedgerRequestRPC_test.cpp b/src/test/rpc/LedgerRequestRPC_test.cpp index b34233991e..03be9fb29b 100644 --- a/src/test/rpc/LedgerRequestRPC_test.cpp +++ b/src/test/rpc/LedgerRequestRPC_test.cpp @@ -376,7 +376,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(LedgerRequestRPC, app, ripple); +BEAST_DEFINE_TESTSUITE(LedgerRequestRPC, rpc, ripple); } // namespace RPC } // namespace ripple diff --git a/src/test/rpc/NoRipple_test.cpp b/src/test/rpc/NoRipple_test.cpp index 926de31e83..93457ada8c 100644 --- a/src/test/rpc/NoRipple_test.cpp +++ b/src/test/rpc/NoRipple_test.cpp @@ -299,7 +299,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(NoRipple, app, ripple); +BEAST_DEFINE_TESTSUITE(NoRipple, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/OwnerInfo_test.cpp b/src/test/rpc/OwnerInfo_test.cpp index 15bbad42e3..0c517058ca 100644 --- a/src/test/rpc/OwnerInfo_test.cpp +++ b/src/test/rpc/OwnerInfo_test.cpp @@ -219,6 +219,6 @@ public: } }; -BEAST_DEFINE_TESTSUITE(OwnerInfo, app, ripple); +BEAST_DEFINE_TESTSUITE(OwnerInfo, rpc, ripple); } // namespace ripple diff --git a/src/test/rpc/RPCCall_test.cpp b/src/test/rpc/RPCCall_test.cpp index be0f32b5ce..b73f2e11a0 100644 --- a/src/test/rpc/RPCCall_test.cpp +++ b/src/test/rpc/RPCCall_test.cpp @@ -5948,7 +5948,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(RPCCall, app, ripple); +BEAST_DEFINE_TESTSUITE(RPCCall, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/RPCHelpers_test.cpp b/src/test/rpc/RPCHelpers_test.cpp index 531649b8af..1716301dae 100644 --- a/src/test/rpc/RPCHelpers_test.cpp +++ b/src/test/rpc/RPCHelpers_test.cpp @@ -87,7 +87,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(RPCHelpers, app, ripple); +BEAST_DEFINE_TESTSUITE(RPCHelpers, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/RPCOverload_test.cpp b/src/test/rpc/RPCOverload_test.cpp index efe69496fb..35755eff20 100644 --- a/src/test/rpc/RPCOverload_test.cpp +++ b/src/test/rpc/RPCOverload_test.cpp @@ -87,7 +87,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(RPCOverload, app, ripple); +BEAST_DEFINE_TESTSUITE(RPCOverload, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/RobustTransaction_test.cpp b/src/test/rpc/RobustTransaction_test.cpp index aa53bd6e0a..bfd9e6251b 100644 --- a/src/test/rpc/RobustTransaction_test.cpp +++ b/src/test/rpc/RobustTransaction_test.cpp @@ -510,7 +510,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(RobustTransaction, app, ripple); +BEAST_DEFINE_TESTSUITE(RobustTransaction, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/Roles_test.cpp b/src/test/rpc/Roles_test.cpp index 5ac8654330..949d84c1e5 100644 --- a/src/test/rpc/Roles_test.cpp +++ b/src/test/rpc/Roles_test.cpp @@ -389,7 +389,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Roles, app, ripple); +BEAST_DEFINE_TESTSUITE(Roles, rpc, ripple); } // namespace test diff --git a/src/test/rpc/ServerInfo_test.cpp b/src/test/rpc/ServerInfo_test.cpp index 21312ef8ff..b5780635cd 100644 --- a/src/test/rpc/ServerInfo_test.cpp +++ b/src/test/rpc/ServerInfo_test.cpp @@ -308,7 +308,7 @@ admin = 127.0.0.1 } }; -BEAST_DEFINE_TESTSUITE(ServerInfo, app, ripple); +BEAST_DEFINE_TESTSUITE(ServerInfo, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/Status_test.cpp b/src/test/rpc/Status_test.cpp index e37fe2dabd..884e684fb3 100644 --- a/src/test/rpc/Status_test.cpp +++ b/src/test/rpc/Status_test.cpp @@ -94,7 +94,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(codeString, Status, RPC); +BEAST_DEFINE_TESTSUITE(codeString, rpc, RPC); class fillJson_test : public beast::unit_test::suite { @@ -218,7 +218,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(fillJson, Status, RPC); +BEAST_DEFINE_TESTSUITE(fillJson, rpc, RPC); } // namespace RPC } // namespace ripple diff --git a/src/test/rpc/Subscribe_test.cpp b/src/test/rpc/Subscribe_test.cpp index e0db79bf53..9ed02fa532 100644 --- a/src/test/rpc/Subscribe_test.cpp +++ b/src/test/rpc/Subscribe_test.cpp @@ -1608,7 +1608,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Subscribe, app, ripple); +BEAST_DEFINE_TESTSUITE(Subscribe, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/rpc/ValidatorRPC_test.cpp b/src/test/rpc/ValidatorRPC_test.cpp index d03cbbf841..d139a662de 100644 --- a/src/test/rpc/ValidatorRPC_test.cpp +++ b/src/test/rpc/ValidatorRPC_test.cpp @@ -594,7 +594,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(ValidatorRPC, app, ripple); +BEAST_DEFINE_TESTSUITE(ValidatorRPC, rpc, ripple); } // namespace test } // namespace ripple diff --git a/src/test/server/Server_test.cpp b/src/test/server/Server_test.cpp index f8895ae7e9..fab271ff1c 100644 --- a/src/test/server/Server_test.cpp +++ b/src/test/server/Server_test.cpp @@ -533,7 +533,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(Server, http, ripple); +BEAST_DEFINE_TESTSUITE(Server, server, ripple); } // namespace test } // namespace ripple diff --git a/src/test/shamap/SHAMap_test.cpp b/src/test/shamap/SHAMap_test.cpp index 3197e0944d..1a15310b58 100644 --- a/src/test/shamap/SHAMap_test.cpp +++ b/src/test/shamap/SHAMap_test.cpp @@ -402,7 +402,7 @@ class SHAMapPathProof_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(SHAMap, ripple_app, ripple); -BEAST_DEFINE_TESTSUITE(SHAMapPathProof, ripple_app, ripple); +BEAST_DEFINE_TESTSUITE(SHAMap, shamap, ripple); +BEAST_DEFINE_TESTSUITE(SHAMapPathProof, shamap, ripple); } // namespace tests } // namespace ripple From c9d73b613596c50e6ab5c2d3719d4bba5536d631 Mon Sep 17 00:00:00 2001 From: Vito Tumas <5780819+Tapanito@users.noreply.github.com> Date: Mon, 11 Aug 2025 20:52:47 +0200 Subject: [PATCH 06/16] fix: Improve logging of the reason to refuse a peer connection (#5664) Currently, all peer connection rejections are logged with the reason "slots full". This is inaccurate, as the PeerFinder can also reject connections if they are a duplicate. This change updates the logging logic to correctly report the specific reason (full or duplicate) for a rejected peer connection, providing more accurate diagnostic information. --- src/xrpld/overlay/detail/ConnectAttempt.cpp | 2 +- src/xrpld/overlay/detail/OverlayImpl.cpp | 7 ++--- src/xrpld/peerfinder/PeerfinderManager.h | 32 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/xrpld/overlay/detail/ConnectAttempt.cpp b/src/xrpld/overlay/detail/ConnectAttempt.cpp index 84fbd36d32..61049579c5 100644 --- a/src/xrpld/overlay/detail/ConnectAttempt.cpp +++ b/src/xrpld/overlay/detail/ConnectAttempt.cpp @@ -379,7 +379,7 @@ ConnectAttempt::processResponse() auto const result = overlay_.peerFinder().activate( slot_, publicKey, static_cast(member)); if (result != PeerFinder::Result::success) - return fail("Outbound slots full"); + return fail("Outbound " + std::string(to_string(result))); auto const peer = std::make_shared( app_, diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index 53b4cad646..874f951f56 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -41,8 +42,6 @@ #include -#include "xrpld/overlay/detail/TrafficCount.h" - namespace ripple { namespace CrawlOptions { @@ -269,8 +268,8 @@ OverlayImpl::onHandoff( if (result != PeerFinder::Result::success) { m_peerFinder->on_closed(slot); - JLOG(journal.debug()) - << "Peer " << remote_endpoint << " redirected, slots full"; + JLOG(journal.debug()) << "Peer " << remote_endpoint + << " redirected, " << to_string(result); handoff.moved = false; handoff.response = makeRedirectResponse( slot, request, remote_endpoint.address()); diff --git a/src/xrpld/peerfinder/PeerfinderManager.h b/src/xrpld/peerfinder/PeerfinderManager.h index a670fb8780..f399251c38 100644 --- a/src/xrpld/peerfinder/PeerfinderManager.h +++ b/src/xrpld/peerfinder/PeerfinderManager.h @@ -28,6 +28,8 @@ #include +#include + namespace ripple { namespace PeerFinder { @@ -136,6 +138,36 @@ using Endpoints = std::vector; /** Possible results from activating a slot. */ enum class Result { duplicate, full, success }; +/** + * @brief Converts a `Result` enum value to its string representation. + * + * This function provides a human-readable string for a given `Result` enum, + * which is useful for logging, debugging, or displaying status messages. + * + * @param result The `Result` enum value to convert. + * @return A `std::string_view` representing the enum value. Returns "unknown" + * if the enum value is not explicitly handled. + * + * @note This function returns a `std::string_view` for performance. + * A `std::string` would need to allocate memory on the heap and copy the + * string literal into it every time the function is called. + */ +inline std::string_view +to_string(Result result) noexcept +{ + switch (result) + { + case Result::success: + return "success"; + case Result::duplicate: + return "duplicate connection"; + case Result::full: + return "slots full"; + } + + return "unknown"; +} + /** Maintains a set of IP addresses used for getting into the network. */ class Manager : public beast::PropertyStream::Source { From da82e526136bf05d7a60dd6262f6f3186e820db5 Mon Sep 17 00:00:00 2001 From: Michael Legleux Date: Tue, 12 Aug 2025 13:40:34 -0700 Subject: [PATCH 07/16] Set version to 2.6.0-rc1 --- src/libxrpl/protocol/BuildInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libxrpl/protocol/BuildInfo.cpp b/src/libxrpl/protocol/BuildInfo.cpp index 4cb6fbfd36..fb4bc086f6 100644 --- a/src/libxrpl/protocol/BuildInfo.cpp +++ b/src/libxrpl/protocol/BuildInfo.cpp @@ -36,7 +36,7 @@ namespace BuildInfo { // and follow the format described at http://semver.org/ //------------------------------------------------------------------------------ // clang-format off -char const* const versionString = "2.5.0" +char const* const versionString = "2.6.0-rc1" // clang-format on #if defined(DEBUG) || defined(SANITIZER) From c9a723128a16ce8b78469aa53fc3d334cae0aa1d Mon Sep 17 00:00:00 2001 From: Bronek Kozicki Date: Wed, 13 Aug 2025 12:23:36 +0100 Subject: [PATCH 08/16] Fix BUILD.md instruction (#5676) --- BUILD.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BUILD.md b/BUILD.md index 958bf19b8c..c8ec31f826 100644 --- a/BUILD.md +++ b/BUILD.md @@ -147,8 +147,9 @@ git sparse-checkout set recipes/snappy git sparse-checkout add recipes/soci git fetch origin master git checkout master -conan export --version 1.1.10 external/recipes/snappy -conan export --version 4.0.3 external/recipes/soci +conan export --version 1.1.10 recipes/snappy/all +conan export --version 4.0.3 recipes/soci/all +rm -rf .git ``` In the case we switch to a newer version of a dependency that still requires a From 28eec6ce1b606adff043885cd1f9d85124baa4a5 Mon Sep 17 00:00:00 2001 From: "Elliot." Date: Wed, 13 Aug 2025 11:00:22 -0700 Subject: [PATCH 09/16] Update .git-blame-ignore-revs for #5657 (#5675) Now that #5657 has been squashed and merged, we can add its commit hash to .git-blame-ignore-revs. --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index a72fc4afd8..a9805e705c 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -11,3 +11,4 @@ b9d007813378ad0ff45660dc07285b823c7e9855 fe9a5365b8a52d4acc42eb27369247e6f238a4f9 9a93577314e6a8d4b4a8368cc9d2b15a5d8303e8 552377c76f55b403a1c876df873a23d780fcc81c +97f0747e103f13e26e45b731731059b32f7679ac From de33a6a241ef76b049b440afbfce20a31101c186 Mon Sep 17 00:00:00 2001 From: Bart Date: Thu, 14 Aug 2025 06:07:09 -0400 Subject: [PATCH 10/16] fix: Add -Wno-deprecated-declarations for Clang only (#5680) This change adds `-Wno-deprecated-declarations` for Clang only (not for GCC) builds in `cmake/RippledCompiler.cmake`. --- cmake/RippledCompiler.cmake | 1 + include/xrpl/basics/Expected.h | 10 ---------- include/xrpl/beast/hash/hash_append.h | 27 +-------------------------- 3 files changed, 2 insertions(+), 36 deletions(-) diff --git a/cmake/RippledCompiler.cmake b/cmake/RippledCompiler.cmake index 30058fd503..bc3a62a48c 100644 --- a/cmake/RippledCompiler.cmake +++ b/cmake/RippledCompiler.cmake @@ -94,6 +94,7 @@ else () INTERFACE -Wall -Wdeprecated + $<$:-Wno-deprecated-declarations> $<$:-Wextra -Wno-unused-parameter> $<$:-Werror> -fstack-protector diff --git a/include/xrpl/basics/Expected.h b/include/xrpl/basics/Expected.h index d2440f63ab..9afb160d9d 100644 --- a/include/xrpl/basics/Expected.h +++ b/include/xrpl/basics/Expected.h @@ -22,18 +22,8 @@ #include -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - #include -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - #include namespace ripple { diff --git a/include/xrpl/beast/hash/hash_append.h b/include/xrpl/beast/hash/hash_append.h index e113567ab1..a4ffeaf30c 100644 --- a/include/xrpl/beast/hash/hash_append.h +++ b/include/xrpl/beast/hash/hash_append.h @@ -24,35 +24,10 @@ #include #include -/* - -Workaround for overzealous clang warning, which trips on libstdc++ headers - - In file included from - /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_algo.h:61: - /usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stl_tempbuf.h:263:8: - error: 'get_temporary_buffer> *>>' is deprecated - [-Werror,-Wdeprecated-declarations] 263 | - std::get_temporary_buffer(_M_original_len)); - ^ -*/ - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated" -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - -#include - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - #include #include #include +#include #include #include #include From a14551b1517382ae0626471fb852ee55333edf4e Mon Sep 17 00:00:00 2001 From: "Elliot." Date: Thu, 14 Aug 2025 09:28:01 -0700 Subject: [PATCH 11/16] fix: Change log to debug level for AMM offer retrieval and IOU payment check (#5686) Reduce log noise by changing two log statements from error/warn level to debug level. These logs occur during normal operation when AMM offers are not available or when IOU authorization checks fail, which are expected scenarios that don't require an elevated log level. --- src/xrpld/app/paths/detail/AMMLiquidity.cpp | 2 +- src/xrpld/app/paths/detail/DirectStep.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/xrpld/app/paths/detail/AMMLiquidity.cpp b/src/xrpld/app/paths/detail/AMMLiquidity.cpp index 83894b2e76..f24e67c7e1 100644 --- a/src/xrpld/app/paths/detail/AMMLiquidity.cpp +++ b/src/xrpld/app/paths/detail/AMMLiquidity.cpp @@ -248,7 +248,7 @@ AMMLiquidity::getOffer( return offer; } - JLOG(j_.error()) << "AMMLiquidity::getOffer, failed " + JLOG(j_.debug()) << "AMMLiquidity::getOffer, no valid offer " << ammContext_.multiPath() << " " << ammContext_.curIters() << " " << (clobQuality ? clobQuality->rate() : STAmount{}) diff --git a/src/xrpld/app/paths/detail/DirectStep.cpp b/src/xrpld/app/paths/detail/DirectStep.cpp index 4dc9cbf20d..5e62a289a3 100644 --- a/src/xrpld/app/paths/detail/DirectStep.cpp +++ b/src/xrpld/app/paths/detail/DirectStep.cpp @@ -423,7 +423,7 @@ DirectIPaymentStep::check( !((*sleLine)[sfFlags] & authField) && (*sleLine)[sfBalance] == beast::zero) { - JLOG(j_.warn()) + JLOG(j_.debug()) << "DirectStepI: can't receive IOUs from issuer without auth." << " src: " << src_; return terNO_AUTH; From d8628d481d0c439635c6ae7d26ca24f7e9c115b9 Mon Sep 17 00:00:00 2001 From: Bart Date: Thu, 14 Aug 2025 16:17:37 -0400 Subject: [PATCH 12/16] docs: Updates list of maintainers and reviewers (#5687) --- CONTRIBUTING.md | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb29de5b7e..b0ae72ae54 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -384,9 +384,8 @@ Maintainers are users with maintain or admin access to the repo. - [bthomee](https://github.com/bthomee) (Ripple) - [intelliot](https://github.com/intelliot) (Ripple) - [JoelKatz](https://github.com/JoelKatz) (Ripple) -- [nixer89](https://github.com/nixer89) (XRP Ledger Foundation) -- [RichardAH](https://github.com/RichardAH) (XRP Ledger Foundation) -- [Silkjaer](https://github.com/Silkjaer) (XRP Ledger Foundation) +- [legleux](https://github.com/legleux) (Ripple) +- [mankins](https://github.com/mankins) (XRP Ledger Foundation) - [WietseWind](https://github.com/WietseWind) (XRPL Labs + XRP Ledger Foundation) - [ximinez](https://github.com/ximinez) (Ripple) @@ -395,27 +394,24 @@ Maintainers are users with maintain or admin access to the repo. Code Reviewers are developers who have the ability to review, approve, and in some cases merge source code changes. -- [HowardHinnant](https://github.com/HowardHinnant) (Ripple) -- [scottschurr](https://github.com/scottschurr) (Ripple) -- [seelabs](https://github.com/seelabs) (Ripple) -- [Ed Hennis](https://github.com/ximinez) (Ripple) -- [mvadari](https://github.com/mvadari) (Ripple) -- [thejohnfreeman](https://github.com/thejohnfreeman) (Ripple) +- [a1q123456](https://github.com/a1q123456) (Ripple) - [Bronek](https://github.com/Bronek) (Ripple) -- [manojsdoshi](https://github.com/manojsdoshi) (Ripple) -- [godexsoft](https://github.com/godexsoft) (Ripple) -- [mDuo13](https://github.com/mDuo13) (Ripple) -- [ckniffen](https://github.com/ckniffen) (Ripple) -- [arihantkothari](https://github.com/arihantkothari) (Ripple) -- [pwang200](https://github.com/pwang200) (Ripple) -- [sophiax851](https://github.com/sophiax851) (Ripple) -- [shawnxie999](https://github.com/shawnxie999) (Ripple) -- [gregtatcam](https://github.com/gregtatcam) (Ripple) -- [mtrippled](https://github.com/mtrippled) (Ripple) +- [bthomee](https://github.com/bthomee) (Ripple) - [ckeshava](https://github.com/ckeshava) (Ripple) -- [nbougalis](https://github.com/nbougalis) None -- [RichardAH](https://github.com/RichardAH) (XRPL Labs + XRP Ledger Foundation) - [dangell7](https://github.com/dangell7) (XRPL Labs) +- [godexsoft](https://github.com/godexsoft) (Ripple) +- [gregtatcam](https://github.com/gregtatcam) (Ripple) +- [kuznetsss](https://github.com/kuznetsss) (Ripple) +- [lmaisons](https://github.com/lmaisons) (Ripple) +- [mathbunnyru](https://github.com/mathbunnyru) (Ripple) +- [mvadari](https://github.com/mvadari) (Ripple) +- [oleks-rip](https://github.com/oleks-rip) (Ripple) +- [PeterChen13579](https://github.com/PeterChen13579) (Ripple) +- [pwang200](https://github.com/pwang200) (Ripple) +- [q73zhao](https://github.com/q73zhao) (Ripple) +- [shawnxie999](https://github.com/shawnxie999) (Ripple) +- [Tapanito](https://github.com/Tapanito) (Ripple) +- [ximinez](https://github.com/ximinez) (Ripple) Developers not on this list are able and encouraged to submit feedback on pending code changes (open pull requests). From fb89213d4db171c4bb88703d9f4dee4ea98360a5 Mon Sep 17 00:00:00 2001 From: Michael Legleux Date: Fri, 15 Aug 2025 14:50:35 -0700 Subject: [PATCH 13/16] Set version to 2.6.0-rc2 --- src/libxrpl/protocol/BuildInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libxrpl/protocol/BuildInfo.cpp b/src/libxrpl/protocol/BuildInfo.cpp index fb4bc086f6..0d7ea1a7ca 100644 --- a/src/libxrpl/protocol/BuildInfo.cpp +++ b/src/libxrpl/protocol/BuildInfo.cpp @@ -36,7 +36,7 @@ namespace BuildInfo { // and follow the format described at http://semver.org/ //------------------------------------------------------------------------------ // clang-format off -char const* const versionString = "2.6.0-rc1" +char const* const versionString = "2.6.0-rc2" // clang-format on #if defined(DEBUG) || defined(SANITIZER) From ceb0ce5634e57eaa5207bd13da8705cb0117ebc3 Mon Sep 17 00:00:00 2001 From: Jingchen Date: Sat, 16 Aug 2025 00:27:13 +0100 Subject: [PATCH 14/16] refactor: Decouple net from xrpld and move rpc-related classes to the rpc folder (#5477) As a step of modularisation, this change moves code from `xrpld` to `libxrpl`. --- Builds/levelization/results/loops.txt | 9 -------- Builds/levelization/results/ordering.txt | 13 ++++++----- cmake/RippledCore.cmake | 10 +++++++++ cmake/RippledInstall.cmake | 1 + {src/xrpld => include/xrpl}/net/AutoSocket.h | 0 {src/xrpld => include/xrpl}/net/HTTPClient.h | 9 +++++--- .../xrpl}/net/HTTPClientSSLContext.h | 21 +++++++++--------- .../xrpl}/net/RegisterSSLCerts.h | 0 .../net/detail => libxrpl/net}/HTTPClient.cpp | 15 ++++++++----- .../net}/RegisterSSLCerts.cpp | 2 +- .../net/images/interrupt_sequence.png | Bin src/{xrpld => libxrpl}/net/images/states.png | Bin src/test/jtx/impl/Env.cpp | 10 ++++++--- src/test/jtx/impl/utility.cpp | 2 +- src/test/rpc/RPCCall_test.cpp | 2 +- src/xrpld/app/ledger/BookListeners.h | 2 +- src/xrpld/app/main/GRPCServer.h | 2 +- src/xrpld/app/main/Main.cpp | 2 +- src/xrpld/app/misc/NetworkOPs.h | 2 +- src/xrpld/app/misc/detail/WorkSSL.cpp | 7 +++++- src/xrpld/app/misc/detail/WorkSSL.h | 2 +- src/xrpld/app/paths/PathRequest.h | 2 +- src/xrpld/core/detail/Config.cpp | 5 +++-- src/xrpld/rpc/Context.h | 2 +- src/xrpld/{net => rpc}/InfoSub.h | 0 src/xrpld/{net => rpc}/RPCCall.h | 0 src/xrpld/{net => rpc}/RPCSub.h | 2 +- src/xrpld/{net => rpc}/detail/InfoSub.cpp | 2 +- src/xrpld/{net => rpc}/detail/RPCCall.cpp | 13 +++++------ src/xrpld/rpc/detail/RPCHandler.cpp | 2 +- src/xrpld/{net => rpc}/detail/RPCSub.cpp | 4 ++-- src/xrpld/rpc/detail/WSInfoSub.h | 2 +- src/xrpld/rpc/handlers/Subscribe.cpp | 2 +- 33 files changed, 83 insertions(+), 64 deletions(-) rename {src/xrpld => include/xrpl}/net/AutoSocket.h (100%) rename {src/xrpld => include/xrpl}/net/HTTPClient.h (93%) rename {src/xrpld => include/xrpl}/net/HTTPClientSSLContext.h (92%) rename {src/xrpld => include/xrpl}/net/RegisterSSLCerts.h (100%) rename src/{xrpld/net/detail => libxrpl/net}/HTTPClient.cpp (98%) rename src/{xrpld/net/detail => libxrpl/net}/RegisterSSLCerts.cpp (98%) rename src/{xrpld => libxrpl}/net/images/interrupt_sequence.png (100%) rename src/{xrpld => libxrpl}/net/images/states.png (100%) rename src/xrpld/{net => rpc}/InfoSub.h (100%) rename src/xrpld/{net => rpc}/RPCCall.h (100%) rename src/xrpld/{net => rpc}/RPCSub.h (98%) rename src/xrpld/{net => rpc}/detail/InfoSub.cpp (99%) rename src/xrpld/{net => rpc}/detail/RPCCall.cpp (99%) rename src/xrpld/{net => rpc}/detail/RPCSub.cpp (99%) diff --git a/Builds/levelization/results/loops.txt b/Builds/levelization/results/loops.txt index df1d273f93..0bbd65a9e4 100644 --- a/Builds/levelization/results/loops.txt +++ b/Builds/levelization/results/loops.txt @@ -10,9 +10,6 @@ Loop: xrpld.app xrpld.core Loop: xrpld.app xrpld.ledger xrpld.app > xrpld.ledger -Loop: xrpld.app xrpld.net - xrpld.app > xrpld.net - Loop: xrpld.app xrpld.overlay xrpld.overlay > xrpld.app @@ -25,15 +22,9 @@ Loop: xrpld.app xrpld.rpc Loop: xrpld.app xrpld.shamap xrpld.app > xrpld.shamap -Loop: xrpld.core xrpld.net - xrpld.net > xrpld.core - Loop: xrpld.core xrpld.perflog xrpld.perflog == xrpld.core -Loop: xrpld.net xrpld.rpc - xrpld.rpc ~= xrpld.net - Loop: xrpld.overlay xrpld.rpc xrpld.rpc ~= xrpld.overlay diff --git a/Builds/levelization/results/ordering.txt b/Builds/levelization/results/ordering.txt index ce22d8edb0..bf2d1db693 100644 --- a/Builds/levelization/results/ordering.txt +++ b/Builds/levelization/results/ordering.txt @@ -2,6 +2,8 @@ libxrpl.basics > xrpl.basics libxrpl.crypto > xrpl.basics libxrpl.json > xrpl.basics libxrpl.json > xrpl.json +libxrpl.net > xrpl.basics +libxrpl.net > xrpl.net libxrpl.protocol > xrpl.basics libxrpl.protocol > xrpl.json libxrpl.protocol > xrpl.protocol @@ -62,9 +64,9 @@ test.jtx > xrpl.basics test.jtx > xrpld.app test.jtx > xrpld.core test.jtx > xrpld.ledger -test.jtx > xrpld.net test.jtx > xrpld.rpc test.jtx > xrpl.json +test.jtx > xrpl.net test.jtx > xrpl.protocol test.jtx > xrpl.resource test.jtx > xrpl.server @@ -109,7 +111,6 @@ test.rpc > test.toplevel test.rpc > xrpl.basics test.rpc > xrpld.app test.rpc > xrpld.core -test.rpc > xrpld.net test.rpc > xrpld.overlay test.rpc > xrpld.rpc test.rpc > xrpl.json @@ -134,6 +135,7 @@ test.toplevel > xrpl.json test.unit_test > xrpl.basics tests.libxrpl > xrpl.basics xrpl.json > xrpl.basics +xrpl.net > xrpl.basics xrpl.protocol > xrpl.basics xrpl.protocol > xrpl.json xrpl.resource > xrpl.basics @@ -149,6 +151,7 @@ xrpld.app > xrpld.consensus xrpld.app > xrpld.nodestore xrpld.app > xrpld.perflog xrpld.app > xrpl.json +xrpld.app > xrpl.net xrpld.app > xrpl.protocol xrpld.app > xrpl.resource xrpld.conditions > xrpl.basics @@ -158,14 +161,11 @@ xrpld.consensus > xrpl.json xrpld.consensus > xrpl.protocol xrpld.core > xrpl.basics xrpld.core > xrpl.json +xrpld.core > xrpl.net xrpld.core > xrpl.protocol xrpld.ledger > xrpl.basics xrpld.ledger > xrpl.json xrpld.ledger > xrpl.protocol -xrpld.net > xrpl.basics -xrpld.net > xrpl.json -xrpld.net > xrpl.protocol -xrpld.net > xrpl.resource xrpld.nodestore > xrpl.basics xrpld.nodestore > xrpld.core xrpld.nodestore > xrpld.unity @@ -189,6 +189,7 @@ xrpld.rpc > xrpld.core xrpld.rpc > xrpld.ledger xrpld.rpc > xrpld.nodestore xrpld.rpc > xrpl.json +xrpld.rpc > xrpl.net xrpld.rpc > xrpl.protocol xrpld.rpc > xrpl.resource xrpld.rpc > xrpl.server diff --git a/cmake/RippledCore.cmake b/cmake/RippledCore.cmake index 1ef5a4ad68..83b27e6c4f 100644 --- a/cmake/RippledCore.cmake +++ b/cmake/RippledCore.cmake @@ -99,6 +99,15 @@ target_link_libraries(xrpl.libxrpl.protocol PUBLIC add_module(xrpl resource) target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol) +# Level 06 +add_module(xrpl net) +target_link_libraries(xrpl.libxrpl.net PUBLIC + xrpl.libxrpl.basics + xrpl.libxrpl.json + xrpl.libxrpl.protocol + xrpl.libxrpl.resource +) + add_module(xrpl server) target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol) @@ -121,6 +130,7 @@ target_link_modules(xrpl PUBLIC protocol resource server + net ) # All headers in libxrpl are in modules. diff --git a/cmake/RippledInstall.cmake b/cmake/RippledInstall.cmake index 9ce288d785..f32781f596 100644 --- a/cmake/RippledInstall.cmake +++ b/cmake/RippledInstall.cmake @@ -19,6 +19,7 @@ install ( xrpl.libxrpl.protocol xrpl.libxrpl.resource xrpl.libxrpl.server + xrpl.libxrpl.net xrpl.libxrpl antithesis-sdk-cpp EXPORT RippleExports diff --git a/src/xrpld/net/AutoSocket.h b/include/xrpl/net/AutoSocket.h similarity index 100% rename from src/xrpld/net/AutoSocket.h rename to include/xrpl/net/AutoSocket.h diff --git a/src/xrpld/net/HTTPClient.h b/include/xrpl/net/HTTPClient.h similarity index 93% rename from src/xrpld/net/HTTPClient.h rename to include/xrpl/net/HTTPClient.h index a11b885290..ef295e8e5a 100644 --- a/src/xrpld/net/HTTPClient.h +++ b/include/xrpl/net/HTTPClient.h @@ -20,9 +20,8 @@ #ifndef RIPPLE_NET_HTTPCLIENT_H_INCLUDED #define RIPPLE_NET_HTTPCLIENT_H_INCLUDED -#include - #include +#include #include #include @@ -44,7 +43,11 @@ public: static constexpr auto maxClientHeaderBytes = kilobytes(32); static void - initializeSSLContext(Config const& config, beast::Journal j); + initializeSSLContext( + std::string const& sslVerifyDir, + std::string const& sslVerifyFile, + bool sslVerify, + beast::Journal j); static void get(bool bSSL, diff --git a/src/xrpld/net/HTTPClientSSLContext.h b/include/xrpl/net/HTTPClientSSLContext.h similarity index 92% rename from src/xrpld/net/HTTPClientSSLContext.h rename to include/xrpl/net/HTTPClientSSLContext.h index 68f91b18b0..2f7d6c005e 100644 --- a/src/xrpld/net/HTTPClientSSLContext.h +++ b/include/xrpl/net/HTTPClientSSLContext.h @@ -20,11 +20,10 @@ #ifndef RIPPLE_NET_HTTPCLIENTSSLCONTEXT_H_INCLUDED #define RIPPLE_NET_HTTPCLIENTSSLCONTEXT_H_INCLUDED -#include -#include - #include #include +#include +#include #include #include @@ -37,31 +36,33 @@ class HTTPClientSSLContext { public: explicit HTTPClientSSLContext( - Config const& config, + std::string const& sslVerifyDir, + std::string const& sslVerifyFile, + bool sslVerify, beast::Journal j, boost::asio::ssl::context_base::method method = boost::asio::ssl::context::sslv23) - : ssl_context_{method}, j_(j), verify_{config.SSL_VERIFY} + : ssl_context_{method}, j_(j), verify_{sslVerify} { boost::system::error_code ec; - if (config.SSL_VERIFY_FILE.empty()) + if (sslVerifyFile.empty()) { registerSSLCerts(ssl_context_, ec, j_); - if (ec && config.SSL_VERIFY_DIR.empty()) + if (ec && sslVerifyDir.empty()) Throw(boost::str( boost::format("Failed to set_default_verify_paths: %s") % ec.message())); } else { - ssl_context_.load_verify_file(config.SSL_VERIFY_FILE); + ssl_context_.load_verify_file(sslVerifyFile); } - if (!config.SSL_VERIFY_DIR.empty()) + if (!sslVerifyDir.empty()) { - ssl_context_.add_verify_path(config.SSL_VERIFY_DIR, ec); + ssl_context_.add_verify_path(sslVerifyDir, ec); if (ec) Throw(boost::str( diff --git a/src/xrpld/net/RegisterSSLCerts.h b/include/xrpl/net/RegisterSSLCerts.h similarity index 100% rename from src/xrpld/net/RegisterSSLCerts.h rename to include/xrpl/net/RegisterSSLCerts.h diff --git a/src/xrpld/net/detail/HTTPClient.cpp b/src/libxrpl/net/HTTPClient.cpp similarity index 98% rename from src/xrpld/net/detail/HTTPClient.cpp rename to src/libxrpl/net/HTTPClient.cpp index 901237e1e3..f7d540750a 100644 --- a/src/xrpld/net/detail/HTTPClient.cpp +++ b/src/libxrpl/net/HTTPClient.cpp @@ -17,12 +17,11 @@ */ //============================================================================== -#include -#include -#include - #include #include +#include +#include +#include #include #include @@ -36,9 +35,13 @@ namespace ripple { static std::optional httpClientSSLContext; void -HTTPClient::initializeSSLContext(Config const& config, beast::Journal j) +HTTPClient::initializeSSLContext( + std::string const& sslVerifyDir, + std::string const& sslVerifyFile, + bool sslVerify, + beast::Journal j) { - httpClientSSLContext.emplace(config, j); + httpClientSSLContext.emplace(sslVerifyDir, sslVerifyFile, sslVerify, j); } //------------------------------------------------------------------------------ diff --git a/src/xrpld/net/detail/RegisterSSLCerts.cpp b/src/libxrpl/net/RegisterSSLCerts.cpp similarity index 98% rename from src/xrpld/net/detail/RegisterSSLCerts.cpp rename to src/libxrpl/net/RegisterSSLCerts.cpp index 5a710323ad..cd5bd631aa 100644 --- a/src/xrpld/net/detail/RegisterSSLCerts.cpp +++ b/src/libxrpl/net/RegisterSSLCerts.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include #if BOOST_OS_WINDOWS #include diff --git a/src/xrpld/net/images/interrupt_sequence.png b/src/libxrpl/net/images/interrupt_sequence.png similarity index 100% rename from src/xrpld/net/images/interrupt_sequence.png rename to src/libxrpl/net/images/interrupt_sequence.png diff --git a/src/xrpld/net/images/states.png b/src/libxrpl/net/images/states.png similarity index 100% rename from src/xrpld/net/images/states.png rename to src/libxrpl/net/images/states.png diff --git a/src/test/jtx/impl/Env.cpp b/src/test/jtx/impl/Env.cpp index 7c17687eee..46558a188a 100644 --- a/src/test/jtx/impl/Env.cpp +++ b/src/test/jtx/impl/Env.cpp @@ -30,12 +30,12 @@ #include #include -#include -#include +#include #include #include #include +#include #include #include #include @@ -74,7 +74,11 @@ Env::AppBundle::AppBundle( auto timeKeeper_ = std::make_unique(); timeKeeper = timeKeeper_.get(); // Hack so we don't have to call Config::setup - HTTPClient::initializeSSLContext(*config, debugLog()); + HTTPClient::initializeSSLContext( + config->SSL_VERIFY_DIR, + config->SSL_VERIFY_FILE, + config->SSL_VERIFY, + debugLog()); owned = make_Application( std::move(config), std::move(logs), std::move(timeKeeper_)); app = owned.get(); diff --git a/src/test/jtx/impl/utility.cpp b/src/test/jtx/impl/utility.cpp index afa7ee8f35..27b45a32cb 100644 --- a/src/test/jtx/impl/utility.cpp +++ b/src/test/jtx/impl/utility.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include #include diff --git a/src/test/rpc/RPCCall_test.cpp b/src/test/rpc/RPCCall_test.cpp index b73f2e11a0..d22896388d 100644 --- a/src/test/rpc/RPCCall_test.cpp +++ b/src/test/rpc/RPCCall_test.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/src/xrpld/app/ledger/BookListeners.h b/src/xrpld/app/ledger/BookListeners.h index ca58bf3058..5522ad3ec0 100644 --- a/src/xrpld/app/ledger/BookListeners.h +++ b/src/xrpld/app/ledger/BookListeners.h @@ -20,7 +20,7 @@ #ifndef RIPPLE_APP_LEDGER_BOOKLISTENERS_H_INCLUDED #define RIPPLE_APP_LEDGER_BOOKLISTENERS_H_INCLUDED -#include +#include #include diff --git a/src/xrpld/app/main/GRPCServer.h b/src/xrpld/app/main/GRPCServer.h index 5ed4ba8454..c48138cd92 100644 --- a/src/xrpld/app/main/GRPCServer.h +++ b/src/xrpld/app/main/GRPCServer.h @@ -22,9 +22,9 @@ #include #include -#include #include #include +#include #include #include #include diff --git a/src/xrpld/app/main/Main.cpp b/src/xrpld/app/main/Main.cpp index 19c8c9910d..3fdf362dd9 100644 --- a/src/xrpld/app/main/Main.cpp +++ b/src/xrpld/app/main/Main.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/xrpld/app/misc/NetworkOPs.h b/src/xrpld/app/misc/NetworkOPs.h index b8da7d7dc7..639cd782b7 100644 --- a/src/xrpld/app/misc/NetworkOPs.h +++ b/src/xrpld/app/misc/NetworkOPs.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/xrpld/app/misc/detail/WorkSSL.cpp b/src/xrpld/app/misc/detail/WorkSSL.cpp index 0285f43502..0d6801ab84 100644 --- a/src/xrpld/app/misc/detail/WorkSSL.cpp +++ b/src/xrpld/app/misc/detail/WorkSSL.cpp @@ -33,7 +33,12 @@ WorkSSL::WorkSSL( bool lastStatus, callback_type cb) : WorkBase(host, path, port, ios, lastEndpoint, lastStatus, cb) - , context_(config, j, boost::asio::ssl::context::tlsv12_client) + , context_( + config.SSL_VERIFY_DIR, + config.SSL_VERIFY_FILE, + config.SSL_VERIFY, + j, + boost::asio::ssl::context::tlsv12_client) , stream_(socket_, context_.context()) { auto ec = context_.preConnectVerify(stream_, host_); diff --git a/src/xrpld/app/misc/detail/WorkSSL.h b/src/xrpld/app/misc/detail/WorkSSL.h index 2d423a9e50..6a310986e7 100644 --- a/src/xrpld/app/misc/detail/WorkSSL.h +++ b/src/xrpld/app/misc/detail/WorkSSL.h @@ -22,9 +22,9 @@ #include #include -#include #include +#include #include #include diff --git a/src/xrpld/app/paths/PathRequest.h b/src/xrpld/app/paths/PathRequest.h index aea0e564fb..854a0f6129 100644 --- a/src/xrpld/app/paths/PathRequest.h +++ b/src/xrpld/app/paths/PathRequest.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/xrpld/core/detail/Config.cpp b/src/xrpld/core/detail/Config.cpp index 1a07109b74..95147e23d5 100644 --- a/src/xrpld/core/detail/Config.cpp +++ b/src/xrpld/core/detail/Config.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -27,6 +26,7 @@ #include #include #include +#include #include #include @@ -409,7 +409,8 @@ Config::setup( legacy("database_path", boost::filesystem::absolute(dataDir).string()); } - HTTPClient::initializeSSLContext(*this, j_); + HTTPClient::initializeSSLContext( + this->SSL_VERIFY_DIR, this->SSL_VERIFY_FILE, this->SSL_VERIFY, j_); if (RUN_STANDALONE) LEDGER_HISTORY = 0; diff --git a/src/xrpld/rpc/Context.h b/src/xrpld/rpc/Context.h index 32a7cca653..0b1a8dfbf5 100644 --- a/src/xrpld/rpc/Context.h +++ b/src/xrpld/rpc/Context.h @@ -21,7 +21,7 @@ #define RIPPLE_RPC_CONTEXT_H_INCLUDED #include -#include +#include #include #include diff --git a/src/xrpld/net/InfoSub.h b/src/xrpld/rpc/InfoSub.h similarity index 100% rename from src/xrpld/net/InfoSub.h rename to src/xrpld/rpc/InfoSub.h diff --git a/src/xrpld/net/RPCCall.h b/src/xrpld/rpc/RPCCall.h similarity index 100% rename from src/xrpld/net/RPCCall.h rename to src/xrpld/rpc/RPCCall.h diff --git a/src/xrpld/net/RPCSub.h b/src/xrpld/rpc/RPCSub.h similarity index 98% rename from src/xrpld/net/RPCSub.h rename to src/xrpld/rpc/RPCSub.h index 9730ca2dec..0f106be018 100644 --- a/src/xrpld/net/RPCSub.h +++ b/src/xrpld/rpc/RPCSub.h @@ -21,7 +21,7 @@ #define RIPPLE_NET_RPCSUB_H_INCLUDED #include -#include +#include #include diff --git a/src/xrpld/net/detail/InfoSub.cpp b/src/xrpld/rpc/detail/InfoSub.cpp similarity index 99% rename from src/xrpld/net/detail/InfoSub.cpp rename to src/xrpld/rpc/detail/InfoSub.cpp index 9f394cf08e..de00f518a5 100644 --- a/src/xrpld/net/detail/InfoSub.cpp +++ b/src/xrpld/rpc/detail/InfoSub.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -#include +#include namespace ripple { diff --git a/src/xrpld/net/detail/RPCCall.cpp b/src/xrpld/rpc/detail/RPCCall.cpp similarity index 99% rename from src/xrpld/net/detail/RPCCall.cpp rename to src/xrpld/rpc/detail/RPCCall.cpp index 0cc3cb6618..aa8c80fff7 100644 --- a/src/xrpld/net/detail/RPCCall.cpp +++ b/src/xrpld/rpc/detail/RPCCall.cpp @@ -17,12 +17,8 @@ */ //============================================================================== -#include -#include -#include -#include +#include #include -#include #include #include @@ -33,7 +29,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -160,7 +159,7 @@ private: std::string const& strPk, TokenType type = TokenType::AccountPublic) { - if (parseBase58(type, strPk)) + if (parseBase58(type, strPk)) return true; auto pkHex = strUnHex(strPk); @@ -1508,7 +1507,7 @@ rpcClient( } else { - ServerHandler::Setup setup; + ripple::ServerHandler::Setup setup; try { setup = setup_ServerHandler( diff --git a/src/xrpld/rpc/detail/RPCHandler.cpp b/src/xrpld/rpc/detail/RPCHandler.cpp index c261666eb9..b2e4c2c440 100644 --- a/src/xrpld/rpc/detail/RPCHandler.cpp +++ b/src/xrpld/rpc/detail/RPCHandler.cpp @@ -24,9 +24,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/src/xrpld/net/detail/RPCSub.cpp b/src/xrpld/rpc/detail/RPCSub.cpp similarity index 99% rename from src/xrpld/net/detail/RPCSub.cpp rename to src/xrpld/rpc/detail/RPCSub.cpp index 3f0c923e13..966ad6df4b 100644 --- a/src/xrpld/net/detail/RPCSub.cpp +++ b/src/xrpld/rpc/detail/RPCSub.cpp @@ -17,8 +17,8 @@ */ //============================================================================== -#include -#include +#include +#include #include #include diff --git a/src/xrpld/rpc/detail/WSInfoSub.h b/src/xrpld/rpc/detail/WSInfoSub.h index 1652617455..030eac318e 100644 --- a/src/xrpld/rpc/detail/WSInfoSub.h +++ b/src/xrpld/rpc/detail/WSInfoSub.h @@ -20,7 +20,7 @@ #ifndef RIPPLE_RPC_WSINFOSUB_H #define RIPPLE_RPC_WSINFOSUB_H -#include +#include #include #include diff --git a/src/xrpld/rpc/handlers/Subscribe.cpp b/src/xrpld/rpc/handlers/Subscribe.cpp index e71d973b7b..c089f0255d 100644 --- a/src/xrpld/rpc/handlers/Subscribe.cpp +++ b/src/xrpld/rpc/handlers/Subscribe.cpp @@ -21,8 +21,8 @@ #include #include #include -#include #include +#include #include #include From dc1caa41b2577f5bfd4601aa3590a324f1be8a34 Mon Sep 17 00:00:00 2001 From: Bart Date: Mon, 18 Aug 2025 10:21:43 -0400 Subject: [PATCH 15/16] refactor: Revamp CI workflows (#5661) This change refactors the CI workflows to leverage the new CI Docker images for Debian, Red Hat, and Ubuntu. --- .github/actions/build-deps/action.yml | 71 +++ .github/actions/build-test/action.yml | 102 +++++ .github/actions/build/action.yml | 34 -- .github/actions/dependencies/action.yml | 38 -- .../scripts}/levelization/README.md | 10 +- .../scripts/levelization/generate.sh | 4 +- .../scripts}/levelization/results/loops.txt | 0 .../levelization/results/ordering.txt | 0 .github/scripts/strategy-matrix/generate.py | 153 +++++++ .github/scripts/strategy-matrix/linux.json | 170 +++++++ .github/scripts/strategy-matrix/macos.json | 29 ++ .github/scripts/strategy-matrix/windows.json | 26 ++ .github/workflows/build-test.yml | 191 ++++++++ .github/workflows/check-format.yml | 112 +++++ .github/workflows/check-levelization.yml | 46 ++ .github/workflows/check-missing-commits.yml | 62 +++ .github/workflows/clang-format.yml | 64 --- .github/workflows/doxygen.yml | 37 -- .github/workflows/levelization.yml | 53 --- .github/workflows/libxrpl.yml | 91 ---- .github/workflows/macos.yml | 112 ----- .github/workflows/missing-commits.yml | 60 --- .github/workflows/nix.yml | 422 ------------------ .github/workflows/notify-clio.yml | 80 ++++ .github/workflows/on-pr.yml | 133 ++++++ .github/workflows/on-trigger.yml | 140 ++++++ .github/workflows/publish-docs.yml | 58 +++ .github/workflows/windows.yml | 106 ----- .gitignore | 7 +- .prettierignore | 2 + CONTRIBUTING.md | 2 +- README.md | 2 +- conan/global.conf | 9 + external/README.md | 3 +- 34 files changed, 1397 insertions(+), 1032 deletions(-) create mode 100644 .github/actions/build-deps/action.yml create mode 100644 .github/actions/build-test/action.yml delete mode 100644 .github/actions/build/action.yml delete mode 100644 .github/actions/dependencies/action.yml rename {Builds => .github/scripts}/levelization/README.md (95%) rename Builds/levelization/levelization.sh => .github/scripts/levelization/generate.sh (98%) rename {Builds => .github/scripts}/levelization/results/loops.txt (100%) rename {Builds => .github/scripts}/levelization/results/ordering.txt (100%) create mode 100644 .github/scripts/strategy-matrix/generate.py create mode 100644 .github/scripts/strategy-matrix/linux.json create mode 100644 .github/scripts/strategy-matrix/macos.json create mode 100644 .github/scripts/strategy-matrix/windows.json create mode 100644 .github/workflows/build-test.yml create mode 100644 .github/workflows/check-format.yml create mode 100644 .github/workflows/check-levelization.yml create mode 100644 .github/workflows/check-missing-commits.yml delete mode 100644 .github/workflows/clang-format.yml delete mode 100644 .github/workflows/doxygen.yml delete mode 100644 .github/workflows/levelization.yml delete mode 100644 .github/workflows/libxrpl.yml delete mode 100644 .github/workflows/macos.yml delete mode 100644 .github/workflows/missing-commits.yml delete mode 100644 .github/workflows/nix.yml create mode 100644 .github/workflows/notify-clio.yml create mode 100644 .github/workflows/on-pr.yml create mode 100644 .github/workflows/on-trigger.yml create mode 100644 .github/workflows/publish-docs.yml delete mode 100644 .github/workflows/windows.yml create mode 100644 .prettierignore create mode 100644 conan/global.conf diff --git a/.github/actions/build-deps/action.yml b/.github/actions/build-deps/action.yml new file mode 100644 index 0000000000..12d80e859c --- /dev/null +++ b/.github/actions/build-deps/action.yml @@ -0,0 +1,71 @@ +# This action installs and optionally uploads Conan dependencies to a remote +# repository. The dependencies will only be uploaded if the credentials are +# provided. +name: Build Conan dependencies + +inputs: + build_dir: + description: 'The directory where to build.' + required: true + type: string + build_type: + description: 'The build type to use.' + required: true + type: choice + options: + - 'Debug' + - 'Release' + conan_remote_name: + description: 'The name of the Conan remote to use.' + required: true + type: string + conan_remote_url: + description: 'The URL of the Conan endpoint to use.' + required: true + type: string + conan_remote_username: + description: 'The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + type: string + default: '' + conan_remote_password: + description: 'The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + type: string + default: '' + force_build: + description: 'Force building of all dependencies.' + required: false + type: boolean + default: false + force_upload: + description: 'Force uploading of all dependencies.' + required: false + type: boolean + default: false + +runs: + using: composite + steps: + - name: Install Conan dependencies + shell: bash + run: | + echo 'Installing dependencies.' + mkdir -p ${{ inputs.build_dir }} + cd ${{ inputs.build_dir }} + conan install \ + --output-folder . \ + --build ${{ inputs.force_build && '"*"' || 'missing' }} \ + --options:host '&:tests=True' \ + --options:host '&:xrpld=True' \ + --settings:all build_type=${{ inputs.build_type }} \ + --format=json .. + - name: Upload Conan dependencies + if: ${{ inputs.conan_remote_username && inputs.conan_remote_password }} + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo "Logging into Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." + conan remote login ${{ inputs.conan_remote_name }} "${{ inputs.conan_remote_username }}" --password "${{ inputs.conan_remote_password }}" + echo 'Uploading dependencies.' + conan upload '*' --confirm --check ${{ inputs.force_upload && '--force' || '' }} --remote=${{ inputs.conan_remote_name }} diff --git a/.github/actions/build-test/action.yml b/.github/actions/build-test/action.yml new file mode 100644 index 0000000000..30337ddb98 --- /dev/null +++ b/.github/actions/build-test/action.yml @@ -0,0 +1,102 @@ +# This action build and tests the binary. The Conan dependencies must have +# already been installed (see the build-deps action). +name: Build and Test + +inputs: + build_dir: + description: 'The directory where to build.' + required: true + type: string + build_type: + description: 'The build type to use.' + required: true + type: choice + options: + - 'Debug' + - 'Release' + cmake_args: + description: 'Additional arguments to pass to CMake.' + required: false + type: string + default: '' + cmake_target: + description: 'The CMake target to build.' + required: true + type: string + codecov_token: + description: 'The Codecov token to use for uploading coverage reports.' + required: false + type: string + default: '' + os: + description: 'The operating system to use for the build (linux, macos, or windows).' + required: true + type: choice + options: + - 'linux' + - 'macos' + - 'windows' + +runs: + using: composite + steps: + - name: Configure CMake + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Configuring CMake.' + cmake \ + -G '${{ inputs.os == 'windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \ + -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ + -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ + ${{ inputs.cmake_args }} \ + .. + - name: Build the binary + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Building binary.' + cmake \ + --build . \ + --config ${{ inputs.build_type }} \ + --parallel $(nproc) \ + --target ${{ inputs.cmake_target }} + - name: Check linking + if: ${{ inputs.os == 'linux' }} + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Checking linking.' + ldd ./rippled + if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then + echo 'The binary is statically linked.' + else + echo 'The binary is dynamically linked.' + exit 1 + fi + - name: Verify voidstar + if: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }} + shell: bash + working-directory: ${{ inputs.build_dir }} + run: | + echo 'Verifying presence of instrumentation.' + ./rippled --version | grep libvoidstar + - name: Test the binary + if: ${{ inputs.cmake_target != 'coverage' }} + shell: bash + working-directory: ${{ inputs.build_dir }}/${{ inputs.os == 'windows' && inputs.build_type || '' }} + run: | + echo 'Testing binary.' + ./rippled --unittest --unittest-jobs $(nproc) + ctest -j $(nproc) --output-on-failure + - name: Upload coverage report + if: ${{ inputs.cmake_target == 'coverage' && inputs.codecov_token }} + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3 + with: + disable_search: true + disable_telem: true + fail_ci_if_error: true + files: ${{ inputs.build_dir }}/coverage.xml + plugins: noop + token: ${{ inputs.codecov_token }} + verbose: true diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml deleted file mode 100644 index 6714369155..0000000000 --- a/.github/actions/build/action.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: build -inputs: - generator: - default: null - configuration: - required: true - cmake-args: - default: null - cmake-target: - default: all -# An implicit input is the environment variable `build_dir`. -runs: - using: composite - steps: - - name: configure - shell: bash - run: | - cd ${build_dir} - cmake \ - ${{ inputs.generator && format('-G "{0}"', inputs.generator) || '' }} \ - -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \ - -DCMAKE_BUILD_TYPE=${{ inputs.configuration }} \ - -Dtests=TRUE \ - -Dxrpld=TRUE \ - ${{ inputs.cmake-args }} \ - .. - - name: build - shell: bash - run: | - cmake \ - --build ${build_dir} \ - --config ${{ inputs.configuration }} \ - --parallel ${NUM_PROCESSORS:-$(nproc)} \ - --target ${{ inputs.cmake-target }} diff --git a/.github/actions/dependencies/action.yml b/.github/actions/dependencies/action.yml deleted file mode 100644 index 0bd28f15dd..0000000000 --- a/.github/actions/dependencies/action.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: dependencies -inputs: - configuration: - required: true -# Implicit inputs are the environment variables `build_dir`, CONAN_REMOTE_URL, -# CONAN_REMOTE_USERNAME, and CONAN_REMOTE_PASSWORD. The latter two are only -# used to upload newly built dependencies to the Conan remote. -runs: - using: composite - steps: - - name: add Conan remote - if: ${{ env.CONAN_REMOTE_URL != '' }} - shell: bash - run: | - echo "Adding Conan remote 'xrplf' at ${{ env.CONAN_REMOTE_URL }}." - conan remote add --index 0 --force xrplf ${{ env.CONAN_REMOTE_URL }} - echo "Listing Conan remotes." - conan remote list - - name: install dependencies - shell: bash - run: | - mkdir -p ${{ env.build_dir }} - cd ${{ env.build_dir }} - conan install \ - --output-folder . \ - --build missing \ - --options:host "&:tests=True" \ - --options:host "&:xrpld=True" \ - --settings:all build_type=${{ inputs.configuration }} \ - .. - - name: upload dependencies - if: ${{ env.CONAN_REMOTE_URL != '' && env.CONAN_REMOTE_USERNAME != '' && env.CONAN_REMOTE_PASSWORD != '' && github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }} - shell: bash - run: | - echo "Logging into Conan remote 'xrplf' at ${{ env.CONAN_REMOTE_URL }}." - conan remote login xrplf "${{ env.CONAN_REMOTE_USERNAME }}" --password "${{ env.CONAN_REMOTE_PASSWORD }}" - echo "Uploading dependencies." - conan upload '*' --confirm --check --remote xrplf diff --git a/Builds/levelization/README.md b/.github/scripts/levelization/README.md similarity index 95% rename from Builds/levelization/README.md rename to .github/scripts/levelization/README.md index 93aa316b61..ec41a021cc 100644 --- a/Builds/levelization/README.md +++ b/.github/scripts/levelization/README.md @@ -50,7 +50,7 @@ that `test` code should _never_ be included in `ripple` code.) ## Validation -The [levelization.sh](levelization.sh) script takes no parameters, +The [levelization](generate.sh) script takes no parameters, reads no environment variables, and can be run from any directory, as long as it is in the expected location in the rippled repo. It can be run at any time from within a checked out repo, and will @@ -72,15 +72,15 @@ It generates many files of [results](results): desired as described above. In a perfect repo, this file will be empty. This file is committed to the repo, and is used by the [levelization - Github workflow](../../.github/workflows/levelization.yml) to validate + Github workflow](../../workflows/check-levelization.yml) to validate that nothing changed. - [`ordering.txt`](results/ordering.txt): A list showing relationships between modules where there are no loops as they actually exist, as opposed to how they are desired as described above. This file is committed to the repo, and is used by the [levelization - Github workflow](../../.github/workflows/levelization.yml) to validate + Github workflow](../../workflows/check-levelization.yml) to validate that nothing changed. -- [`levelization.yml`](../../.github/workflows/levelization.yml) +- [`levelization.yml`](../../workflows/check-levelization.yml) Github Actions workflow to test that levelization loops haven't changed. Unfortunately, if changes are detected, it can't tell if they are improvements or not, so if you have resolved any issues or @@ -111,4 +111,4 @@ get those details locally. 1. Run `levelization.sh` 2. Grep the modules in `paths.txt`. - For example, if a cycle is found `A ~= B`, simply `grep -w -A Builds/levelization/results/paths.txt | grep -w B` + A .github/scripts/levelization/results/paths.txt | grep -w B` diff --git a/Builds/levelization/levelization.sh b/.github/scripts/levelization/generate.sh similarity index 98% rename from Builds/levelization/levelization.sh rename to .github/scripts/levelization/generate.sh index c18ca703f7..775ddf789f 100755 --- a/Builds/levelization/levelization.sh +++ b/.github/scripts/levelization/generate.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Usage: levelization.sh +# Usage: generate.sh # This script takes no parameters, reads no environment variables, # and can be run from any directory, as long as it is in the expected # location in the repo. @@ -19,7 +19,7 @@ export LANG=C rm -rfv results mkdir results includes="$( pwd )/results/rawincludes.txt" -pushd ../.. +pushd ../../.. echo Raw includes: grep -r '^[ ]*#include.*/.*\.h' include src | \ grep -v boost | tee ${includes} diff --git a/Builds/levelization/results/loops.txt b/.github/scripts/levelization/results/loops.txt similarity index 100% rename from Builds/levelization/results/loops.txt rename to .github/scripts/levelization/results/loops.txt diff --git a/Builds/levelization/results/ordering.txt b/.github/scripts/levelization/results/ordering.txt similarity index 100% rename from Builds/levelization/results/ordering.txt rename to .github/scripts/levelization/results/ordering.txt diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py new file mode 100644 index 0000000000..a5180c942d --- /dev/null +++ b/.github/scripts/strategy-matrix/generate.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +import argparse +import itertools +import json +import re + +''' +Generate a strategy matrix for GitHub Actions CI. + +On each PR commit we will build a selection of Debian, RHEL, Ubuntu, MacOS, and +Windows configurations, while upon merge into the develop, release, or master +branches, we will build all configurations. + +We will further set additional CMake arguments as follows: +- All builds will have the `tests`, `werr`, and `xrpld` options. +- All builds will have the `wextra` option except for GCC 12 and Clang 16. +- All release builds will have the `assert` option. +- Certain Debian Bookworm configurations will change the reference fee, enable + codecov, and enable voidstar in PRs. +''' +def generate_strategy_matrix(all: bool, architecture: list[dict], os: list[dict], build_type: list[str], cmake_args: list[str]) -> dict: + configurations = [] + for architecture, os, build_type, cmake_args in itertools.product(architecture, os, build_type, cmake_args): + # The default CMake target is 'all' for Linux and MacOS and 'install' + # for Windows, but it can get overridden for certain configurations. + cmake_target = 'install' if os["distro_name"] == 'windows' else 'all' + + # Only generate a subset of configurations in PRs. + if not all: + # Debian: + # - Bookworm using GCC 13: Release and Unity on linux/arm64, set + # the reference fee to 500. + # - Bookworm using GCC 15: Debug and no Unity on linux/amd64, enable + # code coverage. + # - Bookworm using Clang 16: Debug and no Unity on linux/arm64, + # enable voidstar. + # - Bookworm using Clang 17: Release and no Unity on linux/amd64, + # set the reference fee to 1000. + # - Bookworm using Clang 20: Debug and Unity on linux/amd64. + if os['distro_name'] == 'debian': + skip = True + if os['distro_version'] == 'bookworm': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-13' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64': + cmake_args = f'{cmake_args} -DUNIT_TEST_REFERENCE_FEE=500' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-15' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + cmake_args = f'{cmake_args} -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0' + cmake_target = 'coverage' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-16' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': + cmake_args = f'{cmake_args} -Dvoidstar=ON' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-17' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + cmake_args = f'{cmake_args} -DUNIT_TEST_REFERENCE_FEE=1000' + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-20' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if skip: + continue + + # RHEL: + # - 9.4 using GCC 12: Debug and Unity on linux/amd64. + # - 9.6 using Clang: Release and no Unity on linux/amd64. + if os['distro_name'] == 'rhel': + skip = True + if os['distro_version'] == '9.4': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + elif os['distro_version'] == '9.6': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-any' and build_type == 'Release' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if skip: + continue + + # Ubuntu: + # - Jammy using GCC 12: Debug and no Unity on linux/arm64. + # - Noble using GCC 14: Release and Unity on linux/amd64. + # - Noble using Clang 18: Debug and no Unity on linux/amd64. + # - Noble using Clang 19: Release and Unity on linux/arm64. + if os['distro_name'] == 'ubuntu': + skip = True + if os['distro_version'] == 'jammy': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-12' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/arm64': + skip = False + elif os['distro_version'] == 'noble': + if f'{os['compiler_name']}-{os['compiler_version']}' == 'gcc-14' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-18' and build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'linux/amd64': + skip = False + if f'{os['compiler_name']}-{os['compiler_version']}' == 'clang-19' and build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'linux/arm64': + skip = False + if skip: + continue + + # MacOS: + # - Debug and no Unity on macos/arm64. + if os['distro_name'] == 'macos' and not (build_type == 'Debug' and '-Dunity=OFF' in cmake_args and architecture['platform'] == 'macos/arm64'): + continue + + # Windows: + # - Release and Unity on windows/amd64. + if os['distro_name'] == 'windows' and not (build_type == 'Release' and '-Dunity=ON' in cmake_args and architecture['platform'] == 'windows/amd64'): + continue + + + # Additional CMake arguments. + cmake_args = f'{cmake_args} -Dtests=ON -Dwerr=ON -Dxrpld=ON' + if not f'{os['compiler_name']}-{os['compiler_version']}' in ['gcc-12', 'clang-16']: + cmake_args = f'{cmake_args} -Dwextra=ON' + if build_type == 'Release': + cmake_args = f'{cmake_args} -Dassert=ON' + + # Generate a unique name for the configuration, e.g. macos-arm64-debug + # or debian-bookworm-gcc-12-amd64-release-unity. + config_name = os['distro_name'] + if (n := os['distro_version']) != '': + config_name += f'-{n}' + if (n := os['compiler_name']) != '': + config_name += f'-{n}' + if (n := os['compiler_version']) != '': + config_name += f'-{n}' + config_name += f'-{architecture['platform'][architecture['platform'].find('/')+1:]}' + config_name += f'-{build_type.lower()}' + if '-Dunity=ON' in cmake_args: + config_name += '-unity' + + configurations.append({ + 'architecture': architecture, + 'os': os, + 'build_type': build_type, + 'cmake_args': cmake_args, + 'cmake_target': cmake_target, + 'config_name': config_name, + }) + + return {'include': configurations} + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-a', '--all', help='Set to generate all configurations (generally used when merging a PR) or leave unset to generate a subset of configurations (generally used when committing to a PR).', action="store_true") + parser.add_argument('-c', '--config', help='Path to the JSON file containing the strategy matrix configurations.', required=True, type=str) + args = parser.parse_args() + + # Load the JSON configuration file. + config = None + with open(args.config, 'r') as f: + config = json.load(f) + if config['architecture'] is None or config['os'] is None or config['build_type'] is None or config['cmake_args'] is None: + raise Exception('Invalid configuration file.') + + # Generate the strategy matrix. + print(f'matrix={json.dumps(generate_strategy_matrix(args.all, config['architecture'], config['os'], config['build_type'], config['cmake_args']))}') diff --git a/.github/scripts/strategy-matrix/linux.json b/.github/scripts/strategy-matrix/linux.json new file mode 100644 index 0000000000..d8f176273d --- /dev/null +++ b/.github/scripts/strategy-matrix/linux.json @@ -0,0 +1,170 @@ +{ + "architecture": [ + { + "platform": "linux/amd64", + "runner": [ + "self-hosted", + "Linux", + "X64", + "heavy" + ] + }, + { + "platform": "linux/arm64", + "runner": [ + "self-hosted", + "Linux", + "ARM64", + "heavy-arm64" + ] + } + ], + "os": [ + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "12" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "gcc", + "compiler_version": "15" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "16" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "17" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "18" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "19" + }, + { + "distro_name": "debian", + "distro_version": "bookworm", + "compiler_name": "clang", + "compiler_version": "20" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "gcc", + "compiler_version": "12" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "rhel", + "distro_version": "9.6", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "rhel", + "distro_version": "9.6", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "rhel", + "distro_version": "9.4", + "compiler_name": "clang", + "compiler_version": "any" + }, + { + "distro_name": "rhel", + "distro_version": "9.6", + "compiler_name": "clang", + "compiler_version": "any" + }, + { + "distro_name": "ubuntu", + "distro_version": "jammy", + "compiler_name": "gcc", + "compiler_version": "12" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "gcc", + "compiler_version": "13" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "gcc", + "compiler_version": "14" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "16" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "17" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "18" + }, + { + "distro_name": "ubuntu", + "distro_version": "noble", + "compiler_name": "clang", + "compiler_version": "19" + } + ], + "build_type": [ + "Debug", + "Release" + ], + "cmake_args": [ + "-Dunity=OFF", + "-Dunity=ON" + ] +} diff --git a/.github/scripts/strategy-matrix/macos.json b/.github/scripts/strategy-matrix/macos.json new file mode 100644 index 0000000000..a6ffdf14b7 --- /dev/null +++ b/.github/scripts/strategy-matrix/macos.json @@ -0,0 +1,29 @@ +{ + "architecture": [ + { + "platform": "macos/arm64", + "runner": [ + "self-hosted", + "macOS", + "ARM64", + "mac-runner-m1" + ] + } + ], + "os": [ + { + "distro_name": "macos", + "distro_version": "", + "compiler_name": "", + "compiler_version": "" + } + ], + "build_type": [ + "Debug", + "Release" + ], + "cmake_args": [ + "-Dunity=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5", + "-Dunity=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5" + ] +} diff --git a/.github/scripts/strategy-matrix/windows.json b/.github/scripts/strategy-matrix/windows.json new file mode 100644 index 0000000000..aaa8c94411 --- /dev/null +++ b/.github/scripts/strategy-matrix/windows.json @@ -0,0 +1,26 @@ +{ + "architecture": [ + { + "platform": "windows/amd64", + "runner": [ + "windows-latest" + ] + } + ], + "os": [ + { + "distro_name": "windows", + "distro_version": "", + "compiler_name": "", + "compiler_version": "" + } + ], + "build_type": [ + "Debug", + "Release" + ], + "cmake_args": [ + "-Dunity=OFF", + "-Dunity=ON" + ] +} diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml new file mode 100644 index 0000000000..f3b3374090 --- /dev/null +++ b/.github/workflows/build-test.yml @@ -0,0 +1,191 @@ +# This workflow builds and tests the binary for various configurations. +name: Build and test + +# This workflow can only be triggered by other workflows. +on: + workflow_call: + inputs: + build_dir: + description: 'The directory where to build.' + required: false + type: string + default: '.build' + conan_remote_name: + description: 'The name of the Conan remote to use.' + required: true + type: string + conan_remote_url: + description: 'The URL of the Conan endpoint to use.' + required: true + type: string + dependencies_force_build: + description: 'Force building of all dependencies.' + required: false + type: boolean + default: false + dependencies_force_upload: + description: 'Force uploading of all dependencies.' + required: false + type: boolean + default: false + os: + description: 'The operating system to use for the build (linux, macos, or windows).' + required: true + type: string + strategy_matrix_all: + description: 'Generate a strategy matrix containing all configurations.' + required: false + type: boolean + default: false + secrets: + codecov_token: + description: 'The Codecov token to use for uploading coverage reports.' + required: false + conan_remote_username: + description: 'The username for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + conan_remote_password: + description: 'The password for logging into the Conan remote. If not provided, the dependencies will not be uploaded.' + required: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.os }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + # Generate the strategy matrix to be used by the following job. + generate-matrix: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Set up Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: 3.13 + - name: Generate strategy matrix + working-directory: .github/scripts/strategy-matrix + id: generate + run: python generate.py ${{ inputs.strategy_matrix_all && '--all' || '' }} --config=${{ inputs.os }}.json | tee "${GITHUB_OUTPUT}" + outputs: + matrix: ${{ steps.generate.outputs.matrix }} + + # Build and test the binary. + build-test: + needs: + - generate-matrix + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} + runs-on: ${{ matrix.architecture.runner }} + container: ${{ inputs.os == 'linux' && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version) || null }} + steps: + - name: Clean workspace (MacOS) + if: ${{ inputs.os == 'macos' }} + run: | + WORKSPACE=${{ github.workspace }} + echo "Cleaning workspace '${WORKSPACE}'." + if [ -z "${WORKSPACE}" ] || [ "${WORKSPACE}" = "/" ]; then + echo "Invalid working directory '${WORKSPACE}'." + exit 1 + fi + find "${WORKSPACE}" -depth 1 | xargs rm -rfv + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Set up Python (Windows) + if: ${{ inputs.os == 'windows' }} + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: 3.13 + - name: Install Conan (Windows) + if: ${{ inputs.os == 'windows' }} + run: pip install wheel conan + - name: Check configuration (Windows) + if: ${{ inputs.os == 'windows' }} + run: | + echo 'Checking environment variables.' + set + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking Conan version.' + conan --version + - name: Check configuration (Linux and MacOS) + if: ${{ inputs.os == 'linux' || inputs.os == 'macos' }} + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking compiler version.' + ${{ inputs.os == 'linux' && '${CC}' || 'clang' }} --version + + echo 'Checking Conan version.' + conan --version + + echo 'Checking Ninja version.' + ninja --version + - name: Set up Conan home directory (MacOS) + if: ${{ inputs.os == 'macos' }} + run: | + echo 'Setting up Conan home directory.' + export CONAN_HOME=${{ github.workspace }}/.conan + mkdir -p ${CONAN_HOME} + - name: Set up Conan home directory (Windows) + if: ${{ inputs.os == 'windows' }} + run: | + echo 'Setting up Conan home directory.' + set CONAN_HOME=${{ github.workspace }}\.conan + mkdir -p %CONAN_HOME% + - name: Set up Conan configuration + run: | + echo 'Installing configuration.' + cat conan/global.conf ${{ inputs.os == 'linux' && '>>' || '>' }} $(conan config home)/global.conf + + echo 'Conan configuration:' + conan config show '*' + - name: Set up Conan profile + run: | + echo 'Installing profile.' + conan config install conan/profiles/default -tf $(conan config home)/profiles/ + + echo 'Conan profile:' + conan profile show + - name: Set up Conan remote + shell: bash + run: | + echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." + conan remote add --index 0 --force ${{ inputs.conan_remote_name }} ${{ inputs.conan_remote_url }} + + echo 'Listing Conan remotes.' + conan remote list + - name: Build dependencies + uses: ./.github/actions/build-deps + with: + build_dir: ${{ inputs.build_dir }} + build_type: ${{ matrix.build_type }} + conan_remote_name: ${{ inputs.conan_remote_name }} + conan_remote_url: ${{ inputs.conan_remote_url }} + conan_remote_username: ${{ secrets.conan_remote_username }} + conan_remote_password: ${{ secrets.conan_remote_password }} + force_build: ${{ inputs.dependencies_force_build }} + force_upload: ${{ inputs.dependencies_force_upload }} + - name: Build and test binary + uses: ./.github/actions/build-test + with: + build_dir: ${{ inputs.build_dir }} + build_type: ${{ matrix.build_type }} + cmake_args: ${{ matrix.cmake_args }} + cmake_target: ${{ matrix.cmake_target }} + codecov_token: ${{ secrets.codecov_token }} + os: ${{ inputs.os }} diff --git a/.github/workflows/check-format.yml b/.github/workflows/check-format.yml new file mode 100644 index 0000000000..5e3da10028 --- /dev/null +++ b/.github/workflows/check-format.yml @@ -0,0 +1,112 @@ +# This workflow checks if the code is properly formatted. +name: Check format + +# This workflow can only be triggered by other workflows. +on: workflow_call + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-format + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + clang-format: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/tools-rippled-clang-format + steps: + # The $GITHUB_WORKSPACE and ${{ github.workspace }} might not point to the + # same directory for jobs running in containers. The actions/checkout step + # is *supposed* to checkout into $GITHUB_WORKSPACE and then add it to + # safe.directory (see instructions at https://github.com/actions/checkout) + # but that is apparently not happening for some container images. We + # therefore preemptively add both directories to safe.directory. See also + # https://github.com/actions/runner/issues/2058 for more details. + - name: Configure git safe.directory + run: | + git config --global --add safe.directory $GITHUB_WORKSPACE + git config --global --add safe.directory ${{ github.workspace }} + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Check configuration + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking clang-format version.' + clang-format --version + - name: Format code + run: find include src tests -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format -i {} + + - name: Check for differences + env: + MESSAGE: | + One or more files did not conform to the formatting specified in + .clang-format. Maybe you did not run 'git-clang-format' or + 'clang-format' before committing, or your version of clang-format + has an incompatibility with the one used here (see the "Check + configuration" step above). + + Run 'git-clang-format --extensions cpp,h,hpp,ipp develop' in your + repo, and then commit and push the changes. + run: | + DIFF=$(git status --porcelain) + if [ -n "${DIFF}" ]; then + # Print the files that changed to give the contributor a hint about + # what to expect when running git-clang-format on their own machine. + git status + echo "${MESSAGE}" + exit 1 + fi + + prettier: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/tools-rippled-prettier + steps: + - name: Configure git safe.directory + run: | + git config --global --add safe.directory $GITHUB_WORKSPACE + git config --global --add safe.directory ${{ github.workspace }} + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + - name: Check configuration + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking NPM version.' + npm --version + + echo 'Checking Node.js version.' + node --version + + echo 'Checking prettier version.' + prettier --version + - name: Format code + run: prettier --check . + - name: Check for differences + env: + MESSAGE: | + One or more files did not conform to the formatting rules specified + by Prettier. Maybe you did not run 'prettier' before committing, or + your version of prettier has an incompatibility with the one used + here (see the "Check configuration" step above). + + Run 'prettier --check .' in your repo, and then commit and push the + changes. + run: | + DIFF=$(git status --porcelain) + if [ -n "${DIFF}" ]; then + # Print the files that changed to give the contributor a hint about + # what to expect when running prettier on their own machine. + git status + echo "${MESSAGE}" + exit 1 + fi diff --git a/.github/workflows/check-levelization.yml b/.github/workflows/check-levelization.yml new file mode 100644 index 0000000000..3430ca28a2 --- /dev/null +++ b/.github/workflows/check-levelization.yml @@ -0,0 +1,46 @@ +# This workflow checks if the dependencies between the modules are correctly +# indexed. +name: Check levelization + +# This workflow can only be triggered by other workflows. +on: workflow_call + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-levelization + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + levelization: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Check levelization + run: .github/scripts/levelization/generate.sh + - name: Check for differences + env: + MESSAGE: | + + The dependency relationships between the modules in rippled have + changed, which may be an improvement or a regression. + + A rule of thumb is that if your changes caused something to be + removed from loops.txt, it's probably an improvement, while if + something was added, it's probably a regression. + + Run '.github/scripts/levelization/generate.sh' in your repo, commit + and push the changes. See .github/scripts/levelization/README.md for + more info. + run: | + DIFF=$(git status --porcelain) + if [ -n "${DIFF}" ]; then + # Print the differences to give the contributor a hint about what to + # expect when running levelization on their own machine. + git diff + echo "${MESSAGE}" + exit 1 + fi diff --git a/.github/workflows/check-missing-commits.yml b/.github/workflows/check-missing-commits.yml new file mode 100644 index 0000000000..da0e296e70 --- /dev/null +++ b/.github/workflows/check-missing-commits.yml @@ -0,0 +1,62 @@ +# This workflow checks that all commits in the "master" branch are also in the +# "release" and "develop" branches, and that all commits in the "release" branch +# are also in the "develop" branch. +name: Check for missing commits + +# This workflow can only be triggered by other workflows. +on: workflow_call + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-missing-commits + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + fetch-depth: 0 + - name: Check for missing commits + env: + MESSAGE: | + + If you are reading this, then the commits indicated above are missing + from the "develop" and/or "release" branch. Do a reverse-merge as soon + as possible. See CONTRIBUTING.md for instructions. + run: | + set -o pipefail + # Branches are ordered by how "canonical" they are. Every commit in one + # branch should be in all the branches behind it. + order=(master release develop) + branches=() + for branch in "${order[@]}"; do + # Check that the branches exist so that this job will work on forked + # repos, which don't necessarily have master and release branches. + echo "Checking if ${branch} exists." + if git ls-remote --exit-code --heads origin \ + refs/heads/${branch} > /dev/null; then + branches+=(origin/${branch}) + fi + done + + prior=() + for branch in "${branches[@]}"; do + if [[ ${#prior[@]} -ne 0 ]]; then + echo "Checking ${prior[@]} for commits missing from ${branch}." + git log --oneline --no-merges "${prior[@]}" \ + ^$branch | tee -a "missing-commits.txt" + echo + fi + prior+=("${branch}") + done + + if [[ $(cat missing-commits.txt | wc -l) -ne 0 ]]; then + echo "${MESSAGE}" + exit 1 + fi diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml deleted file mode 100644 index 0d81f87791..0000000000 --- a/.github/workflows/clang-format.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: clang-format - -on: - push: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -jobs: - check: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - runs-on: ubuntu-24.04 - container: ghcr.io/xrplf/ci/tools-rippled-clang-format - steps: - # For jobs running in containers, $GITHUB_WORKSPACE and ${{ github.workspace }} might not be the - # same directory. The actions/checkout step is *supposed* to checkout into $GITHUB_WORKSPACE and - # then add it to safe.directory (see instructions at https://github.com/actions/checkout) - # but that's apparently not happening for some container images. We can't be sure what is actually - # happening, so let's pre-emptively add both directories to safe.directory. There's a - # Github issue opened in 2022 and not resolved in 2025 https://github.com/actions/runner/issues/2058 ¯\_(ツ)_/¯ - - run: | - git config --global --add safe.directory $GITHUB_WORKSPACE - git config --global --add safe.directory ${{ github.workspace }} - - uses: actions/checkout@v4 - - name: Format first-party sources - run: | - clang-format --version - find include src tests -type f \( -name '*.cpp' -o -name '*.hpp' -o -name '*.h' -o -name '*.ipp' \) -exec clang-format -i {} + - - name: Check for differences - id: assert - shell: bash - run: | - set -o pipefail - git diff --exit-code | tee "clang-format.patch" - - name: Upload patch - if: failure() && steps.assert.outcome == 'failure' - uses: actions/upload-artifact@v4 - continue-on-error: true - with: - name: clang-format.patch - if-no-files-found: ignore - path: clang-format.patch - - name: What happened? - if: failure() && steps.assert.outcome == 'failure' - env: - PREAMBLE: | - If you are reading this, you are looking at a failed Github Actions - job. That means you pushed one or more files that did not conform - to the formatting specified in .clang-format. That may be because - you neglected to run 'git clang-format' or 'clang-format' before - committing, or that your version of clang-format has an - incompatibility with the one on this - machine, which is: - SUGGESTION: | - - To fix it, you can do one of two things: - 1. Download and apply the patch generated as an artifact of this - job to your repo, commit, and push. - 2. Run 'git-clang-format --extensions cpp,h,hpp,ipp develop' - in your repo, commit, and push. - run: | - echo "${PREAMBLE}" - clang-format --version - echo "${SUGGESTION}" - exit 1 diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml deleted file mode 100644 index 01e04a3f5a..0000000000 --- a/.github/workflows/doxygen.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build and publish Doxygen documentation -# To test this workflow, push your changes to your fork's `develop` branch. -on: - push: - branches: - - develop - - doxygen -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - documentation: - runs-on: ubuntu-latest - permissions: - contents: write - container: ghcr.io/xrplf/rippled-build-ubuntu:aaf5e3e - steps: - - name: checkout - uses: actions/checkout@v4 - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - cmake --version - doxygen --version - env | sort - - name: build - run: | - mkdir build - cd build - cmake -Donly_docs=TRUE .. - cmake --build . --target docs --parallel $(nproc) - - name: publish - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: build/docs/html diff --git a/.github/workflows/levelization.yml b/.github/workflows/levelization.yml deleted file mode 100644 index 979049d630..0000000000 --- a/.github/workflows/levelization.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: levelization - -on: - push: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - -jobs: - check: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - runs-on: ubuntu-latest - env: - CLANG_VERSION: 10 - steps: - - uses: actions/checkout@v4 - - name: Check levelization - run: Builds/levelization/levelization.sh - - name: Check for differences - id: assert - run: | - set -o pipefail - git diff --exit-code | tee "levelization.patch" - - name: Upload patch - if: failure() && steps.assert.outcome == 'failure' - uses: actions/upload-artifact@v4 - continue-on-error: true - with: - name: levelization.patch - if-no-files-found: ignore - path: levelization.patch - - name: What happened? - if: failure() && steps.assert.outcome == 'failure' - env: - MESSAGE: | - If you are reading this, you are looking at a failed Github - Actions job. That means you changed the dependency relationships - between the modules in rippled. That may be an improvement or a - regression. This check doesn't judge. - - A rule of thumb, though, is that if your changes caused - something to be removed from loops.txt, that's probably an - improvement. If something was added, it's probably a regression. - - To fix it, you can do one of two things: - 1. Download and apply the patch generated as an artifact of this - job to your repo, commit, and push. - 2. Run './Builds/levelization/levelization.sh' in your repo, - commit, and push. - - See Builds/levelization/README.md for more info. - run: | - echo "${MESSAGE}" - exit 1 diff --git a/.github/workflows/libxrpl.yml b/.github/workflows/libxrpl.yml deleted file mode 100644 index 5880c03d71..0000000000 --- a/.github/workflows/libxrpl.yml +++ /dev/null @@ -1,91 +0,0 @@ -name: Check libXRPL compatibility with Clio -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_LOGIN_USERNAME_XRPLF: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_PASSWORD_XRPLF: ${{ secrets.CONAN_REMOTE_PASSWORD }} -on: - pull_request: - paths: - - "src/libxrpl/protocol/BuildInfo.cpp" - - ".github/workflows/libxrpl.yml" - types: [opened, reopened, synchronize, ready_for_review] -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - publish: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - name: Publish libXRPL - outputs: - outcome: ${{ steps.upload.outputs.outcome }} - version: ${{ steps.version.outputs.version }} - channel: ${{ steps.channel.outputs.channel }} - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/rippled-build-ubuntu:aaf5e3e - steps: - - name: Wait for essential checks to succeed - uses: lewagon/wait-on-check-action@v1.3.4 - with: - ref: ${{ github.event.pull_request.head.sha || github.sha }} - running-workflow-name: wait-for-check-regexp - check-regexp: "(dependencies|test).*linux.*" # Ignore windows and mac tests but make sure linux passes - repo-token: ${{ secrets.GITHUB_TOKEN }} - wait-interval: 10 - - name: Checkout - uses: actions/checkout@v4 - - name: Generate channel - id: channel - shell: bash - run: | - echo channel="clio/pr_${{ github.event.pull_request.number }}" | tee ${GITHUB_OUTPUT} - - name: Export new package - shell: bash - run: | - conan export . ${{ steps.channel.outputs.channel }} - - name: Add Conan remote - shell: bash - run: | - echo "Adding Conan remote 'xrplf' at ${{ env.CONAN_REMOTE_URL }}." - conan remote add xrplf ${{ env.CONAN_REMOTE_URL }} --insert 0 --force - echo "Listing Conan remotes." - conan remote list - - name: Parse new version - id: version - shell: bash - run: | - echo version="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" \ - | awk -F '"' '{print $2}')" | tee ${GITHUB_OUTPUT} - - name: Try to authenticate to Conan remote - id: remote - shell: bash - run: | - # `conan user` implicitly uses the environment variables CONAN_LOGIN_USERNAME_ and CONAN_PASSWORD_. - # https://docs.conan.io/1/reference/commands/misc/user.html#using-environment-variables - # https://docs.conan.io/1/reference/env_vars.html#conan-login-username-conan-login-username-remote-name - # https://docs.conan.io/1/reference/env_vars.html#conan-password-conan-password-remote-name - echo outcome=$(conan user --remote xrplf --password >&2 \ - && echo success || echo failure) | tee ${GITHUB_OUTPUT} - - name: Upload new package - id: upload - if: (steps.remote.outputs.outcome == 'success') - shell: bash - run: | - echo "conan upload version ${{ steps.version.outputs.version }} on channel ${{ steps.channel.outputs.channel }}" - echo outcome=$(conan upload xrpl/${{ steps.version.outputs.version }}@${{ steps.channel.outputs.channel }} --remote ripple --confirm >&2 \ - && echo success || echo failure) | tee ${GITHUB_OUTPUT} - notify_clio: - name: Notify Clio - runs-on: ubuntu-latest - needs: publish - env: - GH_TOKEN: ${{ secrets.CLIO_NOTIFY_TOKEN }} - steps: - - name: Notify Clio about new version - if: (needs.publish.outputs.outcome == 'success') - shell: bash - run: | - gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ - /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \ - -F "client_payload[version]=${{ needs.publish.outputs.version }}@${{ needs.publish.outputs.channel }}" \ - -F "client_payload[pr]=${{ github.event.pull_request.number }}" diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml deleted file mode 100644 index 73e25c357f..0000000000 --- a/.github/workflows/macos.yml +++ /dev/null @@ -1,112 +0,0 @@ -name: macos -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - push: - # If the branches list is ever changed, be sure to change it on all - # build/test jobs (nix, macos, windows, instrumentation) - branches: - # Always build the package branches - - develop - - release - - master - # Branches that opt-in to running - - "ci/**" -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -# This part of Conan configuration is specific to this workflow only; we do not want -# to pollute conan/profiles directory with settings which might not work for others -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} - # This part of the Conan configuration is specific to this workflow only; we - # do not want to pollute the 'conan/profiles' directory with settings that - # might not work for other workflows. - CONAN_GLOBAL_CONF: | - core.download:parallel={{os.cpu_count()}} - core.upload:parallel={{os.cpu_count()}} - tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} - tools.build:verbosity=verbose - tools.compilation:verbosity=verbose - -jobs: - test: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - strategy: - matrix: - platform: - - macos - generator: - - Ninja - configuration: - - Release - runs-on: [self-hosted, macOS, mac-runner-m1] - env: - # The `build` action requires these variables. - build_dir: .build - NUM_PROCESSORS: 12 - steps: - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: install Conan - run: | - brew install conan - - name: install Ninja - if: matrix.generator == 'Ninja' - run: brew install ninja - - name: install python - run: | - if which python > /dev/null 2>&1; then - echo "Python executable exists" - else - brew install python@3.13 - ln -s /opt/homebrew/bin/python3 /opt/homebrew/bin/python - fi - - name: install cmake - run: | - if which cmake > /dev/null 2>&1; then - echo "cmake executable exists" - else - brew install cmake - fi - - name: install nproc - run: | - brew install coreutils - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - python --version - conan --version - cmake --version - nproc --version - echo -n "nproc returns: " - nproc - system_profiler SPHardwareDataType - sysctl -n hw.logicalcpu - clang --version - - name: configure Conan - run: | - echo "${CONAN_GLOBAL_CONF}" > $(conan config home)/global.conf - conan config install conan/profiles/ -tf $(conan config home)/profiles/ - conan profile show - - name: build dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: ${{ matrix.generator }} - configuration: ${{ matrix.configuration }} - cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}" - - name: test - run: | - n=$(nproc) - echo "Using $n test jobs" - - cd ${build_dir} - ./rippled --unittest --unittest-jobs $n - ctest -j $n --output-on-failure diff --git a/.github/workflows/missing-commits.yml b/.github/workflows/missing-commits.yml deleted file mode 100644 index ed478a2327..0000000000 --- a/.github/workflows/missing-commits.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: missing-commits - -on: - push: - branches: - # Only check that the branches are up to date when updating the - # relevant branches. - - develop - - release - -jobs: - up_to_date: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Check for missing commits - id: commits - env: - SUGGESTION: | - - If you are reading this, then the commits indicated above are - missing from "develop" and/or "release". Do a reverse-merge - as soon as possible. See CONTRIBUTING.md for instructions. - run: | - set -o pipefail - # Branches ordered by how "canonical" they are. Every commit in - # one branch should be in all the branches behind it - order=( master release develop ) - branches=() - for branch in "${order[@]}" - do - # Check that the branches exist so that this job will work on - # forked repos, which don't necessarily have master and - # release branches. - if git ls-remote --exit-code --heads origin \ - refs/heads/${branch} > /dev/null - then - branches+=( origin/${branch} ) - fi - done - - prior=() - for branch in "${branches[@]}" - do - if [[ ${#prior[@]} -ne 0 ]] - then - echo "Checking ${prior[@]} for commits missing from ${branch}" - git log --oneline --no-merges "${prior[@]}" \ - ^$branch | tee -a "missing-commits.txt" - echo - fi - prior+=( "${branch}" ) - done - if [[ $( cat missing-commits.txt | wc -l ) -ne 0 ]] - then - echo "${SUGGESTION}" - exit 1 - fi diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml deleted file mode 100644 index 395bd72b8d..0000000000 --- a/.github/workflows/nix.yml +++ /dev/null @@ -1,422 +0,0 @@ -name: nix -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - push: - # If the branches list is ever changed, be sure to change it on all - # build/test jobs (nix, macos, windows) - branches: - # Always build the package branches - - develop - - release - - master - # Branches that opt-in to running - - "ci/**" -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} - # This part of the Conan configuration is specific to this workflow only; we - # do not want to pollute the 'conan/profiles' directory with settings that - # might not work for other workflows. - CONAN_GLOBAL_CONF: | - core.download:parallel={{ os.cpu_count() }} - core.upload:parallel={{ os.cpu_count() }} - tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} - tools.build:verbosity=verbose - tools.compilation:verbosity=verbose - -# This workflow has multiple job matrixes. -# They can be considered phases because most of the matrices ("test", -# "coverage", "conan", ) depend on the first ("dependencies"). -# -# The first phase has a job in the matrix for each combination of -# variables that affects dependency ABI: -# platform, compiler, and configuration. -# It creates a GitHub artifact holding the Conan profile, -# and builds and caches binaries for all the dependencies. -# If an Artifactory remote is configured, they are cached there. -# If not, they are added to the GitHub artifact. -# GitHub's "cache" action has a size limit (10 GB) that is too small -# to hold the binaries if they are built locally. -# We must use the "{upload,download}-artifact" actions instead. -# -# The remaining phases have a job in the matrix for each test -# configuration. They install dependency binaries from the cache, -# whichever was used, and build and test rippled. -# -# "instrumentation" is independent, but is included here because it also -# builds on linux in the same "on:" conditions. - -jobs: - dependencies: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - - clang - configuration: - - Debug - - Release - include: - - compiler: gcc - compiler_version: 12 - distro: ubuntu - codename: jammy - - compiler: clang - compiler_version: 16 - distro: debian - codename: bookworm - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/${{ matrix.distro }}-${{ matrix.codename }}:${{ matrix.compiler }}-${{ matrix.compiler_version }} - env: - build_dir: .build - steps: - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - lsb_release -a || true - ${{ matrix.compiler }}-${{ matrix.compiler_version }} --version - conan --version - cmake --version - env | sort - - name: configure Conan - run: | - echo "${CONAN_GLOBAL_CONF}" >> $(conan config home)/global.conf - conan config install conan/profiles/ -tf $(conan config home)/profiles/ - conan profile show - - name: archive profile - # Create this archive before dependencies are added to the local cache. - run: tar -czf conan.tar.gz -C ${CONAN_HOME} . - - name: build dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: upload archive - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - path: conan.tar.gz - if-no-files-found: error - - test: - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - - clang - configuration: - - Debug - - Release - include: - - compiler: gcc - compiler_version: 12 - distro: ubuntu - codename: jammy - - compiler: clang - compiler_version: 16 - distro: debian - codename: bookworm - cmake-args: - - - - "-Dunity=ON" - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/${{ matrix.distro }}-${{ matrix.codename }}:${{ matrix.compiler }}-${{ matrix.compiler_version }} - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: Ninja - configuration: ${{ matrix.configuration }} - cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}" - - name: check linking - run: | - cd ${build_dir} - ldd ./rippled - if [ "$(ldd ./rippled | grep -E '(libstdc\+\+|libgcc)' | wc -l)" -eq 0 ]; then - echo 'The binary is statically linked.' - else - echo 'The binary is dynamically linked.' - exit 1 - fi - - name: test - run: | - cd ${build_dir} - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure - - reference-fee-test: - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - configuration: - - Debug - cmake-args: - - "-DUNIT_TEST_REFERENCE_FEE=200" - - "-DUNIT_TEST_REFERENCE_FEE=1000" - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12 - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: Ninja - configuration: ${{ matrix.configuration }} - cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}" - - name: test - run: | - cd ${build_dir} - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure - - coverage: - strategy: - fail-fast: false - matrix: - platform: - - linux - compiler: - - gcc - configuration: - - Debug - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12 - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - gcovr --version - env | sort - ls ${CONAN_HOME} - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration }} - - name: build - uses: ./.github/actions/build - with: - generator: Ninja - configuration: ${{ matrix.configuration }} - cmake-args: >- - -Dassert=TRUE - -Dwerr=TRUE - -Dcoverage=ON - -Dcoverage_format=xml - -DCODE_COVERAGE_VERBOSE=ON - -DCMAKE_CXX_FLAGS="-O0" - -DCMAKE_C_FLAGS="-O0" - cmake-target: coverage - - name: move coverage report - shell: bash - run: | - mv "${build_dir}/coverage.xml" ./ - - name: archive coverage report - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - with: - name: coverage.xml - path: coverage.xml - retention-days: 30 - - name: upload coverage report - uses: wandalen/wretry.action@v1.4.10 - with: - action: codecov/codecov-action@v4.5.0 - with: | - files: coverage.xml - fail_ci_if_error: true - disable_search: true - verbose: true - plugin: noop - token: ${{ secrets.CODECOV_TOKEN }} - attempt_limit: 5 - attempt_delay: 210000 # in milliseconds - - conan: - needs: dependencies - runs-on: [self-hosted, heavy] - container: - image: ghcr.io/xrplf/ci/ubuntu-jammy:gcc-12 - env: - build_dir: .build - platform: linux - compiler: gcc - compiler_version: 12 - configuration: Release - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: ${{ env.platform }}-${{ env.compiler }}-${{ env.configuration }} - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - name: check environment - run: | - env | sort - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ env.configuration }} - - name: export - run: | - conan export . --version head - - name: build - run: | - cd tests/conan - mkdir ${build_dir} && cd ${build_dir} - conan install .. \ - --settings:all build_type=${configuration} \ - --output-folder . \ - --build missing - cmake .. \ - -DCMAKE_TOOLCHAIN_FILE:FILEPATH=./build/${configuration}/generators/conan_toolchain.cmake \ - -DCMAKE_BUILD_TYPE=${configuration} - cmake --build . - ./example | grep '^[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+' - - instrumentation-build: - needs: dependencies - runs-on: [self-hosted, heavy] - container: ghcr.io/xrplf/ci/debian-bookworm:clang-16 - env: - build_dir: .build - steps: - - name: download cache - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 - with: - name: linux-clang-Debug - - - name: extract cache - run: | - mkdir -p ${CONAN_HOME} - tar -xzf conan.tar.gz -C ${CONAN_HOME} - - - name: check environment - run: | - echo ${PATH} | tr ':' '\n' - conan --version - cmake --version - env | sort - ls ${CONAN_HOME} - - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - - name: dependencies - uses: ./.github/actions/dependencies - with: - configuration: Debug - - - name: prepare environment - run: | - mkdir -p ${build_dir} - echo "SOURCE_DIR=$(pwd)" >> $GITHUB_ENV - echo "BUILD_DIR=$(pwd)/${build_dir}" >> $GITHUB_ENV - - - name: build with instrumentation - run: | - cd ${BUILD_DIR} - cmake -S ${SOURCE_DIR} -B ${BUILD_DIR} \ - -Dvoidstar=ON \ - -Dtests=ON \ - -Dxrpld=ON \ - -DCMAKE_BUILD_TYPE=Debug \ - -DSECP256K1_BUILD_BENCHMARK=OFF \ - -DSECP256K1_BUILD_TESTS=OFF \ - -DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \ - -DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/build/generators/conan_toolchain.cmake - cmake --build . --parallel $(nproc) - - - name: verify instrumentation enabled - run: | - cd ${BUILD_DIR} - ./rippled --version | grep libvoidstar - - - name: run unit tests - run: | - cd ${BUILD_DIR} - ./rippled -u --unittest-jobs $(( $(nproc)/4 )) - ctest -j $(nproc) --output-on-failure diff --git a/.github/workflows/notify-clio.yml b/.github/workflows/notify-clio.yml new file mode 100644 index 0000000000..32ac01d61a --- /dev/null +++ b/.github/workflows/notify-clio.yml @@ -0,0 +1,80 @@ +# This workflow exports the built libxrpl package to the Conan remote on a +# a channel named after the pull request, and notifies the Clio repository about +# the new version so it can check for compatibility. +name: Notify Clio + +# This workflow can only be triggered by other workflows. +on: + workflow_call: + inputs: + conan_remote_name: + description: 'The name of the Conan remote to use.' + required: true + type: string + conan_remote_url: + description: 'The URL of the Conan endpoint to use.' + required: true + type: string + secrets: + clio_notify_token: + description: 'The GitHub token to notify Clio about new versions.' + required: true + conan_remote_username: + description: 'The username for logging into the Conan remote.' + required: true + conan_remote_password: + description: 'The password for logging into the Conan remote.' + required: true + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-clio + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + upload: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13 + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Generate outputs + id: generate + run: | + echo 'Generating channel.' + echo channel="clio/pr_${{ github.event.pull_request.number }}" | tee "${GITHUB_OUTPUT}" + echo 'Extracting version.' + echo version="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" | tee "${GITHUB_OUTPUT}" + - name: Add Conan remote + run: | + echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." + conan remote add --index 0 --force ${{ inputs.conan_remote_name }} ${{ inputs.conan_remote_url }} + echo 'Listing Conan remotes.' + conan remote list + - name: Log into Conan remote + run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}" + - name: Upload package + run: | + echo 'Exporting package to channel ${{ steps.generate.outputs.channel }}.' + conan export --channel=${{ steps.generate.outputs.channel }} . + echo 'Uploading package version ${{ steps.generate.outputs.version }} on channel ${{ steps.generate.outputs.channel }}.' + conan upload --confirm --check --remote=${{ inputs.conan_remote_name }} xrpl/${{ steps.generate.outputs.version }}@${{ steps.generate.outputs.channel }} + outputs: + channel: ${{ steps.generate.outputs.channel }} + version: ${{ steps.generate.outputs.version }} + + notify: + needs: upload + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.clio_notify_token }} + steps: + - name: Notify Clio + run: | + gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \ + -F "client_payload[version]=${{ needs.upload.outputs.version }}@${{ needs.upload.outputs.channel }}" \ + -F "client_payload[pr]=${{ github.event.pull_request.number }}" diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml new file mode 100644 index 0000000000..10bc61797a --- /dev/null +++ b/.github/workflows/on-pr.yml @@ -0,0 +1,133 @@ +# This workflow runs all workflows to check, build and test the project on +# various Linux flavors, as well as on MacOS and Windows, on every push to a +# user branch. However, it will not run if the pull request is a draft unless it +# has the 'DraftRunCI' label. +name: PR + +on: + pull_request: + paths: + - '.github/actions/build-deps/**' + - '.github/actions/build-test/**' + - '.github/scripts/levelization/**' + - '.github/scripts/strategy-matrix/**' + - '.github/workflows/build-test.yml' + - '.github/workflows/check-format.yml' + - '.github/workflows/check-levelization.yml' + - '.github/workflows/notify-clio.yml' + - '.github/workflows/on-pr.yml' + # Keep the list of paths below in sync with those in the `on-trigger.yml` + # file. + - 'cmake/**' + - 'conan/**' + - 'external/**' + - 'include/**' + - 'src/**' + - 'tests/**' + - '.clang-format' + - '.codecov.yml' + - '.pre-commit-config.yaml' + - 'CMakeLists.txt' + - 'conanfile.py' + types: + - opened + - synchronize + - labeled + - unlabeled + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + CONAN_REMOTE_NAME: xrplf + CONAN_REMOTE_URL: https://conan.ripplex.io + +jobs: + # This job determines whether the workflow should run. It runs when: + # * Opened as a non-draft PR. + # * A commit is added to a non-draft PR or the PR has the 'DraftRunCI' label. + # * A draft PR has the 'DraftRunCI' label added. + # * A non-draft PR has the 'DraftRunCI' label removed. + # These checks are in part to ensure the workflow won't run needlessly while + # also allowing it to be triggered without having to add a no-op commit. A new + # workflow execution can be triggered by adding and then removing the label on + # a non-draft PR, or conversely by removing it and then adding it back on a + # draft PR; this can be useful in certain cases. + should-run: + if: >- + ${{ + (github.event.action == 'opened' && !github.event.pull_request.draft) || + (github.event.action == 'synchronize' && (!github.event.pull_request.draft || contains(github.event.pull_request.labels.*.name, 'DraftRunCI'))) || + (github.event.action == 'labeled' && github.event.pull_request.draft && github.event.label.name == 'DraftRunCI') || + (github.event.action == 'unlabeled' && !github.event.pull_request.draft && github.event.label.name == 'DraftRunCI') + }} + runs-on: ubuntu-latest + steps: + - name: No-op + run: echo '' + + check-clang-format: + needs: should-run + uses: ./.github/workflows/check-format.yml + + check-levelization: + needs: should-run + uses: ./.github/workflows/check-levelization.yml + + # This job works around the limitation that GitHub Actions does not support + # using environment variables as inputs for reusable workflows. + generate-outputs: + needs: should-run + runs-on: ubuntu-latest + steps: + - name: No-op + run: echo '' + outputs: + conan_remote_name: ${{ env.CONAN_REMOTE_NAME }} + conan_remote_url: ${{ env.CONAN_REMOTE_URL }} + + build-linux: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + os: 'linux' + secrets: + codecov_token: ${{ secrets.CODECOV_TOKEN }} + + build-macos: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + os: 'macos' + + build-windows: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + os: 'windows' + + notify-clio: + needs: + - generate-outputs + - build-linux + - build-macos + - build-windows + uses: ./.github/workflows/notify-clio.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + secrets: + clio_notify_token: ${{ secrets.CLIO_NOTIFY_TOKEN }} + conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} + conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml new file mode 100644 index 0000000000..a6dded7fd8 --- /dev/null +++ b/.github/workflows/on-trigger.yml @@ -0,0 +1,140 @@ +# This workflow runs all workflows to build the dependencies required for the +# project on various Linux flavors, as well as on MacOS and Windows, on a +# scheduled basis, on merge into the 'develop', 'release', or 'master' branches, +# or manually. The missing commits check is only run when the code is merged +# into the 'develop' or 'release' branches, and the documentation is built when +# the code is merged into the 'develop' branch. +name: Trigger + +on: + push: + branches: + - develop + - release + - master + paths: + - '.github/actions/build-deps/**' + - '.github/actions/build-test/**' + - '.github/scripts/strategy-matrix/**' + - '.github/workflows/build-test.yml' + - '.github/workflows/check-missing-commits.yml' + - '.github/workflows/on-trigger.yml' + - '.github/workflows/publish-docs.yml' + # Keep the list of paths below in sync with those in `on-pr.yml`. + - 'cmake/**' + - 'conan/**' + - 'external/**' + - 'include/**' + - 'src/**' + - 'tests/**' + - '.clang-format' + - '.codecov.yml' + - '.pre-commit-config.yaml' + - 'CMakeLists.txt' + - 'conanfile.py' + # Run at 06:32 UTC on every day of the week from Monday through Friday. This + # will force all dependencies to be rebuilt, which is useful to verify that + # all dependencies can be built successfully. Only the dependencies that + # are actually missing from the remote will be uploaded. + schedule: + - cron: '32 6 * * 1-5' + # Run when manually triggered via the GitHub UI or API. If `force_upload` is + # true, then the dependencies that were missing (`force_rebuild` is false) or + # rebuilt (`force_rebuild` is true) will be uploaded, overwriting existing + # dependencies if needed. + workflow_dispatch: + inputs: + dependencies_force_build: + description: 'Force building of all dependencies.' + required: false + type: boolean + default: false + dependencies_force_upload: + description: 'Force uploading of all dependencies.' + required: false + type: boolean + default: false + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + CONAN_REMOTE_NAME: xrplf + CONAN_REMOTE_URL: https://conan.ripplex.io + +jobs: + check-missing-commits: + if: ${{ github.event_name == 'push' && github.ref_type == 'branch' && contains(fromJSON('["develop", "release"]'), github.ref_name) }} + uses: ./.github/workflows/check-missing-commits.yml + + # This job works around the limitation that GitHub Actions does not support + # using environment variables as inputs for reusable workflows. It also sets + # outputs that depend on the event that triggered the workflow. + generate-outputs: + runs-on: ubuntu-latest + steps: + - name: Check inputs and set outputs + id: generate + run: | + if [[ "${{ github.event_name }}" == 'push' ]]; then + echo 'dependencies_force_build=false' | tee "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=false' | tee "${GITHUB_OUTPUT}" + elif [[ "${{ github.event_name }}" == 'schedule' ]]; then + echo 'dependencies_force_build=true' | tee "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=false' | tee "${GITHUB_OUTPUT}" + else + echo 'dependencies_force_build=${{ inputs.dependencies_force_build }}' | tee "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=${{ inputs.dependencies_force_upload }}' | tee "${GITHUB_OUTPUT}" + fi + outputs: + conan_remote_name: ${{ env.CONAN_REMOTE_NAME }} + conan_remote_url: ${{ env.CONAN_REMOTE_URL }} + dependencies_force_build: ${{ steps.generate.outputs.dependencies_force_build }} + dependencies_force_upload: ${{ steps.generate.outputs.dependencies_force_upload }} + + build-linux: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + dependencies_force_build: ${{ needs.generate-outputs.outputs.dependencies_force_build }} + dependencies_force_upload: ${{ needs.generate-outputs.outputs.dependencies_force_upload }} + os: 'linux' + strategy_matrix_all: true + secrets: + conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} + conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} + + build-macos: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + dependencies_force_build: ${{ needs.generate-outputs.outputs.dependencies_force_build }} + dependencies_force_upload: ${{ needs.generate-outputs.outputs.dependencies_force_upload }} + os: 'macos' + strategy_matrix_all: true + secrets: + conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} + conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} + + build-windows: + needs: generate-outputs + uses: ./.github/workflows/build-test.yml + with: + conan_remote_name: ${{ needs.generate-outputs.outputs.conan_remote_name }} + conan_remote_url: ${{ needs.generate-outputs.outputs.conan_remote_url }} + dependencies_force_build: ${{ needs.generate-outputs.outputs.dependencies_force_build }} + dependencies_force_upload: ${{ needs.generate-outputs.outputs.dependencies_force_upload }} + os: 'windows' + strategy_matrix_all: true + secrets: + conan_remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} + conan_remote_password: ${{ secrets.CONAN_REMOTE_PASSWORD }} diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 0000000000..a2c24bd076 --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,58 @@ +# This workflow builds the documentation for the repository, and publishes it to +# GitHub Pages when changes are merged into the default branch. +name: Build and publish documentation + +on: + push: + paths: + - '.github/workflows/publish-docs.yml' + - '*.md' + - '**/*.md' + - 'docs/**' + - 'include/**' + - 'src/libxrpl/**' + - 'src/xrpld/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +env: + BUILD_DIR: .build + +jobs: + publish: + runs-on: ubuntu-latest + container: ghcr.io/xrplf/ci/tools-rippled-documentation + steps: + - name: Checkout repository + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Check configuration + run: | + echo 'Checking path.' + echo ${PATH} | tr ':' '\n' + + echo 'Checking environment variables.' + env | sort + + echo 'Checking CMake version.' + cmake --version + + echo 'Checking Doxygen version.' + doxygen --version + - name: Build documentation + run: | + mkdir -p ${{ env.BUILD_DIR }} + cd ${{ env.BUILD_DIR }} + cmake -Donly_docs=ON .. + cmake --build . --target docs --parallel $(nproc) + - name: Publish documentation + if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }} + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ${{ env.BUILD_DIR }}/docs/html diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index b81ffc8d3a..0000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,106 +0,0 @@ -name: windows - -on: - pull_request: - types: [opened, reopened, synchronize, ready_for_review] - push: - # If the branches list is ever changed, be sure to change it on all - # build/test jobs (nix, macos, windows, instrumentation) - branches: - # Always build the package branches - - develop - - release - - master - # Branches that opt-in to running - - "ci/**" - -# https://docs.github.com/en/actions/using-jobs/using-concurrency -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -env: - CONAN_REMOTE_URL: https://conan.ripplex.io - CONAN_REMOTE_USERNAME: ${{ secrets.CONAN_REMOTE_USERNAME }} - CONAN_REMOTE_PASSWORD: ${{ secrets.CONAN_REMOTE_PASSWORD }} - # This part of the Conan configuration is specific to this workflow only; we - # do not want to pollute the 'conan/profiles' directory with settings that - # might not work for other workflows. - CONAN_GLOBAL_CONF: | - core.download:parallel={{os.cpu_count()}} - core.upload:parallel={{os.cpu_count()}} - tools.build:jobs=24 - tools.build:verbosity=verbose - tools.compilation:verbosity=verbose - -jobs: - test: - if: ${{ github.event_name == 'push' || github.event.pull_request.draft != true || contains(github.event.pull_request.labels.*.name, 'DraftRunCI') }} - strategy: - fail-fast: false - matrix: - version: - - generator: Visual Studio 17 2022 - runs-on: windows-2022 - configuration: - - type: Release - tests: true - - type: Debug - # Skip running unit tests on debug builds, because they - # take an unreasonable amount of time - tests: false - runtime: d - runs-on: ${{ matrix.version.runs-on }} - env: - build_dir: .build - steps: - - name: checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - - name: choose Python - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 - with: - python-version: 3.13 - - name: learn Python cache directory - id: pip-cache - shell: bash - run: | - python -m pip install --upgrade pip - echo "dir=$(pip cache dir)" | tee ${GITHUB_OUTPUT} - - name: restore Python cache directory - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: ${{ runner.os }}-${{ hashFiles('.github/workflows/windows.yml') }} - - name: install Conan - run: pip install wheel conan - - name: check environment - run: | - dir env: - $env:PATH -split ';' - python --version - conan --version - cmake --version - - name: configure Conan - shell: bash - run: | - echo "${CONAN_GLOBAL_CONF}" > $(conan config home)/global.conf - conan config install conan/profiles/ -tf $(conan config home)/profiles/ - conan profile show - - name: build dependencies - uses: ./.github/actions/dependencies - with: - configuration: ${{ matrix.configuration.type }} - - name: build - uses: ./.github/actions/build - with: - generator: "${{ matrix.version.generator }}" - configuration: ${{ matrix.configuration.type }} - # Hard code for now. Move to the matrix if varied options are needed - cmake-args: "-Dassert=TRUE -Dwerr=TRUE -Dreporting=OFF -Dunity=ON" - cmake-target: install - - name: test - shell: bash - if: ${{ matrix.configuration.tests }} - run: | - cd ${build_dir}/${{ matrix.configuration.type }} - ./rippled --unittest --unittest-jobs $(nproc) - ctest -j $(nproc) --output-on-failure diff --git a/.gitignore b/.gitignore index e5952e0de1..ab54adba74 100644 --- a/.gitignore +++ b/.gitignore @@ -37,10 +37,9 @@ Release/*.* *.gcov # Levelization checking -Builds/levelization/results/rawincludes.txt -Builds/levelization/results/paths.txt -Builds/levelization/results/includes/ -Builds/levelization/results/includedby/ +.github/scripts/levelization/results/* +!.github/scripts/levelization/results/loops.txt +!.github/scripts/levelization/results/ordering.txt # Ignore tmp directory. tmp diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..477120ade1 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +external +.* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b0ae72ae54..a5e0933d00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ If you create new source files, they must be organized as follows: The source must be formatted according to the style guide below. -Header includes must be [levelized](./Builds/levelization). +Header includes must be [levelized](.github/scripts/levelization). Changes should be usually squashed down into a single commit. Some larger or more complicated change sets make more sense, diff --git a/README.md b/README.md index 4fdb89dffa..fe7daa38bc 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ If you are interested in running an **API Server** (including a **Full History S Here are some good places to start learning the source code: - Read the markdown files in the source tree: `src/ripple/**/*.md`. -- Read [the levelization document](./Builds/levelization) to get an idea of the internal dependency graph. +- Read [the levelization document](.github/scripts/levelization) to get an idea of the internal dependency graph. - In the big picture, the `main` function constructs an `ApplicationImp` object, which implements the `Application` virtual interface. Almost every component in the application takes an `Application&` parameter in its constructor, typically named `app` and stored as a member variable `app_`. This allows most components to depend on any other component. ### Repository Contents diff --git a/conan/global.conf b/conan/global.conf new file mode 100644 index 0000000000..ae03818232 --- /dev/null +++ b/conan/global.conf @@ -0,0 +1,9 @@ +# Global configuration for Conan. This is used to set the number of parallel +# downloads, uploads, and build jobs. The verbosity is set to verbose to +# provide more information during the build process. +core:non_interactive=True +core.download:parallel={{ os.cpu_count() }} +core.upload:parallel={{ os.cpu_count() }} +tools.build:jobs={{ (os.cpu_count() * 4/5) | int }} +tools.build:verbosity=verbose +tools.compilation:verbosity=verbose diff --git a/external/README.md b/external/README.md index 99ce2c337e..7de1fd25a0 100644 --- a/external/README.md +++ b/external/README.md @@ -1,7 +1,6 @@ # External Conan recipes -The subdirectories in this directory contain copies of external libraries used -by rippled. +The subdirectories in this directory contain external libraries used by rippled. | Folder | Upstream | Description | | :--------------- | :------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | From b04d239926f265f2c7b5e1fd4a86b76d2479f322 Mon Sep 17 00:00:00 2001 From: Bart Date: Mon, 18 Aug 2025 10:49:55 -0400 Subject: [PATCH 16/16] fix: Modify jobs to use '>>' instead of 'tee' for GITHUB_OUTPUT (#5699) --- .github/workflows/build-test.yml | 2 +- .github/workflows/notify-clio.yml | 4 ++-- .github/workflows/on-trigger.yml | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index f3b3374090..3fb8f057a2 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -70,7 +70,7 @@ jobs: - name: Generate strategy matrix working-directory: .github/scripts/strategy-matrix id: generate - run: python generate.py ${{ inputs.strategy_matrix_all && '--all' || '' }} --config=${{ inputs.os }}.json | tee "${GITHUB_OUTPUT}" + run: python generate.py ${{ inputs.strategy_matrix_all && '--all' || '' }} --config=${{ inputs.os }}.json >> "${GITHUB_OUTPUT}" outputs: matrix: ${{ steps.generate.outputs.matrix }} diff --git a/.github/workflows/notify-clio.yml b/.github/workflows/notify-clio.yml index 32ac01d61a..ae95d04db0 100644 --- a/.github/workflows/notify-clio.yml +++ b/.github/workflows/notify-clio.yml @@ -45,9 +45,9 @@ jobs: id: generate run: | echo 'Generating channel.' - echo channel="clio/pr_${{ github.event.pull_request.number }}" | tee "${GITHUB_OUTPUT}" + echo channel="clio/pr_${{ github.event.pull_request.number }}" >> "${GITHUB_OUTPUT}" echo 'Extracting version.' - echo version="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" | tee "${GITHUB_OUTPUT}" + echo version="$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}" - name: Add Conan remote run: | echo "Adding Conan remote '${{ inputs.conan_remote_name }}' at ${{ inputs.conan_remote_url }}." diff --git a/.github/workflows/on-trigger.yml b/.github/workflows/on-trigger.yml index a6dded7fd8..004e44c1fb 100644 --- a/.github/workflows/on-trigger.yml +++ b/.github/workflows/on-trigger.yml @@ -82,14 +82,14 @@ jobs: id: generate run: | if [[ "${{ github.event_name }}" == 'push' ]]; then - echo 'dependencies_force_build=false' | tee "${GITHUB_OUTPUT}" - echo 'dependencies_force_upload=false' | tee "${GITHUB_OUTPUT}" + echo 'dependencies_force_build=false' >> "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=false' >> "${GITHUB_OUTPUT}" elif [[ "${{ github.event_name }}" == 'schedule' ]]; then - echo 'dependencies_force_build=true' | tee "${GITHUB_OUTPUT}" - echo 'dependencies_force_upload=false' | tee "${GITHUB_OUTPUT}" + echo 'dependencies_force_build=true' >> "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=false' >> "${GITHUB_OUTPUT}" else - echo 'dependencies_force_build=${{ inputs.dependencies_force_build }}' | tee "${GITHUB_OUTPUT}" - echo 'dependencies_force_upload=${{ inputs.dependencies_force_upload }}' | tee "${GITHUB_OUTPUT}" + echo 'dependencies_force_build=${{ inputs.dependencies_force_build }}' >> "${GITHUB_OUTPUT}" + echo 'dependencies_force_upload=${{ inputs.dependencies_force_upload }}' >> "${GITHUB_OUTPUT}" fi outputs: conan_remote_name: ${{ env.CONAN_REMOTE_NAME }}