diff options
author | Alexander Blair <snipa@jagtech.io> | 2020-08-27 12:03:18 -0700 |
---|---|---|
committer | Alexander Blair <snipa@jagtech.io> | 2020-08-27 12:03:24 -0700 |
commit | 39a087406d20e2d2df6e9b66037a1271daef0592 (patch) | |
tree | f988a1e1a85cfc2f5db3412315619b61d7746a15 /src/device | |
parent | Merge pull request #6771 (diff) | |
parent | draft support of clsag (diff) | |
download | monero-39a087406d20e2d2df6e9b66037a1271daef0592.tar.xz |
Merge pull request #6739
1660fe8a2 draft support of clsag (cslashm)
703944c4d CLSAG device support (Sarang Noether)
aff87b5f6 Added balance check to MLSAG/CLSAG performance tests (Sarang Noether)
f964a92c5 Updated MLSAG and CLSAG tests for consistency (Sarang Noether)
5aa1575e9 CLSAG verification performance test (Sarang Noether)
641b08c92 CLSAG optimizations (Sarang Noether)
82ee01699 Integrate CLSAGs into monero (moneromooo-monero)
8cd1d6df8 unit_tests: add ge_triple_scalarmult_base_vartime test (moneromooo-monero)
4b328c661 CLSAG signatures (Sarang Noether)
Diffstat (limited to '')
-rw-r--r-- | src/device/device.hpp | 4 | ||||
-rw-r--r-- | src/device/device_default.cpp | 23 | ||||
-rw-r--r-- | src/device/device_default.hpp | 4 | ||||
-rw-r--r-- | src/device/device_ledger.cpp | 158 | ||||
-rw-r--r-- | src/device/device_ledger.hpp | 5 | ||||
-rw-r--r-- | src/device_trezor/trezor/protocol.hpp | 2 |
6 files changed, 192 insertions, 4 deletions
diff --git a/src/device/device.hpp b/src/device/device.hpp index ef973c9f4..582eb2242 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -231,6 +231,10 @@ namespace hw { virtual bool mlsag_hash(const rct::keyV &long_message, rct::key &c) = 0; virtual bool mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) = 0; + virtual bool clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) = 0; + virtual bool clsag_hash(const rct::keyV &data, rct::key &hash) = 0; + virtual bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) = 0; + virtual bool close_tx(void) = 0; virtual bool has_ki_cold_sync(void) const { return false; } diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index 096cb35ba..145197212 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -402,6 +402,29 @@ namespace hw { return true; } + bool device_default::clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) { + rct::skpkGen(a,aG); // aG = a*G + rct::scalarmultKey(aH,H,a); // aH = a*H + rct::scalarmultKey(I,H,p); // I = p*H + rct::scalarmultKey(D,H,z); // D = z*H + return true; + } + + bool device_default::clsag_hash(const rct::keyV &data, rct::key &hash) { + hash = rct::hash_to_scalar(data); + return true; + } + + bool device_default::clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) { + rct::key s0_p_mu_P; + sc_mul(s0_p_mu_P.bytes,mu_P.bytes,p.bytes); + rct::key s0_add_z_mu_C; + sc_muladd(s0_add_z_mu_C.bytes,mu_C.bytes,z.bytes,s0_p_mu_P.bytes); + sc_mulsub(s.bytes,c.bytes,s0_add_z_mu_C.bytes,a.bytes); + + return true; + } + bool device_default::close_tx() { return true; } diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index bdd99f89c..2493bd67d 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -134,6 +134,10 @@ namespace hw { bool mlsag_hash(const rct::keyV &long_message, rct::key &c) override; bool mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) override; + bool clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) override; + bool clsag_hash(const rct::keyV &data, rct::key &hash) override; + bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) override; + bool close_tx(void) override; }; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 30964848d..4e89f835d 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -299,6 +299,7 @@ namespace hw { #define INS_PREFIX_HASH 0x7D #define INS_VALIDATE 0x7C #define INS_MLSAG 0x7E + #define INS_CLSAG 0x7F #define INS_CLOSE_TX 0x80 #define INS_GET_TX_PROOF 0xA0 @@ -1857,7 +1858,7 @@ namespace hw { // ====== Aout, Bout, AKout, C, v, k ====== kv_offset = data_offset; - if (type==rct::RCTTypeBulletproof2) { + if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG) { C_offset = kv_offset+ (8)*outputs_size; } else { C_offset = kv_offset+ (32+32)*outputs_size; @@ -1874,7 +1875,7 @@ namespace hw { offset = set_command_header(INS_VALIDATE, 0x02, i+1); //options this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ; - this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2)?0x02:0x00; + this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG)?0x02:0x00; offset += 1; //is_subaddress this->buffer_send[offset] = outKeys.is_subaddress; @@ -1895,7 +1896,7 @@ namespace hw { memmove(this->buffer_send+offset, data+C_offset,32); offset += 32; C_offset += 32; - if (type==rct::RCTTypeBulletproof2) { + if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG) { //k memset(this->buffer_send+offset, 0, 32); offset += 32; @@ -2121,6 +2122,157 @@ namespace hw { return true; } + bool device_ledger::clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) { + AUTO_LOCK_CMD(); + #ifdef DEBUG_HWDEVICE + const rct::key p_x = hw::ledger::decrypt(p); + const rct::key z_x = hw::ledger::decrypt(z); + rct::key I_x; + rct::key D_x; + const rct::key H_x = H; + rct::key a_x; + rct::key aG_x; + rct::key aH_x; + this->controle_device->clsag_prepare(p_x, z_x, I_x, D_x, H_x, a_x, aG_x, aH_x); + #endif + + /* + rct::skpkGen(a,aG); // aG = a*G + rct::scalarmultKey(aH,H,a); // aH = a*H + rct::scalarmultKey(I,H,p); // I = p*H + rct::scalarmultKey(D,H,z); // D = z*H + */ + int offset = set_command_header_noopt(INS_CLSAG, 0x01); + //p + this->send_secret(p.bytes, offset); + //z + this->send_secret(z.bytes, offset); + //H + memmove(this->buffer_send+offset, H.bytes, 32); + offset += 32; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + + offset = 0; + //a + this->receive_secret(a.bytes, offset); + //aG + memmove(aG.bytes, this->buffer_recv+offset, 32); + offset +=32; + //aH + memmove(aH.bytes, this->buffer_recv+offset, 32); + offset +=32; + //I = pH + memmove(I.bytes, this->buffer_recv+offset, 32); + offset +=32; + //D = zH + memmove(D.bytes, this->buffer_recv+offset, 32); + offset +=32; + + #ifdef DEBUG_HWDEVICE + hw::ledger::check32("clsag_prepare", "I", (char*)I_x.bytes, (char*)I.bytes); + hw::ledger::check32("clsag_prepare", "D", (char*)D_x.bytes, (char*)D.bytes); + hw::ledger::check32("clsag_prepare", "a", (char*)a_x.bytes, (char*)a.bytes); + hw::ledger::check32("clsag_prepare", "aG", (char*)aG_x.bytes, (char*)aG.bytes); + hw::ledger::check32("clsag_prepare", "aH", (char*)aH_x.bytes, (char*)aH.bytes); + #endif + + return true; + } + + bool device_ledger::clsag_hash(const rct::keyV &data, rct::key &hash) { + AUTO_LOCK_CMD(); + + #ifdef DEBUG_HWDEVICE + const rct::keyV data_x = data; + rct::key hash_x; + this->controle_device->mlsag_hash(data_x, hash_x); + #endif + + size_t cnt; + int offset; + + cnt = data.size(); + for (size_t i = 0; i<cnt; i++) { + offset = set_command_header(INS_CLSAG, 0x02, i+1); + //options + this->buffer_send[offset] = (i==(cnt-1))?0x00:0x80; //last + offset += 1; + //msg part + memmove(this->buffer_send+offset, data[i].bytes, 32); + offset += 32; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + } + + //c/hash + memmove(hash.bytes, &this->buffer_recv[0], 32); + + #ifdef DEBUG_HWDEVICE + hw::ledger::check32("mlsag_hash", "hash", (char*)hash_x.bytes, (char*)hash.bytes); + #endif + return true; + } + + bool device_ledger::clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) { + AUTO_LOCK_CMD(); + + #ifdef DEBUG_HWDEVICE + const rct::key c_x = c; + const rct::key a_x = hw::ledger::decrypt(a); + const rct::key p_x = hw::ledger::decrypt(p); + const rct::key z_x = hw::ledger::decrypt(z); + const rct::key mu_P_x = mu_P; + const rct::key mu_C_x = mu_C; + rct::key s_x; + this->controle_device->clsag_sign(c_x, a_x, p_x, z_x, mu_P_x, mu_C_x, s_x); + #endif + + /* + rct::key s0_p_mu_P; + sc_mul(s0_p_mu_P.bytes,mu_P.bytes,p.bytes); + rct::key s0_add_z_mu_C; + sc_muladd(s0_add_z_mu_C.bytes,mu_C.bytes,z.bytes,s0_p_mu_P.bytes); + sc_mulsub(s.bytes,c.bytes,s0_add_z_mu_C.bytes,a.bytes); + */ + + int offset = set_command_header_noopt(INS_CLSAG, 0x03); + + //c + //discard, unse internal one + //a + this->send_secret(a.bytes, offset); + //p + this->send_secret(p.bytes, offset); + //z + this->send_secret(z.bytes, offset); + //mu_P + memmove(this->buffer_send+offset, mu_P.bytes, 32); + offset += 32; + //mu_C + memmove(this->buffer_send+offset, mu_C.bytes, 32); + offset += 32; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + + offset = 0; + //s + memmove(s.bytes, this->buffer_recv+offset, 32); + + #ifdef DEBUG_HWDEVICE + hw::ledger::check32("clsag_sign", "s", (char*)s_x.bytes, (char*)s.bytes); + #endif + + return true; + } + + bool device_ledger::close_tx() { AUTO_LOCK_CMD(); send_simple(INS_CLOSE_TX); diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 4036035c8..d3ec08288 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -297,6 +297,11 @@ namespace hw { bool mlsag_hash(const rct::keyV &long_message, rct::key &c) override; bool mlsag_sign( const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) override; + bool clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) override; + bool clsag_hash(const rct::keyV &data, rct::key &hash) override; + bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) override; + + bool close_tx(void) override; }; diff --git a/src/device_trezor/trezor/protocol.hpp b/src/device_trezor/trezor/protocol.hpp index 35e7d9605..fa824ec3b 100644 --- a/src/device_trezor/trezor/protocol.hpp +++ b/src/device_trezor/trezor/protocol.hpp @@ -309,7 +309,7 @@ namespace tx { throw std::invalid_argument("RV not initialized"); } auto tp = m_ct.rv->type; - return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2; + return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2 || tp == rct::RCTTypeCLSAG; } bool is_offloading() const { |